aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.merlin2
-rw-r--r--.travis.yml11
-rw-r--r--CHANGES12
-rw-r--r--META.coq27
-rw-r--r--Makefile.build4
-rw-r--r--Makefile.ci2
-rw-r--r--Makefile.common5
-rw-r--r--Makefile.doc2
-rw-r--r--checker/reduction.ml6
-rw-r--r--configure.ml9
-rw-r--r--dev/ci/ci-basic-overlay.sh11
-rw-r--r--dev/ci/ci-common.sh8
-rwxr-xr-xdev/ci/ci-iris-coq.sh14
-rwxr-xr-xdev/ci/ci-vst.sh13
-rw-r--r--dev/core.dbg1
-rw-r--r--dev/doc/changes.txt69
-rw-r--r--dev/doc/proof-engine.md134
-rw-r--r--dev/top_printers.ml2
-rw-r--r--doc/refman/Polynom.tex8
-rw-r--r--doc/refman/RefMan-com.tex6
-rw-r--r--doc/refman/RefMan-decl.tex823
-rw-r--r--doc/refman/RefMan-ext.tex2
-rw-r--r--doc/refman/RefMan-syn.tex2
-rw-r--r--doc/refman/Reference-Manual.tex1
-rw-r--r--engine/evd.ml4
-rw-r--r--engine/evd.mli4
-rw-r--r--engine/universes.ml7
-rw-r--r--grammar/tacextend.mlp24
-rw-r--r--ide/coq.ml56
-rw-r--r--ide/coq.mli13
-rw-r--r--ide/coqOps.ml84
-rw-r--r--ide/coqide.ml22
-rw-r--r--ide/coqidetop.mllib2
-rw-r--r--ide/ide.mllib5
-rw-r--r--ide/ide_slave.ml137
-rw-r--r--ide/ideutils.ml33
-rw-r--r--ide/ideutils.mli4
-rw-r--r--ide/interface.mli25
-rw-r--r--ide/minilib.ml6
-rw-r--r--ide/minilib.mli3
-rw-r--r--ide/richpp.ml (renamed from lib/richpp.ml)60
-rw-r--r--ide/richpp.mli (renamed from lib/richpp.mli)31
-rw-r--r--ide/richprinter.ml23
-rw-r--r--ide/richprinter.mli36
-rw-r--r--ide/texmacspp.ml13
-rw-r--r--ide/wg_Command.ml11
-rw-r--r--ide/wg_MessageView.ml74
-rw-r--r--ide/wg_MessageView.mli5
-rw-r--r--ide/wg_ProofView.ml47
-rw-r--r--ide/wg_ProofView.mli3
-rw-r--r--ide/xmlprotocol.ml98
-rw-r--r--ide/xmlprotocol.mli19
-rw-r--r--interp/constrexpr_ops.ml66
-rw-r--r--interp/constrexpr_ops.mli26
-rw-r--r--interp/constrextern.ml43
-rw-r--r--interp/constrextern.mli2
-rw-r--r--interp/constrintern.ml136
-rw-r--r--interp/constrintern.mli10
-rw-r--r--interp/dumpglob.ml17
-rw-r--r--interp/implicit_quantifiers.ml20
-rw-r--r--interp/implicit_quantifiers.mli2
-rw-r--r--interp/notation_ops.ml109
-rw-r--r--interp/notation_ops.mli5
-rw-r--r--interp/smartlocate.ml2
-rw-r--r--interp/topconstr.ml36
-rw-r--r--interp/topconstr.mli2
-rw-r--r--intf/constrexpr.mli16
-rw-r--r--intf/glob_term.mli7
-rw-r--r--intf/notation_term.mli2
-rw-r--r--intf/pattern.mli2
-rw-r--r--intf/vernacexpr.mli35
-rw-r--r--kernel/cClosure.ml11
-rw-r--r--kernel/cemitcodes.ml78
-rw-r--r--kernel/cooking.ml8
-rw-r--r--kernel/cooking.mli2
-rw-r--r--kernel/entries.mli2
-rw-r--r--kernel/names.ml9
-rw-r--r--kernel/names.mli1
-rw-r--r--kernel/nativevalues.ml8
-rw-r--r--kernel/opaqueproof.ml53
-rw-r--r--kernel/opaqueproof.mli5
-rw-r--r--kernel/reduction.ml13
-rw-r--r--kernel/safe_typing.ml14
-rw-r--r--kernel/safe_typing.mli9
-rw-r--r--kernel/term_typing.ml143
-rw-r--r--kernel/term_typing.mli12
-rw-r--r--lib/cErrors.ml27
-rw-r--r--lib/cErrors.mli5
-rw-r--r--lib/cThread.ml18
-rw-r--r--lib/cThread.mli4
-rw-r--r--lib/cUnix.ml8
-rw-r--r--lib/cUnix.mli2
-rw-r--r--lib/clib.mllib3
-rw-r--r--lib/feedback.ml184
-rw-r--r--lib/feedback.mli41
-rw-r--r--lib/future.ml18
-rw-r--r--lib/future.mli15
-rw-r--r--lib/pp.ml265
-rw-r--r--lib/pp.mli116
-rw-r--r--lib/pp_control.ml93
-rw-r--r--lib/ppstyle.ml73
-rw-r--r--lib/ppstyle.mli63
-rw-r--r--lib/util.ml8
-rw-r--r--library/lib.ml84
-rw-r--r--library/libobject.ml12
-rw-r--r--library/nameops.ml20
-rw-r--r--library/summary.ml6
-rw-r--r--parsing/cLexer.ml420
-rw-r--r--parsing/egramcoq.ml8
-rw-r--r--parsing/g_constr.ml449
-rw-r--r--parsing/g_prim.ml45
-rw-r--r--parsing/g_vernac.ml414
-rw-r--r--parsing/pcoq.ml1
-rw-r--r--parsing/pcoq.mli11
-rw-r--r--plugins/decl_mode/decl_expr.mli102
-rw-r--r--plugins/decl_mode/decl_interp.ml474
-rw-r--r--plugins/decl_mode/decl_mode.ml136
-rw-r--r--plugins/decl_mode/decl_mode.mli79
-rw-r--r--plugins/decl_mode/decl_mode_plugin.mlpack5
-rw-r--r--plugins/decl_mode/decl_proof_instr.ml1554
-rw-r--r--plugins/decl_mode/decl_proof_instr.mli108
-rw-r--r--plugins/decl_mode/g_decl_mode.ml4387
-rw-r--r--plugins/decl_mode/ppdecl_proof.ml216
-rw-r--r--plugins/decl_mode/ppdecl_proof.mli14
-rw-r--r--plugins/extraction/common.ml9
-rw-r--r--plugins/extraction/extract_env.ml9
-rw-r--r--plugins/extraction/ocaml.ml8
-rw-r--r--plugins/extraction/scheme.ml6
-rw-r--r--plugins/extraction/table.ml4
-rw-r--r--plugins/firstorder/g_ground.ml418
-rw-r--r--plugins/fourier/Fourier.v2
-rw-r--r--plugins/funind/functional_principles_proofs.ml3
-rw-r--r--plugins/funind/glob_term_to_relation.ml75
-rw-r--r--plugins/funind/glob_term_to_relation.mli2
-rw-r--r--plugins/funind/glob_termops.ml60
-rw-r--r--plugins/funind/glob_termops.mli2
-rw-r--r--plugins/funind/indfun.ml46
-rw-r--r--plugins/funind/indfun_common.ml4
-rw-r--r--plugins/funind/indfun_common.mli2
-rw-r--r--plugins/funind/merge.ml18
-rw-r--r--plugins/ltac/extratactics.ml48
-rw-r--r--plugins/ltac/g_auto.ml42
-rw-r--r--plugins/ltac/g_ltac.ml42
-rw-r--r--plugins/ltac/g_obligations.ml42
-rw-r--r--plugins/ltac/g_rewrite.ml42
-rw-r--r--plugins/ltac/pptactic.ml94
-rw-r--r--plugins/ltac/pptactic.mli70
-rw-r--r--plugins/ltac/pptacticsig.mli81
-rw-r--r--plugins/ltac/profile_ltac.ml2
-rw-r--r--plugins/ltac/rewrite.mli6
-rw-r--r--plugins/ltac/tacentries.ml12
-rw-r--r--plugins/ltac/tacentries.mli2
-rw-r--r--plugins/ltac/tacinterp.ml33
-rw-r--r--plugins/micromega/RMicromega.v315
-rw-r--r--plugins/micromega/coq_micromega.ml3
-rw-r--r--plugins/rtauto/proof_search.ml6
-rw-r--r--plugins/setoid_ring/RealField.v21
-rw-r--r--plugins/setoid_ring/newring.ml21
-rw-r--r--plugins/ssrmatching/ssrmatching.ml44
-rw-r--r--plugins/syntax/r_syntax.ml159
-rw-r--r--pretyping/constr_matching.ml6
-rw-r--r--pretyping/detyping.ml23
-rw-r--r--pretyping/evarconv.ml35
-rw-r--r--pretyping/glob_ops.ml32
-rw-r--r--pretyping/patternops.ml28
-rw-r--r--pretyping/pretyping.ml78
-rw-r--r--pretyping/pretyping.mli4
-rw-r--r--pretyping/unification.ml4
-rw-r--r--pretyping/unification.mli4
-rw-r--r--printing/ppannotation.ml33
-rw-r--r--printing/ppannotation.mli29
-rw-r--r--printing/ppconstr.ml175
-rw-r--r--printing/ppconstr.mli86
-rw-r--r--printing/ppconstrsig.mli95
-rw-r--r--printing/ppvernac.ml45
-rw-r--r--printing/ppvernac.mli15
-rw-r--r--printing/ppvernacsig.mli20
-rw-r--r--printing/prettyp.ml8
-rw-r--r--printing/printer.ml2
-rw-r--r--printing/printing.mllib1
-rw-r--r--printing/printmod.ml42
-rw-r--r--printing/printmod.mli5
-rw-r--r--proofs/pfedit.ml12
-rw-r--r--proofs/pfedit.mli2
-rw-r--r--proofs/proof_global.ml4
-rw-r--r--proofs/proof_using.ml2
-rw-r--r--stm/asyncTaskQueue.ml37
-rw-r--r--stm/proofworkertop.ml6
-rw-r--r--stm/queryworkertop.ml6
-rw-r--r--stm/stm.ml112
-rw-r--r--stm/stm.mllib1
-rw-r--r--stm/tacworkertop.ml6
-rw-r--r--stm/vernac_classifier.ml21
-rw-r--r--stm/workerLoop.ml (renamed from printing/printmodsig.mli)18
-rw-r--r--stm/workerLoop.mli (renamed from plugins/decl_mode/decl_interp.mli)8
-rw-r--r--tactics/class_tactics.ml12
-rw-r--r--tactics/tactics.ml20
-rw-r--r--tactics/tactics.mli2
-rw-r--r--test-suite/bugs/closed/2640.v17
-rw-r--r--test-suite/bugs/closed/4957.v6
-rw-r--r--test-suite/bugs/closed/4969.v11
-rw-r--r--test-suite/bugs/closed/5345.v7
-rw-r--r--test-suite/bugs/closed/5372.v7
-rw-r--r--test-suite/ide/undo.v103
-rw-r--r--test-suite/ide/undo011.fake34
-rw-r--r--test-suite/output/Arguments.out4
-rw-r--r--test-suite/output/Arguments_renaming.out14
-rw-r--r--test-suite/output/ErrorInModule.out3
-rw-r--r--test-suite/output/ErrorInModule.v4
-rw-r--r--test-suite/output/ErrorInSection.out3
-rw-r--r--test-suite/output/ErrorInSection.v4
-rw-r--r--test-suite/output/Errors.out2
-rw-r--r--test-suite/output/FunExt.out2
-rw-r--r--test-suite/output/Notations.out20
-rw-r--r--test-suite/output/Notations2.out2
-rw-r--r--test-suite/output/UnivBinders.out6
-rw-r--r--test-suite/output/UnivBinders.v7
-rw-r--r--test-suite/output/inference.out2
-rw-r--r--test-suite/output/ltac.out5
-rw-r--r--test-suite/output/ltac_missing_args.out20
-rw-r--r--test-suite/output/ltac_missing_args.v19
-rw-r--r--test-suite/output/qualification.out1
-rw-r--r--test-suite/success/Notations.v7
-rw-r--r--test-suite/success/decl_mode.v182
-rw-r--r--test-suite/success/decl_mode2.v249
-rw-r--r--test-suite/success/ltac_match_pattern_names.v28
-rw-r--r--test-suite/success/univnames.v13
-rw-r--r--theories/Init/Logic.v3
-rw-r--r--theories/Init/Prelude.v1
-rw-r--r--theories/Init/Specif.v23
-rw-r--r--theories/Lists/List.v4
-rw-r--r--theories/Logic/JMeq.v2
-rw-r--r--theories/Logic/vo.itarget2
-rw-r--r--theories/QArith/Qreals.v30
-rw-r--r--theories/QArith/Qround.v2
-rw-r--r--theories/Reals/Alembert.v2
-rw-r--r--theories/Reals/AltSeries.v58
-rw-r--r--theories/Reals/ArithProp.v2
-rw-r--r--theories/Reals/Cos_plus.v8
-rw-r--r--theories/Reals/DiscrR.v9
-rw-r--r--theories/Reals/Exp_prop.v14
-rw-r--r--theories/Reals/Machin.v2
-rw-r--r--theories/Reals/RIneq.v189
-rw-r--r--theories/Reals/R_Ifp.v70
-rw-r--r--theories/Reals/R_sqr.v53
-rw-r--r--theories/Reals/R_sqrt.v121
-rw-r--r--theories/Reals/Ranalysis2.v21
-rw-r--r--theories/Reals/Ranalysis3.v32
-rw-r--r--theories/Reals/Ranalysis4.v11
-rw-r--r--theories/Reals/Ranalysis5.v5
-rw-r--r--theories/Reals/Ratan.v46
-rw-r--r--theories/Reals/Raxioms.v13
-rw-r--r--theories/Reals/Rbasic_fun.v27
-rw-r--r--theories/Reals/Rdefinitions.v29
-rw-r--r--theories/Reals/Rderiv.v12
-rw-r--r--theories/Reals/Rfunctions.v5
-rw-r--r--theories/Reals/RiemannInt_SF.v9
-rw-r--r--theories/Reals/Rlimit.v38
-rw-r--r--theories/Reals/Rpow_def.v2
-rw-r--r--theories/Reals/Rpower.v30
-rw-r--r--theories/Reals/Rseries.v2
-rw-r--r--theories/Reals/Rsqrt_def.v2
-rw-r--r--theories/Reals/Rtrigo1.v373
-rw-r--r--theories/Reals/Rtrigo_alt.v69
-rw-r--r--theories/Reals/Rtrigo_calc.v181
-rw-r--r--theories/Reals/Rtrigo_def.v34
-rw-r--r--theories/Reals/Rtrigo_reg.v14
-rw-r--r--theories/Reals/SeqProp.v2
-rw-r--r--theories/Reals/Sqrt_reg.v1
-rw-r--r--theories/Vectors/VectorDef.v10
-rw-r--r--theories/Vectors/VectorSpec.v29
-rw-r--r--tools/coq_makefile.ml22
-rw-r--r--tools/coqdoc/alpha.ml7
-rw-r--r--tools/coqdoc/index.ml12
-rw-r--r--tools/coqworkmgr.ml9
-rw-r--r--tools/fake_ide.ml43
-rw-r--r--toplevel/coqloop.ml197
-rw-r--r--toplevel/coqloop.mli9
-rw-r--r--toplevel/coqtop.ml69
-rw-r--r--toplevel/usage.ml1
-rw-r--r--toplevel/vernac.ml30
-rw-r--r--vernac/auto_ind_decl.ml4
-rw-r--r--vernac/classes.ml2
-rw-r--r--vernac/classes.mli4
-rw-r--r--vernac/command.ml26
-rw-r--r--vernac/command.mli10
-rw-r--r--vernac/explainErr.ml44
-rw-r--r--vernac/explainErr.mli2
-rw-r--r--vernac/lemmas.ml4
-rw-r--r--vernac/metasyntax.ml16
-rw-r--r--vernac/record.ml8
-rw-r--r--vernac/record.mli2
-rw-r--r--vernac/search.ml2
-rw-r--r--vernac/search.mli2
-rw-r--r--vernac/topfmt.ml288
-rw-r--r--vernac/topfmt.mli (renamed from lib/pp_control.mli)25
-rw-r--r--vernac/vernac.mllib1
-rw-r--r--vernac/vernacentries.ml30
298 files changed, 3654 insertions, 8918 deletions
diff --git a/.merlin b/.merlin
index bda18d5490..394db528d4 100644
--- a/.merlin
+++ b/.merlin
@@ -1,4 +1,4 @@
-FLG -rectypes -thread
+FLG -rectypes -thread -safe-string
S ltac
B ltac
diff --git a/.travis.yml b/.travis.yml
index 7138d5c61e..d35b7a8422 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -40,6 +40,7 @@ env:
- TEST_TARGET="ci-math-comp"
- TEST_TARGET="ci-sf"
- TEST_TARGET="ci-unimath"
+ - TEST_TARGET="ci-vst"
# Not ready yet for 8.7
# - TEST_TARGET="ci-cpdt"
# - TEST_TARGET="ci-metacoq"
@@ -49,6 +50,7 @@ matrix:
allow_failures:
- env: TEST_TARGET="ci-geocoq"
+ - env: TEST_TARGET="ci-vst"
# Full Coq test-suite with two compilers
# [TODO: use yaml refs and avoid duplication for packages list]
@@ -121,3 +123,12 @@ script:
- echo 'Running tests...' && echo -en 'travis_fold:start:coq.test\\r'
- ${TW} make -j ${NJOBS} ${TEST_TARGET}
- echo -en 'travis_fold:end:coq.test\\r'
+
+# Testing Gitter webhook
+notifications:
+ webhooks:
+ urls:
+ - https://webhooks.gitter.im/e/3cdabdec318214c7cd63
+ on_success: change # options: [always|never|change] default: always
+ on_failure: always # options: [always|never|change] default: always
+ on_start: never # options: [always|never|change] default: always
diff --git a/CHANGES b/CHANGES
index a7cba9aa4f..240d71ec04 100644
--- a/CHANGES
+++ b/CHANGES
@@ -7,7 +7,7 @@ Tactics
functional extensionality in H supposed to be a quantified equality
until giving a bare equality.
-Libraries
+Standard Library
- New file PropExtensionality.v to explicitly work in the axiomatic
context of propositional extensionality.
@@ -16,6 +16,16 @@ Libraries
Various proof-theoretic characterizations of choice over setoids in
file ChoiceFacts.v.
+- IZR (Reals) has been changed to produce a compact representation of
+ integers. As a consequence, IZR is no longer convertible to INR and
+ lemmas such as INR_IZR_INZ should be used instead.
+- Real constants are now represented using IZR rather than R0 and R1;
+ this might cause rewriting rules to fail to apply to constants.
+
+Plugins
+
+- The mathematical proof language (also known as declarative mode) was removed.
+
Changes from V8.6beta1 to V8.6
==============================
diff --git a/META.coq b/META.coq
index 83134d4a08..074c2e457b 100644
--- a/META.coq
+++ b/META.coq
@@ -252,6 +252,33 @@ package "highparsing" (
)
+package "idetop" (
+
+ description = "Coq IDE Libraries"
+ version = "8.7"
+
+ requires = "coq.toplevel"
+ directory = "ide"
+
+ archive(byte) = "coqidetop.cma"
+ archive(native) = "coqidetop.cmxa"
+
+)
+
+package "ide" (
+
+ description = "Coq IDE Libraries"
+ version = "8.7"
+
+# XXX Add GTK
+ requires = "coq.toplevel"
+ directory = "ide"
+
+ archive(byte) = "ide.cma"
+ archive(native) = "ide.cmxa"
+
+)
+
package "ltac" (
description = "Coq LTAC Plugin"
diff --git a/Makefile.build b/Makefile.build
index 9d76638e12..01cc4d8780 100644
--- a/Makefile.build
+++ b/Makefile.build
@@ -440,9 +440,9 @@ $(COQWORKMGR): $(call bestobj, lib/clib.cma stm/coqworkmgrApi.cmo tools/coqworkm
# fake_ide : for debugging or test-suite purpose, a fake ide simulating
# a connection to coqtop -ideslave
-FAKEIDECMO:= lib/clib.cma lib/cErrors.cmo lib/spawn.cmo ide/document.cmo \
+FAKEIDECMO:= lib/clib.cma lib/cErrors.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
+ ide/richpp.cmo ide/xmlprotocol.cmo tools/fake_ide.cmo
$(FAKEIDE): $(call bestobj, $(FAKEIDECMO)) | $(IDETOPLOOPCMA:.cma=$(BESTDYN))
$(SHOW)'OCAMLBEST -o $@'
diff --git a/Makefile.ci b/Makefile.ci
index 897318c4dd..b055ada8e5 100644
--- a/Makefile.ci
+++ b/Makefile.ci
@@ -1,7 +1,7 @@
CI_TARGETS=ci-all ci-hott ci-math-comp ci-compcert ci-sf ci-cpdt \
ci-color ci-math-classes ci-tlc ci-fiat-crypto ci-fiat-parsers \
ci-coquelicot ci-flocq ci-iris-coq ci-metacoq ci-geocoq \
- ci-unimath
+ ci-unimath ci-vst
.PHONY: $(CI_TARGETS)
diff --git a/Makefile.common b/Makefile.common
index 1e71bcf7d9..d5f79d76b5 100644
--- a/Makefile.common
+++ b/Makefile.common
@@ -61,7 +61,7 @@ PLUGINDIRS:=\
omega romega micromega quote \
setoid_ring extraction fourier \
cc funind firstorder derive \
- rtauto nsatz syntax decl_mode btauto \
+ rtauto nsatz syntax btauto \
ssrmatching ltac
SRCDIRS:=\
@@ -117,12 +117,11 @@ OTHERSYNTAXCMO:=$(addprefix plugins/syntax/, \
r_syntax_plugin.cmo \
ascii_syntax_plugin.cmo \
string_syntax_plugin.cmo )
-DECLMODECMO:=plugins/decl_mode/decl_mode_plugin.cmo
DERIVECMO:=plugins/derive/derive_plugin.cmo
LTACCMO:=plugins/ltac/ltac_plugin.cmo
SSRMATCHINGCMO:=plugins/ssrmatching/ssrmatching_plugin.cmo
-PLUGINSCMO:=$(LTACCMO) $(OMEGACMO) $(ROMEGACMO) $(MICROMEGACMO) $(DECLMODECMO) \
+PLUGINSCMO:=$(LTACCMO) $(OMEGACMO) $(ROMEGACMO) $(MICROMEGACMO) \
$(QUOTECMO) $(RINGCMO) \
$(FOURIERCMO) $(EXTRACTIONCMO) \
$(CCCMO) $(FOCMO) $(RTAUTOCMO) $(BTAUTOCMO) \
diff --git a/Makefile.doc b/Makefile.doc
index 9ae20ba765..39c3255f5c 100644
--- a/Makefile.doc
+++ b/Makefile.doc
@@ -48,7 +48,7 @@ REFMANCOQTEXFILES:=$(addprefix doc/refman/, \
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 \
+ 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 \
diff --git a/checker/reduction.ml b/checker/reduction.ml
index ec16aa2615..28c0126b41 100644
--- a/checker/reduction.ml
+++ b/checker/reduction.ml
@@ -176,9 +176,9 @@ let sort_cmp env univ pb s0 s1 =
then begin
if !Flags.debug then begin
let op = match pb with CONV -> "=" | CUMUL -> "<=" in
- Printf.eprintf "sort_cmp: %s\n%!" Pp.(string_of_ppcmds
- (str"Error: " ++ Univ.pr_uni u1 ++ str op ++ Univ.pr_uni u2 ++ str ":" ++ cut()
- ++ Univ.pr_universes univ))
+ Format.eprintf "sort_cmp: @[%a@]\n%!" Pp.pp_with Pp.(
+ str"Error: " ++ Univ.pr_uni u1 ++ str op ++ Univ.pr_uni u2 ++ str ":" ++ cut()
+ ++ Univ.pr_universes univ)
end;
raise NotConvertible
end
diff --git a/configure.ml b/configure.ml
index 82ce931d67..dfc6724a2d 100644
--- a/configure.ml
+++ b/configure.ml
@@ -264,6 +264,10 @@ module Prefs = struct
let debug = ref true
let profile = ref false
let annotate = ref false
+ (* Note, disabling this should be OK, but be careful with the
+ sharing invariants.
+ *)
+ let safe_string = ref true
let nativecompiler = ref (not (os_type_win32 || os_type_cygwin))
let coqwebsite = ref "http://coq.inria.fr/"
let force_caml_version = ref false
@@ -386,6 +390,9 @@ let coq_annotate_flag =
then if program_in_path "ocamlmerlin" then "-bin-annot" else "-annot"
else ""
+let coq_safe_string =
+ if !Prefs.safe_string then "-safe-string" else ""
+
let cflags = "-Wall -Wno-unused -g -O2"
(** * Architecture *)
@@ -1118,7 +1125,7 @@ let write_makefile f =
pr "CAMLHLIB=%S\n\n" camllib;
pr "# Caml link command and Caml make top command\n";
pr "# Caml flags\n";
- pr "CAMLFLAGS=-rectypes %s\n" coq_annotate_flag;
+ pr "CAMLFLAGS=-rectypes %s %s\n" coq_annotate_flag coq_safe_string;
pr "# User compilation flag\n";
pr "USERFLAGS=\n\n";
pr "# Flags for GCC\n";
diff --git a/dev/ci/ci-basic-overlay.sh b/dev/ci/ci-basic-overlay.sh
index da5b425794..336ce9d8f1 100644
--- a/dev/ci/ci-basic-overlay.sh
+++ b/dev/ci/ci-basic-overlay.sh
@@ -46,8 +46,11 @@
########################################################################
# HoTT
########################################################################
+# Temporal overlay
: ${HoTT_CI_BRANCH:=mz-8.7}
: ${HoTT_CI_GITURL:=https://github.com/ejgallego/HoTT.git}
+# : ${HoTT_CI_BRANCH:=master}
+# : ${HoTT_CI_GITURL:=https://github.com/HoTT/HoTT.git}
########################################################################
# GeoCoq
@@ -68,12 +71,18 @@
: ${Coquelicot_CI_GITURL:=https://scm.gforge.inria.fr/anonscm/git/coquelicot/coquelicot.git}
########################################################################
-# Coquelicot
+# CompCert
########################################################################
: ${CompCert_CI_BRANCH:=master}
: ${CompCert_CI_GITURL:=https://github.com/AbsInt/CompCert.git}
########################################################################
+# VST
+########################################################################
+: ${VST_CI_BRANCH:=master}
+: ${VST_CI_GITURL:=https://github.com/PrincetonUniversity/VST.git}
+
+########################################################################
# fiat_parsers
########################################################################
: ${fiat_parsers_CI_BRANCH:=master}
diff --git a/dev/ci/ci-common.sh b/dev/ci/ci-common.sh
index c94f150263..2711b7ecaa 100644
--- a/dev/ci/ci-common.sh
+++ b/dev/ci/ci-common.sh
@@ -25,12 +25,16 @@ git_checkout()
local _URL=${2}
local _DEST=${3}
+ # Allow an optional 4th argument for the commit
+ local _COMMIT=${4:-FETCH_HEAD}
+ local _DEPTH=$(if [ -z "${4}" ]; then echo "--depth 1"; fi)
+
mkdir -p ${_DEST}
( cd ${_DEST} && \
- if [ ! -d .git ] ; then git clone --depth 1 ${_URL} . ; fi && \
+ if [ ! -d .git ] ; then git clone ${_DEPTH} ${_URL} . ; fi && \
echo "Checking out ${_DEST}" && \
git fetch ${_URL} ${_BRANCH} && \
- git checkout FETCH_HEAD && \
+ git checkout ${_COMMIT} && \
echo "${_DEST}: `git log -1 --format='%s | %H | %cd | %aN'`" )
}
diff --git a/dev/ci/ci-iris-coq.sh b/dev/ci/ci-iris-coq.sh
index eb1d1be078..262dd6fa01 100755
--- a/dev/ci/ci-iris-coq.sh
+++ b/dev/ci/ci-iris-coq.sh
@@ -9,14 +9,18 @@ Iris_CI_DIR=${CI_BUILD_DIR}/iris-coq
install_ssreflect
-# Setup stdpp
+# Setup Iris first, as it is needed to compute the dependencies
-git_checkout ${stdpp_CI_BRANCH} ${stdpp_CI_GITURL} ${stdpp_CI_DIR}
+git_checkout ${Iris_CI_BRANCH} ${Iris_CI_GITURL} ${Iris_CI_DIR}
+read -a IRIS_DEP < ${Iris_CI_DIR}/opam.pins
-( cd ${stdpp_CI_DIR} && make -j ${NJOBS} && make install )
+# Setup stdpp
+stdpp_CI_GITURL=${IRIS_DEP[1]}.git
+stdpp_CI_COMMIT=${IRIS_DEP[2]}
-# Setup Iris
+git_checkout ${stdpp_CI_BRANCH} ${stdpp_CI_GITURL} ${stdpp_CI_DIR} ${stdpp_CI_COMMIT}
-git_checkout ${Iris_CI_BRANCH} ${Iris_CI_GITURL} ${Iris_CI_DIR}
+( cd ${stdpp_CI_DIR} && make -j ${NJOBS} && make install )
+# Build iris now
( cd ${Iris_CI_DIR} && make -j ${NJOBS} )
diff --git a/dev/ci/ci-vst.sh b/dev/ci/ci-vst.sh
new file mode 100755
index 0000000000..c111951852
--- /dev/null
+++ b/dev/ci/ci-vst.sh
@@ -0,0 +1,13 @@
+#!/usr/bin/env bash
+
+ci_dir="$(dirname "$0")"
+source ${ci_dir}/ci-common.sh
+
+VST_CI_DIR=${CI_BUILD_DIR}/VST
+
+# opam install -j ${NJOBS} -y menhir
+git_checkout ${VST_CI_BRANCH} ${VST_CI_GITURL} ${VST_CI_DIR}
+
+# Targets are: msl veric floyd
+# Patch to avoid the upper version limit
+( cd ${VST_CI_DIR} && sed -i.bak 's/8.6$/8.6 or-else trunk/' Makefile && make -j ${NJOBS} )
diff --git a/dev/core.dbg b/dev/core.dbg
index f04e5c07b7..6acdd01528 100644
--- a/dev/core.dbg
+++ b/dev/core.dbg
@@ -3,6 +3,7 @@ load_printer threads.cma
load_printer str.cma
load_printer clib.cma
load_printer lib.cma
+load_printer dynlink.cma
load_printer kernel.cma
load_printer library.cma
load_printer engine.cma
diff --git a/dev/doc/changes.txt b/dev/doc/changes.txt
index 12c3ec4546..af077bbb40 100644
--- a/dev/doc/changes.txt
+++ b/dev/doc/changes.txt
@@ -2,6 +2,12 @@
= CHANGES BETWEEN COQ V8.6 AND COQ V8.7 =
=========================================
+* Ocaml *
+
+Coq is compiled with -safe-string enabled and requires plugins to do
+the same. This means that code using `String` in an imperative way
+will fail to compile now. They should switch to `Bytes.t`
+
* ML API *
We renamed the following functions:
@@ -27,6 +33,17 @@ The following type aliases where removed
The module Constrarg was merged into Stdarg.
+The following types have been moved and modified:
+
+ local_binder -> local_binder_expr
+ glob_binder merged with glob_decl
+
+The following constructors have been renamed:
+
+ LocalRawDef -> CLocalDef
+ LocalRawAssum -> CLocalAssum
+ LocalPattern -> CLocalPattern
+
** Ltac API **
Many Ltac specific API has been moved in its own ltac/ folder. Amongst other
@@ -70,6 +87,58 @@ work for EXTEND macros though.
- The header parameter to `user_err` has been made optional.
+** Pretty printing **
+
+Some functions have been removed, see pretty printing below for more
+details.
+
+* Pretty Printing and XML protocol *
+
+The type std_cmdpps has been reworked and made the canonical "Coq rich
+document type". This allows for a more uniform handling of printing
+(specially in IDEs). The main consequences are:
+
+ - Richpp has been confined to IDE use. Most of previous uses of the
+ `richpp` type should be replaced now by `Pp.std_cmdpps`. Main API
+ has been updated.
+
+ - The XML protocol will send a new message type of `pp`, which should
+ be rendered client-wise.
+
+ - `Set Printing Width` is deprecated, now width is controlled
+ client-side.
+
+ - `Pp_control` has removed. The new module `Topfmt` implements
+ console control for the toplevel.
+
+ - The impure tag system in Pp has been removed. This also does away
+ with the printer signatures and functors. Now printers tag
+ unconditionally.
+
+ - The following functions have been removed from `Pp`:
+
+ val stras : int * string -> std_ppcmds
+ val tbrk : int * int -> std_ppcmds
+ val tab : unit -> std_ppcmds
+ val pifb : unit -> std_ppcmds
+ val comment : int -> std_ppcmds
+ val comments : ((int * int) * string) list ref
+ val eval_ppcmds : std_ppcmds -> std_ppcmds
+ val is_empty : std_ppcmds -> bool
+ val t : std_ppcmds -> std_ppcmds
+ val hb : int -> std_ppcmds
+ val vb : int -> std_ppcmds
+ val hvb : int -> std_ppcmds
+ val hovb : int -> std_ppcmds
+ val tb : unit -> std_ppcmds
+ val close : unit -> std_ppcmds
+ val tclose : unit -> std_ppcmds
+ val open_tag : Tag.t -> std_ppcmds
+ val close_tag : unit -> std_ppcmds
+ val msg_with : ...
+
+ module Tag
+
=========================================
= CHANGES BETWEEN COQ V8.5 AND COQ V8.6 =
=========================================
diff --git a/dev/doc/proof-engine.md b/dev/doc/proof-engine.md
new file mode 100644
index 0000000000..db69b08a20
--- /dev/null
+++ b/dev/doc/proof-engine.md
@@ -0,0 +1,134 @@
+Tutorial on the new proof engine for ML tactic writers
+======================================================
+
+Starting from Coq 8.5, a new proof engine has been introduced, replacing the old
+meta-based engine which had a lot of drawbacks, ranging from expressivity to
+soundness, the major one being that the type of tactics was transparent. This
+was pervasively abused and made virtually impossible to tweak the implementation
+of the engine.
+
+The old engine is deprecated and is slowly getting removed from the source code.
+
+The new engine relies on a monadic API defined in the `Proofview` module. Helper
+functions and higher-level operations are defined in the `Tacmach` and
+`Tacticals` modules, and end-user tactics are defined amongst other in the
+`Tactics` module.
+
+At the root of the engine is a representation of proofs as partial terms that
+can contain typed holes, called evars, short for *existential variable*. An evar
+is essentially defined by its context and return type, that we will write
+`?e : [Γ ⊢ _ : A]`. An evar `?e` must be applied to a substitution `σ` of type
+`Γ` (i.e. a list of terms) to produce a term of type `A`, which is done by
+applying `EConstr.mkEvar`, and which we will write `?e{σ}`.
+
+The engine monad features a notion of global state called `evar_map`, defined in
+the `Evd` module, which is the structure containing the incremental refinement
+of evars. `Evd` is a low-level API and its use is discouraged in favour of the
+`Evarutil` module which provides more abstract primitives.
+
+In addition to this state, the monad also features a goal state, that is
+an ordered list of current holes to be filled. While these holes are referred
+to as goals at a high-enough level, they are actually no more than evars. The
+API provided to deal with these holes can be found in the `Proofview.Goal`
+module. Tactics are naturally operating on several goals at once, so that it is
+usual to use the `Proofview.Goal.enter` function and its variants to dispatch a
+tactic to each of the goals under focus.
+
+Primitive tactics by term refining
+-------------------------------------
+
+A typical low-level tactic will be defined by plugging partial terms in the
+goal holes thanks to the `Refine` module, and in particular to the
+`Refine.refine` primitive.
+
+```ocaml
+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. *)
+```
+
+In a first approximation, we can think of `'a Sigma.run` as
+`evar_map -> 'a * evar_map`. What the function does is first evaluate the
+`Constr.t Sigma.run` argument in the current proof state, and then use the
+resulting term as a filler for the proof under focus. All evars that have been
+created by the invocation of this thunk are then turned into new goals added in
+the order of their creation.
+
+To see how we can use it, let us have a look at an idealized example, the `cut`
+tactic. Assuming `X` is a type, `cut X` fills the current goal `[Γ ⊢ _ : A]`
+with a term `let x : X := ?e2{Γ} in ?e1{Γ} x` where `x` is a fresh variable and
+`?e1 : [Γ ⊢ _ : X -> A]` and `?e2 : [Γ ⊢ _ : X]`. The current goal is solved and
+two new holes `[e1, e2]` are added to the goal state in this order.
+
+```ocaml
+let cut c =
+ let open Sigma in
+ Proofview.Goal.nf_enter { enter = begin fun gl ->
+ (** In this block, we focus on one goal at a time indicated by gl *)
+ let env = Proofview.Goal.env gl in
+ (** Get the context of the goal, essentially [Γ] *)
+ let concl = Proofview.Goal.concl gl in
+ (** Get the conclusion [A] of the goal *)
+ let hyps = Tacmach.New.pf_ids_of_hyps gl in
+ (** List of hypotheses from the context of the goal *)
+ let id = Namegen.next_name_away Anonymous hyps in
+ (** Generate a fresh identifier *)
+ let t = mkArrow c (Vars.lift 1 concl) in
+ (** Build [X -> A]. Note the lifting of [A] due to being on the right hand
+ side of the arrow. *)
+ Refine.refine { run = begin fun sigma ->
+ (** All evars generated by this block will be added as goals *)
+ let Sigma (f, sigma, p) = Evarutil.new_evar env sigma t in
+ (** Generate ?e1 : [Γ ⊢ _ : X -> A], add it to sigma, and return the
+ term [f := Γ ⊢ ?e1{Γ} : X -> A] with the updated sigma. The identity
+ substitution for [Γ] is extracted from the [env] argument, so that
+ one must be careful to pass the correct context here in order for the
+ resulting term to be well-typed. The [p] return value is a proof term
+ used to enforce sigma monotonicity. *)
+ let Sigma (x, sigma, q) = Evarutil.new_evar env sigma c in
+ (** Generate ?e2 : [Γ ⊢ _ : X] in sigma and return
+ [x := Γ ⊢ ?e2{Γ} : X]. *)
+ let r = mkLetIn (Name id, x, c, mkApp (Vars.lift 1 r, [|mkRel 1|])) in
+ (** Build [r := Γ ⊢ let id : X := ?e2{Γ} in ?e1{Γ} id : A] *)
+ Sigma (r, sigma, p +> q)
+ (** Fills the current hole with [r]. The [p +> q] thingy ensures
+ monotonicity of sigma. *)
+ end }
+ end }
+```
+
+The `Evarutil.new_evar` function is the preferred way to generate evars in
+tactics. It returns a ready-to-use term, so that one does not have to call
+the `mkEvar` primitive. There are lower-level variants whose use is dedicated to
+special use cases, *e.g.* whenever one wants a non-identity substitution. One
+should take care to call it with the proper `env` argument so that the evar
+and term it generates make sense in the context they will be plugged in.
+
+For the sake of completeness, the old engine was relying on the `Tacmach.refine`
+function to provide a similar feature. Nonetheless, it was using untyped metas
+instead of evars, so that it had to mangle the argument term to actually produce
+the term that would be put into the hole. For instance, to work around the
+untypedness, some metas had to be coerced with a cast to enforce their type,
+otherwise leading to runtime errors. This was working for very simple
+instances, but was unreliable for everything else.
+
+High-level composition of tactics
+------------------------------------
+
+It is possible to combine low-level refinement tactics to create more powerful
+abstractions. While it was the standard way of doing things in the old engine
+to overcome its technical limitations (namely that one was forced to go through
+a limited set of derivation rules), it is recommended to generate proofs as
+much as possible by refining in ML tactics when it is possible and easy enough.
+Indeed, this prevents dependence on fragile constructions such as unification.
+
+Obviously, it does not forbid the use of tacticals to mimick what one would do
+in Ltac. Each Ltac primitive has a corresponding ML counterpart with simple
+semantics. A list of such tacticals can be found in the `Tacticals` module. Most
+of them are a porting of the tacticals from the old engine to the new one, so
+that if they share the same name they are expected to have the same semantics.
diff --git a/dev/top_printers.ml b/dev/top_printers.ml
index dc354b130b..cd464801b0 100644
--- a/dev/top_printers.ml
+++ b/dev/top_printers.ml
@@ -29,7 +29,7 @@ let _ = set_bool_option_value ["Printing";"Matching"] false
let _ = Detyping.set_detype_anonymous (fun _ _ -> raise Not_found)
(* std_ppcmds *)
-let pp x = Pp.pp_with !Pp_control.std_ft x
+let pp x = Pp.pp_with !Topfmt.std_ft x
(** Future printer *)
diff --git a/doc/refman/Polynom.tex b/doc/refman/Polynom.tex
index 0664bf9095..77d5928345 100644
--- a/doc/refman/Polynom.tex
+++ b/doc/refman/Polynom.tex
@@ -342,16 +342,16 @@ describes their syntax and effects:
By default the tactic does not recognize power expressions as ring
expressions.
\item[sign {\term}] allows {\tt ring\_simplify} to use a minus operation
- when outputing its normal form, i.e writing $x - y$ instead of $x + (-y)$.
+ when outputting its normal form, i.e writing $x - y$ instead of $x + (-y)$.
The term {\term} is a proof that a given sign function indicates expressions
that are signed ({\term} has to be a
- proof of {\tt Ring\_theory.get\_sign}). See {\tt plugins/setoid\_ring/IntialRing.v} for examples of sign function.
-\item[div {\term}] allows {\tt ring} and {\tt ring\_simplify} to use moniomals
+ proof of {\tt Ring\_theory.get\_sign}). See {\tt plugins/setoid\_ring/InitialRing.v} for examples of sign function.
+\item[div {\term}] allows {\tt ring} and {\tt ring\_simplify} to use monomials
with coefficient other than 1 in the rewriting. The term {\term} is a proof that a given division function satisfies the specification of an euclidean
division function ({\term} has to be a
proof of {\tt Ring\_theory.div\_theory}). For example, this function is
called when trying to rewrite $7x$ by $2x = z$ to tell that $7 = 3 * 2 + 1$.
- See {\tt plugins/setoid\_ring/IntialRing.v} for examples of div function.
+ See {\tt plugins/setoid\_ring/InitialRing.v} for examples of div function.
\end{description}
diff --git a/doc/refman/RefMan-com.tex b/doc/refman/RefMan-com.tex
index bef0a1686f..45230fb6e5 100644
--- a/doc/refman/RefMan-com.tex
+++ b/doc/refman/RefMan-com.tex
@@ -123,12 +123,6 @@ The following command-line options are recognized by the commands {\tt
valid for {\tt coqc} as the toplevel module name is inferred from the
name of the output file.
-\item[{\tt -notop}]\ %
-
- Use the empty logical path for the toplevel module name instead of {\tt
- Top}. Not valid for {\tt coqc} as the toplevel module name is
- inferred from the name of the output file.
-
\item[{\tt -exclude-dir} {\em directory}]\ %
Exclude any subdirectory named {\em directory} while
diff --git a/doc/refman/RefMan-decl.tex b/doc/refman/RefMan-decl.tex
deleted file mode 100644
index aae10e323c..0000000000
--- a/doc/refman/RefMan-decl.tex
+++ /dev/null
@@ -1,823 +0,0 @@
-\newcommand{\DPL}{Mathematical Proof Language}
-
-\chapter{The \DPL\label{DPL}\index{DPL}}
-
-\section{Introduction}
-
-\subsection{Foreword}
-
-In this chapter, we describe an alternative language that may be used
-to do proofs using the Coq proof assistant. The language described
-here uses the same objects (proof-terms) as Coq, but it differs in the
-way proofs are described. This language was created by Pierre
-Corbineau at the Radboud University of Nijmegen, The Netherlands.
-
-The intent is to provide language where proofs are less formalism-{}
-and implementation-{}sensitive, and in the process to ease a bit the
-learning of computer-{}aided proof verification.
-
-\subsection{What is a declarative proof?}
-In vanilla Coq, proofs are written in the imperative style: the user
-issues commands that transform a so called proof state until it
-reaches a state where the proof is completed. In the process, the user
-mostly described the transitions of this system rather than the
-intermediate states it goes through.
-
-The purpose of a declarative proof language is to take the opposite
-approach where intermediate states are always given by the user, but
-the transitions of the system are automated as much as possible.
-
-\subsection{Well-formedness and Completeness}
-
-The \DPL{} introduces a notion of well-formed
-proofs which are weaker than correct (and complete)
-proofs. Well-formed proofs are actually proof script where only the
-reasoning is incomplete. All the other aspects of the proof are
-correct:
-\begin{itemize}
-\item All objects referred to exist where they are used
-\item Conclusion steps actually prove something related to the
- conclusion of the theorem (the {\tt thesis}.
-\item Hypothesis introduction steps are done when the goal is an
- implication with a corresponding assumption.
-\item Sub-objects in the elimination steps for tuples are correct
- sub-objects of the tuple being decomposed.
-\item Patterns in case analysis are type-correct, and induction is well guarded.
-\end{itemize}
-
-\subsection{Note for tactics users}
-
-This section explain what differences the casual Coq user will
-experience using the \DPL.
-\begin{enumerate}
-\item The focusing mechanism is constrained so that only one goal at
- a time is visible.
-\item Giving a statement that Coq cannot prove does not produce an
- error, only a warning: this allows going on with the proof and fill
- the gap later.
-\item Tactics can still be used for justifications and after
-{\texttt{escape}}.
-\end{enumerate}
-
-\subsection{Compatibility}
-
-The \DPL{} is available for all Coq interfaces that use
-text-based interaction, including:
-\begin{itemize}
-\item the command-{}line toplevel {\texttt{coqtop}}
-\item the native GUI {\CoqIDE}
-\item the {\ProofGeneral} Emacs mode
-\item Cezary Kaliszyk'{}s Web interface
-\item L.E. Mamane'{}s tmEgg TeXmacs plugin
-\end{itemize}
-
-However it is not supported by structured editors such as PCoq.
-
-
-
-\section{Syntax}
-
-Here is a complete formal description of the syntax for \DPL{} commands.
-
-\begin{figure}[htbp]
-\begin{centerframe}
-\begin{tabular}{lcl@{\qquad}r}
- instruction & ::= & {\tt proof} \\
- & $|$ & {\tt assume } \nelist{statement}{\tt and}
- \zeroone{[{\tt and } \{{\tt we have}\}-clause]} \\
- & $|$ & \{{\tt let},{\tt be}\}-clause \\
- & $|$ & \{{\tt given}\}-clause \\
- & $|$ & \{{\tt consider}\}-clause {\tt from} term \\
- & $|$ & ({\tt have} $|$ {\tt then} $|$ {\tt thus} $|$ {\tt hence}]) statement
- justification \\
- & $|$ & \zeroone{\tt thus} ($\sim${\tt =}|{\tt =}$\sim$) \zeroone{\ident{\tt :}}\term\relax justification \\ & $|$ & {\tt suffices} (\{{\tt to have}\}-clause $|$
- \nelist{statement}{\tt and } \zeroone{{\tt and} \{{\tt to have}\}-clause})\\
- & & {\tt to show} statement justification \\
- & $|$ & ({\tt claim} $|$ {\tt focus on}) statement \\
- & $|$ & {\tt take} \term \\
- & $|$ & {\tt define} \ident \sequence{var}{,} {\tt as} \term\\
- & $|$ & {\tt reconsider} (\ident $|$ {\tt thesis}) {\tt as} type\\
- & $|$ &
- {\tt per} ({\tt cases}$|${\tt induction}) {\tt on} \term \\
- & $|$ & {\tt per cases of} type justification \\
- & $|$ & {\tt suppose} \zeroone{\nelist{ident}{,} {\tt and}}~
- {\tt it is }pattern\\
- & & \zeroone{{\tt such that} \nelist{statement} {\tt and} \zeroone{{\tt and} \{{\tt we have}\}-clause}} \\
- & $|$ & {\tt end}
- ({\tt proof} $|$ {\tt claim} $|$ {\tt focus} $|$ {\tt cases} $|$ {\tt induction}) \\
- & $|$ & {\tt escape} \\
- & $|$ & {\tt return} \medskip \\
- \{$\alpha,\beta$\}-clause & ::=& $\alpha$ \nelist{var}{,}~
- $\beta$ {\tt such that} \nelist{statement}{\tt and } \\
- & & \zeroone{{\tt and } \{$\alpha,\beta$\}-clause} \medskip\\
- statement & ::= & \zeroone{\ident {\tt :}} type \\
- & $|$ & {\tt thesis} \\
- & $|$ & {\tt thesis for} \ident \medskip \\
- var & ::= & \ident \zeroone{{\tt :} type} \medskip \\
- justification & ::= &
- \zeroone{{\tt by} ({\tt *} | \nelist{\term}{,})}
- ~\zeroone{{\tt using} tactic} \\
-\end{tabular}
-\end{centerframe}
-\caption{Syntax of mathematical proof commands}
-\end{figure}
-
-The lexical conventions used here follows those of section \ref{lexical}.
-
-
-Conventions:\begin{itemize}
-
- \item {\texttt{<{}tactic>{}}} stands for a Coq tactic.
-
- \end{itemize}
-
-\subsection{Temporary names}
-
-In proof commands where an optional name is asked for, omitting the
-name will trigger the creation of a fresh temporary name (e.g. for a
-hypothesis). Temporary names always start with an underscore `\_'
-character (e.g. {\tt \_hyp0}). Temporary names have a lifespan of one
-command: they get erased after the next command. They can however be safely in the step after their creation.
-
-\section{Language description}
-
-\subsection{Starting and Ending a mathematical proof}
-
-The standard way to use the \DPL{} is to first state a \texttt{Lemma} /
-\texttt{Theorem} / \texttt{Definition} and then use the \texttt{proof}
-command to switch the current subgoal to mathematical mode. After the
-proof is completed, the \texttt{end proof} command will close the
-mathematical proof. If any subgoal remains to be proved, they will be
-displayed using the usual Coq display.
-
-\begin{coq_example}
-Theorem this_is_trivial: True.
-proof.
- thus thesis.
-end proof.
-Qed.
-\end{coq_example}
-
-The {\texttt{proof}} command only applies to \emph{one subgoal}, thus
-if several sub-goals are already present, the {\texttt{proof ... end
- proof}} sequence has to be used several times.
-
-\begin{coq_example*}
-Theorem T: (True /\ True) /\ True.
- split. split.
-\end{coq_example*}
-\begin{coq_example}
- Show.
- proof. (* first subgoal *)
- thus thesis.
- end proof.
- trivial. (* second subgoal *)
- proof. (* third subgoal *)
- thus thesis.
- end proof.
-\end{coq_example}
-\begin{coq_eval}
-Abort.
-\end{coq_eval}
-
-As with all other block structures, the {\texttt{end proof}} command
-assumes that your proof is complete. If not, executing it will be
-equivalent to admitting that the statement is proved: A warning will
-be issued and you will not be able to run the {\texttt{Qed}}
-command. Instead, you can run {\texttt{Admitted}} if you wish to start
-another theorem and come back
-later.
-
-\begin{coq_example}
-Theorem this_is_not_so_trivial: False.
-proof.
-end proof. (* here a warning is issued *)
-Fail Qed. (* fails: the proof in incomplete *)
-Admitted. (* Oops! *)
-\end{coq_example}
-\begin{coq_eval}
-Reset this_is_not_so_trivial.
-\end{coq_eval}
-
-\subsection{Switching modes}
-
-When writing a mathematical proof, you may wish to use procedural
-tactics at some point. One way to do so is to write a using-{}phrase
-in a deduction step (see section~\ref{justifications}). The other way
-is to use an {\texttt{escape...return}} block.
-
-\begin{coq_eval}
-Theorem T: True.
-proof.
-\end{coq_eval}
-\begin{coq_example}
- Show.
- escape.
- auto.
- return.
-\end{coq_example}
-\begin{coq_eval}
-Abort.
-\end{coq_eval}
-
-The return statement expects all subgoals to be closed, otherwise a
-warning is issued and the proof cannot be saved anymore.
-
-It is possible to use the {\texttt{proof}} command inside an
-{\texttt{escape...return}} block, thus nesting a mathematical proof
-inside a procedural proof inside a mathematical proof...
-
-\subsection{Computation steps}
-
-The {\tt reconsider ... as} command allows changing the type of a hypothesis or of {\tt thesis} to a convertible one.
-
-\begin{coq_eval}
-Theorem T: let a:=false in let b:= true in ( if a then True else False -> if b then True else False).
-intros a b.
-proof.
-assume H:(if a then True else False).
-\end{coq_eval}
-\begin{coq_example}
- Show.
- reconsider H as False.
- reconsider thesis as True.
-\end{coq_example}
-\begin{coq_eval}
-Abort.
-\end{coq_eval}
-
-
-\subsection{Deduction steps}
-
-The most common instruction in a mathematical proof is the deduction
-step: it asserts a new statement (a formula/type of the \CIC) and tries
-to prove it using a user-provided indication: the justification. The
-asserted statement is then added as a hypothesis to the proof context.
-
-\begin{coq_eval}
-Theorem T: forall x, x=2 -> 2+x=4.
-proof.
-let x be such that H:(x=2).
-\end{coq_eval}
-\begin{coq_example}
- Show.
- have H':(2+x=2+2) by H.
-\end{coq_example}
-\begin{coq_eval}
-Abort.
-\end{coq_eval}
-
-It is often the case that the justifications uses the last hypothesis
-introduced in the context, so the {\tt then} keyword can be used as a
-shortcut, e.g. if we want to do the same as the last example:
-
-\begin{coq_eval}
-Theorem T: forall x, x=2 -> 2+x=4.
-proof.
-let x be such that H:(x=2).
-\end{coq_eval}
-\begin{coq_example}
- Show.
- then (2+x=2+2).
-\end{coq_example}
-\begin{coq_eval}
-Abort.
-\end{coq_eval}
-
-In this example, you can also see the creation of a temporary name {\tt \_fact}.
-
-\subsection{Iterated equalities}
-
-A common proof pattern when doing a chain of deductions is to do
-multiple rewriting steps over the same term, thus proving the
-corresponding equalities. The iterated equalities are a syntactic
-support for this kind of reasoning:
-
-\begin{coq_eval}
-Theorem T: forall x, x=2 -> x + x = x * x.
-proof.
-let x be such that H:(x=2).
-\end{coq_eval}
-\begin{coq_example}
- Show.
- have (4 = 4).
- ~= (2 * 2).
- ~= (x * x) by H.
- =~ (2 + 2).
- =~ H':(x + x) by H.
-\end{coq_example}
-\begin{coq_eval}
-Abort.
-\end{coq_eval}
-
-Notice that here we use temporary names heavily.
-
-\subsection{Subproofs}
-
-When an intermediate step in a proof gets too complicated or involves a
-well contained set of intermediate deductions, it can be useful to insert
-its proof as a subproof of the current proof. This is done by using the
-{\tt claim ... end claim} pair of commands.
-
-\begin{coq_eval}
-Theorem T: forall x, x + x = x * x -> x = 0 \/ x = 2.
-proof.
-let x be such that H:(x + x = x * x).
-\end{coq_eval}
-\begin{coq_example}
-Show.
-claim H':((x - 2) * x = 0).
-\end{coq_example}
-
-A few steps later...
-
-\begin{coq_example}
-thus thesis.
-end claim.
-\end{coq_example}
-
-Now the rest of the proof can happen.
-
-\begin{coq_eval}
-Abort.
-\end{coq_eval}
-
-\subsection{Conclusion steps}
-
-The commands described above have a conclusion counterpart, where the
-new hypothesis is used to refine the conclusion.
-
-\begin{figure}[b]
- \centering
-\begin{tabular}{c|c|c|c|c|}
- X & \,simple\, & \,with previous step\, &
- \,opens sub-proof\, & \,iterated equality\, \\
-\hline
-intermediate step & {\tt have} & {\tt then} &
- {\tt claim} & {\tt $\sim$=/=$\sim$}\\
-conclusion step & {\tt thus} & {\tt hence} &
- {\tt focus on} & {\tt thus $\sim$=/=$\sim$}\\
-\hline
-\end{tabular}
-\caption{Correspondence between basic forward steps and conclusion steps}
-\end{figure}
-
-Let us begin with simple examples:
-
-\begin{coq_eval}
-Theorem T: forall (A B:Prop), A -> B -> A /\ B.
-intros A B HA HB.
-proof.
-\end{coq_eval}
-\begin{coq_example}
-Show.
-hence B.
-\end{coq_example}
-\begin{coq_eval}
-Abort.
-\end{coq_eval}
-
-In the next example, we have to use {\tt thus} because {\tt HB} is no longer
-the last hypothesis.
-
-\begin{coq_eval}
-Theorem T: forall (A B C:Prop), A -> B -> C -> A /\ B /\ C.
-intros A B C HA HB HC.
-proof.
-\end{coq_eval}
-\begin{coq_example}
-Show.
-thus B by HB.
-\end{coq_example}
-\begin{coq_eval}
-Abort.
-\end{coq_eval}
-
-The command fails if the refinement process cannot find a place to fit
-the object in a proof of the conclusion.
-
-
-\begin{coq_eval}
-Theorem T: forall (A B C:Prop), A -> B -> C -> A /\ B.
-intros A B C HA HB HC.
-proof.
-\end{coq_eval}
-\begin{coq_example}
-Show.
-Fail hence C. (* fails *)
-\end{coq_example}
-\begin{coq_eval}
-Abort.
-\end{coq_eval}
-
-The refinement process may induce non
-reversible choices, e.g. when proving a disjunction it may {\it
- choose} one side of the disjunction.
-
-\begin{coq_eval}
-Theorem T: forall (A B:Prop), B -> A \/ B.
-intros A B HB.
-proof.
-\end{coq_eval}
-\begin{coq_example}
-Show.
-hence B.
-\end{coq_example}
-\begin{coq_eval}
-Abort.
-\end{coq_eval}
-
-In this example you can see that the right branch was chosen since {\tt D} remains to be proved.
-
-\begin{coq_eval}
-Theorem T: forall (A B C D:Prop), C -> D -> (A /\ B) \/ (C /\ D).
-intros A B C D HC HD.
-proof.
-\end{coq_eval}
-\begin{coq_example}
-Show.
-thus C by HC.
-\end{coq_example}
-\begin{coq_eval}
-Abort.
-\end{coq_eval}
-
-Now for existential statements, we can use the {\tt take} command to
-choose {\tt 2} as an explicit witness of existence.
-
-\begin{coq_eval}
-Theorem T: forall (P:nat -> Prop), P 2 -> exists x,P x.
-intros P HP.
-proof.
-\end{coq_eval}
-\begin{coq_example}
-Show.
-take 2.
-\end{coq_example}
-\begin{coq_eval}
-Abort.
-\end{coq_eval}
-
-It is also possible to prove the existence directly.
-
-\begin{coq_eval}
-Theorem T: forall (P:nat -> Prop), P 2 -> exists x,P x.
-intros P HP.
-proof.
-\end{coq_eval}
-\begin{coq_example}
-Show.
-hence (P 2).
-\end{coq_example}
-\begin{coq_eval}
-Abort.
-\end{coq_eval}
-
-Here a more involved example where the choice of {\tt P 2} propagates
-the choice of {\tt 2} to another part of the formula.
-
-\begin{coq_eval}
-Theorem T: forall (P:nat -> Prop) (R:nat -> nat -> Prop), P 2 -> R 0 2 -> exists x, exists y, P y /\ R x y.
-intros P R HP HR.
-proof.
-\end{coq_eval}
-\begin{coq_example}
-Show.
-thus (P 2) by HP.
-\end{coq_example}
-\begin{coq_eval}
-Abort.
-\end{coq_eval}
-
-Now, an example with the {\tt suffices} command. {\tt suffices}
-is a sort of dual for {\tt have}: it allows replacing the conclusion
-(or part of it) by a sufficient condition.
-
-\begin{coq_eval}
-Theorem T: forall (A B:Prop) (P:nat -> Prop), (forall x, P x -> B) -> A -> A /\ B.
-intros A B P HP HA.
-proof.
-\end{coq_eval}
-\begin{coq_example}
-Show.
-suffices to have x such that HP':(P x) to show B by HP,HP'.
-\end{coq_example}
-\begin{coq_eval}
-Abort.
-\end{coq_eval}
-
-Finally, an example where {\tt focus} is handy: local assumptions.
-
-\begin{coq_eval}
-Theorem T: forall (A:Prop) (P:nat -> Prop), P 2 -> A -> A /\ (forall x, x = 2 -> P x).
-intros A P HP HA.
-proof.
-\end{coq_eval}
-\begin{coq_example}
-Show.
-focus on (forall x, x = 2 -> P x).
-let x be such that (x = 2).
-hence thesis by HP.
-end focus.
-\end{coq_example}
-\begin{coq_eval}
-Abort.
-\end{coq_eval}
-
-\subsection{Declaring an Abbreviation}
-
-In order to shorten long expressions, it is possible to use the {\tt
- define ... as ...} command to give a name to recurring expressions.
-
-\begin{coq_eval}
-Theorem T: forall x, x = 0 -> x + x = x * x.
-proof.
-let x be such that H:(x = 0).
-\end{coq_eval}
-\begin{coq_example}
-Show.
-define sqr x as (x * x).
-reconsider thesis as (x + x = sqr x).
-\end{coq_example}
-\begin{coq_eval}
-Abort.
-\end{coq_eval}
-
-\subsection{Introduction steps}
-
-When the {\tt thesis} consists of a hypothetical formula (implication
-or universal quantification (e.g. \verb+A -> B+), it is possible to
-assume the hypothetical part {\tt A} and then prove {\tt B}. In the
-\DPL{}, this comes in two syntactic flavors that are semantically
-equivalent: {\tt let} and {\tt assume}. Their syntax is designed so that
-{\tt let} works better for universal quantifiers and {\tt assume} for
-implications.
-
-\begin{coq_eval}
-Theorem T: forall (P:nat -> Prop), forall x, P x -> P x.
-proof.
-let P:(nat -> Prop).
-\end{coq_eval}
-\begin{coq_example}
-Show.
-let x:nat.
-assume HP:(P x).
-\end{coq_example}
-\begin{coq_eval}
-Abort.
-\end{coq_eval}
-
-In the {\tt let} variant, the type of the assumed object is optional
-provided it can be deduced from the command. The objects introduced by
-let can be followed by assumptions using {\tt such that}.
-
-\begin{coq_eval}
-Theorem T: forall (P:nat -> Prop), forall x, P x -> P x.
-proof.
-let P:(nat -> Prop).
-\end{coq_eval}
-\begin{coq_example}
-Show.
-Fail let x. (* fails because x's type is not clear *)
-let x be such that HP:(P x). (* here x's type is inferred from (P x) *)
-\end{coq_example}
-\begin{coq_eval}
-Abort.
-\end{coq_eval}
-
-In the {\tt assume } variant, the type of the assumed object is mandatory
-but the name is optional:
-
-\begin{coq_eval}
-Theorem T: forall (P:nat -> Prop), forall x, P x -> P x -> P x.
-proof.
-let P:(nat -> Prop).
-let x:nat.
-\end{coq_eval}
-\begin{coq_example}
-Show.
-assume (P x). (* temporary name created *)
-\end{coq_example}
-\begin{coq_eval}
-Abort.
-\end{coq_eval}
-
-After {\tt such that}, it is also the case:
-
-\begin{coq_eval}
-Theorem T: forall (P:nat -> Prop), forall x, P x -> P x.
-proof.
-let P:(nat -> Prop).
-\end{coq_eval}
-\begin{coq_example}
-Show.
-let x be such that (P x). (* temporary name created *)
-\end{coq_example}
-\begin{coq_eval}
-Abort.
-\end{coq_eval}
-
-\subsection{Tuple elimination steps}
-
-In the \CIC, many objects dealt with in simple proofs are tuples:
-pairs, records, existentially quantified formulas. These are so
-common that the \DPL{} provides a mechanism to extract members of
-those tuples, and also objects in tuples within tuples within
-tuples...
-
-\begin{coq_eval}
-Theorem T: forall (P:nat -> Prop) (A:Prop), (exists x, (P x /\ A)) -> A.
-proof.
-let P:(nat -> Prop),A:Prop be such that H:(exists x, P x /\ A).
-\end{coq_eval}
-\begin{coq_example}
-Show.
-consider x such that HP:(P x) and HA:A from H.
-\end{coq_example}
-\begin{coq_eval}
-Abort.
-\end{coq_eval}
-
-Here is an example with pairs:
-
-\begin{coq_eval}
-Theorem T: forall p:(nat * nat)%type, (fst p >= snd p) \/ (fst p < snd p).
-proof.
-let p:(nat * nat)%type.
-\end{coq_eval}
-\begin{coq_example}
-Show.
-consider x:nat,y:nat from p.
-reconsider thesis as (x >= y \/ x < y).
-\end{coq_example}
-\begin{coq_eval}
-Abort.
-\end{coq_eval}
-
-It is sometimes desirable to combine assumption and tuple
-decomposition. This can be done using the {\tt given} command.
-
-\begin{coq_eval}
-Theorem T: forall P:(nat -> Prop), (forall n, P n -> P (n - 1)) ->
-(exists m, P m) -> P 0.
-proof.
-let P:(nat -> Prop) be such that HP:(forall n, P n -> P (n - 1)).
-\end{coq_eval}
-\begin{coq_example}
-Show.
-given m such that Hm:(P m).
-\end{coq_example}
-\begin{coq_eval}
-Abort.
-\end{coq_eval}
-
-\subsection{Disjunctive reasoning}
-
-In some proofs (most of them usually) one has to consider several
-cases and prove that the {\tt thesis} holds in all the cases. This is
-done by first specifying which object will be subject to case
-distinction (usually a disjunction) using {\tt per cases}, and then specifying which case is being proved by using {\tt suppose}.
-
-
-\begin{coq_eval}
-Theorem T: forall (A B C:Prop), (A -> C) -> (B -> C) -> (A \/ B) -> C.
-proof.
-let A:Prop,B:Prop,C:Prop be such that HAC:(A -> C) and HBC:(B -> C).
-assume HAB:(A \/ B).
-\end{coq_eval}
-\begin{coq_example}
-per cases on HAB.
-suppose A.
- hence thesis by HAC.
-suppose HB:B.
- thus thesis by HB,HBC.
-end cases.
-\end{coq_example}
-\begin{coq_eval}
-Abort.
-\end{coq_eval}
-
-The proof is well formed (but incomplete) even if you type {\tt end
- cases} or the next {\tt suppose} before the previous case is proved.
-
-If the disjunction is derived from a more general principle, e.g. the
-excluded middle axiom), it is desirable to just specify which instance
-of it is being used:
-
-\begin{coq_eval}
-Section Coq.
-\end{coq_eval}
-\begin{coq_example}
-Hypothesis EM : forall P:Prop, P \/ ~ P.
-\end{coq_example}
-\begin{coq_eval}
-Theorem T: forall (A C:Prop), (A -> C) -> (~A -> C) -> C.
-proof.
-let A:Prop,C:Prop be such that HAC:(A -> C) and HNAC:(~A -> C).
-\end{coq_eval}
-\begin{coq_example}
-per cases of (A \/ ~A) by EM.
-suppose (~A).
- hence thesis by HNAC.
-suppose A.
- hence thesis by HAC.
-end cases.
-\end{coq_example}
-\begin{coq_eval}
-Abort.
-\end{coq_eval}
-
-\subsection{Proofs per cases}
-
-If the case analysis is to be made on a particular object, the script
-is very similar: it starts with {\tt per cases on }\emph{object} instead.
-
-\begin{coq_eval}
-Theorem T: forall (A C:Prop), (A -> C) -> (~A -> C) -> C.
-proof.
-let A:Prop,C:Prop be such that HAC:(A -> C) and HNAC:(~A -> C).
-\end{coq_eval}
-\begin{coq_example}
-per cases on (EM A).
-suppose (~A).
-\end{coq_example}
-\begin{coq_eval}
-Abort.
-End Coq.
-\end{coq_eval}
-
-If the object on which a case analysis occurs in the statement to be
-proved, the command {\tt suppose it is }\emph{pattern} is better
-suited than {\tt suppose}. \emph{pattern} may contain nested patterns
-with {\tt as} clauses. A detailed description of patterns is to be
-found in figure \ref{term-syntax-aux}. here is an example.
-
-\begin{coq_eval}
-Theorem T: forall (A B:Prop) (x:bool), (if x then A else B) -> A \/ B.
-proof.
-let A:Prop,B:Prop,x:bool.
-\end{coq_eval}
-\begin{coq_example}
-per cases on x.
-suppose it is true.
- assume A.
- hence A.
-suppose it is false.
- assume B.
- hence B.
-end cases.
-\end{coq_example}
-\begin{coq_eval}
-Abort.
-\end{coq_eval}
-
-\subsection{Proofs by induction}
-
-Proofs by induction are very similar to proofs per cases: they start
-with {\tt per induction on }{\tt object} and proceed with {\tt suppose
- it is }\emph{pattern}{\tt and }\emph{induction hypothesis}. The
-induction hypothesis can be given explicitly or identified by the
-sub-object $m$ it refers to using {\tt thesis for }\emph{m}.
-
-\begin{coq_eval}
-Theorem T: forall (n:nat), n + 0 = n.
-proof.
-let n:nat.
-\end{coq_eval}
-\begin{coq_example}
-per induction on n.
-suppose it is 0.
- thus (0 + 0 = 0).
-suppose it is (S m) and H:thesis for m.
- then (S (m + 0) = S m).
- thus =~ (S m + 0).
-end induction.
-\end{coq_example}
-\begin{coq_eval}
-Abort.
-\end{coq_eval}
-
-\subsection{Justifications}\label{justifications}
-
-
-Intuitively, justifications are hints for the system to understand how
-to prove the statements the user types in. In the case of this
-language justifications are made of two components:
-
-Justification objects: {\texttt{by}} followed by a comma-{}separated
-list of objects that will be used by a selected tactic to prove the
-statement. This defaults to the empty list (the statement should then
-be tautological). The * wildcard provides the usual tactics behavior:
-use all statements in local context. However, this wildcard should be
-avoided since it reduces the robustness of the script.
-
-Justification tactic: {\texttt{using}} followed by a Coq tactic that
-is executed to prove the statement. The default is a solver for
-(intuitionistic) first-{}order with equality.
-
-\section{More details and Formal Semantics}
-
-I suggest the users looking for more information have a look at the
-paper \cite{corbineau08types}. They will find in that paper a formal
-semantics of the proof state transition induces by mathematical
-commands.
diff --git a/doc/refman/RefMan-ext.tex b/doc/refman/RefMan-ext.tex
index 03fe92c772..1860c0465c 100644
--- a/doc/refman/RefMan-ext.tex
+++ b/doc/refman/RefMan-ext.tex
@@ -996,7 +996,7 @@ but library file names based on other roots can be obtained by using
{\Coq} commands ({\tt coqc}, {\tt coqtop}, {\tt coqdep}, \dots) options
{\tt -Q} or {\tt -R} (see Section~\ref{coqoptions}). Also, when an
interactive {\Coq} session starts, a library of root {\tt Top} is
-started, unless option {\tt -top} or {\tt -notop} is set (see
+started, unless option {\tt -top} is set (see
Section~\ref{coqoptions}).
\subsection{Qualified names
diff --git a/doc/refman/RefMan-syn.tex b/doc/refman/RefMan-syn.tex
index 61093709ec..ecaf82806e 100644
--- a/doc/refman/RefMan-syn.tex
+++ b/doc/refman/RefMan-syn.tex
@@ -120,7 +120,7 @@ Notation "A \/ B" := (or A B) (at level 85, right associativity).
By default, a notation is considered non associative, but the
precedence level is mandatory (except for special cases whose level is
-canonical). The level is either a number or the mention {\tt next
+canonical). The level is either a number or the phrase {\tt next
level} whose meaning is obvious. The list of levels already assigned
is on Figure~\ref{init-notations}.
diff --git a/doc/refman/Reference-Manual.tex b/doc/refman/Reference-Manual.tex
index dcb98d96b3..291c07de4c 100644
--- a/doc/refman/Reference-Manual.tex
+++ b/doc/refman/Reference-Manual.tex
@@ -98,7 +98,6 @@ Options A and B of the licence are {\em not} elected.}
\include{RefMan-tac.v}% Tactics and tacticals
\include{RefMan-ltac.v}% Writing tactics
\include{RefMan-tacex.v}% Detailed Examples of tactics
-\include{RefMan-decl.v}% The mathematical proof language
\part{User extensions}
\include{RefMan-syn.v}% The Syntax and the Grammar commands
diff --git a/engine/evd.ml b/engine/evd.ml
index 62d3963954..b7d56a698e 100644
--- a/engine/evd.ml
+++ b/engine/evd.ml
@@ -1157,10 +1157,6 @@ let set_extra_data extras evd = { evd with extras }
(*******************************************************************)
-type pending = (* before: *) evar_map * (* after: *) evar_map
-
-type pending_constr = pending * constr
-
type open_constr = evar_map * constr
(*******************************************************************)
diff --git a/engine/evd.mli b/engine/evd.mli
index 993ed300bc..5619b7af29 100644
--- a/engine/evd.mli
+++ b/engine/evd.mli
@@ -601,10 +601,6 @@ val e_eq_constr_univs : evar_map ref -> constr -> constr -> bool
(* constr with holes and pending resolution of classes, conversion *)
(* problems, candidates, etc. *)
-type pending = (* before: *) evar_map * (* after: *) evar_map
-
-type pending_constr = pending * constr
-
type open_constr = evar_map * constr (* Special case when before is empty *)
(** Partially constructed constrs. *)
diff --git a/engine/universes.ml b/engine/universes.ml
index 6720fcef8f..30a9ef1634 100644
--- a/engine/universes.ml
+++ b/engine/universes.ml
@@ -416,10 +416,9 @@ let constr_of_global gr =
(* Should be an error as we might forget constraints, allow for now
to make firstorder work with "using" clauses *)
c
- else raise (Invalid_argument
- ("constr_of_global: globalization of polymorphic reference " ^
- Pp.string_of_ppcmds (Nametab.pr_global_env Id.Set.empty gr) ^
- " would forget universes."))
+ else CErrors.user_err ~hdr:"constr_of_global"
+ Pp.(str "globalization of polymorphic reference " ++ Nametab.pr_global_env Id.Set.empty gr ++
+ str " would forget universes.")
else c
let constr_of_reference = constr_of_global
diff --git a/grammar/tacextend.mlp b/grammar/tacextend.mlp
index 8605dda3a0..8c0614a7be 100644
--- a/grammar/tacextend.mlp
+++ b/grammar/tacextend.mlp
@@ -82,14 +82,14 @@ let make_var = function
| ExtNonTerminal (_, p) -> Some p
| _ -> assert false
-let declare_tactic loc s c cl = match cl with
+let declare_tactic loc tacname ~level classification clause = match clause with
| [(ExtTerminal name) :: rem, _, tac] when List.for_all is_constr_gram rem ->
(** The extension is only made of a name followed by constr entries: we do not
add any grammar nor printing rule and add it as a true Ltac definition. *)
let patt = make_patt rem in
let vars = List.map make_var rem in
let vars = mlexpr_of_list (mlexpr_of_name mlexpr_of_ident) vars in
- let entry = mlexpr_of_string s in
+ let entry = mlexpr_of_string tacname in
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
@@ -117,13 +117,14 @@ let declare_tactic loc s c cl = match cl with
| _ ->
(** Otherwise we add parsing and printing rules to generate a call to a
TacML tactic. *)
- let entry = mlexpr_of_string s in
+ let entry = mlexpr_of_string tacname in
let se = <:expr< { Tacexpr.mltac_tactic = $entry$; Tacexpr.mltac_plugin = $plugin_name$ } >> in
- let gl = mlexpr_of_clause cl in
- let obj = <:expr< fun () -> Tacentries.add_ml_tactic_notation $se$ $gl$ >> in
+ let gl = mlexpr_of_clause clause in
+ let level = mlexpr_of_int level in
+ let obj = <:expr< fun () -> Tacentries.add_ml_tactic_notation $se$ $level$ $gl$ >> in
declare_str_items loc
[ <:str_item< do {
- Tacenv.register_ml_tactic $se$ (Array.of_list $make_fun_clauses loc s cl$);
+ Tacenv.register_ml_tactic $se$ (Array.of_list $make_fun_clauses loc tacname clause$);
Mltop.declare_cache_obj $obj$ $plugin_name$; } >>
]
@@ -134,20 +135,17 @@ EXTEND
GLOBAL: str_item;
str_item:
[ [ "TACTIC"; "EXTEND"; s = tac_name;
+ level = OPT [ "AT"; UIDENT "LEVEL"; level = INT -> level ];
c = OPT [ "CLASSIFIED"; "BY"; c = LIDENT -> <:expr< $lid:c$ >> ];
OPT "|"; l = LIST1 tacrule SEP "|";
"END" ->
- declare_tactic loc s c l ] ]
+ let level = match level with Some i -> int_of_string i | None -> 0 in
+ declare_tactic loc s ~level c l ] ]
;
tacrule:
[ [ "["; l = LIST1 tacargs; "]";
c = OPT [ "=>"; "["; c = Pcaml.expr; "]" -> c ];
- "->"; "["; e = Pcaml.expr; "]" ->
- (match l with
- | ExtNonTerminal _ :: _ ->
- (* En attendant la syntaxe de tacticielles *)
- failwith "Tactic syntax must start with an identifier"
- | _ -> (l,c,e))
+ "->"; "["; e = Pcaml.expr; "]" -> (l,c,e)
] ]
;
tacargs:
diff --git a/ide/coq.ml b/ide/coq.ml
index 6d44ca59e3..3a1d877872 100644
--- a/ide/coq.ml
+++ b/ide/coq.ml
@@ -205,7 +205,7 @@ type handle = {
proc : CoqTop.process;
xml_oc : Xml_printer.t;
mutable alive : bool;
- mutable waiting_for : (ccb * logger) option; (* last call + callback + log *)
+ mutable waiting_for : ccb option; (* last call + callback *)
}
(** Coqtop process status :
@@ -290,18 +290,6 @@ let rec check_errors = function
| `NVAL :: _ -> raise (TubeError "NVAL")
| `OUT :: _ -> raise (TubeError "OUT")
-let handle_intermediate_message handle level content =
- let logger = match handle.waiting_for with
- | Some (_, l) -> l
- | None -> function
- | 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 content
-
let handle_feedback feedback_processor xml =
let feedback = Xmlprotocol.to_feedback xml in
feedback_processor feedback
@@ -310,7 +298,7 @@ let handle_final_answer handle xml =
let () = Minilib.log "Handling coqtop answer" in
let ccb = match handle.waiting_for with
| None -> raise (AnswerWithoutRequest (Xml_printer.to_string_fmt xml))
- | Some (c, _) -> c in
+ | Some c -> c in
let () = handle.waiting_for <- None in
with_ccb ccb { bind_ccb = fun (c, f) -> f (Xmlprotocol.to_answer c xml) }
@@ -332,18 +320,13 @@ 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;
- match Xmlprotocol.is_message xml with
- | Some (lvl, _loc, msg) ->
- handle_intermediate_message handle lvl msg;
+ if Xmlprotocol.is_feedback xml then begin
+ handle_feedback feedback_processor xml;
loop ()
- | None ->
- if Xmlprotocol.is_feedback xml then begin
- handle_feedback feedback_processor xml;
- loop ()
- end else
- begin
- ignore (handle_final_answer handle xml)
- end
+ end else
+ begin
+ ignore (handle_final_answer handle xml)
+ end
in
try loop ()
with Xml_parser.Error _ as e ->
@@ -383,7 +366,7 @@ let bind_self_as f =
(** This launches a fresh handle from its command line arguments. *)
let spawn_handle args respawner feedback_processor =
let prog = coqtop_path () in
- let args = Array.of_list ("-async-proofs" :: "on" :: "-ideslave" :: args) in
+ let args = Array.of_list ("--xml_format=Ppcmds" :: "-async-proofs" :: "on" :: "-ideslave" :: args) in
let env =
match !Flags.ideslave_coqtop_flags with
| None -> None
@@ -493,20 +476,20 @@ let init_coqtop coqtop task =
type 'a query = 'a Interface.value task
-let eval_call ?(logger=default_logger) call handle k =
+let eval_call call handle k =
(** Send messages to coqtop and prepare the decoding of the answer *)
Minilib.log ("Start eval_call " ^ Xmlprotocol.pr_call call);
assert (handle.alive && handle.waiting_for = None);
- handle.waiting_for <- Some (mk_ccb (call,k), logger);
+ handle.waiting_for <- Some (mk_ccb (call,k));
Xml_printer.print handle.xml_oc (Xmlprotocol.of_call call);
Minilib.log "End eval_call";
Void
-let add ?(logger=default_logger) x = eval_call ~logger (Xmlprotocol.add x)
+let add x = eval_call (Xmlprotocol.add x)
let edit_at i = eval_call (Xmlprotocol.edit_at i)
-let query ?(logger=default_logger) x = eval_call ~logger (Xmlprotocol.query x)
+let query x = eval_call (Xmlprotocol.query x)
let mkcases s = eval_call (Xmlprotocol.mkcases s)
-let status ?logger force = eval_call ?logger (Xmlprotocol.status force)
+let status force = eval_call (Xmlprotocol.status force)
let hints x = eval_call (Xmlprotocol.hints x)
let search flags = eval_call (Xmlprotocol.search flags)
let init x = eval_call (Xmlprotocol.init x)
@@ -566,18 +549,11 @@ struct
let _ = reset ()
- (** Integer option *)
-
- let width = ["Printing"; "Width"]
- let width_state = ref None
- let set_printing_width w = width_state := Some w
-
(** Transmitting options to coqtop *)
let enforce h k =
let mkopt o v acc = (o, Interface.BoolValue v) :: acc in
let opts = Hashtbl.fold mkopt current_state [] in
- let opts = (width, Interface.IntValue !width_state) :: opts in
eval_call (Xmlprotocol.set_options opts) h
(function
| Interface.Good () -> k ()
@@ -585,8 +561,8 @@ struct
end
-let goals ?logger x h k =
- PrintOpt.enforce h (fun () -> eval_call ?logger (Xmlprotocol.goals x) h k)
+let goals x h k =
+ PrintOpt.enforce h (fun () -> eval_call (Xmlprotocol.goals x) h k)
let evars x h k =
PrintOpt.enforce h (fun () -> eval_call (Xmlprotocol.evars x) h k)
diff --git a/ide/coq.mli b/ide/coq.mli
index 8a1fa3ed15..ab8c12a6f1 100644
--- a/ide/coq.mli
+++ b/ide/coq.mli
@@ -115,15 +115,11 @@ val try_grab : coqtop -> unit task -> (unit -> unit) -> unit
type 'a query = 'a Interface.value task
(** A type abbreviation for coqtop specific answers *)
-val add : ?logger:Ideutils.logger ->
- Interface.add_sty -> Interface.add_rty query
+val add : Interface.add_sty -> Interface.add_rty query
val edit_at : Interface.edit_at_sty -> Interface.edit_at_rty query
-val query : ?logger:Ideutils.logger ->
- Interface.query_sty -> Interface.query_rty query
-val status : ?logger:Ideutils.logger ->
- Interface.status_sty -> Interface.status_rty query
-val goals : ?logger:Ideutils.logger ->
- Interface.goals_sty -> Interface.goals_rty query
+val query : Interface.query_sty -> Interface.query_rty query
+val status : Interface.status_sty -> Interface.status_rty query
+val goals : Interface.goals_sty -> Interface.goals_rty query
val evars : Interface.evars_sty -> Interface.evars_rty query
val hints : Interface.hints_sty -> Interface.hints_rty query
val mkcases : Interface.mkcases_sty -> Interface.mkcases_rty query
@@ -143,7 +139,6 @@ sig
val bool_items : bool_descr list
val set : t -> bool -> unit
- val set_printing_width : int -> unit
(** [enforce] transmits to coq the current option values.
It is also called by [goals] and [evars] above. *)
diff --git a/ide/coqOps.ml b/ide/coqOps.ml
index 1563c7ffb4..45b5a1007a 100644
--- a/ide/coqOps.ml
+++ b/ide/coqOps.ml
@@ -128,6 +128,9 @@ end = struct
end
open SentenceId
+let log_pp msg : unit task =
+ Coq.lift (fun () -> Minilib.log_pp msg)
+
let log msg : unit task =
Coq.lift (fun () -> Minilib.log msg)
@@ -162,13 +165,16 @@ let flags_to_color f =
else if List.mem `INCOMPLETE f then `NAME "gray"
else `NAME Preferences.processed_color#get
-let validate s =
- let open Xml_datatype in
- let rec validate = function
- | PCData s -> Glib.Utf8.validate s
- | Element (_, _, children) -> List.for_all validate children
- in
- validate (Richpp.repr s)
+(* Move to utils? *)
+let rec validate (s : Pp.std_ppcmds) = match Pp.repr s with
+ | Pp.Ppcmd_empty
+ | Pp.Ppcmd_print_break _
+ | Pp.Ppcmd_force_newline -> true
+ | Pp.Ppcmd_glue l -> List.for_all validate l
+ | Pp.Ppcmd_string s -> Glib.Utf8.validate s
+ | Pp.Ppcmd_box (_,s)
+ | Pp.Ppcmd_tag (_,s) -> validate s
+ | Pp.Ppcmd_comment s -> List.for_all Glib.Utf8.validate s
module Doc = Document
@@ -305,7 +311,7 @@ object(self)
method private print_stack =
Minilib.log "document:";
- Minilib.log (Pp.string_of_ppcmds (Doc.print document (dbg_to_string buffer)))
+ Minilib.log_pp (Doc.print document (dbg_to_string buffer))
method private enter_focus start stop =
let at id id' _ = Stateid.equal id' id in
@@ -337,7 +343,6 @@ object(self)
buffer#get_iter_at_mark `INSERT
method private show_goals_aux ?(move_insert=false) () =
- Coq.PrintOpt.set_printing_width proof#width;
if move_insert then begin
let dest = self#get_start_of_input in
if (buffer#get_iter_at_mark `INSERT)#compare dest <= 0 then begin
@@ -345,7 +350,7 @@ object(self)
script#recenter_insert
end
end;
- Coq.bind (Coq.goals ~logger:messages#push ()) (function
+ Coq.bind (Coq.goals ()) (function
| Fail x -> self#handle_failure_aux ~move_insert x
| Good goals ->
Coq.bind (Coq.evars ()) (function
@@ -353,7 +358,7 @@ object(self)
| Good evs ->
proof#set_goals goals;
proof#set_evars evs;
- proof#refresh ();
+ proof#refresh ~force:true;
Coq.return ()
)
)
@@ -368,7 +373,7 @@ object(self)
else messages#add s;
in
let query =
- Coq.query ~logger:messages#push (phrase,Stateid.dummy) in
+ Coq.query (phrase,Stateid.dummy) in
let next = function
| Fail (_, _, err) -> display_error err; Coq.return ()
| Good msg ->
@@ -377,8 +382,7 @@ object(self)
Coq.bind (Coq.seq action query) next
method private mark_as_needed sentence =
- Minilib.log("Marking " ^
- Pp.string_of_ppcmds (dbg_to_string buffer false None sentence));
+ Minilib.log_pp Pp.(str "Marking " ++ dbg_to_string buffer false None sentence);
let start = buffer#get_iter_at_mark sentence.start in
let stop = buffer#get_iter_at_mark sentence.stop in
let to_process = Tags.Script.to_process in
@@ -418,9 +422,10 @@ object(self)
| _ -> false
method private enqueue_feedback msg =
+ (* Minilib.log ("Feedback received: " ^ Xml_printer.to_string_fmt (Xmlprotocol.of_feedback msg)); *)
let id = msg.id in
if self#is_dummy_id id then () else Queue.add msg feedbacks
-
+
method private process_feedback () =
let rec eat_feedback n =
if n = 0 then true else
@@ -434,9 +439,11 @@ object(self)
| _ -> None in
try Some (Doc.find_map document finder)
with Not_found -> None in
- let log s state_id =
- Minilib.log ("Feedback " ^ s ^ " on " ^ Stateid.to_string
- (Option.default Stateid.dummy state_id)) in
+ let log_pp s state_id =
+ Minilib.log_pp Pp.(seq
+ [str "Feedback "; s; str " on ";
+ str (Stateid.to_string (Option.default Stateid.dummy state_id))]) in
+ let log s state_id = log_pp (Pp.str s) state_id in
begin match msg.contents, sentence with
| AddedAxiom, Some (id,sentence) ->
log "AddedAxiom" id;
@@ -466,22 +473,24 @@ object(self)
(Printf.sprintf "%s %s %s" filepath ident ty)
| Message(Error, loc, msg), Some (id,sentence) ->
let loc = Option.default Loc.ghost loc in
- let msg = Richpp.raw_print msg in
- log "ErrorMsg" id;
+ log_pp Pp.(str "ErrorMsg" ++ msg) id;
remove_flag sentence `PROCESSING;
- add_flag sentence (`ERROR (loc, msg));
+ let rmsg = Pp.string_of_ppcmds msg in
+ add_flag sentence (`ERROR (loc, rmsg));
self#mark_as_needed sentence;
- self#attach_tooltip sentence loc msg;
+ self#attach_tooltip sentence loc rmsg;
if not (Loc.is_ghost loc) then
self#position_error_tag_at_sentence sentence (Some (Loc.unloc loc))
| Message(Warning, loc, msg), Some (id,sentence) ->
let loc = Option.default Loc.ghost loc in
- let msg = Richpp.raw_print msg in
- log "WarningMsg" id;
- add_flag sentence (`WARNING (loc, msg));
- self#attach_tooltip sentence loc msg;
- self#position_warning_tag_at_sentence sentence loc
- | Message((Info|Notice|Debug as lvl), _, msg), _ ->
+ log_pp Pp.(str "WarningMsg" ++ msg) id;
+ let rmsg = Pp.string_of_ppcmds msg in
+ add_flag sentence (`WARNING (loc, rmsg));
+ self#attach_tooltip sentence loc rmsg;
+ self#position_warning_tag_at_sentence sentence loc;
+ messages#push Warning msg
+ | Message(lvl, loc, msg), Some (id,sentence) ->
+ log_pp Pp.(str "Msg" ++ msg) id;
messages#push lvl msg
| InProgress n, _ ->
if n < 0 then processed <- processed + abs n
@@ -628,10 +637,9 @@ object(self)
if Queue.is_empty queue then conclude topstack else
match Queue.pop queue, topstack with
| `Skip(start,stop), [] ->
-
- logger Feedback.Error (Richpp.richpp_of_string "You must close the proof with Qed or Admitted");
+ logger Feedback.Error (Pp.str "You must close the proof with Qed or Admitted");
self#discard_command_queue queue;
- conclude []
+ conclude []
| `Skip(start,stop), (_,s) :: topstack ->
assert(start#equal (buffer#get_iter_at_mark s.start));
assert(stop#equal (buffer#get_iter_at_mark s.stop));
@@ -641,11 +649,11 @@ object(self)
add_flag sentence `PROCESSING;
Doc.push document sentence;
let _, _, phrase = self#get_sentence sentence in
- let coq_query = Coq.add ~logger ((phrase,edit_id),(tip,verbose)) in
+ let coq_query = Coq.add ((phrase,edit_id),(tip,verbose)) in
let handle_answer = function
| Good (id, (Util.Inl (* NewTip *) (), msg)) ->
Doc.assign_tip_id document id;
- logger Feedback.Notice (Richpp.richpp_of_string msg);
+ logger Feedback.Notice (Pp.str msg);
self#commit_queue_transaction sentence;
loop id []
| Good (id, (Util.Inr (* Unfocus *) tip, msg)) ->
@@ -653,7 +661,7 @@ object(self)
let topstack, _ = Doc.context document in
self#exit_focus;
self#cleanup (Doc.cut_at document tip);
- logger Feedback.Notice (Richpp.richpp_of_string msg);
+ logger Feedback.Notice (Pp.str msg);
self#mark_as_needed sentence;
if Queue.is_empty queue then loop tip []
else loop tip (List.rev topstack)
@@ -672,10 +680,10 @@ object(self)
let next = function
| Good _ ->
messages#clear;
- messages#push Feedback.Info (Richpp.richpp_of_string "All proof terms checked by the kernel");
+ messages#push Feedback.Info (Pp.str "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
+ Coq.bind (Coq.status true) next
method stop_worker n =
Coq.bind (Coq.stop_worker n) (fun _ -> Coq.return ())
@@ -859,7 +867,7 @@ object(self)
let next = function
| Fail (_, l, str) -> (* FIXME: check *)
display_error (l, str);
- messages#add (Richpp.richpp_of_string ("Unsuccessfully tried: "^phrase));
+ messages#add (Pp.str ("Unsuccessfully tried: "^phrase));
more
| Good msg ->
messages#add_string msg;
@@ -905,7 +913,7 @@ object(self)
let get_initial_state =
let next = function
| Fail (_, _, message) ->
- let message = "Couldn't initialize coqtop\n\n" ^ (Richpp.raw_print message) in
+ let message = "Couldn't initialize coqtop\n\n" ^ (Pp.string_of_ppcmds 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
diff --git a/ide/coqide.ml b/ide/coqide.ml
index 450bfcdfb1..25858acced 100644
--- a/ide/coqide.ml
+++ b/ide/coqide.ml
@@ -318,7 +318,7 @@ let export kind sn =
local_cd f ^ cmd_coqdoc#get ^ " --" ^ kind ^ " -o " ^
(Filename.quote output) ^ " " ^ (Filename.quote basef) ^ " 2>&1"
in
- sn.messages#set (Richpp.richpp_of_string ("Running: "^cmd));
+ sn.messages#set (Pp.str ("Running: "^cmd));
let finally st = flash_info (cmd ^ pr_exit_status st)
in
run_command (fun msg -> sn.messages#add_string msg) finally cmd
@@ -431,7 +431,7 @@ let compile sn =
^ " " ^ (Filename.quote f) ^ " 2>&1"
in
let buf = Buffer.create 1024 in
- sn.messages#set (Richpp.richpp_of_string ("Running: "^cmd));
+ sn.messages#set (Pp.str ("Running: "^cmd));
let display s =
sn.messages#add_string s;
Buffer.add_string buf s
@@ -441,8 +441,8 @@ let compile sn =
flash_info (f ^ " successfully compiled")
else begin
flash_info (f ^ " failed to compile");
- sn.messages#set (Richpp.richpp_of_string "Compilation output:\n");
- sn.messages#add (Richpp.richpp_of_string (Buffer.contents buf));
+ sn.messages#set (Pp.str "Compilation output:\n");
+ sn.messages#add (Pp.str (Buffer.contents buf));
end
in
run_command display finally cmd
@@ -464,7 +464,7 @@ let make sn =
|Some f ->
File.saveall ();
let cmd = local_cd f ^ cmd_make#get ^ " 2>&1" in
- sn.messages#set (Richpp.richpp_of_string "Compilation output:\n");
+ sn.messages#set (Pp.str "Compilation output:\n");
Buffer.reset last_make_buf;
last_make := "";
last_make_index := 0;
@@ -508,11 +508,11 @@ let next_error sn =
let stopi = b#get_iter_at_byte ~line:(line-1) stop in
b#apply_tag Tags.Script.error ~start:starti ~stop:stopi;
b#place_cursor ~where:starti;
- sn.messages#set (Richpp.richpp_of_string error_msg);
+ sn.messages#set (Pp.str error_msg);
sn.script#misc#grab_focus ()
with Not_found ->
last_make_index := 0;
- sn.messages#set (Richpp.richpp_of_string "No more errors.\n")
+ sn.messages#set (Pp.str "No more errors.\n")
let next_error = cb_on_current_term next_error
@@ -536,7 +536,7 @@ let update_status sn =
display ("Ready"^ (if nanoPG#get then ", [μPG]" else "") ^ path ^ name);
Coq.return ()
in
- Coq.bind (Coq.status ~logger:sn.messages#push false) next
+ Coq.bind (Coq.status false) next
let find_next_occurrence ~backward sn =
(** go to the next occurrence of the current word, forward or backward *)
@@ -789,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 Feedback.Error (Richpp.richpp_of_string msg)
+ sn.messages#push Feedback.Error (Pp.str msg)
else dialog#destroy ()
in
let _ = entry#connect#activate ok_cb in
@@ -887,8 +887,8 @@ let alpha_items menu_name item_name l =
| [] -> ()
| [s] -> mk_item s
| s::_ as ll ->
- let name = item_name^" "^(String.make 1 s.[0]) in
- let label = "_@..." in label.[1] <- s.[0];
+ let name = Printf.sprintf "%s %c" item_name s.[0] in
+ let label = Printf.sprintf "_%c..." s.[0] in
item name ~label menu_name;
List.iter mk_item ll
in
diff --git a/ide/coqidetop.mllib b/ide/coqidetop.mllib
index ed1fa465d2..043ad6008b 100644
--- a/ide/coqidetop.mllib
+++ b/ide/coqidetop.mllib
@@ -2,7 +2,7 @@ Xml_lexer
Xml_parser
Xml_printer
Serialize
-Richprinter
+Richpp
Xmlprotocol
Texmacspp
Document
diff --git a/ide/ide.mllib b/ide/ide.mllib
index 72a14134bf..78b4c01e8c 100644
--- a/ide/ide.mllib
+++ b/ide/ide.mllib
@@ -9,11 +9,12 @@ Config_lexer
Utf8_convert
Preferences
Project_file
-Serialize
-Richprinter
Xml_lexer
Xml_parser
Xml_printer
+Serialize
+Richpp
+Topfmt
Xmlprotocol
Ideutils
Coq
diff --git a/ide/ide_slave.ml b/ide/ide_slave.ml
index ae3dcd94a9..8cadf1a263 100644
--- a/ide/ide_slave.ml
+++ b/ide/ide_slave.ml
@@ -32,24 +32,6 @@ let init_signal_handler () =
let f _ = if !catch_break then raise Sys.Break else Control.interrupt := true in
Sys.set_signal Sys.sigint (Sys.Signal_handle f)
-
-(** Redirection of standard output to a printable buffer *)
-
-let init_stdout, read_stdout =
- let out_buff = Buffer.create 100 in
- let out_ft = Format.formatter_of_buffer out_buff in
- let deep_out_ft = Format.formatter_of_buffer out_buff in
- let _ = Pp_control.set_gp deep_out_ft Pp_control.deep_gp in
- (fun () ->
- flush_all ();
- Pp_control.std_ft := out_ft;
- Pp_control.err_ft := out_ft;
- Pp_control.deep_ft := deep_out_ft;
- ),
- (fun () -> Format.pp_print_flush out_ft ();
- let r = Buffer.contents out_buff in
- Buffer.clear out_buff; r)
-
let pr_with_pid s = Printf.eprintf "[pid %d] %s\n%!" (Unix.getpid ()) s
let pr_error s = pr_with_pid s
@@ -97,42 +79,58 @@ let is_undo cmd = match cmd with
| VernacUndo _ | VernacUndoTo _ -> true
| _ -> false
-(** Check whether a command is forbidden by CoqIDE *)
+(** Check whether a command is forbidden in the IDE *)
-let coqide_cmd_checks (loc,ast) =
+let ide_cmd_checks (loc,ast) =
let user_error s = CErrors.user_err ~loc ~hdr:"CoqIde" (str s) in
if is_debug ast then
- user_error "Debug mode not available within CoqIDE";
+ user_error "Debug mode not available in the IDE";
if is_known_option ast then
- Feedback.msg_warning (strbrk"This will not work. Use CoqIDE view menu instead");
+ Feedback.msg_warning (strbrk "Set this option from the IDE menu instead");
if Vernac.is_navigation_vernac ast || is_undo ast then
- Feedback.msg_warning (strbrk "Rather use CoqIDE navigation instead");
+ Feedback.msg_warning (strbrk "Use IDE navigation instead");
if is_query ast then
Feedback.msg_warning (strbrk "Query commands should not be inserted in scripts")
(** Interpretation (cf. [Ide_intf.interp]) *)
let add ((s,eid),(sid,verbose)) =
- let newid, rc = Stm.add ~ontop:sid verbose ~check:coqide_cmd_checks eid s in
+ let newid, rc = Stm.add ~ontop:sid verbose ~check:ide_cmd_checks eid s in
let rc = match rc with `NewTip -> CSig.Inl () | `Unfocus id -> CSig.Inr id in
- newid, (rc, read_stdout ())
+ (* TODO: the "" parameter is a leftover of the times the protocol
+ * used to include stderr/stdout output.
+ *
+ * Currently, we force all the output meant for the to go via the
+ * feedback mechanism, and we don't manipulate stderr/stdout, which
+ * are left to the client's discrection. The parameter is still there
+ * as not to break the core protocol for this minor change, but it should
+ * be removed in the next version of the protocol.
+ *)
+ newid, (rc, "")
let edit_at id =
match Stm.edit_at id with
| `NewTip -> CSig.Inl ()
| `Focus { Stm.start; stop; tip} -> CSig.Inr (start, (stop, tip))
-let query (s,id) = Stm.query ~at:id s; read_stdout ()
+(* TODO: the "" parameter is a leftover of the times the protocol
+ * used to include stderr/stdout output.
+ *
+ * Currently, we force all the output meant for the to go via the
+ * feedback mechanism, and we don't manipulate stderr/stdout, which
+ * are left to the client's discrection. The parameter is still there
+ * as not to break the core protocol for this minor change, but it should
+ * be removed in the next version of the protocol.
+ *)
+let query (s,id) = Stm.query ~at:id s; ""
let annotate phrase =
let (loc, ast) =
let pa = Pcoq.Gram.parsable (Stream.of_string phrase) in
Vernac.parse_sentence (pa,None)
in
- let (_, xml) =
- Richprinter.richpp_vernac ast
- in
- xml
+ (* XXX: Width should be a parameter of annotate... *)
+ Richpp.richpp_of_pp 78 (Ppvernac.pr_vernac ast)
(** Goal display *)
@@ -192,13 +190,13 @@ let process_goal sigma g =
let id = Goal.uid g in
let ccl =
let norm_constr = Reductionops.nf_evar sigma (Goal.V82.concl sigma g) in
- Richpp.richpp_of_pp (pr_goal_concl_style_env env sigma norm_constr)
+ pr_goal_concl_style_env env sigma norm_constr
in
let process_hyp d (env,l) =
let d = CompactedDecl.map_constr (Reductionops.nf_evar sigma) d in
let d' = CompactedDecl.to_named_context d in
(List.fold_right Environ.push_named d' env,
- (Richpp.richpp_of_pp (pr_compacted_decl env sigma d)) :: l) in
+ (pr_compacted_decl env sigma d) :: l) in
let (_env, hyps) =
Context.Compacted.fold process_hyp
(Termops.compact_named_context (Environ.named_context env)) ~init:(min_env,[]) in
@@ -214,8 +212,6 @@ let export_pre_goals pgs =
let goals () =
Stm.finish ();
- let s = read_stdout () in
- 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))
@@ -224,8 +220,6 @@ let goals () =
let evars () =
try
Stm.finish ();
- let s = read_stdout () in
- 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
@@ -257,8 +251,6 @@ let status force =
and display the other parts (opened sections and modules) *)
Stm.finish ();
if force then Stm.join ();
- let s = read_stdout () in
- 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,7 +273,7 @@ let status force =
let export_coq_object t = {
Interface.coq_object_prefix = t.Search.coq_object_prefix;
Interface.coq_object_qualid = t.Search.coq_object_qualid;
- Interface.coq_object_object = t.Search.coq_object_object
+ Interface.coq_object_object = Pp.string_of_ppcmds (pr_lconstr_env (Global.env ()) Evd.empty t.Search.coq_object_object)
}
let pattern_of_string ?env s =
@@ -364,14 +356,10 @@ let handle_exn (e, info) =
let loc_of e = match Loc.get_loc e with
| Some loc when not (Loc.is_ghost loc) -> Some (Loc.unloc loc)
| _ -> None in
- let mk_msg () =
- let msg = read_stdout () in
- let msg = str msg ++ fnl () ++ CErrors.print ~info e in
- Richpp.richpp_of_pp msg
- in
+ let mk_msg () = CErrors.print ~info e in
match e with
- | CErrors.Drop -> dummy, None, Richpp.richpp_of_string "Drop is not allowed by coqide!"
- | CErrors.Quit -> dummy, None, Richpp.richpp_of_string "Quit is not allowed by coqide!"
+ | CErrors.Drop -> dummy, None, Pp.str "Drop is not allowed by coqide!"
+ | CErrors.Quit -> dummy, None, Pp.str "Quit is not allowed by coqide!"
| e ->
match Stateid.get info with
| Some (valid, _) -> valid, loc_of info, mk_msg ()
@@ -409,7 +397,16 @@ let interp ((_raw, verbose), s) =
| Some ast -> ast)
() in
Stm.interp verbose (vernac_parse s);
- Stm.get_current_state (), CSig.Inl (read_stdout ())
+ (* TODO: the "" parameter is a leftover of the times the protocol
+ * used to include stderr/stdout output.
+ *
+ * Currently, we force all the output meant for the to go via the
+ * feedback mechanism, and we don't manipulate stderr/stdout, which
+ * are left to the client's discrection. The parameter is still there
+ * as not to break the core protocol for this minor change, but it should
+ * be removed in the next version of the protocol.
+ *)
+ Stm.get_current_state (), CSig.Inl ""
(** When receiving the Quit call, we don't directly do an [exit 0],
but rather set this reference, in order to send a final answer
@@ -428,14 +425,12 @@ let print_ast id =
(** Grouping all call handlers together + error handling *)
-let eval_call xml_oc log c =
+let eval_call c =
let interruptible f x =
catch_break := true;
Control.check_for_interrupt ();
let r = f x in
catch_break := false;
- let out = read_stdout () in
- if not (String.is_empty out) then log (str out);
r
in
let handler = {
@@ -473,16 +468,8 @@ let print_xml =
try Xml_printer.print oc xml; Mutex.unlock m
with e -> let e = CErrors.push e in Mutex.unlock m; iraise e
-
-let slave_logger xml_oc ?loc level message =
- (* convert the message into XML *)
- let msg = hov 0 message in
- let () = pr_debug (Printf.sprintf "-> %S" (string_of_ppcmds msg)) in
- let xml = Xmlprotocol.of_message level loc (Richpp.richpp_of_pp message) in
- print_xml xml_oc xml
-
-let slave_feeder xml_oc msg =
- let xml = Xmlprotocol.of_feedback msg in
+let slave_feeder fmt xml_oc msg =
+ let xml = Xmlprotocol.(of_feedback fmt msg) in
print_xml xml_oc xml
(** The main loop *)
@@ -491,17 +478,22 @@ let slave_feeder xml_oc msg =
messages by [handle_exn] above. Otherwise, we die badly, without
trying to answer malformed requests. *)
+let msg_format = ref (fun () ->
+ let margin = Option.default 72 (Topfmt.get_margin ()) in
+ Xmlprotocol.Richpp margin
+)
+
let loop () =
init_signal_handler ();
catch_break := false;
- let in_ch, out_ch = Spawned.get_channels () in
- let xml_oc = Xml_printer.make (Xml_printer.TChannel out_ch) in
- let in_lb = Lexing.from_function (fun s len ->
- CThread.thread_friendly_read in_ch s ~off:0 ~len) in
- let xml_ic = Xml_parser.make (Xml_parser.SLexbuf in_lb) in
+ let in_ch, out_ch = Spawned.get_channels () in
+ let xml_oc = Xml_printer.make (Xml_printer.TChannel out_ch) in
+ let in_lb = Lexing.from_function (fun s len ->
+ CThread.thread_friendly_read in_ch s ~off:0 ~len) in
+ (* SEXP parser make *)
+ let xml_ic = Xml_parser.make (Xml_parser.SLexbuf in_lb) in
let () = Xml_parser.check_eof xml_ic false in
- Feedback.set_logger (slave_logger xml_oc);
- Feedback.add_feeder (slave_feeder xml_oc);
+ ignore (Feedback.add_feeder (slave_feeder (!msg_format ()) xml_oc));
(* We'll handle goal fetching and display in our own way *)
Vernacentries.enable_goal_printing := false;
Vernacentries.qed_display_script := false;
@@ -511,10 +503,10 @@ 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 Feedback.Notice) q in
+ let r = eval_call 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);
+ print_xml xml_oc Xmlprotocol.(of_answer (!msg_format ()) q r);
flush out_ch
with
| Xml_parser.Error (Xml_parser.Empty, _) ->
@@ -536,16 +528,19 @@ let loop () =
let rec parse = function
| "--help-XML-protocol" :: rest ->
Xmlprotocol.document Xml_printer.to_string_fmt; exit 0
+ | "--xml_format=Ppcmds" :: rest ->
+ msg_format := (fun () -> Xmlprotocol.Ppcmds); parse rest
| x :: rest -> x :: parse rest
| [] -> []
let () = Coqtop.toploop_init := (fun args ->
let args = parse args in
Flags.make_silent true;
- init_stdout ();
CoqworkmgrApi.(init Flags.High);
args)
let () = Coqtop.toploop_run := loop
-let () = Usage.add_to_usage "coqidetop" " --help-XML-protocol print the documentation of the XML protocol used by CoqIDE\n"
+let () = Usage.add_to_usage "coqidetop"
+" --xml_format=Ppcmds serialize pretty printing messages using the std_ppcmds format
+ --help-XML-protocol print the documentation of the XML protocol used by CoqIDE\n"
diff --git a/ide/ideutils.ml b/ide/ideutils.ml
index 06a1327320..da867e689e 100644
--- a/ide/ideutils.ml
+++ b/ide/ideutils.ml
@@ -43,7 +43,7 @@ let xml_to_string xml =
| Element (_, _, children) ->
List.iter iter children
in
- let () = iter (Richpp.repr xml) in
+ let () = iter xml in
Buffer.contents buf
let insert_with_tags (buf : #GText.buffer_skel) mark rmark tags text =
@@ -75,7 +75,7 @@ let insert_xml ?(mark = `INSERT) ?(tags = []) (buf : #GText.buffer_skel) msg =
let tags = try tag t :: tags with Not_found -> tags in
List.iter (fun xml -> insert tags xml) children
in
- let () = try insert tags (Richpp.repr msg) with _ -> () in
+ let () = try insert tags msg with _ -> () in
buf#delete_mark rmark
let set_location = ref (function s -> failwith "not ready")
@@ -294,18 +294,20 @@ let coqtop_path () =
match cmd_coqtop#get with
| Some s -> s
| None ->
- let prog = String.copy Sys.executable_name in
try
- let pos = String.length prog - 6 in
- let i = Str.search_backward (Str.regexp_string "coqide") prog pos
+ let old_prog = Sys.executable_name in
+ let pos = String.length old_prog - 6 in
+ let i = Str.search_backward (Str.regexp_string "coqide") old_prog pos
in
- String.blit "coqtop" 0 prog i 6;
- if Sys.file_exists prog then prog
+ let new_prog = Bytes.of_string old_prog in
+ Bytes.blit_string "coqtop" 0 new_prog i 6;
+ let new_prog = Bytes.to_string new_prog in
+ if Sys.file_exists new_prog then new_prog
else
let in_macos_bundle =
Filename.concat
- (Filename.dirname prog)
- (Filename.concat "../Resources/bin" (Filename.basename prog))
+ (Filename.dirname new_prog)
+ (Filename.concat "../Resources/bin" (Filename.basename new_prog))
in if Sys.file_exists in_macos_bundle then in_macos_bundle
else "coqtop"
with Not_found -> "coqtop"
@@ -325,7 +327,7 @@ let textview_width (view : #GText.view_skel) =
let char_width = GPango.to_pixels metrics#approx_char_width in
pixel_width / char_width
-type logger = Feedback.level -> Richpp.richpp -> unit
+type logger = Feedback.level -> Pp.std_ppcmds -> unit
let default_logger level message =
let level = match level with
@@ -335,7 +337,7 @@ let default_logger level message =
| Feedback.Warning -> `WARNING
| Feedback.Error -> `ERROR
in
- Minilib.log ~level (xml_to_string message)
+ Minilib.log_pp ~level message
(** {6 File operations} *)
@@ -357,7 +359,7 @@ let stat f =
let maxread = 4096
-let read_string = String.create maxread
+let read_string = Bytes.create maxread
let read_buffer = Buffer.create maxread
(** Read the content of file [f] and add it to buffer [b].
@@ -368,7 +370,7 @@ let read_file name buf =
let len = ref 0 in
try
while len := input ic read_string 0 maxread; !len > 0 do
- Buffer.add_substring buf read_string 0 !len
+ Buffer.add_subbytes buf read_string 0 !len
done;
close_in ic
with e -> close_in ic; raise e
@@ -381,8 +383,9 @@ let read_file name buf =
let io_read_all chan =
Buffer.clear read_buffer;
let read_once () =
- let len = Glib.Io.read_chars ~buf:read_string ~pos:0 ~len:maxread chan in
- Buffer.add_substring read_buffer read_string 0 len
+ (* XXX: Glib.Io must be converted to bytes / -safe-string upstream *)
+ let len = Glib.Io.read_chars ~buf:(Bytes.unsafe_to_string read_string) ~pos:0 ~len:maxread chan in
+ Buffer.add_subbytes read_buffer read_string 0 len
in
begin
try while true do read_once () done
diff --git a/ide/ideutils.mli b/ide/ideutils.mli
index e32a4d9e38..4b4ba72b0b 100644
--- a/ide/ideutils.mli
+++ b/ide/ideutils.mli
@@ -52,8 +52,6 @@ val pop_info : unit -> unit
val clear_info : unit -> unit
val flash_info : ?delay:int -> string -> unit
-val xml_to_string : Richpp.richpp -> string
-
val insert_xml : ?mark:GText.mark -> ?tags:GText.tag list ->
#GText.buffer_skel -> Richpp.richpp -> unit
@@ -69,7 +67,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 = Feedback.level -> Richpp.richpp -> unit
+type logger = Feedback.level -> Pp.std_ppcmds -> unit
val default_logger : logger
(** Default logger. It logs messages that the casual user should not see. *)
diff --git a/ide/interface.mli b/ide/interface.mli
index 123cac6c22..9ed6062588 100644
--- a/ide/interface.mli
+++ b/ide/interface.mli
@@ -12,15 +12,14 @@
type raw = bool
type verbose = bool
-type richpp = Richpp.richpp
(** The type of coqtop goals *)
type goal = {
goal_id : string;
(** Unique goal identifier *)
- goal_hyp : richpp list;
+ goal_hyp : Pp.std_ppcmds list;
(** List of hypotheses *)
- goal_ccl : richpp;
+ goal_ccl : Pp.std_ppcmds;
(** Goal conclusion *)
}
@@ -119,7 +118,7 @@ type edit_id = Feedback.edit_id
should probably retract to that point *)
type 'a value =
| Good of 'a
- | Fail of (state_id * location * richpp)
+ | Fail of (state_id * location * Pp.std_ppcmds)
type ('a, 'b) union = ('a, 'b) Util.union
@@ -128,9 +127,13 @@ type ('a, 'b) union = ('a, 'b) Util.union
(** [add ((s,eid),(sid,v))] adds the phrase [s] with edit id [eid]
on top of the current edit position (that is asserted to be [sid])
verbosely if [v] is true. The response [(id,(rc,s)] is the new state
- [id] assigned to the phrase, some output [s]. [rc] is [Inl] if the new
+ [id] assigned to the phrase. [rc] is [Inl] if the new
state id is the tip of the edit point, or [Inr tip] if the new phrase
- closes a focus and [tip] is the new edit tip *)
+ closes a focus and [tip] is the new edit tip
+
+ [s] used to contain Coq's console output and has been deprecated
+ in favor of sending feedback, it will be removed in a future
+ version of the protocol. *)
type add_sty = (string * edit_id) * (state_id * verbose)
type add_rty = state_id * ((unit, state_id) union * string)
@@ -143,8 +146,12 @@ type add_rty = state_id * ((unit, state_id) union * string)
type edit_at_sty = state_id
type edit_at_rty = (unit, state_id * (state_id * state_id)) union
-(** [query s id] executes [s] at state [id] and does not record any state
- change but for the printings that are sent in response *)
+(** [query s id] executes [s] at state [id].
+
+ query used to reply with the contents of Coq's console output, and
+ has been deprecated in favor of sending the query answers as
+ feedback. It will be removed in a future version of the protocol.
+*)
type query_sty = string * state_id
type query_rty = string
@@ -203,7 +210,7 @@ type about_sty = unit
type about_rty = coq_info
type handle_exn_sty = Exninfo.iexn
-type handle_exn_rty = state_id * location * richpp
+type handle_exn_rty = state_id * location * Pp.std_ppcmds
(* Retrocompatibility stuff *)
type interp_sty = (raw * verbose) * string
diff --git a/ide/minilib.ml b/ide/minilib.ml
index d11e8c56b2..2c24e46f8f 100644
--- a/ide/minilib.ml
+++ b/ide/minilib.ml
@@ -30,7 +30,7 @@ let debug = ref false
print in the response buffer.
*)
-let log ?(level = `DEBUG) msg =
+let log_pp ?(level = `DEBUG) msg =
let prefix = match level with
| `DEBUG -> "DEBUG"
| `INFO -> "INFO"
@@ -40,10 +40,12 @@ let log ?(level = `DEBUG) msg =
| `FATAL -> "FATAL"
in
if !debug then begin
- try Printf.eprintf "[%s] %s\n%!" prefix msg
+ try Format.eprintf "[%s] @[%a@]\n%!" prefix Pp.pp_with msg
with _ -> ()
end
+let log ?level str = log_pp ?level (Pp.str str)
+
let coqify d = Filename.concat d "coq"
let coqide_config_home () =
diff --git a/ide/minilib.mli b/ide/minilib.mli
index b7672c9002..4517a23744 100644
--- a/ide/minilib.mli
+++ b/ide/minilib.mli
@@ -22,7 +22,8 @@ type level = [
(** debug printing *)
val debug : bool ref
-val log : ?level:level -> string -> unit
+val log_pp : ?level:level -> Pp.std_ppcmds -> unit
+val log : ?level:level -> string -> unit
val coqide_config_home : unit -> string
val coqide_config_dirs : unit -> string list
diff --git a/lib/richpp.ml b/ide/richpp.ml
index d1c6d158e4..522a3e0b31 100644
--- a/lib/richpp.ml
+++ b/ide/richpp.ml
@@ -24,10 +24,6 @@ type 'a context = {
(** Pending opened nodes *)
mutable offset : int;
(** Quantity of characters printed so far *)
- mutable annotations : 'a option Int.Map.t;
- (** Map associating annotations to indexes *)
- mutable index : int;
- (** Current index of annotations *)
}
(** We use Format to introduce tags inside the pretty-printed document.
@@ -38,23 +34,13 @@ type 'a context = {
marking functions. As those functions are called when actually writing to
the device, the resulting tree is correct.
*)
-let rich_pp annotate ppcmds =
+let rich_pp width ppcmds =
let context = {
stack = Leaf;
offset = 0;
- annotations = Int.Map.empty;
- index = (-1);
} in
- let pp_tag obj =
- let index = context.index + 1 in
- let () = context.index <- index in
- let obj = annotate obj in
- let () = context.annotations <- Int.Map.add index obj context.annotations in
- string_of_int index
- in
-
let pp_buffer = Buffer.create 180 in
let push_pcdata () =
@@ -81,12 +67,8 @@ let rich_pp annotate ppcmds =
| Leaf -> assert false
| Node (node, child, pos, ctx) ->
let () = assert (String.equal tag node) in
- let annotation =
- try Int.Map.find (int_of_string node) context.annotations
- with _ -> None
- in
let annotation = {
- annotation = annotation;
+ annotation = Some tag;
startpos = pos;
endpos = context.offset;
} in
@@ -113,18 +95,20 @@ let rich_pp annotate ppcmds =
pp_set_formatter_tag_functions ft tag_functions;
pp_set_mark_tags ft true;
- (* Set formatter width. This is currently a hack and duplicate code
- with Pp_control. Hopefully it will be fixed better in Coq 8.7 *)
- let w = pp_get_margin str_formatter () in
- let m = max (64 * w / 100) (w-30) in
- pp_set_margin ft w;
+ (* Setting the formatter *)
+ pp_set_margin ft width;
+ let m = max (64 * width / 100) (width-30) in
pp_set_max_indent ft m;
+ pp_set_max_boxes ft 50 ;
+ pp_set_ellipsis_text ft "...";
(** The whole output must be a valid document. To that
end, we nest the document inside <pp> tags. *)
+ pp_open_box ft 0;
pp_open_tag ft "pp";
- Pp.(pp_with ~pp_tag ft ppcmds);
+ Pp.(pp_with ft ppcmds);
pp_close_tag ft ();
+ pp_close_box ft ();
(** Get the resulting XML tree. *)
let () = pp_print_flush ft () in
@@ -172,32 +156,14 @@ let xml_of_rich_pp tag_of_annotation attributes_of_annotation xml =
type richpp = xml
-let repr xml = xml
-let richpp_of_xml xml = xml
-let richpp_of_string s = PCData s
-
-let richpp_of_pp pp =
- let annotate t = match Pp.Tag.prj t Ppstyle.tag with
- | None -> None
- | Some key -> Some (Ppstyle.repr key)
- in
+let richpp_of_pp width pp =
let rec drop = function
| PCData s -> [PCData s]
| Element (_, annotation, cs) ->
let cs = List.concat (List.map drop cs) in
match annotation.annotation with
| None -> cs
- | Some s -> [Element (String.concat "." s, [], cs)]
+ | Some s -> [Element (s, [], cs)]
in
- let xml = rich_pp annotate pp in
+ let xml = rich_pp width pp in
Element ("_", [], drop xml)
-
-let raw_print xml =
- let buf = Buffer.create 1024 in
- let rec print = function
- | PCData s -> Buffer.add_string buf s
- | Element (_, _, cs) -> List.iter print cs
- in
- let () = print xml in
- Buffer.contents buf
-
diff --git a/lib/richpp.mli b/ide/richpp.mli
index 287d265a8f..ea4b189ba8 100644
--- a/lib/richpp.mli
+++ b/ide/richpp.mli
@@ -16,14 +16,15 @@ type 'annotation located = {
endpos : int
}
-(** [rich_pp get_annotations ppcmds] returns the interpretation
+(* XXX: The width parameter should be moved to a `formatter_property`
+ record shared with Topfmt *)
+
+(** [rich_pp width ppcmds] returns the interpretation
of [ppcmds] as a semi-structured document
that represents (located) annotations of this string.
The [get_annotations] function is used to convert tags into the desired
- annotation. *)
-val rich_pp :
- (Pp.Tag.t -> 'annotation option) -> Pp.std_ppcmds ->
- 'annotation located Xml_datatype.gxml
+ annotation. [width] sets the printing witdh of the formatter. *)
+val rich_pp : int -> Pp.std_ppcmds -> Pp.pp_tag located Xml_datatype.gxml
(** [annotations_positions ssdoc] returns a list associating each
annotations with its position in the string from which [ssdoc] is
@@ -42,23 +43,9 @@ val xml_of_rich_pp :
(** {5 Enriched text} *)
-type richpp
+type richpp = Xml_datatype.xml
+
(** Type of text with style annotations *)
-val richpp_of_pp : Pp.std_ppcmds -> richpp
+val richpp_of_pp : int -> Pp.std_ppcmds -> richpp
(** Extract style information from formatted text *)
-
-val richpp_of_xml : Xml_datatype.xml -> richpp
-(** Do not use outside of dedicated areas *)
-
-val richpp_of_string : string -> richpp
-(** Make a styled text out of a normal string *)
-
-val repr : richpp -> Xml_datatype.xml
-(** Observe the styled text as XML *)
-
-(** {5 Debug/Compat} *)
-
-(** Represent the semi-structured document as a string, dropping any additional
- information. *)
-val raw_print : richpp -> string
diff --git a/ide/richprinter.ml b/ide/richprinter.ml
deleted file mode 100644
index 995cef1ac5..0000000000
--- a/ide/richprinter.ml
+++ /dev/null
@@ -1,23 +0,0 @@
-open Richpp
-
-module RichppConstr = Ppconstr.Richpp
-module RichppVernac = Ppvernac.Richpp
-
-type rich_pp =
- Ppannotation.t Richpp.located Xml_datatype.gxml
- * Xml_datatype.xml
-
-let get_annotations obj = Pp.Tag.prj obj Ppannotation.tag
-
-let make_richpp pr ast =
- let rich_pp =
- rich_pp get_annotations (pr ast)
- in
- let xml = Ppannotation.(
- xml_of_rich_pp tag_of_annotation attributes_of_annotation rich_pp
- )
- in
- (rich_pp, xml)
-
-let richpp_vernac = make_richpp RichppVernac.pr_vernac
-let richpp_constr = make_richpp RichppConstr.pr_constr_expr
diff --git a/ide/richprinter.mli b/ide/richprinter.mli
deleted file mode 100644
index c9e84e3eb4..0000000000
--- a/ide/richprinter.mli
+++ /dev/null
@@ -1,36 +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 module provides an entry point to "rich" pretty-printers that
- produce pretty-printing as done by {!Printer} but with additional
- annotations represented as a semi-structured document.
-
- To understand what are these annotations and how they are represented
- as standard XML attributes, please refer to {!Ppannotation}.
-
- In addition to these annotations, each node of the semi-structured
- document contains a [startpos] and an [endpos] attribute that
- relate this node to the raw pretty-printing.
- Please refer to {!Richpp} for more details. *)
-
-(** A rich pretty-print is composed of: *)
-type rich_pp =
-
- (** - a generalized semi-structured document whose attributes are
- annotations ; *)
- Ppannotation.t Richpp.located Xml_datatype.gxml
-
- (** - an XML document, representing annotations as usual textual
- XML attributes. *)
- * Xml_datatype.xml
-
-(** [richpp_vernac phrase] produces a rich pretty-printing of [phrase]. *)
-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
diff --git a/ide/texmacspp.ml b/ide/texmacspp.ml
index 6fbed38fb4..e787e48bf1 100644
--- a/ide/texmacspp.ml
+++ b/ide/texmacspp.ml
@@ -15,6 +15,7 @@ open Bigint
open Decl_kinds
open Extend
open Libnames
+open Constrexpr_ops
let unlock loc =
let start, stop = Loc.unloc loc in
@@ -228,14 +229,15 @@ and pp_decl_notation ((_, s), ce, sc) = (* don't know what it is for now *)
Element ("decl_notation", ["name", s], [pp_expr ce])
and pp_local_binder lb = (* don't know what it is for now *)
match lb with
- | LocalRawDef ((_, nam), ce) ->
+ | CLocalDef ((loc, nam), ce, ty) ->
let attrs = ["name", string_of_name nam] in
- pp_expr ~attr:attrs ce
- | LocalRawAssum (namll, _, ce) ->
+ let value = match ty with Some t -> CCast (Loc.merge (constr_loc ce) (constr_loc t),ce, CastConv t) | None -> ce in
+ pp_expr ~attr:attrs value
+ | CLocalAssum (namll, _, ce) ->
let ppl =
List.map (fun (loc, nam) -> (xmlCst (string_of_name nam) loc)) namll in
xmlTyped (ppl @ [pp_expr ce])
- | LocalPattern _ ->
+ | CLocalPattern _ ->
assert false
and pp_local_decl_expr lde = (* don't know what it is for now *)
match lde with
@@ -465,7 +467,8 @@ and pp_expr ?(attr=[]) e =
[Element ("scrutinees", [], List.map pp_case_expr cel)] @
[pp_branch_expr_list bel]))
| CRecord (_, _) -> assert false
- | CLetIn (loc, (varloc, var), value, body) ->
+ | CLetIn (loc, (varloc, var), value, typ, body) ->
+ let value = match typ with Some t -> CCast (Loc.merge (constr_loc value) (constr_loc t),value, CastConv t) | None -> value in
xmlApply loc
(xmlOperator "let" loc ::
[xmlCst (string_of_name var) varloc; pp_expr value; pp_expr body])
diff --git a/ide/wg_Command.ml b/ide/wg_Command.ml
index 946aaf010d..47dad8f196 100644
--- a/ide/wg_Command.ml
+++ b/ide/wg_Command.ml
@@ -100,18 +100,15 @@ object(self)
if Str.string_match (Str.regexp "\\. *$") com 0 then com
else com ^ " " ^ arg ^" . "
in
- let log level message =
- Ideutils.insert_xml result#buffer message;
- result#buffer#insert "\n";
- in
let process =
- Coq.bind (Coq.query ~logger:log (phrase,Stateid.dummy)) (function
+ Coq.bind (Coq.query (phrase,Stateid.dummy)) (function
| Interface.Fail (_,l,str) ->
- Ideutils.insert_xml result#buffer str;
+ let width = Ideutils.textview_width result in
+ Ideutils.insert_xml result#buffer (Richpp.richpp_of_pp width str);
notebook#set_page ~tab_label:(new_tab_lbl "Error") frame#coerce;
Coq.return ()
| Interface.Good res ->
- result#buffer#insert res;
+ result#buffer#insert res;
notebook#set_page ~tab_label:(new_tab_lbl arg) frame#coerce;
Coq.return ())
in
diff --git a/ide/wg_MessageView.ml b/ide/wg_MessageView.ml
index 0330b8eff1..3d0cd46cd4 100644
--- a/ide/wg_MessageView.ml
+++ b/ide/wg_MessageView.ml
@@ -28,9 +28,10 @@ class type message_view =
inherit GObj.widget
method connect : message_view_signals
method clear : unit
- method add : Richpp.richpp -> unit
+ method add : Pp.std_ppcmds -> unit
method add_string : string -> unit
- method set : Richpp.richpp -> unit
+ method set : Pp.std_ppcmds -> unit
+ method refresh : bool -> unit
method push : Ideutils.logger
(** same as [add], but with an explicit level instead of [Notice] *)
method buffer : GText.buffer
@@ -57,46 +58,71 @@ let message_view () : message_view =
let () = view#set_left_margin 2 in
view#misc#show ();
let cb clr = view#misc#modify_base [`NORMAL, `NAME clr] in
- let _ = background_color#connect#changed cb in
- let _ = view#misc#connect#realize (fun () -> cb background_color#get) in
+ let _ = background_color#connect#changed ~callback:cb in
+ let _ = view#misc#connect#realize ~callback:(fun () -> cb background_color#get) in
let cb ft = view#misc#modify_font (Pango.Font.from_string ft) in
stick text_font view cb;
- object (self)
+
+ (* Inserts at point, advances the mark *)
+ let insert_msg (level, msg) =
+ let tags = match level with
+ | Feedback.Error -> [Tags.Message.error]
+ | Feedback.Warning -> [Tags.Message.warning]
+ | _ -> []
+ in
+ let mark = `MARK mark in
+ let width = Ideutils.textview_width view in
+ Ideutils.insert_xml ~mark buffer ~tags (Richpp.richpp_of_pp width msg);
+ buffer#insert ~iter:(buffer#get_iter_at_mark mark) "\n"
+ in
+
+ let mv = object (self)
inherit GObj.widget box#as_widget
+ (* List of displayed messages *)
+ val mutable last_width = -1
+ val mutable msgs = []
+
val push = new GUtil.signal ()
method connect =
new message_view_signals_impl box#as_widget push
+ method refresh force =
+ (* We need to block updates here due to the following race:
+ insertion of messages may create a vertical scrollbar, this
+ will trigger a width change, calling refresh again and
+ going into an infinite loop. *)
+ let width = Ideutils.textview_width view in
+ (* Could still this method race if the scrollbar changes the
+ textview_width ?? *)
+ let needed = force || last_width <> width in
+ if needed then begin
+ last_width <- width;
+ buffer#set_text "";
+ buffer#move_mark (`MARK mark) ~where:buffer#start_iter;
+ List.(iter insert_msg (rev msgs))
+ end
+
method clear =
- buffer#set_text "";
- buffer#move_mark (`MARK mark) ~where:buffer#start_iter
+ msgs <- []; self#refresh true
method push level msg =
- let tags = match level with
- | Feedback.Error -> [Tags.Message.error]
- | Feedback.Warning -> [Tags.Message.warning]
- | _ -> []
- in
- let rec non_empty = function
- | Xml_datatype.PCData "" -> false
- | Xml_datatype.PCData _ -> true
- | Xml_datatype.Element (_, _, children) -> List.exists non_empty children
- in
- if non_empty (Richpp.repr msg) then begin
- let mark = `MARK mark in
- Ideutils.insert_xml ~mark buffer ~tags msg;
- buffer#insert ~iter:(buffer#get_iter_at_mark mark) "\n";
- push#call (level, msg)
- end
+ msgs <- (level, msg) :: msgs;
+ insert_msg (level, msg);
+ push#call (level, msg)
method add msg = self#push Feedback.Notice msg
- method add_string s = self#add (Richpp.richpp_of_string s)
+ method add_string s = self#add (Pp.str s)
method set msg = self#clear; self#add msg
method buffer = text_buffer
end
+ in
+ (* Is there a better way to connect the signal ? *)
+ let w_cb (_ : Gtk.rectangle) = mv#refresh false in
+ ignore (view#misc#connect#size_allocate ~callback:w_cb);
+ mv
diff --git a/ide/wg_MessageView.mli b/ide/wg_MessageView.mli
index 2d34533dee..d065fcbc80 100644
--- a/ide/wg_MessageView.mli
+++ b/ide/wg_MessageView.mli
@@ -18,9 +18,10 @@ class type message_view =
inherit GObj.widget
method connect : message_view_signals
method clear : unit
- method add : Richpp.richpp -> unit
+ method add : Pp.std_ppcmds -> unit
method add_string : string -> unit
- method set : Richpp.richpp -> unit
+ method set : Pp.std_ppcmds -> unit
+ method refresh : bool -> unit
method push : Ideutils.logger
(** same as [add], but with an explicit level instead of [Notice] *)
method buffer : GText.buffer
diff --git a/ide/wg_ProofView.ml b/ide/wg_ProofView.ml
index 47c86045a5..3cbe583881 100644
--- a/ide/wg_ProofView.ml
+++ b/ide/wg_ProofView.ml
@@ -14,11 +14,10 @@ class type proof_view =
object
inherit GObj.widget
method buffer : GText.buffer
- method refresh : unit -> unit
+ method refresh : force:bool -> unit
method clear : unit -> unit
method set_goals : Interface.goals option -> unit
method set_evars : Interface.evar list option -> unit
- method width : int
end
(* tag is the tag to be hooked, item is the item covered by this tag, make_menu
@@ -74,6 +73,7 @@ let mode_tactic sel_cb (proof : #GText.view_skel) goals hints = match goals with
| None -> [], []
| Some (hl, h) -> (hl, h)
in
+ let width = Ideutils.textview_width proof in
let rec insert_hyp hints hs = match hs with
| [] -> ()
| hyp :: hs ->
@@ -84,7 +84,7 @@ let mode_tactic sel_cb (proof : #GText.view_skel) goals hints = match goals with
let () = hook_tag_cb tag hint sel_cb on_hover in
[tag], hints
in
- let () = insert_xml ~tags proof#buffer hyp in
+ let () = insert_xml ~tags proof#buffer (Richpp.richpp_of_pp width hyp) in
proof#buffer#insert "\n";
insert_hyp rem_hints hs
in
@@ -98,13 +98,13 @@ let mode_tactic sel_cb (proof : #GText.view_skel) goals hints = match goals with
else []
in
proof#buffer#insert (goal_str 1 goals_cnt);
- insert_xml proof#buffer cur_goal;
+ insert_xml proof#buffer (Richpp.richpp_of_pp width cur_goal);
proof#buffer#insert "\n"
in
(* Insert remaining goals (no hypotheses) *)
let fold_goal i _ { Interface.goal_ccl = g } =
proof#buffer#insert (goal_str i goals_cnt);
- insert_xml proof#buffer g;
+ insert_xml proof#buffer (Richpp.richpp_of_pp width g);
proof#buffer#insert "\n"
in
let () = Util.List.fold_left_i fold_goal 2 () rem_goals in
@@ -122,6 +122,7 @@ let rec flatten = function
let display mode (view : #GText.view_skel) goals hints evars =
let () = view#buffer#set_text "" in
+ let width = Ideutils.textview_width view in
match goals with
| None -> ()
(* No proof in progress *)
@@ -144,7 +145,7 @@ let display mode (view : #GText.view_skel) goals hints evars =
(* The proof is finished, with the exception of given up goals. *)
view#buffer#insert "No more subgoals, but there are some goals you gave up:\n\n";
let iter goal =
- insert_xml view#buffer goal.Interface.goal_ccl;
+ insert_xml view#buffer (Richpp.richpp_of_pp width goal.Interface.goal_ccl);
view#buffer#insert "\n"
in
List.iter iter given_up_goals;
@@ -153,7 +154,7 @@ let display mode (view : #GText.view_skel) goals hints evars =
(* All the goals have been resolved but those on the shelf. *)
view#buffer#insert "All the remaining goals are on the shelf:\n\n";
let iter goal =
- insert_xml view#buffer goal.Interface.goal_ccl;
+ insert_xml view#buffer (Richpp.richpp_of_pp width goal.Interface.goal_ccl);
view#buffer#insert "\n"
in
List.iter iter shelved_goals
@@ -166,7 +167,7 @@ let display mode (view : #GText.view_skel) goals hints evars =
view#buffer#insert "This subproof is complete, but there are some unfocused goals:\n\n";
let iter i goal =
let () = view#buffer#insert (goal_str (succ i)) in
- insert_xml view#buffer goal.Interface.goal_ccl;
+ insert_xml view#buffer (Richpp.richpp_of_pp width goal.Interface.goal_ccl);
view#buffer#insert "\n"
in
List.iteri iter bg
@@ -192,10 +193,11 @@ let proof_view () =
let cb ft = view#misc#modify_font (Pango.Font.from_string ft) in
stick text_font view cb;
- object
+ let pf = object
inherit GObj.widget view#as_widget
val mutable goals = None
val mutable evars = None
+ val mutable last_width = -1
method buffer = text_buffer
@@ -205,11 +207,24 @@ let proof_view () =
method set_evars evs = evars <- evs
- method refresh () =
- let dummy _ () = () in
- display (mode_tactic dummy) (view :> GText.view_skel) goals None evars
-
- method width = Ideutils.textview_width (view :> GText.view_skel)
+ method refresh ~force =
+ (* We need to block updates here due to the following race:
+ insertion of messages may create a vertical scrollbar, this
+ will trigger a width change, calling refresh again and
+ going into an infinite loop. *)
+ let width = Ideutils.textview_width view in
+ (* Could still this method race if the scrollbar changes the
+ textview_width ?? *)
+ let needed = force || last_width <> width in
+ if needed then begin
+ last_width <- width;
+ let dummy _ () = () in
+ display (mode_tactic dummy) view goals None evars
+ end
end
-
-(* ignore (proof_buffer#add_selection_clipboard cb); *)
+ in
+ (* Is there a better way to connect the signal ? *)
+ (* Can this be done in the object constructor? *)
+ let w_cb _ = pf#refresh ~force:false in
+ ignore (view#misc#connect#size_allocate w_cb);
+ pf
diff --git a/ide/wg_ProofView.mli b/ide/wg_ProofView.mli
index b6eae48b39..a90d429d04 100644
--- a/ide/wg_ProofView.mli
+++ b/ide/wg_ProofView.mli
@@ -10,11 +10,10 @@ class type proof_view =
object
inherit GObj.widget
method buffer : GText.buffer
- method refresh : unit -> unit
+ method refresh : force:bool -> unit
method clear : unit -> unit
method set_goals : Interface.goals option -> unit
method set_evars : Interface.evar list option -> unit
- method width : int
end
val proof_view : unit -> proof_view
diff --git a/ide/xmlprotocol.ml b/ide/xmlprotocol.ml
index 5f82a8898b..d7950e5fd5 100644
--- a/ide/xmlprotocol.ml
+++ b/ide/xmlprotocol.ml
@@ -12,6 +12,9 @@
let protocol_version = "20150913"
+type msg_format = Richpp of int | Ppcmds
+let msg_format = ref (Richpp 72)
+
(** * Interface of calls to Coq by CoqIde *)
open Util
@@ -92,10 +95,57 @@ let to_stateid = function
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_box (ppb : Pp.block_type) = let open Pp in match ppb with
+ | Pp_hbox i -> constructor "ppbox" "hbox" [of_int i]
+ | Pp_vbox i -> constructor "ppbox" "vbox" [of_int i]
+ | Pp_hvbox i -> constructor "ppbox" "hvbox" [of_int i]
+ | Pp_hovbox i -> constructor "ppbox" "hovbox" [of_int i]
+
+let to_box = let open Pp in
+ do_match "ppbox" (fun s args -> match s with
+ | "hbox" -> Pp_hbox (to_int (singleton args))
+ | "vbox" -> Pp_vbox (to_int (singleton args))
+ | "hvbox" -> Pp_hvbox (to_int (singleton args))
+ | "hovbox" -> Pp_hovbox (to_int (singleton args))
+ | x -> raise (Marshal_error("*ppbox",PCData x))
+ )
+
+let rec of_pp (pp : Pp.std_ppcmds) = let open Pp in match Pp.repr pp with
+ | Ppcmd_empty -> constructor "ppdoc" "empty" []
+ | Ppcmd_string s -> constructor "ppdoc" "string" [of_string s]
+ | Ppcmd_glue sl -> constructor "ppdoc" "glue" [of_list of_pp sl]
+ | Ppcmd_box (bt,s) -> constructor "ppdoc" "box" [of_pair of_box of_pp (bt,s)]
+ | Ppcmd_tag (t,s) -> constructor "ppdoc" "tag" [of_pair of_string of_pp (t,s)]
+ | Ppcmd_print_break (i,j)
+ -> constructor "ppdoc" "break" [of_pair of_int of_int (i,j)]
+ | Ppcmd_force_newline -> constructor "ppdoc" "newline" []
+ | Ppcmd_comment cmd -> constructor "ppdoc" "comment" [of_list of_string cmd]
+
+
+let rec to_pp xpp = let open Pp in
+ Pp.unrepr @@
+ do_match "ppdoc" (fun s args -> match s with
+ | "empty" -> Ppcmd_empty
+ | "string" -> Ppcmd_string (to_string (singleton args))
+ | "glue" -> Ppcmd_glue (to_list to_pp (singleton args))
+ | "box" -> let (bt,s) = to_pair to_box to_pp (singleton args) in
+ Ppcmd_box(bt,s)
+ | "tag" -> let (tg,s) = to_pair to_string to_pp (singleton args) in
+ Ppcmd_tag(tg,s)
+ | "break" -> let (i,j) = to_pair to_int to_int (singleton args) in
+ Ppcmd_print_break(i, j)
+ | "newline" -> Ppcmd_force_newline
+ | "comment" -> Ppcmd_comment (to_list to_string (singleton args))
+ | x -> raise (Marshal_error("*ppdoc",PCData x))
+ ) xpp
+
+let of_richpp x = Element ("richpp", [], [x])
+
+(* Run-time Selectable *)
+let of_pp (pp : Pp.std_ppcmds) =
+ match !msg_format with
+ | Richpp margin -> of_richpp (Richpp.richpp_of_pp margin pp)
+ | Ppcmds -> of_pp pp
let of_value f = function
| Good x -> Element ("value", ["val", "good"], [f x])
@@ -104,7 +154,7 @@ let of_value f = function
| None -> []
| Some (s, e) -> [("loc_s", string_of_int s); ("loc_e", string_of_int e)] in
let id = of_stateid id in
- Element ("value", ["val", "fail"] @ loc, [id; of_richpp msg])
+ Element ("value", ["val", "fail"] @ loc, [id; of_pp msg])
let to_value f = function
| Element ("value", attrs, l) ->
@@ -120,7 +170,7 @@ let to_value f = function
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
+ let msg = to_pp msg in
Fail (id, loc, msg)
else raise (Marshal_error("good or fail",PCData ans))
| x -> raise (Marshal_error("value",x))
@@ -147,15 +197,15 @@ let to_evar = function
| x -> raise (Marshal_error("evar",x))
let of_goal g =
- let hyp = of_list of_richpp g.goal_hyp in
- let ccl = of_richpp g.goal_ccl in
+ let hyp = of_list of_pp g.goal_hyp in
+ let ccl = of_pp 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 to_richpp hyp in
- let ccl = to_richpp ccl in
- let id = to_string id in
+ let hyp = to_list to_pp hyp in
+ let ccl = to_pp ccl in
+ let id = to_string id in
{ goal_hyp = hyp; goal_ccl = ccl; goal_id = id; }
| x -> raise (Marshal_error("goal",x))
@@ -344,8 +394,8 @@ end = struct
Printf.sprintf "Still focussed: [%a]." pr_focus g.bg_goals
else
let pr_goal { goal_hyp = hyps; goal_ccl = goal } =
- "[" ^ String.concat "; " (List.map Richpp.raw_print hyps) ^ " |- " ^
- Richpp.raw_print goal ^ "]" in
+ "[" ^ String.concat "; " (List.map Pp.string_of_ppcmds hyps) ^ " |- " ^
+ Pp.string_of_ppcmds goal ^ "]" in
String.concat " " (List.map pr_goal g.fg_goals)
let pr_evar (e : evar) = "[" ^ e.evar_info ^ "]"
let pr_status (s : status) =
@@ -631,6 +681,9 @@ let of_answer : type a. a call -> a value -> xml = function
| PrintAst _ -> of_value (of_value_type print_ast_rty_t )
| Annotate _ -> of_value (of_value_type annotate_rty_t )
+let of_answer msg_fmt =
+ msg_format := msg_fmt; of_answer
+
let to_answer : type a. a call -> xml -> a value = function
| Add _ -> to_value (to_value_type add_rty_t )
| Edit_at _ -> to_value (to_value_type edit_at_rty_t )
@@ -701,10 +754,10 @@ let to_call : xml -> unknown_call =
let pr_value_gen pr = function
| Good v -> "GOOD " ^ pr v
- | Fail (id,None,str) -> "FAIL "^Stateid.to_string id^" ["^Richpp.raw_print str^"]"
+ | Fail (id,None,str) -> "FAIL "^Stateid.to_string id^" ["^ Pp.string_of_ppcmds str ^ "]"
| Fail (id,Some(i,j),str) ->
"FAIL "^Stateid.to_string id^
- " ("^string_of_int i^","^string_of_int j^")["^Richpp.raw_print str^"]"
+ " ("^string_of_int i^","^string_of_int j^")["^Pp.string_of_ppcmds str^"]"
let pr_value v = pr_value_gen (fun _ -> "FIXME") v
let pr_full_value : type a. a call -> a value -> string = fun call value -> match call with
| Add _ -> pr_value_gen (print add_rty_t ) value
@@ -760,7 +813,7 @@ let document to_string_fmt =
(to_string_fmt (of_value (fun _ -> PCData "b") (Good ())));
Printf.printf "or:\n\n%s\n\nwhere the attributes loc_s and loc_c are optional.\n"
(to_string_fmt (of_value (fun _ -> PCData "b")
- (Fail (Stateid.initial,Some (15,34),Richpp.richpp_of_string "error message"))));
+ (Fail (Stateid.initial,Some (15,34), Pp.str "error message"))));
document_type_encoding to_string_fmt
(* Moved from feedback.mli : This is IDE specific and we don't want to
@@ -787,20 +840,14 @@ let to_message_level =
let of_message lvl loc msg =
let lvl = of_message_level lvl in
let xloc = of_option of_loc loc in
- let content = of_richpp msg in
+ let content = of_pp msg in
Xml_datatype.Element ("message", [], [lvl; xloc; content])
let to_message xml = match xml with
| Xml_datatype.Element ("message", [], [lvl; xloc; content]) ->
- Message(to_message_level lvl, to_option to_loc xloc, to_richpp content)
+ Message(to_message_level lvl, to_option to_loc xloc, to_pp content)
| x -> raise (Marshal_error("message",x))
-let is_message xml =
- try begin match to_message xml with
- | Message(l,c,m) -> Some (l,c,m)
- | _ -> None
- end with | Marshal_error _ -> None
-
let to_feedback_content = do_match "feedback_content" (fun s a -> match s,a with
| "addedaxiom", _ -> AddedAxiom
| "processed", _ -> Processed
@@ -870,6 +917,9 @@ let of_feedback msg =
let route = string_of_int msg.route in
Element ("feedback", obj @ ["route",route], [id;content])
+let of_feedback msg_fmt =
+ msg_format := msg_fmt; of_feedback
+
let to_feedback xml = match xml with
| Element ("feedback", ["object","edit";"route",route], [id;content]) -> {
id = Edit(to_edit_id id);
diff --git a/ide/xmlprotocol.mli b/ide/xmlprotocol.mli
index 1bb9989704..9cefab517f 100644
--- a/ide/xmlprotocol.mli
+++ b/ide/xmlprotocol.mli
@@ -40,12 +40,17 @@ val abstract_eval_call : handler -> 'a call -> 'a value
val protocol_version : string
+(** By default, we still output messages in Richpp so we are
+ compatible with 8.6, however, 8.7 aware clients will want to
+ set this to Ppcmds *)
+type msg_format = Richpp of int | Ppcmds
+
(** * XML data marshalling *)
val of_call : 'a call -> xml
val to_call : xml -> unknown_call
-val of_answer : 'a call -> 'a value -> xml
+val of_answer : msg_format -> 'a call -> 'a value -> xml
val to_answer : 'a call -> xml -> 'a value
(* Prints the documentation of this module *)
@@ -57,16 +62,8 @@ 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 of_feedback : msg_format -> Feedback.feedback -> xml
val to_feedback : xml -> Feedback.feedback
-val is_feedback : xml -> bool
-
-val is_message : xml -> (Feedback.level * Loc.t option * Richpp.richpp) option
-val of_message : Feedback.level -> Loc.t option -> Richpp.richpp -> xml
-(* val to_message : xml -> Feedback.message *)
+val is_feedback : xml -> bool
diff --git a/interp/constrexpr_ops.ml b/interp/constrexpr_ops.ml
index 59c24900d2..53c97f6b6b 100644
--- a/interp/constrexpr_ops.ml
+++ b/interp/constrexpr_ops.ml
@@ -37,10 +37,10 @@ let binder_kind_eq b1 b2 = match b1, b2 with
let default_binder_kind = Default Explicit
let names_of_local_assums bl =
- List.flatten (List.map (function LocalRawAssum(l,_,_)->l|_->[]) bl)
+ List.flatten (List.map (function CLocalAssum(l,_,_)->l|_->[]) bl)
let names_of_local_binders bl =
- List.flatten (List.map (function LocalRawAssum(l,_,_)->l|LocalRawDef(l,_)->[l]|LocalPattern _ -> assert false) bl)
+ List.flatten (List.map (function CLocalAssum(l,_,_)->l|CLocalDef(l,_,_)->[l]|CLocalPattern _ -> assert false) bl)
(**********************************************************************)
(* Functions on constr_expr *)
@@ -113,9 +113,10 @@ let rec constr_expr_eq e1 e2 =
| CLambdaN(_,bl1,a1), CLambdaN(_,bl2,a2) ->
List.equal binder_expr_eq bl1 bl2 &&
constr_expr_eq a1 a2
- | CLetIn(_,(_,na1),a1,b1), CLetIn(_,(_,na2),a2,b2) ->
+ | CLetIn(_,(_,na1),a1,t1,b1), CLetIn(_,(_,na2),a2,t2,b2) ->
Name.equal na1 na2 &&
constr_expr_eq a1 a2 &&
+ Option.equal constr_expr_eq t1 t2 &&
constr_expr_eq b1 b2
| CAppExpl(_,(proj1,r1,_),al1), CAppExpl(_,(proj2,r2,_),al2) ->
Option.equal Int.equal proj1 proj2 &&
@@ -212,9 +213,9 @@ and recursion_order_expr_eq r1 r2 = match r1, r2 with
| _ -> false
and local_binder_eq l1 l2 = match l1, l2 with
-| LocalRawDef (n1, e1), LocalRawDef (n2, e2) ->
- eq_located Name.equal n1 n2 && constr_expr_eq e1 e2
-| LocalRawAssum (n1, _, e1), LocalRawAssum (n2, _, e2) ->
+| CLocalDef (n1, e1, t1), CLocalDef (n2, e2, t2) ->
+ eq_located Name.equal n1 n2 && constr_expr_eq e1 e2 && Option.equal constr_expr_eq t1 t2
+| CLocalAssum (n1, _, e1), CLocalAssum (n2, _, e2) ->
(** Don't care about the [binder_kind] *)
List.equal (eq_located Name.equal) n1 n2 && constr_expr_eq e1 e2
| _ -> false
@@ -234,7 +235,7 @@ let constr_loc = function
| CCoFix (loc,_,_) -> loc
| CProdN (loc,_,_) -> loc
| CLambdaN (loc,_,_) -> loc
- | CLetIn (loc,_,_,_) -> loc
+ | CLetIn (loc,_,_,_,_) -> loc
| CAppExpl (loc,_,_) -> loc
| CApp (loc,_,_) -> loc
| CRecord (loc,_) -> loc
@@ -269,10 +270,11 @@ let raw_cases_pattern_expr_loc = function
| RCPatOr (loc,_) -> loc
let local_binder_loc = function
- | LocalRawAssum ((loc,_)::_,_,t)
- | LocalRawDef ((loc,_),t) -> Loc.merge loc (constr_loc t)
- | LocalRawAssum ([],_,_) -> assert false
- | LocalPattern (loc,_,_) -> loc
+ | CLocalAssum ((loc,_)::_,_,t)
+ | CLocalDef ((loc,_),t,None) -> Loc.merge loc (constr_loc t)
+ | CLocalDef ((loc,_),b,Some t) -> Loc.merge loc (Loc.merge (constr_loc b) (constr_loc t))
+ | CLocalAssum ([],_,_) -> assert false
+ | CLocalPattern (loc,_,_) -> loc
let local_binders_loc bll = match bll with
| [] -> Loc.ghost
@@ -285,7 +287,7 @@ let mkIdentC id = CRef (Ident (Loc.ghost, id),None)
let mkRefC r = CRef (r,None)
let mkCastC (a,k) = CCast (Loc.ghost,a,k)
let mkLambdaC (idl,bk,a,b) = CLambdaN (Loc.ghost,[idl,bk,a],b)
-let mkLetInC (id,a,b) = CLetIn (Loc.ghost,id,a,b)
+let mkLetInC (id,a,t,b) = CLetIn (Loc.ghost,id,a,t,b)
let mkProdC (idl,bk,a,b) = CProdN (Loc.ghost,[idl,bk,a],b)
let mkAppC (f,l) =
@@ -308,17 +310,17 @@ let expand_pattern_binders mkC bl c =
| b :: bl ->
let (env, bl, c) = loop bl c in
match b with
- | LocalRawDef (n, _) ->
+ | CLocalDef (n, _, _) ->
let env = add_name_in_env env n in
(env, b :: bl, c)
- | LocalRawAssum (nl, _, _) ->
+ | CLocalAssum (nl, _, _) ->
let env = List.fold_left add_name_in_env env nl in
(env, b :: bl, c)
- | LocalPattern (loc, p, ty) ->
+ | CLocalPattern (loc, p, ty) ->
let ni = Hook.get fresh_var env c in
let id = (loc, Name ni) in
let b =
- LocalRawAssum
+ CLocalAssum
([id], Default Explicit,
match ty with
| Some ty -> ty
@@ -338,13 +340,13 @@ let expand_pattern_binders mkC bl c =
let mkCProdN loc bll c =
let rec loop loc bll c =
match bll with
- | LocalRawAssum ((loc1,_)::_ as idl,bk,t) :: bll ->
+ | CLocalAssum ((loc1,_)::_ as idl,bk,t) :: bll ->
CProdN (loc,[idl,bk,t],loop (Loc.merge loc1 loc) bll c)
- | LocalRawDef ((loc1,_) as id,b) :: bll ->
- CLetIn (loc,id,b,loop (Loc.merge loc1 loc) bll c)
+ | CLocalDef ((loc1,_) as id,b,t) :: bll ->
+ CLetIn (loc,id,b,t,loop (Loc.merge loc1 loc) bll c)
| [] -> c
- | LocalRawAssum ([],_,_) :: bll -> loop loc bll c
- | LocalPattern (loc,p,ty) :: bll -> assert false
+ | CLocalAssum ([],_,_) :: bll -> loop loc bll c
+ | CLocalPattern (loc,p,ty) :: bll -> assert false
in
let (bll, c) = expand_pattern_binders loop bll c in
loop loc bll c
@@ -352,32 +354,32 @@ let mkCProdN loc bll c =
let mkCLambdaN loc bll c =
let rec loop loc bll c =
match bll with
- | LocalRawAssum ((loc1,_)::_ as idl,bk,t) :: bll ->
+ | CLocalAssum ((loc1,_)::_ as idl,bk,t) :: bll ->
CLambdaN (loc,[idl,bk,t],loop (Loc.merge loc1 loc) bll c)
- | LocalRawDef ((loc1,_) as id,b) :: bll ->
- CLetIn (loc,id,b,loop (Loc.merge loc1 loc) bll c)
+ | CLocalDef ((loc1,_) as id,b,t) :: bll ->
+ CLetIn (loc,id,b,t,loop (Loc.merge loc1 loc) bll c)
| [] -> c
- | LocalRawAssum ([],_,_) :: bll -> loop loc bll c
- | LocalPattern (loc,p,ty) :: bll -> assert false
+ | CLocalAssum ([],_,_) :: bll -> loop loc bll c
+ | CLocalPattern (loc,p,ty) :: bll -> assert false
in
let (bll, c) = expand_pattern_binders loop bll c in
loop loc bll c
let rec abstract_constr_expr c = function
| [] -> c
- | LocalRawDef (x,b)::bl -> mkLetInC(x,b,abstract_constr_expr c bl)
- | LocalRawAssum (idl,bk,t)::bl ->
+ | CLocalDef (x,b,t)::bl -> mkLetInC(x,b,t,abstract_constr_expr c bl)
+ | CLocalAssum (idl,bk,t)::bl ->
List.fold_right (fun x b -> mkLambdaC([x],bk,t,b)) idl
(abstract_constr_expr c bl)
- | LocalPattern _::_ -> assert false
+ | CLocalPattern _::_ -> assert false
let rec prod_constr_expr c = function
| [] -> c
- | LocalRawDef (x,b)::bl -> mkLetInC(x,b,prod_constr_expr c bl)
- | LocalRawAssum (idl,bk,t)::bl ->
+ | CLocalDef (x,b,t)::bl -> mkLetInC(x,b,t,prod_constr_expr c bl)
+ | CLocalAssum (idl,bk,t)::bl ->
List.fold_right (fun x b -> mkProdC([x],bk,t,b)) idl
(prod_constr_expr c bl)
- | LocalPattern _::_ -> assert false
+ | CLocalPattern _::_ -> assert false
let coerce_reference_to_id = function
| Ident (_,id) -> id
diff --git a/interp/constrexpr_ops.mli b/interp/constrexpr_ops.mli
index a92da035f6..45e3a19bc8 100644
--- a/interp/constrexpr_ops.mli
+++ b/interp/constrexpr_ops.mli
@@ -23,8 +23,8 @@ val constr_expr_eq : constr_expr -> constr_expr -> bool
(** Equality on [constr_expr]. This is a syntactical one, which is oblivious to
some parsing details, including locations. *)
-val local_binder_eq : local_binder -> local_binder -> bool
-(** Equality on [local_binder]. Same properties as [constr_expr_eq]. *)
+val local_binder_eq : local_binder_expr -> local_binder_expr -> bool
+(** Equality on [local_binder_expr]. Same properties as [constr_expr_eq]. *)
val binding_kind_eq : Decl_kinds.binding_kind -> Decl_kinds.binding_kind -> bool
(** Equality on [binding_kind] *)
@@ -37,7 +37,7 @@ val binder_kind_eq : binder_kind -> binder_kind -> bool
val constr_loc : constr_expr -> Loc.t
val cases_pattern_expr_loc : cases_pattern_expr -> Loc.t
val raw_cases_pattern_expr_loc : raw_cases_pattern_expr -> Loc.t
-val local_binders_loc : local_binder list -> Loc.t
+val local_binders_loc : local_binder_expr list -> Loc.t
(** {6 Constructors}*)
@@ -46,22 +46,22 @@ val mkRefC : reference -> constr_expr
val mkAppC : constr_expr * constr_expr list -> constr_expr
val mkCastC : constr_expr * constr_expr cast_type -> constr_expr
val mkLambdaC : Name.t located list * binder_kind * constr_expr * constr_expr -> constr_expr
-val mkLetInC : Name.t located * constr_expr * constr_expr -> constr_expr
+val mkLetInC : Name.t located * constr_expr * constr_expr option * constr_expr -> constr_expr
val mkProdC : Name.t located list * binder_kind * constr_expr * constr_expr -> constr_expr
-val abstract_constr_expr : constr_expr -> local_binder list -> constr_expr
-val prod_constr_expr : constr_expr -> local_binder list -> constr_expr
+val abstract_constr_expr : constr_expr -> local_binder_expr list -> constr_expr
+val prod_constr_expr : constr_expr -> local_binder_expr list -> constr_expr
-val mkCLambdaN : Loc.t -> local_binder list -> constr_expr -> constr_expr
+val mkCLambdaN : Loc.t -> local_binder_expr list -> constr_expr -> constr_expr
(** Same as [abstract_constr_expr], with location *)
-val mkCProdN : Loc.t -> local_binder list -> constr_expr -> constr_expr
+val mkCProdN : Loc.t -> local_binder_expr list -> constr_expr -> constr_expr
(** Same as [prod_constr_expr], with location *)
val fresh_var_hook : (Names.Id.t list -> Constrexpr.constr_expr -> Names.Id.t) Hook.t
val expand_pattern_binders :
- (Loc.t -> local_binder list -> constr_expr -> constr_expr) ->
- local_binder list -> constr_expr -> local_binder list * constr_expr
+ (Loc.t -> local_binder_expr list -> constr_expr -> constr_expr) ->
+ local_binder_expr list -> constr_expr -> local_binder_expr list * constr_expr
(** {6 Destructors}*)
@@ -78,9 +78,9 @@ val coerce_to_name : constr_expr -> Name.t located
val default_binder_kind : binder_kind
-val names_of_local_binders : local_binder list -> Name.t located list
+val names_of_local_binders : local_binder_expr list -> Name.t located list
(** Retrieve a list of binding names from a list of binders. *)
-val names_of_local_assums : local_binder list -> Name.t located list
-(** Same as [names_of_local_binders], but does not take the [let] bindings into
+val names_of_local_assums : local_binder_expr list -> Name.t located list
+(** Same as [names_of_local_binder_exprs], but does not take the [let] bindings into
account. *)
diff --git a/interp/constrextern.ml b/interp/constrextern.ml
index 3077231be0..925e9517c7 100644
--- a/interp/constrextern.ml
+++ b/interp/constrextern.ml
@@ -598,6 +598,14 @@ let extern_optimal_prim_token scopes r r' =
| _ -> raise No_match
(**********************************************************************)
+(* mapping decl *)
+
+let extended_glob_local_binder_of_decl loc = function
+ | (p,bk,None,t) -> GLocalAssum (loc,p,bk,t)
+ | (p,bk,Some x,GHole (_, _, Misctypes.IntroAnonymous, None)) -> GLocalDef (loc,p,bk,x,None)
+ | (p,bk,Some x,t) -> GLocalDef (loc,p,bk,x,Some t)
+
+(**********************************************************************)
(* mapping glob_constr to constr_expr *)
let extern_glob_sort = function
@@ -692,8 +700,9 @@ let rec extern inctx scopes vars r =
explicitize loc inctx [] (None,sub_extern false scopes vars f)
(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,
+ | GLetIn (loc,na,b,t,c) ->
+ CLetIn (loc,(loc,na),sub_extern false scopes vars b,
+ Option.map (extern_typ scopes vars) t,
extern inctx scopes (add_vname vars na) c)
| GProd (loc,na,bk,t,c) ->
@@ -756,7 +765,7 @@ let rec extern inctx scopes vars r =
let listdecl =
Array.mapi (fun i fi ->
let (bl,ty,def) = blv.(i), tyv.(i), bv.(i) in
- let bl = List.map (fun (p,bk,x,t) -> (Inl p,bk,x,t)) bl in
+ let bl = List.map (extended_glob_local_binder_of_decl loc) bl in
let (assums,ids,bl) = extern_local_binder scopes vars bl in
let vars0 = List.fold_right (name_fold Id.Set.add) ids vars in
let vars1 = List.fold_right (name_fold Id.Set.add) ids vars' in
@@ -773,7 +782,7 @@ let rec extern inctx scopes vars r =
| GCoFix n ->
let listdecl =
Array.mapi (fun i fi ->
- let bl = List.map (fun (p,bk,x,t) -> (Inl p,bk,x,t)) blv.(i) in
+ let bl = List.map (extended_glob_local_binder_of_decl loc) blv.(i) in
let (_,ids,bl) = extern_local_binder scopes vars bl in
let vars0 = List.fold_right (name_fold Id.Set.add) ids vars in
let vars1 = List.fold_right (name_fold Id.Set.add) ids vars' in
@@ -817,33 +826,32 @@ and factorize_lambda inctx scopes vars na bk aty c =
and extern_local_binder scopes vars = function
[] -> ([],[],[])
- | (Inl na,bk,Some bd,ty)::l ->
+ | GLocalDef (_,na,bk,bd,ty)::l ->
let (assums,ids,l) =
extern_local_binder scopes (name_fold Id.Set.add na vars) l in
(assums,na::ids,
- LocalRawDef((Loc.ghost,na), extern false scopes vars bd) :: l)
+ CLocalDef((Loc.ghost,na), extern false scopes vars bd,
+ Option.map (extern false scopes vars) ty) :: l)
- | (Inl na,bk,None,ty)::l ->
+ | GLocalAssum (_,na,bk,ty)::l ->
let ty = extern_typ scopes vars ty in
(match extern_local_binder scopes (name_fold Id.Set.add na vars) l with
- (assums,ids,LocalRawAssum(nal,k,ty')::l)
+ (assums,ids,CLocalAssum(nal,k,ty')::l)
when constr_expr_eq ty ty' &&
match na with Name id -> not (occur_var_constr_expr id ty')
| _ -> true ->
(na::assums,na::ids,
- LocalRawAssum((Loc.ghost,na)::nal,k,ty')::l)
+ CLocalAssum((Loc.ghost,na)::nal,k,ty')::l)
| (assums,ids,l) ->
(na::assums,na::ids,
- LocalRawAssum([(Loc.ghost,na)],Default bk,ty) :: l))
-
- | (Inr p,bk,Some bd,ty)::l -> assert false
+ CLocalAssum([(Loc.ghost,na)],Default bk,ty) :: l))
- | (Inr p,bk,None,ty)::l ->
+ | GLocalPattern (_,(p,_),_,bk,ty)::l ->
let ty =
if !Flags.raw_print then Some (extern_typ scopes vars ty) else None in
let p = extern_cases_pattern vars p in
let (assums,ids,l) = extern_local_binder scopes vars l in
- (assums,ids, LocalPattern(Loc.ghost,p,ty) :: l)
+ (assums,ids, CLocalPattern(Loc.ghost,p,ty) :: l)
and extern_eqn inctx scopes vars (loc,ids,pl,c) =
(loc,[loc,List.map (extern_cases_pattern_in_scope scopes vars) pl],
@@ -1015,8 +1023,9 @@ let rec glob_of_pat env sigma = function
List.map (glob_of_pat env sigma) args)
| PProd (na,t,c) ->
GProd (loc,na,Explicit,glob_of_pat env sigma t,glob_of_pat (na::env) sigma c)
- | PLetIn (na,t,c) ->
- GLetIn (loc,na,glob_of_pat env sigma t, glob_of_pat (na::env) sigma c)
+ | PLetIn (na,b,t,c) ->
+ GLetIn (loc,na,glob_of_pat env sigma b, Option.map (glob_of_pat env sigma) t,
+ glob_of_pat (na::env) sigma c)
| PLambda (na,t,c) ->
GLambda (loc,na,Explicit,glob_of_pat env sigma t, glob_of_pat (na::env) sigma c)
| PIf (c,b1,b2) ->
@@ -1052,5 +1061,5 @@ let extern_constr_pattern env sigma pat =
let extern_rel_context where env sigma sign =
let a = detype_rel_context where [] (names_of_rel_context env,env) sigma sign in
let vars = vars_of_env env in
- let a = List.map (fun (p,bk,x,t) -> (Inl p,bk,x,t)) a in
+ let a = List.map (extended_glob_local_binder_of_decl Loc.ghost) a in
pi3 (extern_local_binder (None,[]) vars a)
diff --git a/interp/constrextern.mli b/interp/constrextern.mli
index f617faa38a..b39339450a 100644
--- a/interp/constrextern.mli
+++ b/interp/constrextern.mli
@@ -41,7 +41,7 @@ val extern_reference : Loc.t -> Id.Set.t -> global_reference -> reference
val extern_type : bool -> env -> Evd.evar_map -> types -> constr_expr
val extern_sort : Evd.evar_map -> sorts -> glob_sort
val extern_rel_context : constr option -> env -> Evd.evar_map ->
- Context.Rel.t -> local_binder list
+ Context.Rel.t -> local_binder_expr list
(** Printing options *)
val print_implicits : bool ref
diff --git a/interp/constrintern.ml b/interp/constrintern.ml
index 3ed8733df5..8fe6ce85e8 100644
--- a/interp/constrintern.ml
+++ b/interp/constrintern.ml
@@ -65,8 +65,6 @@ type var_internalization_data =
type internalization_env =
(var_internalization_data) Id.Map.t
-type glob_binder = (Name.t * binding_kind * glob_constr option * glob_constr)
-
type ltac_sign = {
ltac_vars : Id.Set.t;
ltac_bound : Id.Set.t;
@@ -306,12 +304,12 @@ let reset_tmp_scope env = {env with tmp_scope = None}
let rec it_mkGProd loc2 env body =
match env with
- (loc1, (na, bk, _, t)) :: tl -> it_mkGProd loc2 tl (GProd (Loc.merge loc1 loc2, na, bk, t, body))
+ (loc1, (na, bk, t)) :: tl -> it_mkGProd loc2 tl (GProd (Loc.merge loc1 loc2, na, bk, t, body))
| [] -> body
let rec it_mkGLambda loc2 env body =
match env with
- (loc1, (na, bk, _, t)) :: tl -> it_mkGLambda loc2 tl (GLambda (Loc.merge loc1 loc2, na, bk, t, body))
+ (loc1, (na, bk, t)) :: tl -> it_mkGLambda loc2 tl (GLambda (Loc.merge loc1 loc2, na, bk, t, body))
| [] -> body
(**********************************************************************)
@@ -399,7 +397,7 @@ let intern_generalized_binder ?(global_level=false) intern_type lvar
env fvs in
let bl = List.map
(fun (id, loc) ->
- (loc, (Name id, b, None, GHole (loc, Evar_kinds.BinderType (Name id), Misctypes.IntroAnonymous, None))))
+ (loc, (Name id, b, GHole (loc, Evar_kinds.BinderType (Name id), Misctypes.IntroAnonymous, None))))
fvs
in
let na = match na with
@@ -414,7 +412,7 @@ let intern_generalized_binder ?(global_level=false) intern_type lvar
in Implicit_quantifiers.make_fresh ids' (Global.env ()) id
in Name name
| _ -> na
- in (push_name_env ~global_level lvar (impls_type_list ty')(*?*) env' (loc,na)), (loc,(na,b',None,ty')) :: List.rev bl
+ in (push_name_env ~global_level lvar (impls_type_list ty')(*?*) env' (loc,na)), (loc,(na,b',ty')) :: List.rev bl
let intern_assumption intern lvar env nal bk ty =
let intern_type env = intern (set_type_scope env) in
@@ -426,7 +424,7 @@ let intern_assumption intern lvar env nal bk ty =
List.fold_left
(fun (env, bl) (loc, na as locna) ->
(push_name_env lvar impls env locna,
- (loc,(na,k,None,locate_if_hole loc na ty))::bl))
+ (loc,(na,k,locate_if_hole loc na ty))::bl))
(env, []) nal
| Generalized (b,b',t) ->
let env, b = intern_generalized_binder intern_type lvar env (List.hd nal) b b' t ty in
@@ -457,47 +455,47 @@ let intern_local_pattern intern lvar env p =
env)
env (free_vars_of_pat [] p)
-type binder_data =
- | BDRawDef of (Loc.t * glob_binder)
- | BDPattern of
- (Loc.t * (cases_pattern * Id.t list) *
- (bool ref *
- (Notation_term.tmp_scope_name option *
- Notation_term.tmp_scope_name list)
- option ref * Notation_term.notation_var_internalization_type)
- Names.Id.Map.t *
- intern_env * constr_expr)
+let glob_local_binder_of_extended = function
+ | GLocalAssum (loc,na,bk,t) -> (na,bk,None,t)
+ | GLocalDef (loc,na,bk,c,Some t) -> (na,bk,Some c,t)
+ | GLocalDef (loc,na,bk,c,None) ->
+ let t = GHole(loc,Evar_kinds.BinderType na,Misctypes.IntroAnonymous,None) in
+ (na,bk,Some c,t)
+ | GLocalPattern (loc,_,_,_,_) ->
+ Loc.raise ~loc (Stream.Error "pattern with quote not allowed here.")
let intern_cases_pattern_fwd = ref (fun _ -> failwith "intern_cases_pattern_fwd")
let intern_local_binder_aux ?(global_level=false) intern lvar (env,bl) = function
- | LocalRawAssum(nal,bk,ty) ->
+ | CLocalAssum(nal,bk,ty) ->
let env, bl' = intern_assumption intern lvar env nal bk ty in
- let bl' = List.map (fun a -> BDRawDef a) bl' in
+ let bl' = List.map (fun (loc,(na,c,t)) -> GLocalAssum (loc,na,c,t)) bl' in
env, bl' @ bl
- | LocalRawDef((loc,na as locna),def) ->
- let indef = intern env def in
- let term, ty =
- match indef with
- | GCast (loc, b, Misctypes.CastConv t) -> b, t
- | _ -> indef, GHole(loc,Evar_kinds.BinderType na,Misctypes.IntroAnonymous,None)
- in
- (push_name_env lvar (impls_term_list indef) env locna,
- (BDRawDef ((loc,(na,Explicit,Some(term),ty))))::bl)
- | LocalPattern (loc,p,ty) ->
+ | CLocalDef((loc,na as locna),def,ty) ->
+ let term = intern env def in
+ let ty = Option.map (intern env) ty in
+ (push_name_env lvar (impls_term_list term) env locna,
+ GLocalDef (loc,na,Explicit,term,ty) :: bl)
+ | CLocalPattern (loc,p,ty) ->
let tyc =
match ty with
| Some ty -> ty
| None -> CHole(loc,None,Misctypes.IntroAnonymous,None)
in
let env = intern_local_pattern intern lvar env p in
+ let il = List.map snd (free_vars_of_pat [] p) in
let cp =
match !intern_cases_pattern_fwd (None,env.scopes) p with
| (_, [(_, cp)]) -> cp
| _ -> assert false
in
- let il = List.map snd (free_vars_of_pat [] p) in
- (env, BDPattern(loc,(cp,il),lvar,env,tyc) :: bl)
+ let ienv = Id.Set.elements env.ids in
+ let id = Namegen.next_ident_away (Id.of_string "pat") ienv in
+ let na = (loc, Name id) in
+ let bk = Default Explicit in
+ let _, bl' = intern_assumption intern lvar env [na] bk tyc in
+ let _,(_,bk,t) = List.hd bl' in
+ (env, GLocalPattern(loc,(cp,il),id,bk,t) :: bl)
let intern_generalization intern env lvar loc bk ak c =
let c = intern {env with unb = true} c in
@@ -567,35 +565,29 @@ let traverse_binder (terms,_,_ as subst) avoid (renaming,env) = function
(renaming',env), Name id'
type letin_param =
- | LPLetIn of Loc.t * (Name.t * glob_constr)
+ | LPLetIn of Loc.t * (Name.t * glob_constr * glob_constr option)
| LPCases of Loc.t * (cases_pattern * Id.t list) * Id.t
let make_letins =
List.fold_right
(fun a c ->
match a with
- | LPLetIn (loc,(na,b)) ->
- GLetIn(loc,na,b,c)
+ | LPLetIn (loc,(na,b,t)) ->
+ GLetIn(loc,na,b,t,c)
| LPCases (loc,(cp,il),id) ->
let tt = (GVar(loc,id),(Name id,None)) in
GCases(loc,Misctypes.LetPatternStyle,None,[tt],[(loc,il,[cp],c)]))
-let rec subordinate_letins intern letins = function
+let rec subordinate_letins letins = function
(* binders come in reverse order; the non-let are returned in reverse order together *)
(* with the subordinated let-in in writing order *)
- | BDRawDef (loc,(na,_,Some b,t))::l ->
- subordinate_letins intern (LPLetIn (loc,(na,b))::letins) l
- | BDRawDef (loc,(na,bk,None,t))::l ->
- let letins',rest = subordinate_letins intern [] l in
+ | GLocalDef (loc,na,_,b,t)::l ->
+ subordinate_letins (LPLetIn (loc,(na,b,t))::letins) l
+ | GLocalAssum (loc,na,bk,t)::l ->
+ let letins',rest = subordinate_letins [] l in
letins',((loc,(na,bk,t)),letins)::rest
- | BDPattern (loc,u,lvar,env,tyc) :: l ->
- let ienv = Id.Set.elements env.ids in
- let id = Namegen.next_ident_away (Id.of_string "pat") ienv in
- let na = (loc, Name id) in
- let bk = Default Explicit in
- let _, bl' = intern_assumption intern lvar env [na] bk tyc in
- let bl' = List.map (fun a -> BDRawDef a) bl' in
- subordinate_letins intern (LPCases (loc,u,id)::letins) (bl'@ l)
+ | GLocalPattern (loc,u,id,bk,t) :: l ->
+ subordinate_letins (LPCases (loc,u,id)::letins) ([GLocalAssum (loc,Name id,bk,t)] @ l)
| [] ->
letins,[]
@@ -609,10 +601,11 @@ let terms_of_binders bl =
let params = List.make (Inductiveops.inductive_nparams (fst c)) hole in
CAppExpl (loc,(None,r,None),params @ List.map term_of_pat l) in
let rec extract_variables = function
- | BDRawDef (loc,(Name id,_,None,_))::l -> CRef (Ident (loc,id), None) :: extract_variables l
- | BDRawDef (loc,(Name id,_,Some _,_))::l -> extract_variables l
- | BDRawDef (loc,(Anonymous,_,_,_))::l -> error "Cannot turn \"_\" into a term."
- | BDPattern (loc,(u,_),lvar,env,tyc) :: l -> term_of_pat u :: extract_variables l
+ | GLocalAssum (loc,Name id,_,_)::l -> CRef (Ident (loc,id), None) :: extract_variables l
+ | GLocalDef (loc,Name id,_,_,_)::l -> extract_variables l
+ | GLocalDef (loc,Anonymous,_,_,_)::l
+ | GLocalAssum (loc,Anonymous,_,_)::l -> error "Cannot turn \"_\" into a term."
+ | GLocalPattern (loc,(u,_),_,_,_) :: l -> term_of_pat u :: extract_variables l
| [] -> [] in
extract_variables bl
@@ -674,7 +667,7 @@ let instantiate_notation_constr loc intern ntnvars subst infos c =
(* All elements of the list are in scopes (scopt,subscopes) *)
let (bl,(scopt,subscopes)) = Id.Map.find x binders in
let env,bl = List.fold_left (intern_local_binder_aux intern ntnvars) (env,[]) bl in
- let letins,bl = subordinate_letins intern [] bl in
+ let letins,bl = subordinate_letins [] bl in
let termin = aux (terms,None,None) (renaming,env) terminator in
let res = List.fold_left (fun t binder ->
aux (terms,Some(y,binder),Some t) subinfos iter)
@@ -1545,10 +1538,8 @@ let internalize globalenv env allow_patvar (_, ntnvars as lvar) c =
let intern_ro_arg f =
let before, after = split_at_annot bl n in
let (env',rbefore) = List.fold_left intern_local_binder (env,[]) before in
- let rbefore = List.map (function BDRawDef a -> a | BDPattern _ -> assert false) rbefore in
let ro = f (intern env') in
- let n' = Option.map (fun _ -> List.count (fun (_,(_,_,b,_)) -> (* remove let-ins *) b = None) rbefore) n in
- let rbefore = List.map (fun a -> BDRawDef a) rbefore in
+ let n' = Option.map (fun _ -> List.count (function GLocalAssum _ -> true | _ -> false (* remove let-ins *)) rbefore) n in
n', ro, List.fold_left intern_local_binder (env',rbefore) after
in
let n, ro, (env',rbl) =
@@ -1560,24 +1551,19 @@ let internalize globalenv env allow_patvar (_, ntnvars as lvar) c =
| CMeasureRec (m,r) ->
intern_ro_arg (fun f -> GMeasureRec (f m, Option.map f r))
in
- let bl =
- List.rev_map
- (function
- | BDRawDef a -> a
- | BDPattern (loc,_,_,_,_) ->
- Loc.raise ~loc (Stream.Error "pattern with quote not allowed after fix")) rbl in
- ((n, ro), bl, intern_type env' ty, env')) dl in
+ let bl = List.rev (List.map glob_local_binder_of_extended rbl) in
+ ((n, ro), bl, intern_type env' ty, env')) dl in
let idl = Array.map2 (fun (_,_,_,_,bd) (a,b,c,env') ->
let env'' = List.fold_left_i (fun i en name ->
let (_,bli,tyi,_) = idl_temp.(i) in
- let fix_args = (List.map (fun (_,(na, bk, _, _)) -> (build_impls bk na)) bli) in
+ let fix_args = (List.map (fun (na, bk, _, _) -> (build_impls bk na)) bli) in
push_name_env ntnvars (impls_type_list ~args:fix_args tyi)
en (Loc.ghost, Name name)) 0 env' lf in
(a,b,c,intern {env'' with tmp_scope = None} bd)) dl idl_temp in
GRec (loc,GFix
(Array.map (fun (ro,_,_,_) -> ro) idl,n),
Array.of_list lf,
- Array.map (fun (_,bl,_,_) -> List.map snd bl) idl,
+ Array.map (fun (_,bl,_,_) -> bl) idl,
Array.map (fun (_,_,ty,_) -> ty) idl,
Array.map (fun (_,_,_,bd) -> bd) idl)
| CCoFix (loc, (locid,iddef), dl) ->
@@ -1591,20 +1577,18 @@ let internalize globalenv env allow_patvar (_, ntnvars as lvar) c =
let idl_tmp = Array.map
(fun ((loc,id),bl,ty,_) ->
let (env',rbl) = List.fold_left intern_local_binder (env,[]) bl in
- let rbl = List.map (function BDRawDef a -> a | BDPattern _ ->
- Loc.raise ~loc (Stream.Error "pattern with quote not allowed after cofix")) rbl in
- (List.rev rbl,
+ (List.rev (List.map glob_local_binder_of_extended rbl),
intern_type env' ty,env')) dl in
let idl = Array.map2 (fun (_,_,_,bd) (b,c,env') ->
let env'' = List.fold_left_i (fun i en name ->
let (bli,tyi,_) = idl_tmp.(i) in
- let cofix_args = List.map (fun (_, (na, bk, _, _)) -> (build_impls bk na)) bli in
+ let cofix_args = List.map (fun (na, bk, _, _) -> (build_impls bk na)) bli in
push_name_env ntnvars (impls_type_list ~args:cofix_args tyi)
en (Loc.ghost, Name name)) 0 env' lf in
(b,c,intern {env'' with tmp_scope = None} bd)) dl idl_tmp in
GRec (loc,GCoFix n,
Array.of_list lf,
- Array.map (fun (bl,_,_) -> List.map snd bl) idl,
+ Array.map (fun (bl,_,_) -> bl) idl,
Array.map (fun (_,ty,_) -> ty) idl,
Array.map (fun (_,_,bd) -> bd) idl)
| CProdN (loc,[],c2) ->
@@ -1615,9 +1599,10 @@ let internalize globalenv env allow_patvar (_, ntnvars as lvar) c =
intern env c2
| CLambdaN (loc,(nal,bk,ty)::bll,c2) ->
iterate_lam loc (reset_tmp_scope env) bk ty (CLambdaN (loc, bll, c2)) nal
- | CLetIn (loc,na,c1,c2) ->
+ | CLetIn (loc,na,c1,t,c2) ->
let inc1 = intern (reset_tmp_scope env) c1 in
- GLetIn (loc, snd na, inc1,
+ let int = Option.map (intern_type env) t in
+ GLetIn (loc, snd na, inc1, int,
intern (push_name_env ntnvars (impls_term_list inc1) env na) c2)
| CNotation (loc,"- _",([CPrim (_,Numeral p)],[],[]))
when Bigint.is_strictly_pos p ->
@@ -2070,18 +2055,11 @@ let intern_context global_level env impl_env binders =
let lvar = (empty_ltac_sign, Id.Map.empty) in
let lenv, bl = List.fold_left
(fun (lenv, bl) b ->
- let bl = List.map (fun a -> BDRawDef a) bl in
let (env, bl) = intern_local_binder_aux ~global_level (my_intern_constr env lvar) Id.Map.empty (lenv, bl) b in
- let bl =
- List.map
- (function
- | BDRawDef a -> a
- | BDPattern (loc,_,_,_,_) ->
- Loc.raise ~loc (Stream.Error "pattern with quote not allowed here")) bl in
(env, bl))
({ids = extract_ids env; unb = false;
tmp_scope = None; scopes = []; impls = impl_env}, []) binders in
- (lenv.impls, List.map snd bl)
+ (lenv.impls, List.map glob_local_binder_of_extended bl)
with InternalizationError (loc,e) ->
user_err ~loc ~hdr:"internalize" (explain_internalization_error e)
diff --git a/interp/constrintern.mli b/interp/constrintern.mli
index 61e7c6f5cb..e45de25887 100644
--- a/interp/constrintern.mli
+++ b/interp/constrintern.mli
@@ -75,8 +75,6 @@ type ltac_sign = {
val empty_ltac_sign : ltac_sign
-type glob_binder = (Name.t * binding_kind * glob_constr option * glob_constr)
-
(** {6 Internalization performs interpretation of global names and notations } *)
val intern_constr : env -> constr_expr -> glob_constr
@@ -90,7 +88,7 @@ val intern_gen : typing_constraint -> env ->
val intern_pattern : env -> cases_pattern_expr ->
Id.t list * (Id.t Id.Map.t * cases_pattern) list
-val intern_context : bool -> env -> internalization_env -> local_binder list -> internalization_env * glob_binder list
+val intern_context : bool -> env -> internalization_env -> local_binder_expr list -> internalization_env * glob_decl list
(** {6 Composing internalization with type inference (pretyping) } *)
@@ -159,16 +157,16 @@ val interp_binder_evars : env -> evar_map ref -> Name.t -> constr_expr -> types
val interp_context_evars :
?global_level:bool -> ?impl_env:internalization_env -> ?shift:int ->
- env -> evar_map ref -> local_binder list ->
+ env -> evar_map ref -> local_binder_expr list ->
internalization_env * ((env * Context.Rel.t) * Impargs.manual_implicits)
(* val interp_context_gen : (env -> glob_constr -> unsafe_type_judgment Evd.in_evar_universe_context) -> *)
(* (env -> Evarutil.type_constraint -> glob_constr -> unsafe_judgment Evd.in_evar_universe_context) -> *)
(* ?global_level:bool -> ?impl_env:internalization_env -> *)
-(* env -> evar_map -> local_binder list -> internalization_env * ((env * Evd.evar_universe_context * rel_context * sorts list) * Impargs.manual_implicits) *)
+(* env -> evar_map -> local_binder_expr list -> internalization_env * ((env * Evd.evar_universe_context * rel_context * sorts list) * Impargs.manual_implicits) *)
(* val interp_context : ?global_level:bool -> ?impl_env:internalization_env -> *)
-(* env -> evar_map -> local_binder list -> *)
+(* env -> evar_map -> local_binder_expr list -> *)
(* internalization_env * *)
(* ((env * Evd.evar_universe_context * rel_context * sorts list) * Impargs.manual_implicits) *)
diff --git a/interp/dumpglob.ml b/interp/dumpglob.ml
index b020f89457..9f549b0c0f 100644
--- a/interp/dumpglob.ml
+++ b/interp/dumpglob.ml
@@ -173,32 +173,33 @@ 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 * 5) '_' in
+ let ntn = Bytes.make (String.length df * 5) '_' in
let j = ref 0 in
let l = String.length df - 1 in
let i = ref 0 in
+ let open Bytes in (* Bytes.set *)
while !i <= l do
assert (df.[!i] != ' ');
if df.[!i] == '_' && (Int.equal !i l || df.[!i+1] == ' ') then
(* Next token is a non-terminal *)
- (ntn.[!j] <- 'x'; incr j; incr i)
+ (set ntn !j 'x'; incr j; incr i)
else begin
(* Next token is a terminal *)
- ntn.[!j] <- '\''; incr j;
+ set ntn !j '\''; incr j;
while !i <= l && df.[!i] != ' ' do
if df.[!i] < ' ' then
let c = char_of_int (int_of_char 'A' + int_of_char df.[!i] - 1) in
(String.blit ("'^" ^ String.make 1 c) 0 ntn !j 3; j := !j+3; incr i)
else begin
- if df.[!i] == '\'' then (ntn.[!j] <- '\''; incr j);
- ntn.[!j] <- df.[!i]; incr j; incr i
+ if df.[!i] == '\'' then (set ntn !j '\''; incr j);
+ set ntn !j df.[!i]; incr j; incr i
end
done;
- ntn.[!j] <- '\''; incr j
+ set ntn !j '\''; incr j
end;
- if !i <= l then (ntn.[!j] <- '_'; incr j; incr i)
+ if !i <= l then (set ntn !j '_'; incr j; incr i)
done;
- let df = String.sub ntn 0 !j in
+ let df = Bytes.sub_string ntn 0 !j in
match sc with Some sc -> ":" ^ sc ^ ":" ^ df | _ -> "::" ^ df
let dump_notation_location posl df (((path,secpath),_),sc) =
diff --git a/interp/implicit_quantifiers.ml b/interp/implicit_quantifiers.ml
index 77a8ed680a..7f11c0a3b6 100644
--- a/interp/implicit_quantifiers.ml
+++ b/interp/implicit_quantifiers.ml
@@ -102,19 +102,20 @@ let free_vars_of_constr_expr c ?(bound=Id.Set.empty) l =
let ids_of_names l =
List.fold_left (fun acc x -> match snd x with Name na -> na :: acc | Anonymous -> acc) [] l
-let free_vars_of_binders ?(bound=Id.Set.empty) l (binders : local_binder list) =
+let free_vars_of_binders ?(bound=Id.Set.empty) l (binders : local_binder_expr list) =
let rec aux bdvars l c = match c with
- ((LocalRawAssum (n, _, c)) :: tl) ->
+ ((CLocalAssum (n, _, c)) :: tl) ->
let bound = ids_of_names n in
let l' = free_vars_of_constr_expr c ~bound:bdvars l in
aux (Id.Set.union (ids_of_list bound) bdvars) l' tl
- | ((LocalRawDef (n, c)) :: tl) ->
+ | ((CLocalDef (n, c, t)) :: tl) ->
let bound = match snd n with Anonymous -> [] | Name n -> [n] in
let l' = free_vars_of_constr_expr c ~bound:bdvars l in
- aux (Id.Set.union (ids_of_list bound) bdvars) l' tl
+ let l'' = Option.fold_left (fun l t -> free_vars_of_constr_expr t ~bound:bdvars l) l' t in
+ aux (Id.Set.union (ids_of_list bound) bdvars) l'' tl
- | LocalPattern _ :: tl -> assert false
+ | CLocalPattern _ :: tl -> assert false
| [] -> bdvars, l
in aux bound l binders
@@ -131,10 +132,15 @@ let generalizable_vars_of_glob_constr ?(bound=Id.Set.empty) ?(allowed=Id.Set.emp
else (id, loc) :: vs
else vs
| GApp (loc,f,args) -> List.fold_left (vars bound) vs (f::args)
- | GLambda (loc,na,_,ty,c) | GProd (loc,na,_,ty,c) | GLetIn (loc,na,ty,c) ->
+ | GLambda (loc,na,_,ty,c) | GProd (loc,na,_,ty,c) ->
let vs' = vars bound vs ty in
let bound' = add_name_to_ids bound na in
vars bound' vs' c
+ | GLetIn (loc,na,b,ty,c) ->
+ let vs' = vars bound vs b in
+ let vs'' = Option.fold_left (vars bound) vs' ty in
+ let bound' = add_name_to_ids bound na in
+ vars bound' vs'' c
| GCases (loc,sty,rtntypopt,tml,pl) ->
let vs1 = vars_option bound vs rtntypopt in
let vs2 = List.fold_left (fun vs (tm,_) -> vars bound vs tm) vs1 tml in
@@ -318,7 +324,7 @@ let implicits_of_glob_constr ?(with_products=true) l =
| _ -> ()
in []
| GLambda (loc, na, bk, t, b) -> abs na bk b
- | GLetIn (loc, na, t, b) -> aux i b
+ | GLetIn (loc, na, b, t, c) -> aux i c
| GRec (_, fix_kind, nas, args, tys, bds) ->
let nb = match fix_kind with |GFix (_, n) -> n | GCoFix n -> n in
List.fold_left_i (fun i l (na,bk,_,_) -> add_impl i na bk l) i (aux (List.length args.(nb) + i) bds.(nb)) args.(nb)
diff --git a/interp/implicit_quantifiers.mli b/interp/implicit_quantifiers.mli
index d0327e5068..71009ec3c2 100644
--- a/interp/implicit_quantifiers.mli
+++ b/interp/implicit_quantifiers.mli
@@ -25,7 +25,7 @@ val free_vars_of_constr_expr : constr_expr -> ?bound:Id.Set.t ->
Id.t list -> Id.t list
val free_vars_of_binders :
- ?bound:Id.Set.t -> Id.t list -> local_binder list -> Id.Set.t * Id.t list
+ ?bound:Id.Set.t -> Id.t list -> local_binder_expr list -> Id.Set.t * Id.t list
(** Returns the generalizable free ids in left-to-right
order with the location of their first occurrence *)
diff --git a/interp/notation_ops.ml b/interp/notation_ops.ml
index 7dbd94aa74..59625426f0 100644
--- a/interp/notation_ops.ml
+++ b/interp/notation_ops.ml
@@ -36,7 +36,7 @@ let compare_glob_constr f add t1 t2 = match t1,t2 with
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 ->
+ | GLetIn (_,na1,b1,t1,c1), GLetIn (_,na2,b2,t2,c2) when Name.equal na1 na2 ->
on_true_do (f b1 b2 && f c1 c2) add na1
| (GCases _ | GRec _
| GPatVar _ | GEvar _ | GLetTuple _ | GIf _ | GCast _),_
@@ -63,8 +63,9 @@ let rec eq_notation_constr (vars1,vars2 as vars) t1 t2 = match t1, t2 with
| NBinderList (i1, j1, t1, u1), NBinderList (i2, j2, t2, u2) ->
Id.equal i1 i2 && Id.equal j1 j2 && (eq_notation_constr vars) t1 t2 &&
(eq_notation_constr vars) u1 u2
-| NLetIn (na1, t1, u1), NLetIn (na2, t2, u2) ->
- Name.equal na1 na2 && (eq_notation_constr vars) t1 t2 && (eq_notation_constr vars) u1 u2
+| NLetIn (na1, b1, t1, u1), NLetIn (na2, b2, t2, u2) ->
+ Name.equal na1 na2 && eq_notation_constr vars b1 b2 &&
+ Option.equal (eq_notation_constr vars) t1 t2 && (eq_notation_constr vars) u1 u2
| NCases (_, o1, r1, p1), NCases (_, o2, r2, p2) -> (** FIXME? *)
let eqpat (p1, t1) (p2, t2) =
List.equal cases_pattern_eq p1 p2 &&
@@ -168,8 +169,8 @@ let glob_constr_of_notation_constr_with_binders loc g f e = function
let e',na = g e na in GLambda (loc,na,Explicit,f e ty,f e' c)
| NProd (na,ty,c) ->
let e',na = g e na in GProd (loc,na,Explicit,f e ty,f e' c)
- | NLetIn (na,b,c) ->
- let e',na = g e na in GLetIn (loc,na,f e b,f e' c)
+ | NLetIn (na,b,t,c) ->
+ let e',na = g e na in GLetIn (loc,na,f e b,Option.map (f e) t,f e' c)
| NCases (sty,rtntypopt,tml,eqnl) ->
let e',tml' = List.fold_right (fun (tm,(na,t)) (e',tml') ->
let e',t' = match t with
@@ -347,7 +348,7 @@ let notation_constr_and_vars_of_glob_constr a =
| GApp (_,g,args) -> NApp (aux g, List.map aux args)
| GLambda (_,na,bk,ty,c) -> add_name found na; NLambda (na,aux ty,aux c)
| GProd (_,na,bk,ty,c) -> add_name found na; NProd (na,aux ty,aux c)
- | GLetIn (_,na,b,c) -> add_name found na; NLetIn (na,aux b,aux c)
+ | GLetIn (_,na,b,t,c) -> add_name found na; NLetIn (na,aux b,Option.map aux t,aux c)
| GCases (_,sty,rtntypopt,tml,eqnl) ->
let f (_,idl,pat,rhs) = List.iter (add_id found) idl; (pat,aux rhs) in
NCases (sty,Option.map aux rtntypopt,
@@ -496,11 +497,12 @@ let rec subst_notation_constr subst bound raw =
if r1' == r1 && r2' == r2 then raw else
NBinderList (id1,id2,r1',r2')
- | NLetIn (n,r1,r2) ->
- let r1' = subst_notation_constr subst bound r1
- and r2' = subst_notation_constr subst bound r2 in
- if r1' == r1 && r2' == r2 then raw else
- NLetIn (n,r1',r2')
+ | NLetIn (n,r1,t,r2) ->
+ let r1' = subst_notation_constr subst bound r1 in
+ let t' = Option.smartmap (subst_notation_constr subst bound) t in
+ let r2' = subst_notation_constr subst bound r2 in
+ if r1' == r1 && t == t' && r2' == r2 then raw else
+ NLetIn (n,r1',t',r2')
| NCases (sty,rtntypopt,rl,branches) ->
let rtntypopt' = Option.smartmap (subst_notation_constr subst bound) rtntypopt
@@ -780,18 +782,23 @@ let bind_bindinglist_env alp (terms,onlybinders,termlists,binderlists as sigma)
| GHole _, _ -> v'
| _, GHole _ -> v
| _, _ -> if glob_constr_eq (alpha_rename (snd alp) v) v' then v else raise No_match in
+ let unify_opt_term alp v v' =
+ match v, v' with
+ | Some t, Some t' -> Some (unify_term alp t t')
+ | (Some _ as x), None | None, (Some _ as x) -> x
+ | None, None -> None in
let unify_binding_kind bk bk' = if bk == bk' then bk' else raise No_match in
let unify_binder alp b b' =
match b, b' with
- | (Inl na, bk, None, t), (Inl na', bk', None, t') (* assum *) ->
+ | GLocalAssum (loc,na,bk,t), GLocalAssum (_,na',bk',t') ->
let alp, na = unify_name alp na na' in
- alp, (Inl na, unify_binding_kind bk bk', None, unify_term alp t t')
- | (Inl na, bk, Some c, t), (Inl na', bk', Some c', t') (* let *) ->
+ alp, GLocalAssum (loc, na, unify_binding_kind bk bk', unify_term alp t t')
+ | GLocalDef (loc,na,bk,c,t), GLocalDef (_,na',bk',c',t') ->
let alp, na = unify_name alp na na' in
- alp, (Inl na, unify_binding_kind bk bk', Some (unify_term alp c c'), unify_term alp t t')
- | (Inr p, bk, None, t), (Inr p', bk', None, t') (* pattern *) ->
+ alp, GLocalDef (loc, na, unify_binding_kind bk bk', unify_term alp c c', unify_opt_term alp t t')
+ | GLocalPattern (loc,(p,ids),id,bk,t), GLocalPattern (_,(p',_),_,bk',t') ->
let alp, p = unify_pat alp p p' in
- alp, (Inr p, unify_binding_kind bk bk', None, unify_term alp t t')
+ alp, GLocalPattern (loc, (p,ids), id, unify_binding_kind bk bk', unify_term alp t t')
| _ -> raise No_match in
let rec unify alp bl bl' =
match bl, bl' with
@@ -820,16 +827,16 @@ let bind_bindinglist_as_term_env alp (terms,onlybinders,termlists,binderlists) v
else raise No_match in
let unify_term_binder c b' =
match c, b' with
- | GVar (_, id), (Inl na', bk', None, t') (* assum *) ->
- (Inl (unify_id id na'), bk', None, t')
- | c, (Inr p', bk', None, t') (* pattern *) ->
+ | GVar (loc, id), GLocalAssum (_, na', bk', t') ->
+ GLocalAssum (loc, unify_id id na', bk', t')
+ | c, GLocalPattern (loc, (p',ids), id, bk', t') ->
let p = pat_binder_of_term c in
- (Inr (unify_pat p p'), bk', None, t')
+ GLocalPattern (loc, (unify_pat p p',ids), id, bk', t')
| _ -> raise No_match in
let rec unify cl bl' =
match cl, bl' with
| [], [] -> []
- | c :: cl, (Inl _, _, Some _,t) :: bl' -> unify cl bl'
+ | c :: cl, GLocalDef (_, _, _, _, t) :: bl' -> unify cl bl'
| c :: cl, b' :: bl' -> unify_term_binder c b' :: unify cl bl'
| _ -> raise No_match in
let bl = unify cl bl' in
@@ -882,19 +889,19 @@ let rec match_cases_pattern_binders metas acc pat1 pat2 =
let glue_letin_with_decls = true
let rec match_iterated_binders islambda decls = function
- | GLambda (_,Name p,bk,t,GCases (_,LetPatternStyle,None,[(GVar(_,e),_)],[(_,_,[cp],b)]))
+ | GLambda (loc,Name p,bk,t,GCases (_,LetPatternStyle,None,[(GVar(_,e),_)],[(_,ids,[cp],b)]))
when islambda && Id.equal p e ->
- match_iterated_binders islambda ((Inr cp,bk,None,t)::decls) b
- | GLambda (_,na,bk,t,b) when islambda ->
- match_iterated_binders islambda ((Inl na,bk,None,t)::decls) b
- | GProd (_,Name p,bk,t,GCases (_,LetPatternStyle,None,[(GVar(_,e),_)],[(_,_,[cp],b)]))
+ match_iterated_binders islambda (GLocalPattern (loc,(cp,ids),p,bk,t)::decls) b
+ | GLambda (loc,na,bk,t,b) when islambda ->
+ match_iterated_binders islambda (GLocalAssum (loc,na,bk,t)::decls) b
+ | GProd (loc,Name p,bk,t,GCases (_,LetPatternStyle,None,[(GVar(_,e),_)],[(_,ids,[cp],b)]))
when not islambda && Id.equal p e ->
- match_iterated_binders islambda ((Inr cp,bk,None,t)::decls) b
- | GProd (_,(Name _ as na),bk,t,b) when not islambda ->
- match_iterated_binders islambda ((Inl na,bk,None,t)::decls) b
- | GLetIn (loc,na,c,b) when glue_letin_with_decls ->
+ match_iterated_binders islambda (GLocalPattern (loc,(cp,ids),p,bk,t)::decls) b
+ | GProd (loc,(Name _ as na),bk,t,b) when not islambda ->
+ match_iterated_binders islambda (GLocalAssum (loc,na,bk,t)::decls) b
+ | GLetIn (loc,na,c,t,b) when glue_letin_with_decls ->
match_iterated_binders islambda
- ((Inl na,Explicit (*?*), Some c,GHole(loc,Evar_kinds.BinderType na,Misctypes.IntroAnonymous,None))::decls) b
+ (GLocalDef (loc,na,Explicit (*?*), c,t)::decls) b
| b -> (decls,b)
let remove_sigma x (terms,onlybinders,termlists,binderlists) =
@@ -971,29 +978,29 @@ let rec match_ inner u alp metas sigma a1 a2 =
match_termlist (match_hd u alp) alp metas sigma r1 x y iter termin lassoc
(* "λ p, let 'cp = p in t" -> "λ 'cp, t" *)
- | GLambda (_,Name p,bk,t1,GCases (_,LetPatternStyle,None,[(GVar(_,e),_)],[(_,_,[cp],b1)])),
+ | GLambda (loc,Name p,bk,t1,GCases (_,LetPatternStyle,None,[(GVar(_,e),_)],[(_,ids,[cp],b1)])),
NBinderList (x,_,NLambda (Name _id2,_,b2),termin) when Id.equal p e ->
- let (decls,b) = match_iterated_binders true [(Inr cp,bk,None,t1)] b1 in
+ let (decls,b) = match_iterated_binders true [GLocalPattern(loc,(cp,ids),p,bk,t1)] b1 in
let alp,sigma = bind_bindinglist_env alp sigma x decls in
match_in u alp metas sigma b termin
(* Matching recursive notations for binders: ad hoc cases supporting let-in *)
- | GLambda (_,na1,bk,t1,b1), NBinderList (x,_,NLambda (Name _id2,_,b2),termin)->
- let (decls,b) = match_iterated_binders true [(Inl na1,bk,None,t1)] b1 in
+ | GLambda (loc,na1,bk,t1,b1), NBinderList (x,_,NLambda (Name _id2,_,b2),termin)->
+ let (decls,b) = match_iterated_binders true [GLocalAssum (loc,na1,bk,t1)] b1 in
(* TODO: address the possibility that termin is a Lambda itself *)
let alp,sigma = bind_bindinglist_env alp sigma x decls in
match_in u alp metas sigma b termin
(* "∀ p, let 'cp = p in t" -> "∀ 'cp, t" *)
- | GProd (_,Name p,bk,t1,GCases (_,LetPatternStyle,None,[(GVar(_,e),_)],[(_,_,[cp],b1)])),
+ | GProd (loc,Name p,bk,t1,GCases (_,LetPatternStyle,None,[(GVar(_,e),_)],[(_,ids,[cp],b1)])),
NBinderList (x,_,NProd (Name _id2,_,b2),(NVar v as termin)) when Id.equal p e ->
- let (decls,b) = match_iterated_binders true [(Inr cp,bk,None,t1)] b1 in
+ let (decls,b) = match_iterated_binders true [GLocalPattern (loc,(cp,ids),p,bk,t1)] b1 in
let alp,sigma = bind_bindinglist_env alp sigma x decls in
match_in u alp metas sigma b termin
- | GProd (_,na1,bk,t1,b1), NBinderList (x,_,NProd (Name _id2,_,b2),termin)
+ | GProd (loc,na1,bk,t1,b1), NBinderList (x,_,NProd (Name _id2,_,b2),termin)
when na1 != Anonymous ->
- let (decls,b) = match_iterated_binders false [(Inl na1,bk,None,t1)] b1 in
+ let (decls,b) = match_iterated_binders false [GLocalAssum (loc,na1,bk,t1)] b1 in
(* TODO: address the possibility that termin is a Prod itself *)
let alp,sigma = bind_bindinglist_env alp sigma x decls in
match_in u alp metas sigma b termin
@@ -1002,18 +1009,18 @@ let rec match_ inner u alp metas sigma a1 a2 =
match_binderlist_with_app (match_hd u) alp metas sigma r x y iter termin
(* Matching individual binders as part of a recursive pattern *)
- | GLambda (_,Name p,bk,t,GCases (_,LetPatternStyle,None,[(GVar(_,e),_)],[(_,_,[cp],b1)])),
+ | GLambda (loc,Name p,bk,t,GCases (_,LetPatternStyle,None,[(GVar(_,e),_)],[(_,ids,[cp],b1)])),
NLambda (Name id,_,b2)
when is_bindinglist_meta id metas ->
- let alp,sigma = bind_bindinglist_env alp sigma id [(Inr cp,bk,None,t)] in
+ let alp,sigma = bind_bindinglist_env alp sigma id [GLocalPattern (loc,(cp,ids),p,bk,t)] in
match_in u alp metas sigma b1 b2
- | GLambda (_,na,bk,t,b1), NLambda (Name id,_,b2)
+ | GLambda (loc,na,bk,t,b1), NLambda (Name id,_,b2)
when is_bindinglist_meta id metas ->
- let alp,sigma = bind_bindinglist_env alp sigma id [(Inl na,bk,None,t)] in
+ let alp,sigma = bind_bindinglist_env alp sigma id [GLocalAssum (loc,na,bk,t)] in
match_in u alp metas sigma b1 b2
- | GProd (_,na,bk,t,b1), NProd (Name id,_,b2)
+ | GProd (loc,na,bk,t,b1), NProd (Name id,_,b2)
when is_bindinglist_meta id metas && na != Anonymous ->
- let alp,sigma = bind_bindinglist_env alp sigma id [(Inl na,bk,None,t)] in
+ let alp,sigma = bind_bindinglist_env alp sigma id [GLocalAssum (loc,na,bk,t)] in
match_in u alp metas sigma b1 b2
(* Matching compositionally *)
@@ -1034,8 +1041,12 @@ let rec match_ inner u alp metas sigma a1 a2 =
match_binders u alp metas na1 na2 (match_in u alp metas sigma t1 t2) b1 b2
| GProd (_,na1,_,t1,b1), NProd (na2,t2,b2) ->
match_binders u alp metas na1 na2 (match_in u alp metas sigma t1 t2) b1 b2
- | GLetIn (_,na1,t1,b1), NLetIn (na2,t2,b2) ->
- match_binders u alp metas na1 na2 (match_in u alp metas sigma t1 t2) b1 b2
+ | GLetIn (_,na1,b1,_,c1), NLetIn (na2,b2,None,c2)
+ | GLetIn (_,na1,b1,None,c1), NLetIn (na2,b2,_,c2) ->
+ match_binders u alp metas na1 na2 (match_in u alp metas sigma b1 b2) c1 c2
+ | GLetIn (_,na1,b1,Some t1,c1), NLetIn (na2,b2,Some t2,c2) ->
+ match_binders u alp metas na1 na2
+ (match_in u alp metas (match_in u alp metas sigma b1 b2) t1 t2) c1 c2
| GCases (_,sty1,rtno1,tml1,eqnl1), NCases (sty2,rtno2,tml2,eqnl2)
when sty1 == sty2
&& Int.equal (List.length tml1) (List.length tml2)
@@ -1101,7 +1112,7 @@ let rec match_ inner u alp metas sigma a1 a2 =
| _ -> assert false in
let (alp,sigma) =
if is_bindinglist_meta id metas then
- bind_bindinglist_env alp sigma id [(Inl (Name id'),Explicit,None,t1)]
+ bind_bindinglist_env alp sigma id [GLocalAssum (Loc.ghost,Name id',Explicit,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
diff --git a/interp/notation_ops.mli b/interp/notation_ops.mli
index c8fcbf7410..a61ba172ee 100644
--- a/interp/notation_ops.mli
+++ b/interp/notation_ops.mli
@@ -47,12 +47,9 @@ val glob_constr_of_notation_constr : Loc.t -> notation_constr -> glob_constr
exception No_match
-type glob_decl2 =
- (name, cases_pattern) Util.union * Decl_kinds.binding_kind *
- glob_constr option * glob_constr
val match_notation_constr : bool -> glob_constr -> interpretation ->
(glob_constr * subscopes) list * (glob_constr list * subscopes) list *
- (glob_decl2 list * subscopes) list
+ (extended_glob_local_binder list * subscopes) list
val match_notation_constr_cases_pattern :
cases_pattern -> interpretation ->
diff --git a/interp/smartlocate.ml b/interp/smartlocate.ml
index 178c1c1f96..d863e05616 100644
--- a/interp/smartlocate.ml
+++ b/interp/smartlocate.ml
@@ -28,7 +28,7 @@ let global_of_extended_global_head = function
| NRef ref -> ref
| NApp (rc, _) -> head_of rc
| NCast (rc, _) -> head_of rc
- | NLetIn (_, _, rc) -> head_of rc
+ | NLetIn (_, _, _, rc) -> head_of rc
| _ -> raise Not_found in
head_of syn_def
diff --git a/interp/topconstr.ml b/interp/topconstr.ml
index fd57b70ca9..89e04b69d2 100644
--- a/interp/topconstr.ml
+++ b/interp/topconstr.ml
@@ -89,13 +89,13 @@ let rec fold_constr_expr_binders g f n acc b = function
f n acc b
let rec fold_local_binders g f n acc b = function
- | LocalRawAssum (nal,bk,t)::l ->
+ | CLocalAssum (nal,bk,t)::l ->
let nal = snd (List.split nal) in
let n' = List.fold_right (name_fold g) nal n in
f n (fold_local_binders g f n' acc b l) t
- | LocalRawDef ((_,na),t)::l ->
- f n (fold_local_binders g f (name_fold g na n) acc b l) t
- | LocalPattern (_,pat,t)::l ->
+ | CLocalDef ((_,na),c,t)::l ->
+ Option.fold_left (f n) (f n (fold_local_binders g f (name_fold g na n) acc b l) c) t
+ | CLocalPattern (_,pat,t)::l ->
let acc = fold_local_binders g f (cases_pattern_fold_names g n pat) acc b l in
Option.fold_left (f n) acc t
| [] ->
@@ -105,7 +105,8 @@ let fold_constr_expr_with_binders g f n acc = function
| CAppExpl (loc,(_,_,_),l) -> List.fold_left (f n) acc l
| CApp (loc,(_,t),l) -> List.fold_left (f n) (f n acc t) (List.map fst l)
| CProdN (_,l,b) | CLambdaN (_,l,b) -> fold_constr_expr_binders g f n acc b l
- | CLetIn (_,na,a,b) -> fold_constr_expr_binders g f n acc b [[na],default_binder_kind,a]
+ | CLetIn (_,na,a,t,b) ->
+ f (name_fold g (snd na) n) (Option.fold_left (f n) (f n acc a) t) b
| CCast (loc,a,(CastConv b|CastVM b|CastNative b)) -> f n (f n acc a) b
| CCast (loc,a,CastCoerce) -> f n acc a
| CNotation (_,_,(l,ll,bll)) ->
@@ -160,7 +161,7 @@ let split_at_annot bl na =
end
| Some (loc, id) ->
let rec aux acc = function
- | LocalRawAssum (bls, k, t) as x :: rest ->
+ | CLocalAssum (bls, k, t) as x :: rest ->
let test (_, na) = match na with
| Name id' -> Id.equal id id'
| Anonymous -> false
@@ -171,12 +172,12 @@ let split_at_annot bl na =
| _ ->
let ans = match l with
| [] -> acc
- | _ -> LocalRawAssum (l, k, t) :: acc
+ | _ -> CLocalAssum (l, k, t) :: acc
in
- (List.rev ans, LocalRawAssum (r, k, t) :: rest)
+ (List.rev ans, CLocalAssum (r, k, t) :: rest)
end
- | LocalRawDef _ as x :: rest -> aux (x :: acc) rest
- | LocalPattern (loc,_,_) :: rest ->
+ | CLocalDef _ as x :: rest -> aux (x :: acc) rest
+ | CLocalPattern (loc,_,_) :: rest ->
Loc.raise ~loc (Stream.Error "pattern with quote not allowed after fix")
| [] ->
user_err ~loc
@@ -196,13 +197,13 @@ let map_binders f g e bl =
let map_local_binders f g e bl =
(* TODO: avoid variable capture in [t] by some [na] in [List.tl nal] *)
let h (e,bl) = function
- LocalRawAssum(nal,k,ty) ->
- (map_binder g e nal, LocalRawAssum(nal,k,f e ty)::bl)
- | LocalRawDef((loc,na),ty) ->
- (name_fold g na e, LocalRawDef((loc,na),f e ty)::bl)
- | LocalPattern (loc,pat,t) ->
+ CLocalAssum(nal,k,ty) ->
+ (map_binder g e nal, CLocalAssum(nal,k,f e ty)::bl)
+ | CLocalDef((loc,na),c,ty) ->
+ (name_fold g na e, CLocalDef((loc,na),f e c,Option.map (f e) ty)::bl)
+ | CLocalPattern (loc,pat,t) ->
let ids = ids_of_pattern pat in
- (Id.Set.fold g ids e, LocalPattern (loc,pat,Option.map (f e) t)::bl) in
+ (Id.Set.fold g ids e, CLocalPattern (loc,pat,Option.map (f e) t)::bl) in
let (e,rbl) = List.fold_left h (e,[]) bl in
(e, List.rev rbl)
@@ -214,7 +215,8 @@ let map_constr_expr_with_binders g f e = function
let (e,bl) = map_binders f g e bl in CProdN (loc,bl,f e b)
| CLambdaN (loc,bl,b) ->
let (e,bl) = map_binders f g e bl in CLambdaN (loc,bl,f e b)
- | CLetIn (loc,na,a,b) -> CLetIn (loc,na,f e a,f (name_fold g (snd na) e) b)
+ | CLetIn (loc,na,a,t,b) ->
+ CLetIn (loc,na,f e a,Option.map (f e) t,f (name_fold g (snd na) e) b)
| CCast (loc,a,c) -> CCast (loc,f e a, Miscops.map_cast_type (f e) c)
| CNotation (loc,n,(l,ll,bll)) ->
(* This is an approximation because we don't know what binds what *)
diff --git a/interp/topconstr.mli b/interp/topconstr.mli
index 95d702f8d5..b6ac40041e 100644
--- a/interp/topconstr.mli
+++ b/interp/topconstr.mli
@@ -25,7 +25,7 @@ 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.Set.t
-val split_at_annot : local_binder list -> Id.t located option -> local_binder list * local_binder list
+val split_at_annot : local_binder_expr list -> Id.t located option -> local_binder_expr list * local_binder_expr list
(** Used in typeclasses *)
diff --git a/intf/constrexpr.mli b/intf/constrexpr.mli
index 0cbb29575d..49bafadc8e 100644
--- a/intf/constrexpr.mli
+++ b/intf/constrexpr.mli
@@ -72,7 +72,7 @@ and constr_expr =
| CCoFix of Loc.t * Id.t located * cofix_expr list
| CProdN of Loc.t * binder_expr list * constr_expr
| CLambdaN of Loc.t * binder_expr list * constr_expr
- | CLetIn of Loc.t * Name.t located * constr_expr * constr_expr
+ | CLetIn of Loc.t * Name.t located * constr_expr * constr_expr option * constr_expr
| CAppExpl of Loc.t * (proj_flag * reference * instance_expr option) * constr_expr list
| CApp of Loc.t * (proj_flag * constr_expr) *
(constr_expr * explicitation located option) list
@@ -111,10 +111,10 @@ and binder_expr =
and fix_expr =
Id.t located * (Id.t located option * recursion_order_expr) *
- local_binder list * constr_expr * constr_expr
+ local_binder_expr list * constr_expr * constr_expr
and cofix_expr =
- Id.t located * local_binder list * constr_expr * constr_expr
+ Id.t located * local_binder_expr list * constr_expr * constr_expr
and recursion_order_expr =
| CStructRec
@@ -122,15 +122,15 @@ and recursion_order_expr =
| CMeasureRec of constr_expr * constr_expr option (** measure, relation *)
(** Anonymous defs allowed ?? *)
-and local_binder =
- | LocalRawDef of Name.t located * constr_expr
- | LocalRawAssum of Name.t located list * binder_kind * constr_expr
- | LocalPattern of Loc.t * cases_pattern_expr * constr_expr option
+and local_binder_expr =
+ | CLocalAssum of Name.t located list * binder_kind * constr_expr
+ | CLocalDef of Name.t located * constr_expr * constr_expr option
+ | CLocalPattern of Loc.t * cases_pattern_expr * constr_expr option
and constr_notation_substitution =
constr_expr list * (** for constr subterms *)
constr_expr list list * (** for recursive notations *)
- local_binder list list (** for binders subexpressions *)
+ local_binder_expr list list (** for binders subexpressions *)
type typeclass_constraint = (Name.t located * Id.t located list option) * binding_kind * constr_expr
diff --git a/intf/glob_term.mli b/intf/glob_term.mli
index b3159c860c..ced5a8b44f 100644
--- a/intf/glob_term.mli
+++ b/intf/glob_term.mli
@@ -42,7 +42,7 @@ type glob_constr =
| GApp of Loc.t * glob_constr * glob_constr list
| GLambda of Loc.t * Name.t * binding_kind * glob_constr * glob_constr
| GProd of Loc.t * Name.t * binding_kind * glob_constr * glob_constr
- | GLetIn of Loc.t * Name.t * glob_constr * glob_constr
+ | GLetIn of Loc.t * Name.t * glob_constr * glob_constr option * glob_constr
| GCases of Loc.t * case_style * glob_constr option * tomatch_tuples * cases_clauses
(** [GCases(l,style,r,tur,cc)] = "match 'tur' return 'r' with 'cc'" (in [MatchStyle]) *)
| GLetTuple of Loc.t * Name.t list * (Name.t * glob_constr option) *
@@ -78,6 +78,11 @@ and cases_clause = (Loc.t * Id.t list * cases_pattern list * glob_constr)
of [t] are members of [il]. *)
and cases_clauses = cases_clause list
+type extended_glob_local_binder =
+ | GLocalAssum of Loc.t * Name.t * binding_kind * glob_constr
+ | GLocalDef of Loc.t * Name.t * binding_kind * glob_constr * glob_constr option
+ | GLocalPattern of Loc.t * (cases_pattern * Id.t list) * Id.t * binding_kind * glob_constr
+
(** A globalised term together with a closure representing the value
of its free variables. Intended for use when these variables are taken
from the Ltac environment. *)
diff --git a/intf/notation_term.mli b/intf/notation_term.mli
index 1ab9980a5c..753fa657a8 100644
--- a/intf/notation_term.mli
+++ b/intf/notation_term.mli
@@ -30,7 +30,7 @@ type notation_constr =
| NLambda of Name.t * notation_constr * notation_constr
| NProd of Name.t * notation_constr * notation_constr
| NBinderList of Id.t * Id.t * notation_constr * notation_constr
- | NLetIn of Name.t * notation_constr * notation_constr
+ | NLetIn of Name.t * notation_constr * notation_constr option * notation_constr
| NCases of case_style * notation_constr option *
(notation_constr * (Name.t * (inductive * Name.t list) option)) list *
(cases_pattern list * notation_constr) list
diff --git a/intf/pattern.mli b/intf/pattern.mli
index 329ae837e1..a32e7e4b94 100644
--- a/intf/pattern.mli
+++ b/intf/pattern.mli
@@ -68,7 +68,7 @@ type constr_pattern =
| PProj of projection * constr_pattern
| PLambda of Name.t * constr_pattern * constr_pattern
| PProd of Name.t * constr_pattern * constr_pattern
- | PLetIn of Name.t * constr_pattern * constr_pattern
+ | PLetIn of Name.t * constr_pattern * constr_pattern option * constr_pattern
| PSort of glob_sort
| PMeta of patvar option
| PIf of constr_pattern * constr_pattern * constr_pattern
diff --git a/intf/vernacexpr.mli b/intf/vernacexpr.mli
index 8827bc132e..25d3c705f4 100644
--- a/intf/vernacexpr.mli
+++ b/intf/vernacexpr.mli
@@ -175,15 +175,15 @@ type plident = lident * lident list option
type sort_expr = glob_sort
type definition_expr =
- | ProveBody of local_binder list * constr_expr
- | DefineBody of local_binder list * Genredexpr.raw_red_expr option * constr_expr
+ | ProveBody of local_binder_expr list * constr_expr
+ | DefineBody of local_binder_expr list * Genredexpr.raw_red_expr option * constr_expr
* constr_expr option
type fixpoint_expr =
- plident * (Id.t located option * recursion_order_expr) * local_binder list * constr_expr * constr_expr option
+ plident * (Id.t located option * recursion_order_expr) * local_binder_expr list * constr_expr * constr_expr option
type cofixpoint_expr =
- plident * local_binder list * constr_expr * constr_expr option
+ plident * local_binder_expr list * constr_expr * constr_expr option
type local_decl_expr =
| AssumExpr of lname * constr_expr
@@ -202,14 +202,14 @@ type constructor_list_or_record_decl_expr =
| Constructors of constructor_expr list
| RecordDecl of lident option * local_decl_expr with_instance with_priority with_notation list
type inductive_expr =
- plident with_coercion * local_binder list * constr_expr option * inductive_kind *
+ plident with_coercion * local_binder_expr list * constr_expr option * inductive_kind *
constructor_list_or_record_decl_expr
type one_inductive_expr =
- plident * local_binder list * constr_expr option * constructor_expr list
+ plident * local_binder_expr list * constr_expr option * constructor_expr list
type proof_expr =
- plident option * (local_binder list * constr_expr * (lident option * recursion_order_expr) option)
+ plident option * (local_binder_expr list * constr_expr * (lident option * recursion_order_expr) option)
type syntax_modifier =
| SetItemLevel of string list * Extend.production_level
@@ -283,14 +283,9 @@ type bullet =
| Plus of int
(** {6 Types concerning Stm} *)
-type 'a stm_vernac =
+type stm_vernac =
| JoinDocument
- | Finish
| Wait
- | PrintDag
- | Observe of Stateid.t
- | Command of 'a (* An out of flow command not to be recorded by Stm *)
- | PGLast of 'a (* To ease the life of PG *)
(** {6 Types concerning the module layer} *)
@@ -370,12 +365,12 @@ type vernac_expr =
(* Type classes *)
| VernacInstance of
bool * (* abstract instance *)
- local_binder list * (* super *)
+ local_binder_expr list * (* super *)
typeclass_constraint * (* instance name, class name, params *)
(bool * constr_expr) option * (* props *)
hint_info_expr
- | VernacContext of local_binder list
+ | VernacContext of local_binder_expr list
| VernacDeclareInstances of
(reference * hint_info_expr) list (* instances names, priorities and patterns *)
@@ -450,8 +445,9 @@ type vernac_expr =
| VernacRegister of lident * register_kind
| VernacComments of comment list
- (* Stm backdoor *)
- | VernacStm of vernac_expr stm_vernac
+ (* Stm backdoor: used in fake_id, will be removed when fake_ide
+ becomes aware of feedback about completed jobs. *)
+ | VernacStm of stm_vernac
(* Proof management *)
| VernacGoal of constr_expr
@@ -509,16 +505,11 @@ and report_with = Stateid.t * Feedback.route_id (* feedback on id/route *)
and vernac_qed_type = VtKeep | VtKeepAsAxiom | VtDrop (* Qed/Admitted, Abort *)
and vernac_start = string * opacity_guarantee * Id.t list
and vernac_sideff_type = Id.t list
-and vernac_is_alias = bool
and vernac_part_of_script = bool
and vernac_control =
- | VtFinish
| VtWait
| VtJoinDocument
- | VtPrintDag
- | VtObserve of Stateid.t
| VtBack of Stateid.t
- | VtPG
and opacity_guarantee =
| GuaranteesOpacity (** Only generates opaque terms at [Qed] *)
| Doesn'tGuaranteeOpacity (** May generate transparent terms even with [Qed].*)
diff --git a/kernel/cClosure.ml b/kernel/cClosure.ml
index fe9ec5794c..b1dd26119e 100644
--- a/kernel/cClosure.ml
+++ b/kernel/cClosure.ml
@@ -540,7 +540,16 @@ let mk_clos e t =
| (CoFix _|Lambda _|Fix _|Prod _|Evar _|App _|Case _|Cast _|LetIn _|Proj _) ->
{norm = Red; term = FCLOS(t,e)}
-let mk_clos_vect env v = CArray.Fun1.map mk_clos env v
+(** Hand-unrolling of the map function to bypass the call to the generic array
+ allocation *)
+let mk_clos_vect env v = match v with
+| [||] -> [||]
+| [|v0|] -> [|mk_clos env v0|]
+| [|v0; v1|] -> [|mk_clos env v0; mk_clos env v1|]
+| [|v0; v1; v2|] -> [|mk_clos env v0; mk_clos env v1; mk_clos env v2|]
+| [|v0; v1; v2; v3|] ->
+ [|mk_clos env v0; mk_clos env v1; mk_clos env v2; mk_clos env v3|]
+| v -> CArray.Fun1.map mk_clos env v
(* Translate the head constructor of t from constr to fconstr. This
function is parameterized by the function to apply on the direct
diff --git a/kernel/cemitcodes.ml b/kernel/cemitcodes.ml
index ad7a41a347..40c1e027d4 100644
--- a/kernel/cemitcodes.ml
+++ b/kernel/cemitcodes.ml
@@ -24,33 +24,45 @@ type reloc_info =
type patch = reloc_info * int
let patch_char4 buff pos c1 c2 c3 c4 =
- String.unsafe_set buff pos c1;
- String.unsafe_set buff (pos + 1) c2;
- String.unsafe_set buff (pos + 2) c3;
- String.unsafe_set buff (pos + 3) c4
+ Bytes.unsafe_set buff pos c1;
+ Bytes.unsafe_set buff (pos + 1) c2;
+ Bytes.unsafe_set buff (pos + 2) c3;
+ Bytes.unsafe_set buff (pos + 3) c4
let patch buff (pos, n) =
patch_char4 buff pos
(Char.unsafe_chr n) (Char.unsafe_chr (n asr 8)) (Char.unsafe_chr (n asr 16))
(Char.unsafe_chr (n asr 24))
+(* val patch_int : emitcodes -> ((\*pos*\)int * int) list -> emitcodes *)
let patch_int buff patches =
(* copy code *before* patching because of nested evaluations:
the code we are patching might be called (and thus "concurrently" patched)
and results in wrong results. Side-effects... *)
- let buff = String.copy buff in
+ let buff = Bytes.of_string buff in
let () = List.iter (fun p -> patch buff p) patches in
- buff
+ (* Note: we follow the apporach suggested by Gabriel Scherer in
+ PR#136 here, and use unsafe as we own buff.
+
+ The crux of the question that avoids defining emitcodes just as a
+ Byte.t is the call to hcons in to_memory below. Even if disabling
+ this optimization has no visible time impact, test data shows
+ that the optimization is indeed triggered quite often so we
+ choose ugliness over altering the semantics.
+
+ Handle with care.
+ *)
+ Bytes.unsafe_to_string buff
(* Buffering of bytecode *)
-let out_buffer = ref(String.create 1024)
+let out_buffer = ref(Bytes.create 1024)
and out_position = ref 0
let out_word b1 b2 b3 b4 =
let p = !out_position in
- if p >= String.length !out_buffer then begin
- let len = String.length !out_buffer in
+ if p >= Bytes.length !out_buffer then begin
+ let len = Bytes.length !out_buffer in
let new_len =
if len <= Sys.max_string_length / 2
then 2 * len
@@ -58,8 +70,8 @@ let out_word b1 b2 b3 b4 =
if len = Sys.max_string_length
then invalid_arg "String.create" (* Pas la bonne exception .... *)
else Sys.max_string_length in
- let new_buffer = String.create new_len in
- String.blit !out_buffer 0 new_buffer 0 len;
+ let new_buffer = Bytes.create new_len in
+ Bytes.blit !out_buffer 0 new_buffer 0 len;
out_buffer := new_buffer
end;
patch_char4 !out_buffer p (Char.unsafe_chr b1)
@@ -94,10 +106,10 @@ let extend_label_table needed =
let backpatch (pos, orig) =
let displ = (!out_position - orig) asr 2 in
- !out_buffer.[pos] <- Char.unsafe_chr displ;
- !out_buffer.[pos+1] <- Char.unsafe_chr (displ asr 8);
- !out_buffer.[pos+2] <- Char.unsafe_chr (displ asr 16);
- !out_buffer.[pos+3] <- Char.unsafe_chr (displ asr 24)
+ Bytes.set !out_buffer pos @@ Char.unsafe_chr displ;
+ Bytes.set !out_buffer (pos+1) @@ Char.unsafe_chr (displ asr 8);
+ Bytes.set !out_buffer (pos+2) @@ Char.unsafe_chr (displ asr 16);
+ Bytes.set !out_buffer (pos+3) @@ Char.unsafe_chr (displ asr 24)
let define_label lbl =
if lbl >= Array.length !label_table then extend_label_table lbl;
@@ -262,41 +274,44 @@ let emit_instr = function
| Kstop ->
out opSTOP
-(* Emission of a list of instructions. Include some peephole optimization. *)
+(* Emission of a current list and remaining lists of instructions. Include some peephole optimization. *)
-let rec emit = function
- | [] -> ()
+let rec emit insns remaining = match insns with
+ | [] ->
+ (match remaining with
+ [] -> ()
+ | (first::rest) -> emit first rest)
(* Peephole optimizations *)
| Kpush :: Kacc n :: c ->
if n < 8 then out(opPUSHACC0 + n) else (out opPUSHACC; out_int n);
- emit c
+ emit c remaining
| Kpush :: Kenvacc n :: c ->
if n >= 1 && n <= 4
then out(opPUSHENVACC1 + n - 1)
else (out opPUSHENVACC; out_int n);
- emit c
+ emit c remaining
| Kpush :: Koffsetclosure ofs :: c ->
if Int.equal ofs (-2) || Int.equal ofs 0 || Int.equal ofs 2
then out(opPUSHOFFSETCLOSURE0 + ofs / 2)
else (out opPUSHOFFSETCLOSURE; out_int ofs);
- emit c
+ emit c remaining
| Kpush :: Kgetglobal id :: c ->
- out opPUSHGETGLOBAL; slot_for_getglobal id; emit c
+ out opPUSHGETGLOBAL; slot_for_getglobal id; emit c remaining
| Kpush :: Kconst (Const_b0 i) :: c ->
if i >= 0 && i <= 3
then out (opPUSHCONST0 + i)
else (out opPUSHCONSTINT; out_int i);
- emit c
+ emit c remaining
| Kpush :: Kconst const :: c ->
out opPUSHGETGLOBAL; slot_for_const const;
- emit c
+ emit c remaining
| Kpop n :: Kjump :: c ->
- out opRETURN; out_int n; emit c
+ out opRETURN; out_int n; emit c remaining
| Ksequence(c1,c2)::c ->
- emit c1; emit c2;emit c
+ emit c1 (c2::c::remaining)
(* Default case *)
| instr :: c ->
- emit_instr instr; emit c
+ emit_instr instr; emit c remaining
(* Initialization *)
@@ -305,7 +320,7 @@ let init () =
label_table := Array.make 16 (Label_undefined []);
reloc_info := []
-type emitcodes = string
+type emitcodes = String.t
let length = String.length
@@ -367,11 +382,10 @@ let repr_body_code = function
let to_memory (init_code, fun_code, fv) =
init();
- emit init_code;
- emit fun_code;
- let code = String.create !out_position in
- String.unsafe_blit !out_buffer 0 code 0 !out_position;
+ emit init_code [];
+ emit fun_code [];
(** Later uses of this string are all purely functional *)
+ let code = Bytes.sub_string !out_buffer 0 !out_position in
let code = CString.hcons code in
let reloc = List.rev !reloc_info in
Array.iter (fun lbl ->
diff --git a/kernel/cooking.ml b/kernel/cooking.ml
index f5059cd750..a9f212393e 100644
--- a/kernel/cooking.ml
+++ b/kernel/cooking.ml
@@ -191,15 +191,19 @@ let lift_univs cb subst =
subst, Univ.UContext.make (inst,cstrs')
else subst, cb.const_universes
-let cook_constant env { from = cb; info } =
+let cook_constant ~hcons env { from = cb; info } =
let { Opaqueproof.modlist; abstract } = info in
let cache = RefTable.create 13 in
let abstract, usubst, abs_ctx = abstract in
let usubst, univs = lift_univs cb usubst in
let expmod = expmod_constr_subst cache modlist usubst in
let hyps = Context.Named.map expmod abstract in
+ let map c =
+ let c = abstract_constant_body (expmod c) hyps in
+ if hcons then hcons_constr c else c
+ in
let body = on_body modlist (hyps, usubst, abs_ctx)
- (fun c -> abstract_constant_body (expmod c) hyps)
+ map
cb.const_body
in
let const_hyps =
diff --git a/kernel/cooking.mli b/kernel/cooking.mli
index eb40730969..7d47eba23e 100644
--- a/kernel/cooking.mli
+++ b/kernel/cooking.mli
@@ -21,7 +21,7 @@ type result =
bool * constant_universes * inline
* Context.Named.t option
-val cook_constant : env -> recipe -> result
+val cook_constant : hcons:bool -> env -> recipe -> result
val cook_constr : Opaqueproof.cooking_info -> Term.constr -> Term.constr
(** {6 Utility functions used in module [Discharge]. } *)
diff --git a/kernel/entries.mli b/kernel/entries.mli
index 77081947ec..1e07c96909 100644
--- a/kernel/entries.mli
+++ b/kernel/entries.mli
@@ -113,5 +113,3 @@ type side_effect = {
from_env : Declarations.structure_body CEphemeron.key;
eff : side_eff;
}
-
-type side_effects = side_effect list
diff --git a/kernel/names.ml b/kernel/names.ml
index 1f138581cc..ee8d838da1 100644
--- a/kernel/names.ml
+++ b/kernel/names.ml
@@ -50,17 +50,20 @@ struct
| None -> true
| Some _ -> false
+ let of_bytes s =
+ let s = Bytes.to_string s in
+ check_soft s;
+ String.hcons s
+
let of_string s =
let () = check_soft s in
- let s = String.copy s in
String.hcons s
let of_string_soft s =
let () = check_soft ~warn:false s in
- let s = String.copy s in
String.hcons s
- let to_string id = String.copy id
+ let to_string id = id
let print id = str id
diff --git a/kernel/names.mli b/kernel/names.mli
index 6b0a80625b..be9b9422b7 100644
--- a/kernel/names.mli
+++ b/kernel/names.mli
@@ -43,6 +43,7 @@ sig
(** Check that a string may be converted to an identifier.
@raise Unicode.Unsupported if the provided string contains unsupported UTF-8 characters. *)
+ val of_bytes : bytes -> t
val of_string : string -> t
(** Converts a string into an identifier.
@raise UserError if the string is not valid, or echo a warning if it contains invalid identifier characters.
diff --git a/kernel/nativevalues.ml b/kernel/nativevalues.ml
index 8093df3044..965ed67b07 100644
--- a/kernel/nativevalues.ml
+++ b/kernel/nativevalues.ml
@@ -491,12 +491,12 @@ let str_encode expr =
let str_decode s =
let mshl_expr_len = String.length s / 2 in
let mshl_expr = Buffer.create mshl_expr_len in
- let buf = String.create 2 in
+ let buf = Bytes.create 2 in
for i = 0 to mshl_expr_len - 1 do
- String.blit s (2*i) buf 0 2;
- Buffer.add_char mshl_expr (bin_of_hex buf)
+ Bytes.blit_string s (2*i) buf 0 2;
+ Buffer.add_char mshl_expr (bin_of_hex (Bytes.to_string buf))
done;
- Marshal.from_string (Buffer.contents mshl_expr) 0
+ Marshal.from_bytes (Buffer.to_bytes mshl_expr) 0
(** Retroknowledge, to be removed when we switch to primitive integers *)
diff --git a/kernel/opaqueproof.ml b/kernel/opaqueproof.ml
index 130f1eb039..d0593c0e05 100644
--- a/kernel/opaqueproof.ml
+++ b/kernel/opaqueproof.ml
@@ -21,8 +21,18 @@ type proofterm = (constr * Univ.universe_context_set) Future.computation
type opaque =
| Indirect of substitution list * DirPath.t * int (* subst, lib, index *)
| Direct of cooking_info list * proofterm
-type opaquetab = (cooking_info list * proofterm) Int.Map.t * DirPath.t
-let empty_opaquetab = Int.Map.empty, DirPath.initial
+type opaquetab = {
+ opaque_val : (cooking_info list * proofterm) Int.Map.t;
+ (** Actual proof terms *)
+ opaque_len : int;
+ (** Size of the above map *)
+ opaque_dir : DirPath.t;
+}
+let empty_opaquetab = {
+ opaque_val = Int.Map.empty;
+ opaque_len = 0;
+ opaque_dir = DirPath.initial;
+}
(* hooks *)
let default_get_opaque dp _ =
@@ -42,21 +52,25 @@ let set_indirect_univ_accessor f = (get_univ := f)
let create cu = Direct ([],cu)
-let turn_indirect dp o (prfs,odp) = match o with
+let turn_indirect dp o tab = match o with
| Indirect (_,_,i) ->
- if not (Int.Map.mem i prfs)
+ if not (Int.Map.mem i tab.opaque_val)
then CErrors.anomaly (Pp.str "Indirect in a different table")
else CErrors.anomaly (Pp.str "Already an indirect opaque")
| Direct (d,cu) ->
- let cu = Future.chain ~pure:true cu (fun (c, u) -> hcons_constr c, u) in
- let id = Int.Map.cardinal prfs in
- let prfs = Int.Map.add id (d,cu) prfs in
- let ndp =
- if DirPath.equal dp odp then odp
- else if DirPath.equal odp DirPath.initial then dp
+ (** Uncomment to check dynamically that all terms turned into
+ indirections are hashconsed. *)
+(* let check_hcons c = let c' = hcons_constr c in assert (c' == c); c in *)
+(* let cu = Future.chain ~pure:true cu (fun (c, u) -> check_hcons c; c, u) in *)
+ let id = tab.opaque_len in
+ let opaque_val = Int.Map.add id (d,cu) tab.opaque_val in
+ let opaque_dir =
+ if DirPath.equal dp tab.opaque_dir then tab.opaque_dir
+ else if DirPath.equal tab.opaque_dir DirPath.initial then dp
else CErrors.anomaly
(Pp.str "Using the same opaque table for multiple dirpaths") in
- Indirect ([],dp,id), (prfs, ndp)
+ let ntab = { opaque_val; opaque_dir; opaque_len = id + 1 } in
+ Indirect ([],dp,id), ntab
let subst_opaque sub = function
| Indirect (s,dp,i) -> Indirect (sub::s,dp,i)
@@ -72,21 +86,21 @@ let discharge_direct_opaque ~cook_constr ci = function
| Direct (d,cu) ->
Direct (ci::d,Future.chain ~pure:true cu (fun (c, u) -> cook_constr c, u))
-let join_opaque (prfs,odp) = function
+let join_opaque { opaque_val = prfs; opaque_dir = odp } = function
| Direct (_,cu) -> ignore(Future.join cu)
| Indirect (_,dp,i) ->
if DirPath.equal dp odp then
let fp = snd (Int.Map.find i prfs) in
ignore(Future.join fp)
-let uuid_opaque (prfs,odp) = function
+let uuid_opaque { opaque_val = prfs; opaque_dir = odp } = function
| Direct (_,cu) -> Some (Future.uuid cu)
| Indirect (_,dp,i) ->
if DirPath.equal dp odp
then Some (Future.uuid (snd (Int.Map.find i prfs)))
else None
-let force_proof (prfs,odp) = function
+let force_proof { opaque_val = prfs; opaque_dir = odp } = function
| Direct (_,cu) ->
fst(Future.force cu)
| Indirect (l,dp,i) ->
@@ -97,7 +111,7 @@ let force_proof (prfs,odp) = function
let c = Future.force pt in
force_constr (List.fold_right subst_substituted l (from_val c))
-let force_constraints (prfs,odp) = function
+let force_constraints { opaque_val = prfs; opaque_dir = odp } = function
| Direct (_,cu) -> snd(Future.force cu)
| Indirect (_,dp,i) ->
if DirPath.equal dp odp
@@ -106,14 +120,14 @@ let force_constraints (prfs,odp) = function
| None -> Univ.ContextSet.empty
| Some u -> Future.force u
-let get_constraints (prfs,odp) = function
+let get_constraints { opaque_val = prfs; opaque_dir = odp } = function
| Direct (_,cu) -> Some(Future.chain ~pure:true cu snd)
| Indirect (_,dp,i) ->
if DirPath.equal dp odp
then Some(Future.chain ~pure:true (snd (Int.Map.find i prfs)) snd)
else !get_univ dp i
-let get_proof (prfs,odp) = function
+let get_proof { opaque_val = prfs; opaque_dir = odp } = function
| Direct (_,cu) -> Future.chain ~pure:true cu fst
| Indirect (l,dp,i) ->
let pt =
@@ -129,14 +143,13 @@ let a_constr = Future.from_val (Term.mkRel 1)
let a_univ = Future.from_val Univ.ContextSet.empty
let a_discharge : cooking_info list = []
-let dump (otab,_) =
- let n = Int.Map.cardinal otab in
+let dump { opaque_val = otab; opaque_len = n } =
let opaque_table = Array.make n a_constr in
let univ_table = Array.make n a_univ in
let disch_table = Array.make n a_discharge in
let f2t_map = ref FMap.empty in
Int.Map.iter (fun n (d,cu) ->
- let c, u = Future.split2 ~greedy:true cu in
+ let c, u = Future.split2 cu in
Future.sink u;
Future.sink c;
opaque_table.(n) <- c;
diff --git a/kernel/opaqueproof.mli b/kernel/opaqueproof.mli
index 5139cf0512..3897d5e51e 100644
--- a/kernel/opaqueproof.mli
+++ b/kernel/opaqueproof.mli
@@ -28,8 +28,9 @@ val empty_opaquetab : opaquetab
(** From a [proofterm] to some [opaque]. *)
val create : proofterm -> opaque
-(** Turn a direct [opaque] into an indirect one, also hashconses constr.
- * The integer is an hint of the maximum id used so far *)
+(** Turn a direct [opaque] into an indirect one. It is your responsibility to
+ hashcons the inner term beforehand. The integer is an hint of the maximum id
+ used so far *)
val turn_indirect : DirPath.t -> opaque -> opaquetab -> opaque * opaquetab
(** From a [opaque] back to a [constr]. This might use the
diff --git a/kernel/reduction.ml b/kernel/reduction.ml
index 1ae89347ad..0d7f77edae 100644
--- a/kernel/reduction.ml
+++ b/kernel/reduction.ml
@@ -71,6 +71,17 @@ let rec zlapp v = function
Zlapp v2 :: s -> zlapp (Array.append v v2) s
| s -> Zlapp v :: s
+(** Hand-unrolling of the map function to bypass the call to the generic array
+ allocation. Type annotation is required to tell OCaml that the array does
+ not contain floats. *)
+let map_lift (l : lift) (v : fconstr array) = match v with
+| [||] -> assert false
+| [|c0|] -> [|(l, c0)|]
+| [|c0; c1|] -> [|(l, c0); (l, c1)|]
+| [|c0; c1; c2|] -> [|(l, c0); (l, c1); (l, c2)|]
+| [|c0; c1; c2; c3|] -> [|(l, c0); (l, c1); (l, c2); (l, c3)|]
+| v -> CArray.Fun1.map (fun l t -> (l, t)) l v
+
let pure_stack lfts stk =
let rec pure_rec lfts stk =
match stk with
@@ -80,7 +91,7 @@ let pure_stack lfts stk =
(Zupdate _,lpstk) -> lpstk
| (Zshift n,(l,pstk)) -> (el_shft n l, pstk)
| (Zapp a, (l,pstk)) ->
- (l,zlapp (Array.map (fun t -> (l,t)) a) pstk)
+ (l,zlapp (map_lift l a) pstk)
| (Zproj (n,m,c), (l,pstk)) ->
(l, Zlproj (c,l)::pstk)
| (Zfix(fx,a),(l,pstk)) ->
diff --git a/kernel/safe_typing.ml b/kernel/safe_typing.ml
index e4b3fcbf1a..caaaff1b89 100644
--- a/kernel/safe_typing.ml
+++ b/kernel/safe_typing.ml
@@ -71,7 +71,7 @@ module NamedDecl = Context.Named.Declaration
- [env] : the underlying environment (cf Environ)
- [modpath] : the current module name
- [modvariant] :
- * NONE before coqtop initialization (or when -notop is used)
+ * NONE before coqtop initialization
* LIBRARY at toplevel of a compilation or a regular coqtop session
* STRUCT (params,oldsenv) : inside a local module, with
module parameters [params] and earlier environment [oldsenv]
@@ -208,19 +208,19 @@ let get_opaque_body env cbo =
Opaqueproof.force_constraints (Environ.opaque_tables env) opaque)
type private_constant = Entries.side_effect
-type private_constants = private_constant list
+type private_constants = Term_typing.side_effects
type private_constant_role = Term_typing.side_effect_role =
| Subproof
| Schema of inductive * string
-let empty_private_constants = []
-let add_private x xs = if List.mem_f Term_typing.equal_eff x xs then xs else x :: xs
-let concat_private xs ys = List.fold_right add_private xs ys
+let empty_private_constants = Term_typing.empty_seff
+let add_private = Term_typing.add_seff
+let concat_private = Term_typing.concat_seff
let mk_pure_proof = Term_typing.mk_pure_proof
let inline_private_constants_in_constr = Term_typing.inline_side_effects
let inline_private_constants_in_definition_entry = Term_typing.inline_entry_side_effects
-let side_effects_of_private_constants x = Term_typing.uniq_seff (List.rev x)
+let side_effects_of_private_constants = Term_typing.uniq_seff
let private_con_of_con env c =
let cbo = Environ.lookup_constant c env.env in
@@ -250,7 +250,7 @@ let universes_of_private eff =
| Entries.SEsubproof (c, cb, e) ->
if cb.const_polymorphic then acc
else Univ.ContextSet.of_context cb.const_universes :: acc)
- [] eff
+ [] (Term_typing.uniq_seff eff)
let env_of_safe_env senv = senv.env
let env_of_senv = env_of_safe_env
diff --git a/kernel/safe_typing.mli b/kernel/safe_typing.mli
index 15ebc7d880..efeb98bd25 100644
--- a/kernel/safe_typing.mli
+++ b/kernel/safe_typing.mli
@@ -47,11 +47,18 @@ type private_constant_role =
| Schema of inductive * string
val side_effects_of_private_constants :
- private_constants -> Entries.side_effects
+ private_constants -> Entries.side_effect list
+(** Return the list of individual side-effects in the order of their
+ creation. *)
val empty_private_constants : private_constants
val add_private : private_constant -> private_constants -> private_constants
+(** Add a constant to a list of private constants. The former must be more
+ recent than all constants appearing in the latter, i.e. one should not
+ create a dependency cycle. *)
val concat_private : private_constants -> private_constants -> private_constants
+(** [concat_private e1 e2] adds the constants of [e1] to [e2], i.e. constants in
+ [e1] must be more recent than those of [e2]. *)
val private_con_of_con : safe_environment -> constant -> private_constant
val private_con_of_scheme : kind:string -> safe_environment -> (inductive * constant) list -> private_constant
diff --git a/kernel/term_typing.ml b/kernel/term_typing.ml
index 3a0d1a2a5e..6dfa64357c 100644
--- a/kernel/term_typing.ml
+++ b/kernel/term_typing.ml
@@ -24,28 +24,8 @@ open Typeops
module RelDecl = Context.Rel.Declaration
module NamedDecl = Context.Named.Declaration
-let constrain_type env j poly subst = function
- | `None ->
- if not poly then (* Old-style polymorphism *)
- make_polymorphic_if_constant_for_ind env j
- else RegularArity (Vars.subst_univs_level_constr subst j.uj_type)
- | `Some t ->
- let tj = infer_type env t in
- let _ = judge_of_cast env j DEFAULTcast tj in
- assert (eq_constr t tj.utj_val);
- RegularArity (Vars.subst_univs_level_constr subst t)
- | `SomeWJ (t, tj) ->
- let tj = infer_type env t in
- let _ = judge_of_cast env j DEFAULTcast tj in
- assert (eq_constr t tj.utj_val);
- RegularArity (Vars.subst_univs_level_constr subst t)
-
-let map_option_typ = function None -> `None | Some x -> `Some x
-
(* Insertion of constants and parameters in environment. *)
-let mk_pure_proof c = (c, Univ.ContextSet.empty), []
-
let equal_eff e1 e2 =
let open Entries in
match e1, e2 with
@@ -57,13 +37,54 @@ let equal_eff e1 e2 =
cl1 cl2
| _ -> false
-let rec uniq_seff = function
- | [] -> []
- | x :: xs -> x :: uniq_seff (List.filter (fun y -> not (equal_eff x y)) xs)
-(* The list of side effects is in reverse order (most recent first).
- * To keep the "topological" order between effects we have to uniq-ize from
- * the tail *)
-let uniq_seff l = List.rev (uniq_seff (List.rev l))
+module SideEffects :
+sig
+ type t
+ val repr : t -> side_effect list
+ val empty : t
+ val add : side_effect -> t -> t
+ val concat : t -> t -> t
+end =
+struct
+
+let compare_seff e1 e2 = match e1, e2 with
+| SEsubproof (c1, _, _), SEsubproof (c2, _, _) -> Constant.CanOrd.compare c1 c2
+| SEscheme (cl1, _), SEscheme (cl2, _) ->
+ let cmp (_, c1, _, _) (_, c2, _, _) = Constant.CanOrd.compare c1 c2 in
+ CList.compare cmp cl1 cl2
+| SEsubproof _, SEscheme _ -> -1
+| SEscheme _, SEsubproof _ -> 1
+
+module SeffOrd = struct
+type t = side_effect
+let compare e1 e2 = compare_seff e1.eff e2.eff
+end
+
+module SeffSet = Set.Make(SeffOrd)
+
+type t = { seff : side_effect list; elts : SeffSet.t }
+(** Invariant: [seff] is a permutation of the elements of [elts] *)
+
+let repr eff = eff.seff
+let empty = { seff = []; elts = SeffSet.empty }
+let add x es =
+ if SeffSet.mem x es.elts then es
+ else { seff = x :: es.seff; elts = SeffSet.add x es.elts }
+let concat xes yes =
+ List.fold_right add xes.seff yes
+
+end
+
+type side_effects = SideEffects.t
+
+let uniq_seff_rev = SideEffects.repr
+let uniq_seff l = List.rev (SideEffects.repr l)
+
+let empty_seff = SideEffects.empty
+let add_seff = SideEffects.add
+let concat_seff = SideEffects.concat
+
+let mk_pure_proof c = (c, Univ.ContextSet.empty), empty_seff
let inline_side_effects env body ctx side_eff =
let handle_sideff (t,ctx,sl) { eff = se; from_env = mb } =
@@ -76,8 +97,7 @@ let inline_side_effects env body ctx side_eff =
let cbl = List.filter not_exists cbl in
let cname c =
let name = string_of_con c in
- for i = 0 to String.length name - 1 do
- if name.[i] == '.' || name.[i] == '#' then name.[i] <- '_' done;
+ let name = String.map (fun c -> if c == '.' || c == '#' then '_' else c) name in
Name (id_of_string name) in
let rec sub c i x = match kind_of_term x with
| Const (c', _) when eq_constant c c' -> mkRel i
@@ -117,7 +137,13 @@ let inline_side_effects env body ctx side_eff =
t, ctx, (mb,List.length cbl) :: sl
in
(* CAVEAT: we assure a proper order *)
- List.fold_left handle_sideff (body,ctx,[]) (uniq_seff side_eff)
+ List.fold_left handle_sideff (body,ctx,[]) (uniq_seff_rev side_eff)
+
+let rec is_nth_suffix n l suf =
+ if Int.equal n 0 then l == suf
+ else match l with
+ | [] -> false
+ | _ :: l -> is_nth_suffix (pred n) l suf
(* Given the list of signatures of side effects, checks if they match.
* I.e. if they are ordered descendants of the current revstruct *)
@@ -131,7 +157,7 @@ let check_signatures curmb sl =
match sl with
| None -> sl, None
| Some n ->
- if List.length mb >= how_many && CList.skipn how_many mb == curmb
+ if is_nth_suffix how_many mb curmb
then Some (n + how_many), Some mb
else None, None
with CEphemeron.InvalidKey -> None, None in
@@ -165,9 +191,6 @@ let rec unzip ctx j =
| `Cut (n,ty,arg) :: ctx ->
unzip ctx { j with uj_val = mkApp (mkLambda (n,ty,j.uj_val),arg) }
-let hcons_j j =
- { uj_val = hcons_constr j.uj_val; uj_type = hcons_constr j.uj_type}
-
let feedback_completion_typecheck =
let open Feedback in
Option.iter (fun state_id ->
@@ -184,6 +207,10 @@ let infer_declaration ~trust env kn dcl =
let t = hcons_constr (Vars.subst_univs_level_constr usubst c) in
Undef nl, RegularArity t, None, poly, univs, false, ctx
+ (** Definition [c] is opaque (Qed), non polymorphic and with a specified type,
+ so we delay the typing and hash consing of its body.
+ Remark: when the universe quantification is given explicitly, we could
+ delay even in the polymorphic case. *)
| DefinitionEntry ({ const_entry_type = Some typ;
const_entry_opaque = true;
const_entry_polymorphic = false} as c) ->
@@ -191,26 +218,28 @@ let infer_declaration ~trust env kn dcl =
let { const_entry_body = body; const_entry_feedback = feedback_id } = c in
let tyj = infer_type env typ in
let proofterm =
- Future.chain ~greedy:true ~pure:true body (fun ((body,uctx),side_eff) ->
+ Future.chain ~pure:true body (fun ((body,uctx),side_eff) ->
let body, uctx, signatures =
inline_side_effects env body uctx side_eff in
let valid_signatures = check_signatures trust signatures in
- let env' = push_context_set uctx env in
+ let env = push_context_set uctx env in
let j =
- let body,env',ectx = skip_trusted_seff valid_signatures body env' in
- let j = infer env' body in
+ let body,env,ectx = skip_trusted_seff valid_signatures body env in
+ let j = infer env body in
unzip ectx j in
- let j = hcons_j j in
let subst = Univ.LMap.empty in
- let _typ = constrain_type env' j c.const_entry_polymorphic subst
- (`SomeWJ (typ,tyj)) in
+ let _ = judge_of_cast env j DEFAULTcast tyj in
+ assert (eq_constr typ tyj.utj_val);
+ let c = hcons_constr j.uj_val in
+ let _typ = RegularArity (Vars.subst_univs_level_constr subst typ) in
feedback_completion_typecheck feedback_id;
- j.uj_val, uctx) in
+ c, uctx) in
let def = OpaqueDef (Opaqueproof.create proofterm) in
def, RegularArity typ, None, c.const_entry_polymorphic,
c.const_entry_universes,
c.const_entry_inline_code, c.const_entry_secctx
+ (** Other definitions have to be processed immediately. *)
| DefinitionEntry c ->
let { const_entry_type = typ; const_entry_opaque = opaque } = c in
let { const_entry_body = body; const_entry_feedback = feedback_id } = c in
@@ -223,7 +252,17 @@ let infer_declaration ~trust env kn dcl =
let usubst, univs =
Univ.abstract_universes abstract (Univ.ContextSet.to_context ctx) in
let j = infer env body in
- let typ = constrain_type env j c.const_entry_polymorphic usubst (map_option_typ typ) in
+ let typ = match typ with
+ | None ->
+ if not c.const_entry_polymorphic then (* Old-style polymorphism *)
+ make_polymorphic_if_constant_for_ind env j
+ else RegularArity (Vars.subst_univs_level_constr usubst j.uj_type)
+ | Some t ->
+ let tj = infer_type env t in
+ let _ = judge_of_cast env j DEFAULTcast tj in
+ assert (eq_constr t tj.utj_val);
+ RegularArity (Vars.subst_univs_level_constr usubst t)
+ in
let def = hcons_constr (Vars.subst_univs_level_constr usubst j.uj_val) in
let def =
if opaque then OpaqueDef (Opaqueproof.create (Future.from_val (def, Univ.ContextSet.empty)))
@@ -383,7 +422,7 @@ let constant_entry_of_side_effect cb u =
| Def b, `Nothing -> Mod_subst.force_constr b, Univ.ContextSet.empty
| _ -> assert false in
DefinitionEntry {
- const_entry_body = Future.from_val (pt, []);
+ const_entry_body = Future.from_val (pt, empty_seff);
const_entry_secctx = None;
const_entry_feedback = None;
const_entry_type =
@@ -416,8 +455,8 @@ let export_side_effects mb env ce =
let { const_entry_body = body } = c in
let _, eff = Future.force body in
let ce = DefinitionEntry { c with
- const_entry_body = Future.chain ~greedy:true ~pure:true body
- (fun (b_ctx, _) -> b_ctx, []) } in
+ const_entry_body = Future.chain ~pure:true body
+ (fun (b_ctx, _) -> b_ctx, empty_seff) } in
let not_exists (c,_,_,_) =
try ignore(Environ.lookup_constant c env); false
with Not_found -> true in
@@ -429,7 +468,7 @@ let export_side_effects mb env ce =
let cbl = List.filter not_exists cbl in
if cbl = [] then acc, sl
else cbl :: acc, (mb,List.length cbl) :: sl in
- let seff, signatures = List.fold_left aux ([],[]) (uniq_seff eff) in
+ let seff, signatures = List.fold_left aux ([],[]) (uniq_seff_rev eff) in
let trusted = check_signatures mb signatures in
let push_seff env = function
| kn, cb, `Nothing, _ ->
@@ -471,7 +510,11 @@ let translate_local_assum env t =
t
let translate_recipe env kn r =
- build_constant_declaration kn env (Cooking.cook_constant env r)
+ (** We only hashcons the term when outside of a section, otherwise this would
+ be useless. It is detected by the dirpath of the constant being empty. *)
+ let (_, dir, _) = Constant.repr3 kn in
+ let hcons = DirPath.is_empty dir in
+ build_constant_declaration kn env (Cooking.cook_constant ~hcons env r)
let translate_local_def mb env id centry =
let def,typ,proj,poly,univs,inline_code,ctx =
@@ -498,10 +541,10 @@ let translate_local_def mb env id centry =
let translate_mind env kn mie = Indtypes.check_inductive env kn mie
let inline_entry_side_effects env ce = { ce with
- const_entry_body = Future.chain ~greedy:true ~pure:true
+ const_entry_body = Future.chain ~pure:true
ce.const_entry_body (fun ((body, ctx), side_eff) ->
let body, ctx',_ = inline_side_effects env body ctx side_eff in
- (body, ctx'), []);
+ (body, ctx'), empty_seff);
}
let inline_side_effects env body side_eff =
diff --git a/kernel/term_typing.mli b/kernel/term_typing.mli
index 89b5fc40e3..075389ea53 100644
--- a/kernel/term_typing.mli
+++ b/kernel/term_typing.mli
@@ -12,6 +12,8 @@ open Environ
open Declarations
open Entries
+type side_effects
+
val translate_local_def : structure_body -> env -> Id.t -> side_effects definition_entry ->
constant_def * types * constant_universes
@@ -29,7 +31,15 @@ val inline_entry_side_effects :
{!Entries.const_entry_body} field. It is meant to get a term out of a not
yet type checked proof. *)
-val uniq_seff : side_effects -> side_effects
+val empty_seff : side_effects
+val add_seff : side_effect -> side_effects -> side_effects
+val concat_seff : side_effects -> side_effects -> side_effects
+(** [concat_seff e1 e2] adds the side-effects of [e1] to [e2], i.e. effects in
+ [e1] must be more recent than those of [e2]. *)
+val uniq_seff : side_effects -> side_effect list
+(** Return the list of individual side-effects in the order of their
+ creation. *)
+
val equal_eff : side_effect -> side_effect -> bool
val translate_constant :
diff --git a/lib/cErrors.ml b/lib/cErrors.ml
index dbebe6a48f..1c1ff7e2fd 100644
--- a/lib/cErrors.ml
+++ b/lib/cErrors.ml
@@ -16,16 +16,6 @@ let push = Backtrace.add_backtrace
exception Anomaly of string option * std_ppcmds (* System errors *)
-(* XXX: To move to common tagging functions in Pp, blocked on tag
- * system cleanup as we cannot define generic error tags now.
- *
- * Anyways, tagging should not happen here, but in the specific
- * listener to the msg_* stuff.
- *)
-let tag_err_str s = tag Ppstyle.(Tag.inj error_tag tag) (str s) ++ spc ()
-let err_str = tag_err_str "Error:"
-let ann_str = tag_err_str "Anomaly:"
-
let _ =
let pr = function
| Anomaly (s, pp) -> Some ("\"Anomaly: " ^ string_of_ppcmds pp ^ "\"")
@@ -102,9 +92,8 @@ let print_backtrace e = match Backtrace.get_backtrace e with
let print_anomaly askreport e =
if askreport then
- hov 0 (ann_str ++ raw_anomaly e ++ spc () ++
- strbrk "Please report at " ++ str Coq_config.wwwbugtracker ++
- str ".")
+ hov 0 (str "Anomaly" ++ spc () ++ quote (raw_anomaly e) ++ spc ()) ++
+ hov 0 (str "Please report at " ++ str Coq_config.wwwbugtracker ++ str ".")
else
hov 0 (raw_anomaly e)
@@ -124,7 +113,7 @@ let iprint_no_report (e, info) =
let _ = register_handler begin function
| UserError(s, pps) ->
- hov 0 (err_str ++ where s ++ pps)
+ hov 0 (where s ++ pps)
| _ -> raise Unhandled
end
@@ -147,13 +136,3 @@ let handled e =
let bottom _ = raise Bottom in
try let _ = print_gen bottom !handle_stack e in true
with Bottom -> false
-
-(** Prints info which is either an error or
- an anomaly and then exits with the appropriate
- error code *)
-
-let fatal_error info anomaly =
- let msg = info ++ fnl () in
- pp_with ~pp_tag:Ppstyle.pp_tag !Pp_control.err_ft msg;
- Format.pp_print_flush !Pp_control.err_ft ();
- exit (if anomaly then 129 else 1)
diff --git a/lib/cErrors.mli b/lib/cErrors.mli
index 5cffc725d9..0665a8ce73 100644
--- a/lib/cErrors.mli
+++ b/lib/cErrors.mli
@@ -98,8 +98,3 @@ val noncritical : exn -> bool
(** Check whether an exception is handled by some toplevel printer. The
[Anomaly] exception is never handled. *)
val handled : exn -> bool
-
-(** Prints info which is either an error or
- an anomaly and then exits with the appropriate
- error code *)
-val fatal_error : Pp.std_ppcmds -> bool -> 'a
diff --git a/lib/cThread.ml b/lib/cThread.ml
index 4f60a69745..9f642b3cec 100644
--- a/lib/cThread.ml
+++ b/lib/cThread.ml
@@ -36,7 +36,7 @@ let really_read_fd fd s off len =
let really_read_fd_2_oc fd oc len =
let i = ref 0 in
let size = 4096 in
- let s = String.create size in
+ let s = Bytes.create size in
while !i < len do
let len = len - !i in
let r = thread_friendly_read_fd fd s ~off:0 ~len:(min len size) in
@@ -55,11 +55,13 @@ let thread_friendly_really_read_line ic =
try
let fd = Unix.descr_of_in_channel ic in
let b = Buffer.create 1024 in
- let s = String.make 1 '\000' in
- while s <> "\n" do
+ let s = Bytes.make 1 '\000' in
+ let endl = Bytes.of_string "\n" in
+ (* Bytes.equal is in 4.03.0 *)
+ while Bytes.compare s endl <> 0 do
let n = thread_friendly_read_fd fd s ~off:0 ~len:1 in
if n = 0 then raise End_of_file;
- if s <> "\n" then Buffer.add_string b s;
+ if Bytes.compare s endl <> 0 then Buffer.add_bytes b s;
done;
Buffer.contents b
with Unix.Unix_error _ -> raise End_of_file
@@ -67,15 +69,15 @@ let thread_friendly_really_read_line ic =
let thread_friendly_input_value ic =
try
let fd = Unix.descr_of_in_channel ic in
- let header = String.create Marshal.header_size in
+ let header = Bytes.create Marshal.header_size in
really_read_fd fd header 0 Marshal.header_size;
let body_size = Marshal.data_size header 0 in
let desired_size = body_size + Marshal.header_size in
if desired_size <= Sys.max_string_length then begin
- let msg = String.create desired_size in
- String.blit header 0 msg 0 Marshal.header_size;
+ let msg = Bytes.create desired_size in
+ Bytes.blit header 0 msg 0 Marshal.header_size;
really_read_fd fd msg Marshal.header_size body_size;
- Marshal.from_string msg 0
+ Marshal.from_bytes msg 0
end else begin
(* Workaround for 32 bit systems and data > 16M *)
let name, oc =
diff --git a/lib/cThread.mli b/lib/cThread.mli
index 7302dfb558..36477a1160 100644
--- a/lib/cThread.mli
+++ b/lib/cThread.mli
@@ -19,8 +19,8 @@ val prepare_in_channel_for_thread_friendly_io : in_channel -> thread_ic
val thread_friendly_input_value : thread_ic -> 'a
val thread_friendly_read :
- thread_ic -> string -> off:int -> len:int -> int
+ thread_ic -> Bytes.t -> off:int -> len:int -> int
val thread_friendly_really_read :
- thread_ic -> string -> off:int -> len:int -> unit
+ thread_ic -> Bytes.t -> off:int -> len:int -> unit
val thread_friendly_really_read_line : thread_ic -> string
diff --git a/lib/cUnix.ml b/lib/cUnix.ml
index cb436511fb..2542b9751b 100644
--- a/lib/cUnix.ml
+++ b/lib/cUnix.ml
@@ -91,15 +91,15 @@ let rec waitpid_non_intr pid =
let run_command ?(hook=(fun _ ->())) c =
let result = Buffer.create 127 in
let cin,cout,cerr = Unix.open_process_full c (Unix.environment ()) in
- let buff = String.make 127 ' ' in
- let buffe = String.make 127 ' ' in
+ let buff = Bytes.make 127 ' ' in
+ let buffe = Bytes.make 127 ' ' in
let n = ref 0 in
let ne = ref 0 in
while n:= input cin buff 0 127 ; ne := input cerr buffe 0 127 ;
!n+ !ne <> 0
do
- let r = String.sub buff 0 !n in (hook r; Buffer.add_string result r);
- let r = String.sub buffe 0 !ne in (hook r; Buffer.add_string result r);
+ let r = Bytes.sub buff 0 !n in (hook r; Buffer.add_bytes result r);
+ let r = Bytes.sub buffe 0 !ne in (hook r; Buffer.add_bytes result r);
done;
(Unix.close_process_full (cin,cout,cerr), Buffer.contents result)
diff --git a/lib/cUnix.mli b/lib/cUnix.mli
index f03719c3d2..c6bcf63475 100644
--- a/lib/cUnix.mli
+++ b/lib/cUnix.mli
@@ -46,7 +46,7 @@ val file_readable_p : string -> bool
is called on each elements read on stdout or stderr. *)
val run_command :
- ?hook:(string->unit) -> string -> Unix.process_status * string
+ ?hook:(bytes->unit) -> string -> Unix.process_status * string
(** [sys_command] launches program [prog] with arguments [args].
It behaves like [Sys.command], except that we rely on
diff --git a/lib/clib.mllib b/lib/clib.mllib
index 1e33173ee1..c73ae9b904 100644
--- a/lib/clib.mllib
+++ b/lib/clib.mllib
@@ -15,7 +15,6 @@ Store
Exninfo
Backtrace
IStream
-Pp_control
Flags
Control
Loc
@@ -28,8 +27,6 @@ CStack
Util
Stateid
Pp
-Ppstyle
-Richpp
Feedback
CUnix
Envars
diff --git a/lib/feedback.ml b/lib/feedback.ml
index 57c6f30a41..7d9d6bf7f0 100644
--- a/lib/feedback.ml
+++ b/lib/feedback.ml
@@ -35,7 +35,7 @@ type feedback_content =
(* Extra metadata *)
| Custom of Loc.t * string * xml
(* Generic messages *)
- | Message of level * Loc.t option * Richpp.richpp
+ | Message of level * Loc.t option * Pp.std_ppcmds
type feedback = {
id : edit_or_state_id;
@@ -45,146 +45,16 @@ type feedback = {
let default_route = 0
-(** Feedback and logging *)
-open Pp
-open Pp_control
-
-type logger = ?loc:Loc.t -> level -> std_ppcmds -> unit
-
-let msgnl_with ?pp_tag fmt strm = msg_with ?pp_tag fmt (strm ++ fnl ())
-
-(* 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 = tag Ppstyle.(Tag.inj debug_tag tag) (str "Debug:") ++ spc ()
-let info_str = mt ()
-let warn_str = tag Ppstyle.(Tag.inj warning_tag tag) (str "Warning:") ++ spc ()
-let err_str = tag Ppstyle.(Tag.inj error_tag tag) (str "Error:" ) ++ spc ()
-
-let make_body quoter info ?loc s =
- let loc = Option.cata Pp.pr_loc (Pp.mt ()) loc in
- quoter (hov 0 (loc ++ info ++ s))
-
-(* Generic logger *)
-let gen_logger dbg err ?pp_tag ?loc level msg = match level with
- | Debug -> msgnl_with ?pp_tag !std_ft (make_body dbg dbg_str ?loc msg)
- | Info -> msgnl_with ?pp_tag !std_ft (make_body dbg info_str ?loc msg)
- | Notice -> msgnl_with ?pp_tag !std_ft msg
- | Warning -> Flags.if_warn (fun () ->
- msgnl_with ?pp_tag !err_ft (make_body err warn_str ?loc msg)) ()
- | Error -> msgnl_with ?pp_tag !err_ft (make_body err err_str ?loc msg)
-
-(* We provide a generic clear_log_backend callback for backends
- wanting to do clenaup after the print.
-*)
-let std_logger_tag = ref None
-let std_logger_cleanup = ref (fun () -> ())
-
-let std_logger ?loc level msg =
- gen_logger (fun x -> x) (fun x -> x) ?pp_tag:!std_logger_tag ?loc level msg;
- !std_logger_cleanup ()
-
-(* Rules for emacs:
- - Debug/info: emacs_quote_info
- - Warning/Error: emacs_quote_err
- - Notice: unquoted
-
- Note the inconsistency.
- *)
-let emacs_logger = gen_logger emacs_quote_info emacs_quote_err ?pp_tag:None
-
-(** Color logging. Moved from pp_style, it may need some more refactoring *)
-
-(** Not thread-safe. We should put a lock somewhere if we print from
- different threads. Do we? *)
-let make_style_stack () =
- (** Default tag is to reset everything *)
- let empty = Terminal.make () in
- let default_tag = Terminal.({
- fg_color = Some `DEFAULT;
- bg_color = Some `DEFAULT;
- bold = Some false;
- italic = Some false;
- underline = Some false;
- negative = Some false;
- })
- in
- let style_stack = ref [] in
- let peek () = match !style_stack with
- | [] -> default_tag (** Anomalous case, but for robustness *)
- | st :: _ -> st
- in
- let push tag =
- let style = match Ppstyle.get_style tag with
- | None -> empty
- | Some st -> st
- in
- (** Use the merging of the latest tag and the one being currently pushed.
- This may be useful if for instance the latest tag changes the background and
- the current one the foreground, so that the two effects are additioned. *)
- let style = Terminal.merge (peek ()) style in
- style_stack := style :: !style_stack;
- Terminal.eval style
- in
- let pop _ = match !style_stack with
- | [] -> (** Something went wrong, we fallback *)
- Terminal.eval default_tag
- | _ :: rem -> style_stack := rem;
- Terminal.eval (peek ())
- in
- let clear () = style_stack := [] in
- push, pop, clear
-
-let init_color_output () =
- let open Pp_control in
- let push_tag, pop_tag, clear_tag = make_style_stack () in
- std_logger_cleanup := clear_tag;
- std_logger_tag := Some Ppstyle.pp_tag;
- let tag_handler = {
- Format.mark_open_tag = push_tag;
- Format.mark_close_tag = pop_tag;
- Format.print_open_tag = ignore;
- Format.print_close_tag = ignore;
- } 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 logger = ref std_logger
-let set_logger l = logger := l
-
-let msg_info ?loc x = !logger ?loc Info x
-let msg_notice ?loc x = !logger ?loc Notice x
-let msg_warning ?loc x = !logger ?loc Warning x
-let msg_error ?loc x = !logger ?loc Error x
-let msg_debug ?loc x = !logger ?loc Debug x
-
(** Feeders *)
-let feeders = ref []
-let add_feeder f = feeders := f :: !feeders
+let feeders : (int, feedback -> unit) Hashtbl.t = Hashtbl.create 7
-let debug_feeder = function
- | { contents = Message (Debug, loc, pp) } ->
- msg_debug ?loc (Pp.str (Richpp.raw_print pp))
- | _ -> ()
+let add_feeder =
+ let f_id = ref 0 in fun f ->
+ incr f_id;
+ Hashtbl.add feeders !f_id f;
+ !f_id
+
+let del_feeder fid = Hashtbl.remove feeders fid
let feedback_id = ref (Edit 0)
let feedback_route = ref default_route
@@ -198,34 +68,14 @@ let feedback ?id ?route what =
route = Option.default !feedback_route route;
id = Option.default !feedback_id id;
} in
- List.iter (fun f -> f m) !feeders
+ Hashtbl.iter (fun _ f -> f m) feeders
+(* Logging messages *)
let feedback_logger ?loc lvl msg =
- feedback ~route:!feedback_route ~id:!feedback_id
- (Message (lvl, loc, Richpp.richpp_of_pp msg))
-
-(* Output to file *)
-let ft_logger old_logger ft ?loc 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 ?loc level mesg
- | Error -> old_logger ?loc 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
+ feedback ~route:!feedback_route ~id:!feedback_id (Message (lvl, loc, msg))
+let msg_info ?loc x = feedback_logger ?loc Info x
+let msg_notice ?loc x = feedback_logger ?loc Notice x
+let msg_warning ?loc x = feedback_logger ?loc Warning x
+let msg_error ?loc x = feedback_logger ?loc Error x
+let msg_debug ?loc x = feedback_logger ?loc Debug x
diff --git a/lib/feedback.mli b/lib/feedback.mli
index b4bed8793d..4bbdfcb5b6 100644
--- a/lib/feedback.mli
+++ b/lib/feedback.mli
@@ -8,7 +8,7 @@
open Xml_datatype
-(* Old plain messages (used to be in Pp) *)
+(* Legacy-style logging messages (used to be in Pp) *)
type level =
| Debug
| Info
@@ -16,7 +16,6 @@ type level =
| Warning
| Error
-
(** Coq "semantic" infos obtained during parsing/execution *)
type edit_id = int
type state_id = Stateid.t
@@ -44,7 +43,7 @@ type feedback_content =
(* Extra metadata *)
| Custom of Loc.t * string * xml
(* Generic messages *)
- | Message of level * Loc.t option * Richpp.richpp
+ | Message of level * Loc.t option * Pp.std_ppcmds
type feedback = {
id : edit_or_state_id; (* The document part concerned *)
@@ -53,37 +52,17 @@ type feedback = {
}
(** {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 = ?loc:Loc.t -> 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
-
-(** [init_color_output ()] Enable color in the std_logger *)
-val init_color_output : unit -> unit
-
-(** [feedback_logger] will produce feedback messages instead IO events *)
-val feedback_logger : logger
-val emacs_logger : logger
+(** [add_feeder f] adds a feeder listiner [f], returning its id *)
+val add_feeder : (feedback -> unit) -> int
-
-(** [add_feeder] feeders observe the feedback *)
-val add_feeder : (feedback -> unit) -> unit
-
-(** Prints feedback messages of kind Message(Debug,_) using msg_debug *)
-val debug_feeder : feedback -> unit
+(** [del_feeder fid] removes the feeder with id [fid] *)
+val del_feeder : int -> unit
(** [feedback ?id ?route fb] produces feedback fb, with [route] and
[id] set appropiatedly, if absent, it will use the defaults set by
@@ -94,10 +73,6 @@ val feedback :
(** [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
@@ -125,7 +100,3 @@ val msg_error : ?loc:Loc.t -> Pp.std_ppcmds -> unit
val msg_debug : ?loc:Loc.t -> Pp.std_ppcmds -> unit
(** For debugging purposes *)
-
-
-
-
diff --git a/lib/future.ml b/lib/future.ml
index ea0382a63d..1360b7ac4a 100644
--- a/lib/future.ml
+++ b/lib/future.ml
@@ -151,8 +151,8 @@ let chain ~pure ck f =
create ~uuid ~name fix_exn (match !c with
| Closure _ | Delegated _ -> Closure (fun () -> f (force ~pure ck))
| Exn _ as x -> x
- | Val (v, None) when pure -> Closure (fun () -> f v)
- | Val (v, Some _) when pure -> Closure (fun () -> f v)
+ | Val (v, None) when pure -> Val (f v, None)
+ | Val (v, Some _) when pure -> Val (f v, None)
| Val (v, Some state) -> Closure (fun () -> !unfreeze state; f v)
| Val (v, None) ->
match !ck with
@@ -191,9 +191,9 @@ let transactify f x =
let purify_future f x = if is_over x then f x else purify f x
let compute x = purify_future (compute ~pure:false) x
let force ~pure x = purify_future (force ~pure) x
-let chain ?(greedy=true) ~pure x f =
+let chain ~pure x f =
let y = chain ~pure x f in
- if is_over x && greedy then ignore(force ~pure y);
+ if is_over x then ignore(force ~pure y);
y
let force x = force ~pure:false x
@@ -204,13 +204,13 @@ let join kx =
let sink kx = if is_val kx then ignore(join kx)
-let split2 ?greedy x =
- chain ?greedy ~pure:true x (fun x -> fst x),
- chain ?greedy ~pure:true x (fun x -> snd x)
+let split2 x =
+ chain ~pure:true x (fun x -> fst x),
+ chain ~pure:true x (fun x -> snd x)
-let map2 ?greedy f x l =
+let map2 f x l =
CList.map_i (fun i y ->
- let xi = chain ?greedy ~pure:true x (fun x ->
+ let xi = chain ~pure:true x (fun x ->
try List.nth x i
with Failure _ | Invalid_argument _ ->
CErrors.anomaly (Pp.str "Future.map2 length mismatch")) in
diff --git a/lib/future.mli b/lib/future.mli
index c780faf324..2a025ae844 100644
--- a/lib/future.mli
+++ b/lib/future.mli
@@ -113,8 +113,9 @@ val is_exn : 'a computation -> bool
val peek_val : 'a computation -> 'a option
val uuid : 'a computation -> UUID.t
-(* [chain greedy pure c f] chains computation [c] with [f].
- * The [greedy] and [pure] parameters are tricky:
+(* [chain pure c f] chains computation [c] with [f].
+ * [chain] forces immediately the new computation if the old one is_over (Exn or Val).
+ * The [pure] parameter is tricky:
* [pure]:
* When pure is true, the returned computation will not keep a copy
* of the global state.
@@ -124,10 +125,8 @@ val uuid : 'a computation -> UUID.t
* one forces c' and then c''.
* [join c; chain ~pure:false c g] is invalid and fails at runtime.
* [force c; chain ~pure:false c g] is correct.
- * [greedy]:
- * The [greedy] parameter forces immediately the new computation if
- * the old one is_over (Exn or Val). Defaults to true. *)
-val chain : ?greedy:bool -> pure:bool ->
+ *)
+val chain : pure:bool ->
'a computation -> ('a -> 'b) -> 'b computation
(* Forcing a computation *)
@@ -143,9 +142,9 @@ val join : 'a computation -> 'a
val sink : 'a computation -> unit
(*** Utility functions ************************************************* ***)
-val split2 : ?greedy:bool ->
+val split2 :
('a * 'b) computation -> 'a computation * 'b computation
-val map2 : ?greedy:bool ->
+val map2 :
('a computation -> 'b -> 'c) ->
'a list computation -> 'b list -> 'c list
diff --git a/lib/pp.ml b/lib/pp.ml
index a51b4458fb..66feae761a 100644
--- a/lib/pp.ml
+++ b/lib/pp.ml
@@ -6,64 +6,6 @@
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
-module Glue : sig
-
- (** The [Glue] module implements a container data structure with
- efficient concatenation. *)
-
- type 'a t
-
- val atom : 'a -> 'a t
- val glue : 'a t -> 'a t -> 'a t
- val empty : 'a t
- val is_empty : 'a t -> bool
- val iter : ('a -> unit) -> 'a t -> unit
-
-end = struct
-
- type 'a t = GEmpty | GLeaf of 'a | GNode of 'a t * 'a t
-
- let atom x = GLeaf x
-
- let glue x y =
- match x, y with
- | GEmpty, _ -> y
- | _, GEmpty -> x
- | _, _ -> GNode (x,y)
-
- let empty = GEmpty
-
- let is_empty x = x = GEmpty
-
- let rec iter f = function
- | GEmpty -> ()
- | GLeaf x -> f x
- | GNode (x,y) -> iter f x; iter f y
-
-end
-
-module Tag :
-sig
- type t
- type 'a key
- val create : string -> 'a key
- val inj : 'a -> 'a key -> t
- val prj : t -> 'a key -> 'a option
-end =
-struct
-
-module Dyn = Dyn.Make(struct end)
-
-type t = Dyn.t
-type 'a key = 'a Dyn.tag
-let create = Dyn.create
-let inj = Dyn.Easy.inj
-let prj = Dyn.Easy.prj
-
-end
-
-open Pp_control
-
(* The different kinds of blocks are:
\begin{description}
\item[hbox:] Horizontal block no line breaking;
@@ -75,45 +17,32 @@ open Pp_control
\end{description}
*)
+type pp_tag = string
+
type block_type =
- | Pp_hbox of int
- | Pp_vbox of int
- | Pp_hvbox of int
+ | Pp_hbox of int
+ | Pp_vbox of int
+ | Pp_hvbox of int
| Pp_hovbox of int
-type str_token =
-| Str_def of string
-| Str_len of string * int (** provided length *)
-
-type 'a ppcmd_token =
- | Ppcmd_print of 'a
- | Ppcmd_box of block_type * ('a ppcmd_token Glue.t)
+type doc_view =
+ | Ppcmd_empty
+ | Ppcmd_string of string
+ | Ppcmd_glue of doc_view list
+ | Ppcmd_box of block_type * doc_view
+ | Ppcmd_tag of pp_tag * doc_view
+ (* Are those redundant? *)
| Ppcmd_print_break of int * int
- | Ppcmd_white_space of int
| Ppcmd_force_newline
- | Ppcmd_print_if_broken
- | Ppcmd_open_box of block_type
- | Ppcmd_close_box
| Ppcmd_comment of string list
- | Ppcmd_open_tag of Tag.t
- | Ppcmd_close_tag
-
-type 'a ppdir_token =
- | Ppdir_ppcmds of 'a ppcmd_token Glue.t
- | Ppdir_print_newline
- | Ppdir_print_flush
-
-type ppcmd = str_token ppcmd_token
-
-type std_ppcmds = ppcmd Glue.t
-type 'a ppdirs = 'a ppdir_token Glue.t
+(* Following discussion on #390, we play on the safe side and make the
+ internal representation opaque here. *)
+type t = doc_view
+type std_ppcmds = t
-let (++) = Glue.glue
-
-let app = Glue.glue
-
-let is_empty g = Glue.is_empty g
+let repr x = x
+let unrepr x = x
(* Compute length of an UTF-8 encoded string
Rem 1 : utf8_length <= String.length (equal if pure ascii)
@@ -151,23 +80,32 @@ let utf8_length s =
done ;
!cnt
+let app s1 s2 = match s1, s2 with
+ | Ppcmd_empty, s
+ | s, Ppcmd_empty -> s
+ | s1, s2 -> Ppcmd_glue [s1; s2]
+
+let seq s = Ppcmd_glue s
+
+let (++) = app
+
(* formatting commands *)
-let str s = Glue.atom(Ppcmd_print (Str_def s))
-let stras (i, s) = Glue.atom(Ppcmd_print (Str_len (s, i)))
-let brk (a,b) = Glue.atom(Ppcmd_print_break (a,b))
-let fnl () = Glue.atom(Ppcmd_force_newline)
-let pifb () = Glue.atom(Ppcmd_print_if_broken)
-let ws n = Glue.atom(Ppcmd_white_space n)
-let comment l = Glue.atom(Ppcmd_comment l)
+let str s = Ppcmd_string s
+let brk (a,b) = Ppcmd_print_break (a,b)
+let fnl () = Ppcmd_force_newline
+let ws n = Ppcmd_print_break (n,0)
+let comment l = Ppcmd_comment l
(* derived commands *)
-let mt () = Glue.empty
-let spc () = Glue.atom(Ppcmd_print_break (1,0))
-let cut () = Glue.atom(Ppcmd_print_break (0,0))
-let align () = Glue.atom(Ppcmd_print_break (0,0))
-let int n = str (string_of_int n)
-let real r = str (string_of_float r)
-let bool b = str (string_of_bool b)
+let mt () = Ppcmd_empty
+let spc () = Ppcmd_print_break (1,0)
+let cut () = Ppcmd_print_break (0,0)
+let align () = Ppcmd_print_break (0,0)
+let int n = str (string_of_int n)
+let real r = str (string_of_float r)
+let bool b = str (string_of_bool b)
+
+(* XXX: To Remove *)
let strbrk s =
let rec aux p n =
if n < String.length s then
@@ -176,47 +114,18 @@ let strbrk s =
else str (String.sub s p (n-p)) :: spc () :: aux (n+1) (n+1)
else aux p (n + 1)
else if p = n then [] else [str (String.sub s p (n-p))]
- in List.fold_left (++) Glue.empty (aux 0 0)
-
-let pr_loc_pos loc =
- if Loc.is_ghost loc then (str"<unknown>")
- else
- let loc = Loc.unloc loc in
- int (fst loc) ++ str"-" ++ int (snd loc)
-
-let pr_loc loc =
- if Loc.is_ghost loc then str"<unknown>" ++ fnl ()
- else
- let fname = loc.Loc.fname in
- if CString.equal fname "" then
- Loc.(str"Toplevel input, characters " ++ int loc.bp ++
- str"-" ++ int loc.ep ++ str":" ++ fnl ())
- else
- Loc.(str"File " ++ str "\"" ++ str fname ++ str "\"" ++
- str", line " ++ int loc.line_nb ++ str", characters " ++
- int (loc.bp-loc.bol_pos) ++ str"-" ++ int (loc.ep-loc.bol_pos) ++
- str":" ++ fnl())
+ in Ppcmd_glue (aux 0 0)
-let ismt = is_empty
+let ismt = function | Ppcmd_empty -> true | _ -> false
(* boxing commands *)
-let h n s = Glue.atom(Ppcmd_box(Pp_hbox n,s))
-let v n s = Glue.atom(Ppcmd_box(Pp_vbox n,s))
-let hv n s = Glue.atom(Ppcmd_box(Pp_hvbox n,s))
-let hov n s = Glue.atom(Ppcmd_box(Pp_hovbox n,s))
-
-(* Opening and closing of boxes *)
-let hb n = Glue.atom(Ppcmd_open_box(Pp_hbox n))
-let vb n = Glue.atom(Ppcmd_open_box(Pp_vbox n))
-let hvb n = Glue.atom(Ppcmd_open_box(Pp_hvbox n))
-let hovb n = Glue.atom(Ppcmd_open_box(Pp_hovbox n))
-let close () = Glue.atom(Ppcmd_close_box)
+let h n s = Ppcmd_box(Pp_hbox n,s)
+let v n s = Ppcmd_box(Pp_vbox n,s)
+let hv n s = Ppcmd_box(Pp_hvbox n,s)
+let hov n s = Ppcmd_box(Pp_hovbox n,s)
(* Opening and closed of tags *)
-let open_tag t = Glue.atom(Ppcmd_open_tag t)
-let close_tag () = Glue.atom(Ppcmd_close_tag)
-let tag t s = open_tag t ++ s ++ close_tag ()
-let eval_ppcmds l = l
+let tag t s = Ppcmd_tag(t,s)
(* In new syntax only double quote char is escaped by repeating it *)
let escape_string s =
@@ -243,67 +152,34 @@ let rec pr_com ft s =
Some s2 -> Format.pp_force_newline ft (); pr_com ft s2
| None -> ()
-type tag_handler = Tag.t -> Format.tag
-
(* pretty printing functions *)
-let pp_dirs ?pp_tag ft =
- let pp_open_box = function
+let pp_with ft =
+ let cpp_open_box = function
| Pp_hbox n -> Format.pp_open_hbox ft ()
| Pp_vbox n -> Format.pp_open_vbox ft n
| Pp_hvbox n -> Format.pp_open_hvbox ft n
| Pp_hovbox n -> Format.pp_open_hovbox ft n
in
- let rec pp_cmd = function
- | Ppcmd_print tok ->
- begin match tok with
- | Str_def s ->
- let n = utf8_length s in
- Format.pp_print_as ft n s
- | Str_len (s, n) ->
- Format.pp_print_as ft n s
- end
- | Ppcmd_box(bty,ss) -> (* Prevent evaluation of the stream! *)
- 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 -> pp_open_box bty
- | Ppcmd_close_box -> Format.pp_close_box ft ()
- | Ppcmd_white_space n -> Format.pp_print_break ft n 0
- | Ppcmd_print_break(m,n) -> Format.pp_print_break ft m n
- | Ppcmd_force_newline -> Format.pp_force_newline ft ()
- | Ppcmd_print_if_broken -> Format.pp_print_if_newline ft ()
+ let rec pp_cmd = let open Format in function
+ | Ppcmd_empty -> ()
+ | Ppcmd_glue sl -> List.iter pp_cmd sl
+ | Ppcmd_string str -> let n = utf8_length str in
+ pp_print_as ft n str
+ | Ppcmd_box(bty,ss) -> cpp_open_box bty ;
+ if not (over_max_boxes ()) then pp_cmd ss;
+ pp_close_box ft ()
+ | Ppcmd_print_break(m,n) -> pp_print_break ft m n
+ | Ppcmd_force_newline -> pp_force_newline ft ()
| Ppcmd_comment coms -> List.iter (pr_com ft) coms
- | Ppcmd_open_tag tag ->
- begin match pp_tag with
- | None -> ()
- | Some f -> Format.pp_open_tag ft (f tag)
- end
- | Ppcmd_close_tag ->
- begin match pp_tag with
- | None -> ()
- | Some _ -> Format.pp_close_tag ft ()
- end
- in
- let pp_dir = function
- | Ppdir_ppcmds cmdstream -> Glue.iter pp_cmd cmdstream
- | Ppdir_print_newline -> Format.pp_print_newline ft ()
- | Ppdir_print_flush -> Format.pp_print_flush ft ()
+ | Ppcmd_tag(tag, s) -> pp_open_tag ft tag;
+ pp_cmd s;
+ pp_close_tag ft ()
in
- fun (dirstream : _ ppdirs) ->
- try
- Glue.iter pp_dir dirstream
- with reraise ->
- let reraise = Backtrace.add_backtrace reraise in
- let () = Format.pp_print_flush ft () in
- Exninfo.iraise reraise
-
-(* pretty printing functions WITHOUT FLUSH *)
-let pp_with ?pp_tag ft strm =
- pp_dirs ?pp_tag ft (Glue.atom (Ppdir_ppcmds strm))
-
-(* pretty printing functions WITH FLUSH *)
-let msg_with ?pp_tag ft strm =
- pp_dirs ?pp_tag ft (Glue.atom(Ppdir_ppcmds strm) ++ Glue.atom(Ppdir_print_flush))
+ try pp_cmd
+ with reraise ->
+ let reraise = Backtrace.add_backtrace reraise in
+ let () = Format.pp_print_flush ft () in
+ Exninfo.iraise reraise
(* If mixing some output and a goal display, please use msg_warning,
so that interfaces (proofgeneral for example) can easily dispatch
@@ -311,7 +187,7 @@ let msg_with ?pp_tag ft strm =
(** Output to a string formatter *)
let string_of_ppcmds c =
- Format.fprintf Format.str_formatter "@[%a@]" (msg_with ?pp_tag:None) c;
+ Format.fprintf Format.str_formatter "@[%a@]" pp_with c;
Format.flush_str_formatter ()
(* Copy paste from Util *)
@@ -338,7 +214,7 @@ let pr_nth n =
(* [prlist pr [a ; ... ; c]] outputs [pr a ++ ... ++ pr c] *)
-let prlist pr l = List.fold_left (fun x e -> x ++ pr e) Glue.empty l
+let prlist pr l = Ppcmd_glue (List.map pr l)
(* unlike all other functions below, [prlist] works lazily.
if a strict behavior is needed, use [prlist_strict] instead.
@@ -403,4 +279,3 @@ 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 f17908262c..7a191b01a8 100644
--- a/lib/pp.mli
+++ b/lib/pp.mli
@@ -6,17 +6,65 @@
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
-(** Pretty-printers. *)
+(** Coq document type. *)
+
+(** Pretty printing guidelines ******************************************)
+(* *)
+(* `Pp.t` or `Pp.std_ppcmds` is the main pretty printing document type *)
+(* in the Coq system. Documents are composed laying out boxes, and *)
+(* users can add arbitrary tag metadata that backends are free *)
+(* *)
+(* The datatype has a public view to allow serialization or advanced *)
+(* uses, however regular users are _strongly_ warned againt its use, *)
+(* they should instead rely on the available functions below. *)
+(* *)
+(* Box order and number is indeed an important factor. Try to create *)
+(* a proper amount of boxes. The `++` operator provides "efficient" *)
+(* concatenation, but using the list constructors is usually preferred. *)
+(* *)
+(* That is to say, this: *)
+(* *)
+(* `hov [str "Term"; hov (pr_term t); str "is defined"]` *)
+(* *)
+(* is preferred to: *)
+(* *)
+(* `hov (str "Term" ++ hov (pr_term t) ++ str "is defined")` *)
+(* *)
+(************************************************************************)
-type std_ppcmds
+(* XXX: Improve and add attributes *)
+type pp_tag = string
+
+(* Following discussion on #390, we play on the safe side and make the
+ internal representation opaque here. *)
+type t
+type std_ppcmds = t
+
+type block_type =
+ | Pp_hbox of int
+ | Pp_vbox of int
+ | Pp_hvbox of int
+ | Pp_hovbox of int
+
+type doc_view =
+ | Ppcmd_empty
+ | Ppcmd_string of string
+ | Ppcmd_glue of t list
+ | Ppcmd_box of block_type * t
+ | Ppcmd_tag of pp_tag * t
+ (* Are those redundant? *)
+ | Ppcmd_print_break of int * int
+ | Ppcmd_force_newline
+ | Ppcmd_comment of string list
+
+val repr : std_ppcmds -> doc_view
+val unrepr : doc_view -> std_ppcmds
(** {6 Formatting commands} *)
val str : string -> std_ppcmds
-val stras : int * string -> std_ppcmds
val brk : int * int -> 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
@@ -28,15 +76,12 @@ val comment : string list -> std_ppcmds
val app : std_ppcmds -> std_ppcmds -> std_ppcmds
(** Concatenation. *)
+val seq : std_ppcmds list -> std_ppcmds
+(** Multi-Concatenation. *)
+
val (++) : std_ppcmds -> std_ppcmds -> std_ppcmds
(** Infix alias for [app]. *)
-val eval_ppcmds : std_ppcmds -> std_ppcmds
-(** Force computation. *)
-
-val is_empty : std_ppcmds -> bool
-(** Test emptyness. *)
-
(** {6 Derived commands} *)
val spc : unit -> std_ppcmds
@@ -57,42 +102,9 @@ val v : int -> std_ppcmds -> std_ppcmds
val hv : int -> std_ppcmds -> std_ppcmds
val hov : int -> std_ppcmds -> std_ppcmds
-(** {6 Opening and closing of boxes} *)
-
-val hb : int -> std_ppcmds
-val vb : int -> std_ppcmds
-val hvb : int -> std_ppcmds
-val hovb : int -> std_ppcmds
-val close : unit -> std_ppcmds
-
-(** {6 Opening and closing of tags} *)
-
-module Tag :
-sig
- type t
- (** Type of tags. Tags are dynamic types comparable to {Dyn.t}. *)
-
- type 'a key
- (** Keys used to inject tags *)
-
- val create : string -> 'a key
- (** Create a key with the given name. Two keys cannot share the same name, if
- ever this is the case this function raises an assertion failure. *)
+(** {6 Tagging} *)
- val inj : 'a -> 'a key -> t
- (** Inject an object into a tag. *)
-
- val prj : t -> 'a key -> 'a option
- (** Project an object from a tag. *)
-end
-
-val tag : Tag.t -> std_ppcmds -> std_ppcmds
-val open_tag : Tag.t -> std_ppcmds
-val close_tag : unit -> std_ppcmds
-
-(** {6 Utilities} *)
-
-val string_of_ppcmds : std_ppcmds -> string
+val tag : pp_tag -> std_ppcmds -> std_ppcmds
(** {6 Printing combinators} *)
@@ -160,15 +172,9 @@ val surround : std_ppcmds -> std_ppcmds
val pr_vertical_list : ('b -> std_ppcmds) -> 'b list -> std_ppcmds
-val pr_loc : Loc.t -> std_ppcmds
-
-(** {6 Low-level pretty-printing functions with and without flush} *)
+(** {6 Main renderers, to formatter and to string } *)
-(** FIXME: These ignore the logging settings and call [Format] directly *)
-type tag_handler = Tag.t -> Format.tag
+(** [pp_with fmt pp] Print [pp] to [fmt] and don't flush [fmt] *)
+val pp_with : Format.formatter -> std_ppcmds -> unit
-(** [msg_with ?pp_tag fmt pp] Print [pp] to [fmt] and flush [fmt] *)
-val msg_with : ?pp_tag:tag_handler -> Format.formatter -> std_ppcmds -> unit
-
-(** [msg_with ?pp_tag fmt pp] Print [pp] to [fmt] and don't flush [fmt] *)
-val pp_with : ?pp_tag:tag_handler -> Format.formatter -> std_ppcmds -> unit
+val string_of_ppcmds : std_ppcmds -> string
diff --git a/lib/pp_control.ml b/lib/pp_control.ml
deleted file mode 100644
index 890ffe0a18..0000000000
--- a/lib/pp_control.ml
+++ /dev/null
@@ -1,93 +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 *)
-(************************************************************************)
-
-(* Parameters of pretty-printing *)
-
-type pp_global_params = {
- margin : int;
- max_indent : int;
- max_depth : int;
- ellipsis : string }
-
-(* Default parameters of pretty-printing *)
-
-let dflt_gp = {
- margin = 78;
- max_indent = 50;
- max_depth = 50;
- ellipsis = "..." }
-
-(* A deeper pretty-printer to print proof scripts *)
-
-let deep_gp = {
- margin = 78;
- max_indent = 50;
- max_depth = 10000;
- ellipsis = "..." }
-
-(* set_gp : Format.formatter -> pp_global_params -> unit
- * set the parameters of a formatter *)
-
-let set_gp ft gp =
- Format.pp_set_margin ft gp.margin ;
- Format.pp_set_max_indent ft gp.max_indent ;
- Format.pp_set_max_boxes ft gp.max_depth ;
- Format.pp_set_ellipsis_text ft gp.ellipsis
-
-let set_dflt_gp ft = set_gp ft dflt_gp
-
-let get_gp ft =
- { margin = Format.pp_get_margin ft ();
- max_indent = Format.pp_get_max_indent ft ();
- max_depth = Format.pp_get_max_boxes ft ();
- ellipsis = Format.pp_get_ellipsis_text ft () }
-
-(* with_fp : 'a pp_formatter_params -> Format.formatter
- * returns of formatter for given formatter functions *)
-
-let with_fp chan out_function flush_function =
- let ft = Format.make_formatter out_function flush_function in
- Format.pp_set_formatter_out_channel ft chan;
- ft
-
-(* Output on a channel ch *)
-
-let with_output_to ch =
- let ft = with_fp ch (output ch) (fun () -> flush ch) in
- set_gp ft deep_gp;
- ft
-
-let std_ft = ref Format.std_formatter
-let _ = set_dflt_gp !std_ft
-
-let err_ft = ref Format.err_formatter
-let _ = set_gp !err_ft deep_gp
-
-let deep_ft = ref (with_output_to stdout)
-let _ = set_gp !deep_ft deep_gp
-
-(* For parametrization through vernacular *)
-let default = Format.pp_get_max_boxes !std_ft ()
-let default_margin = Format.pp_get_margin !std_ft ()
-
-let get_depth_boxes () = Some (Format.pp_get_max_boxes !std_ft ())
-let set_depth_boxes v =
- Format.pp_set_max_boxes !std_ft (match v with None -> default | Some v -> v)
-
-let get_margin () = Some (Format.pp_get_margin !std_ft ())
-let set_margin v =
- let v = match v with None -> default_margin | Some v -> v in
- Format.pp_set_margin Format.str_formatter v;
- Format.pp_set_margin !std_ft v;
- Format.pp_set_margin !deep_ft v;
- (* Heuristic, based on usage: the column on the right of max_indent
- column is 20% of width, capped to 30 characters *)
- let m = max (64 * v / 100) (v-30) in
- Format.pp_set_max_indent Format.str_formatter m;
- Format.pp_set_max_indent !std_ft m;
- Format.pp_set_max_indent !deep_ft m
diff --git a/lib/ppstyle.ml b/lib/ppstyle.ml
deleted file mode 100644
index aa47c51671..0000000000
--- a/lib/ppstyle.ml
+++ /dev/null
@@ -1,73 +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 *)
-(************************************************************************)
-
-module String = CString
-
-type t = string
-(** We use the concatenated string, with dots separating each string. We
- forbid the use of dots in the strings. *)
-
-let tags : Terminal.style option String.Map.t ref = ref String.Map.empty
-
-let make ?style tag =
- let check s = if String.contains s '.' then invalid_arg "Ppstyle.make" in
- let () = List.iter check tag in
- let name = String.concat "." tag in
- let () = assert (not (String.Map.mem name !tags)) in
- let () = tags := String.Map.add name style !tags in
- name
-
-let repr t = String.split '.' t
-
-let get_style tag =
- try String.Map.find tag !tags with Not_found -> assert false
-
-let set_style tag st =
- try tags := String.Map.update tag st !tags with Not_found -> assert false
-
-let clear_styles () =
- tags := String.Map.map (fun _ -> None) !tags
-
-let dump () = String.Map.bindings !tags
-
-let parse_config s =
- let styles = Terminal.parse s in
- let set accu (name, st) =
- try String.Map.update name (Some st) accu with Not_found -> accu
- in
- tags := List.fold_left set !tags styles
-
-let tag = Pp.Tag.create "ppstyle"
-
-(** Default tag is to reset everything *)
-let default = Terminal.({
- fg_color = Some `DEFAULT;
- bg_color = Some `DEFAULT;
- bold = Some false;
- italic = Some false;
- underline = Some false;
- negative = Some false;
-})
-
-let empty = Terminal.make ()
-
-let error_tag =
- let style = Terminal.make ~bold:true ~fg_color:`WHITE ~bg_color:`RED () in
- make ~style ["message"; "error"]
-
-let warning_tag =
- let style = Terminal.make ~bold:true ~fg_color:`WHITE ~bg_color:`YELLOW () in
- make ~style ["message"; "warning"]
-
-let debug_tag =
- let style = Terminal.make ~bold:true ~fg_color:`WHITE ~bg_color:`MAGENTA () in
- make ~style ["message"; "debug"]
-
-let pp_tag t = match Pp.Tag.prj t tag with
-| None -> ""
-| Some key -> key
diff --git a/lib/ppstyle.mli b/lib/ppstyle.mli
deleted file mode 100644
index d9fd757656..0000000000
--- a/lib/ppstyle.mli
+++ /dev/null
@@ -1,63 +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 *)
-(************************************************************************)
-
-(** Highlighting of printers. Used for pretty-printing terms that should be
- displayed on a color-capable terminal. *)
-
-(** {5 Style tags} *)
-
-type t = string
-
-(** Style tags *)
-
-val make : ?style:Terminal.style -> string list -> t
-(** Create a new tag with the given name. Each name must be unique. The optional
- style is taken as the default one. *)
-
-val repr : t -> string list
-(** Gives back the original name of the style tag where each string has been
- concatenated and separated with a dot. *)
-
-val tag : t Pp.Tag.key
-(** An annotation for styles *)
-
-(** {5 Manipulating global styles} *)
-
-val get_style : t -> Terminal.style option
-(** Get the style associated to a tag. *)
-
-val set_style : t -> Terminal.style option -> unit
-(** Set a style associated to a tag. *)
-
-val clear_styles : unit -> unit
-(** Clear all styles. *)
-
-val parse_config : string -> unit
-(** Add all styles from the given string as parsed by {!Terminal.parse}.
- Unregistered tags are ignored. *)
-
-val dump : unit -> (t * Terminal.style option) list
-(** Recover the list of known tags together with their current style. *)
-
-(** {5 Color output} *)
-
-val pp_tag : Pp.tag_handler
-(** Returns the name of a style tag that is understandable by the formatters
- that have been inititialized through {!init_color_output}. To be used with
- {!Pp.pp_with}. *)
-
-(** {5 Tags} *)
-
-val error_tag : t
-(** Tag used by the {!Pp.msg_error} function. *)
-
-val warning_tag : t
-(** Tag used by the {!Pp.msg_warning} function. *)
-
-val debug_tag : t
-(** Tag used by the {!Pp.msg_debug} function. *)
diff --git a/lib/util.ml b/lib/util.ml
index 9fb0d48ee8..0d2425f271 100644
--- a/lib/util.ml
+++ b/lib/util.ml
@@ -161,11 +161,11 @@ let iraise = Exninfo.iraise
let open_utf8_file_in fname =
let is_bom s =
- Int.equal (Char.code s.[0]) 0xEF &&
- Int.equal (Char.code s.[1]) 0xBB &&
- Int.equal (Char.code s.[2]) 0xBF
+ Int.equal (Char.code (Bytes.get s 0)) 0xEF &&
+ Int.equal (Char.code (Bytes.get s 1)) 0xBB &&
+ Int.equal (Char.code (Bytes.get s 2)) 0xBF
in
let in_chan = open_in fname in
- let s = " " in
+ let s = Bytes.make 3 ' ' in
if input in_chan s 0 3 < 3 || not (is_bom s) then seek_in in_chan 0;
in_chan
diff --git a/library/lib.ml b/library/lib.ml
index 4fd29a94de..ddd2ed6afa 100644
--- a/library/lib.ml
+++ b/library/lib.ml
@@ -97,21 +97,30 @@ let segment_of_objects prefix =
let initial_prefix = default_library,(Names.initial_path,Names.DirPath.empty)
-let lib_stk = ref ([] : library_segment)
+type lib_state = {
+ comp_name : Names.DirPath.t option;
+ lib_stk : library_segment;
+ path_prefix : Names.DirPath.t * (Names.module_path * Names.DirPath.t);
+}
-let comp_name = ref None
+let initial_lib_state = {
+ comp_name = None;
+ lib_stk = [];
+ path_prefix = initial_prefix;
+}
+
+let lib_state = ref initial_lib_state
let library_dp () =
- match !comp_name with Some m -> m | None -> default_library
+ match !lib_state.comp_name with Some m -> m | None -> default_library
(* [path_prefix] is a pair of absolute dirpath and a pair of current
module path and relative section path *)
-let path_prefix = ref initial_prefix
-let cwd () = fst !path_prefix
-let current_prefix () = snd !path_prefix
-let current_mp () = fst (snd !path_prefix)
-let current_sections () = snd (snd !path_prefix)
+let cwd () = fst !lib_state.path_prefix
+let current_prefix () = snd !lib_state.path_prefix
+let current_mp () = fst (snd !lib_state.path_prefix)
+let current_sections () = snd (snd !lib_state.path_prefix)
let sections_depth () = List.length (Names.DirPath.repr (current_sections ()))
let sections_are_opened () = not (Names.DirPath.is_empty (current_sections ()))
@@ -132,7 +141,7 @@ let make_kn id =
let mp,dir = current_prefix () in
Names.make_kn mp dir (Names.Label.of_id id)
-let make_oname id = Libnames.make_oname !path_prefix id
+let make_oname id = Libnames.make_oname !lib_state.path_prefix id
let recalc_path_prefix () =
let rec recalc = function
@@ -142,18 +151,18 @@ let recalc_path_prefix () =
| _::l -> recalc l
| [] -> initial_prefix
in
- path_prefix := recalc !lib_stk
+ lib_state := { !lib_state with path_prefix = recalc !lib_state.lib_stk }
let pop_path_prefix () =
- let dir,(mp,sec) = !path_prefix in
- path_prefix := pop_dirpath dir, (mp, pop_dirpath sec)
+ let dir,(mp,sec) = !lib_state.path_prefix in
+ lib_state := { !lib_state with path_prefix = pop_dirpath dir, (mp, pop_dirpath sec)}
let find_entry_p p =
let rec find = function
| [] -> raise Not_found
| ent::l -> if p ent then ent else find l
in
- find !lib_stk
+ find !lib_state.lib_stk
let split_lib_gen test =
let rec collect after equal = function
@@ -174,7 +183,7 @@ let split_lib_gen test =
| _ -> findeq (hd::after) before)
| [] -> None
in
- match findeq [] !lib_stk with
+ match findeq [] !lib_state.lib_stk with
| None -> error "no such entry"
| Some r -> r
@@ -199,10 +208,10 @@ let split_lib_at_opening sp =
(* Adding operations. *)
let add_entry sp node =
- lib_stk := (sp,node) :: !lib_stk
+ lib_state := { !lib_state with lib_stk = (sp,node) :: !lib_state.lib_stk }
let pull_to_head oname =
- lib_stk := (oname,List.assoc oname !lib_stk) :: List.remove_assoc oname !lib_stk
+ lib_state := { !lib_state with lib_stk = (oname,List.assoc oname !lib_state.lib_stk) :: List.remove_assoc oname !lib_state.lib_stk }
let anonymous_id =
let n = ref 0 in
@@ -277,7 +286,7 @@ let start_mod is_type export id mp fs =
if exists then
user_err ~hdr:"open_module" (pr_id id ++ str " already exists");
add_entry (make_oname id) (OpenedModule (is_type,export,prefix,fs));
- path_prefix := prefix;
+ lib_state := { !lib_state with path_prefix = prefix} ;
prefix
let start_module = start_mod false
@@ -299,16 +308,16 @@ let end_mod is_type =
with Not_found -> error "No opened modules."
in
let (after,mark,before) = split_lib_at_opening oname in
- lib_stk := before;
+ lib_state := { !lib_state with lib_stk = before };
add_entry oname (ClosedModule (List.rev (mark::after)));
- let prefix = !path_prefix in
+ let prefix = !lib_state.path_prefix in
recalc_path_prefix ();
(oname, prefix, fs, after)
let end_module () = end_mod false
let end_modtype () = end_mod true
-let contents () = !lib_stk
+let contents () = !lib_state.lib_stk
let contents_after sp = let (after,_,_) = split_lib sp in after
@@ -316,14 +325,14 @@ let contents_after sp = let (after,_,_) = split_lib sp in after
(* TODO: use check_for_module ? *)
let start_compilation s mp =
- if !comp_name != None then
+ if !lib_state.comp_name != None then
error "compilation unit is already started";
if not (Names.DirPath.is_empty (current_sections ())) then
error "some sections are already opened";
let prefix = s, (mp, Names.DirPath.empty) in
let () = add_anonymous_entry (CompilingLibrary prefix) in
- comp_name := Some s;
- path_prefix := prefix
+ lib_state := { !lib_state with comp_name = Some s;
+ path_prefix = prefix }
let end_compilation_checks dir =
let _ =
@@ -344,7 +353,7 @@ let end_compilation_checks dir =
with Not_found -> anomaly (Pp.str "No module declared")
in
let _ =
- match !comp_name with
+ match !lib_state.comp_name with
| None -> anomaly (Pp.str "There should be a module name...")
| Some m ->
if not (Names.DirPath.equal m dir) then anomaly
@@ -355,8 +364,8 @@ let end_compilation_checks dir =
let end_compilation oname =
let (after,mark,before) = split_lib_at_opening oname in
- comp_name := None;
- !path_prefix,after
+ lib_state := { !lib_state with comp_name = None };
+ !lib_state.path_prefix,after
(* Returns true if we are inside an opened module or module type *)
@@ -514,7 +523,7 @@ let (f_xml_open_section, xml_open_section) = Hook.make ~default:ignore ()
let (f_xml_close_section, xml_close_section) = Hook.make ~default:ignore ()
let open_section id =
- let olddir,(mp,oldsec) = !path_prefix in
+ let olddir,(mp,oldsec) = !lib_state.path_prefix in
let dir = add_dirpath_suffix olddir id in
let prefix = dir, (mp, add_dirpath_suffix oldsec id) in
if Nametab.exists_section dir then
@@ -523,7 +532,7 @@ let open_section id =
add_entry (make_oname id) (OpenedSection (prefix, fs));
(*Pushed for the lifetime of the section: removed by unfrozing the summary*)
Nametab.push_dir (Nametab.Until 1) dir (DirOpenSection prefix);
- path_prefix := prefix;
+ lib_state := { !lib_state with path_prefix = prefix };
if !Flags.xml_export then Hook.get f_xml_open_section id;
add_section ()
@@ -549,8 +558,8 @@ let close_section () =
error "No opened section."
in
let (secdecls,mark,before) = split_lib_at_opening oname in
- lib_stk := before;
- let full_olddir = fst !path_prefix in
+ lib_state := { !lib_state with lib_stk = before };
+ let full_olddir = fst !lib_state.path_prefix in
pop_path_prefix ();
add_entry oname (ClosedSection (List.rev (mark::secdecls)));
if !Flags.xml_export then Hook.get f_xml_close_section (basename (fst oname));
@@ -561,7 +570,7 @@ let close_section () =
(* State and initialization. *)
-type frozen = Names.DirPath.t option * library_segment
+type frozen = lib_state
let freeze ~marshallable =
match marshallable with
@@ -578,18 +587,15 @@ let freeze ~marshallable =
Some(n,OpenedSection(op,Summary.empty_frozen))
| n, ClosedSection _ -> Some (n,ClosedSection [])
| _, FrozenState _ -> None)
- !lib_stk in
- !comp_name, lib_stk
+ !lib_state.lib_stk in
+ { !lib_state with lib_stk }
| _ ->
- !comp_name, !lib_stk
+ !lib_state
-let unfreeze (mn,stk) =
- comp_name := mn;
- lib_stk := stk;
- recalc_path_prefix ()
+let unfreeze st = lib_state := st
let init () =
- unfreeze (None,[]);
+ unfreeze initial_lib_state;
Summary.init_summaries ();
add_frozen_state () (* Stores e.g. the keywords declared in g_*.ml4 *)
diff --git a/library/libobject.ml b/library/libobject.ml
index caa03c85be..8757ca08c6 100644
--- a/library/libobject.ml
+++ b/library/libobject.ml
@@ -91,16 +91,8 @@ let declare_object_full odecl =
dyn_rebuild_function = rebuild };
(infun,outfun)
-(* The "try .. with .. " allows for correct printing when calling
- declare_object a loading time.
-*)
-
-let declare_object odecl =
- try fst (declare_object_full odecl)
- with e -> CErrors.fatal_error (CErrors.print e) (CErrors.is_anomaly e)
-let declare_object_full odecl =
- try declare_object_full odecl
- with e -> CErrors.fatal_error (CErrors.print e) (CErrors.is_anomaly e)
+let declare_object odecl = fst (declare_object_full odecl)
+let declare_object_full odecl = declare_object_full odecl
(* this function describes how the cache, load, open, and export functions
are triggered. *)
diff --git a/library/nameops.ml b/library/nameops.ml
index 6020db33d9..098f5112fd 100644
--- a/library/nameops.ml
+++ b/library/nameops.ml
@@ -61,7 +61,7 @@ let make_ident sa = function
if c < code_of_0 || c > code_of_9 then sa ^ (string_of_int n)
else sa ^ "_" ^ (string_of_int n) in
Id.of_string s
- | None -> Id.of_string (String.copy sa)
+ | None -> Id.of_string sa
let root_of_id id =
let suffixstart = cut_ident true id in
@@ -92,20 +92,20 @@ let increment_subscript id =
add (carrypos-1)
end
else begin
- let newid = String.copy id in
- String.fill newid (carrypos+1) (len-1-carrypos) '0';
- newid.[carrypos] <- Char.chr (Char.code c + 1);
+ let newid = Bytes.of_string id in
+ Bytes.fill newid (carrypos+1) (len-1-carrypos) '0';
+ Bytes.set newid carrypos (Char.chr (Char.code c + 1));
newid
end
else begin
- let newid = id^"0" in
+ let newid = Bytes.of_string (id^"0") in
if carrypos < len-1 then begin
- String.fill newid (carrypos+1) (len-1-carrypos) '0';
- newid.[carrypos+1] <- '1'
+ Bytes.fill newid (carrypos+1) (len-1-carrypos) '0';
+ Bytes.set newid (carrypos+1) '1'
end;
newid
end
- in Id.of_string (add (len-1))
+ in Id.of_bytes (add (len-1))
let has_subscript id =
let id = Id.to_string id in
@@ -113,9 +113,9 @@ let has_subscript id =
let forget_subscript id =
let numstart = cut_ident false id in
- let newid = String.make (numstart+1) '0' in
+ let newid = Bytes.make (numstart+1) '0' in
String.blit (Id.to_string id) 0 newid 0 numstart;
- (Id.of_string newid)
+ (Id.of_bytes newid)
let add_suffix id s = Id.of_string (Id.to_string id ^ s)
let add_prefix s id = Id.of_string (s ^ Id.to_string id)
diff --git a/library/summary.ml b/library/summary.ml
index 6efa07f388..d9f6441003 100644
--- a/library/summary.ml
+++ b/library/summary.ml
@@ -107,8 +107,10 @@ let unfreeze_summaries fs =
try fold id decl state
with e when CErrors.noncritical e ->
let e = CErrors.push e in
- Printf.eprintf "Error unfrezing summay %s\n%s\n%!"
- (name_of_summary id) (Pp.string_of_ppcmds (CErrors.iprint e));
+ Feedback.msg_error
+ Pp.(seq [str "Error unfreezing summary %s\n%s\n%!";
+ str (name_of_summary id);
+ CErrors.iprint e]);
iraise e
in
(** We rely on the order of the frozen list, and the order of folding *)
diff --git a/parsing/cLexer.ml4 b/parsing/cLexer.ml4
index 02a720d2d9..3b84eaa816 100644
--- a/parsing/cLexer.ml4
+++ b/parsing/cLexer.ml4
@@ -105,7 +105,7 @@ module Error = struct
Printf.sprintf "Unsupported Unicode character (0x%x)" x)
(* Require to fix the Camlp4 signature *)
- let print ppf x = Pp.pp_with ~pp_tag:Ppstyle.pp_tag ppf (Pp.str (to_string x))
+ let print ppf x = Pp.pp_with ppf (Pp.str (to_string x))
end
open Error
@@ -240,18 +240,19 @@ let unfreeze tt = (token_tree := tt)
(* The string buffering machinery *)
-let buff = ref (String.create 80)
+let buff = ref (Bytes.create 80)
let store len x =
- if len >= String.length !buff then
- buff := !buff ^ String.create (String.length !buff);
- !buff.[len] <- x;
+ let open Bytes in
+ if len >= length !buff then
+ buff := cat !buff (create (length !buff));
+ set !buff len x;
succ len
let rec nstore n len cs =
if n>0 then nstore (n-1) (store len (Stream.next cs)) cs else len
-let get_buff len = String.sub !buff 0 len
+let get_buff len = Bytes.sub_string !buff 0 len
(* The classical lexer: idents, numbers, quoted strings, comments *)
@@ -382,6 +383,7 @@ let push_char c =
real_push_char c
let push_string s = Buffer.add_string current_comment s
+let push_bytes s = Buffer.add_bytes current_comment s
let null_comment s =
let rec null i =
@@ -716,13 +718,13 @@ let strip s =
in
if len == String.length s then s
else
- let s' = String.create len in
+ let s' = Bytes.create len in
let rec loop i i' =
if i == String.length s then s'
else if s.[i] == ' ' then loop (i + 1) i'
- else begin s'.[i'] <- s.[i]; loop (i + 1) (i' + 1) end
+ else begin Bytes.set s' i' s.[i]; loop (i + 1) (i' + 1) end
in
- loop 0 0
+ Bytes.to_string (loop 0 0)
let terminal s =
let s = strip s in
diff --git a/parsing/egramcoq.ml b/parsing/egramcoq.ml
index 07e4ddf844..496b200020 100644
--- a/parsing/egramcoq.ml
+++ b/parsing/egramcoq.ml
@@ -233,11 +233,11 @@ type (_, _) entry =
| TTName : ('self, Name.t Loc.located) entry
| TTReference : ('self, reference) entry
| TTBigint : ('self, Bigint.bigint) entry
-| TTBinder : ('self, local_binder list) entry
+| TTBinder : ('self, local_binder_expr 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
+| TTBinderListT : ('self, local_binder_expr list) entry
+| TTBinderListF : Tok.t list -> ('self, local_binder_expr list list) entry
type _ any_entry = TTAny : ('s, 'r) entry -> 's any_entry
@@ -324,7 +324,7 @@ let cases_pattern_expr_of_name (loc,na) = match na with
type 'r env = {
constrs : 'r list;
constrlists : 'r list list;
- binders : (local_binder list * bool) list;
+ binders : (local_binder_expr list * bool) list;
}
let push_constr subst v = { subst with constrs = v :: subst.constrs }
diff --git a/parsing/g_constr.ml4 b/parsing/g_constr.ml4
index 47455f9842..c127e78803 100644
--- a/parsing/g_constr.ml4
+++ b/parsing/g_constr.ml4
@@ -38,7 +38,7 @@ let mk_cast = function
in CCast(loc, c, CastConv ty)
let binder_of_name expl (loc,na) =
- LocalRawAssum ([loc, na], Default expl,
+ CLocalAssum ([loc, na], Default expl,
CHole (loc, Some (Evar_kinds.BinderType na), IntroAnonymous, None))
let binders_of_names l =
@@ -240,17 +240,18 @@ GEXTEND Gram
mkCLambdaN (!@loc) bl c
| "let"; id=name; bl = binders; ty = type_cstr; ":=";
c1 = operconstr LEVEL "200"; "in"; c2 = operconstr LEVEL "200" ->
- let loc1 =
- Loc.merge (local_binders_loc bl) (constr_loc c1)
- in
- CLetIn(!@loc,id,mkCLambdaN loc1 bl (mk_cast(c1,ty)),c2)
+ let ty,c1 = match ty, c1 with
+ | (_,None), CCast(loc,c, CastConv t) -> (constr_loc t,Some t), c (* Tolerance, see G_vernac.def_body *)
+ | _, _ -> ty, c1 in
+ CLetIn(!@loc,id,mkCLambdaN (constr_loc c1) bl c1,
+ Option.map (mkCProdN (fst ty) bl) (snd ty), c2)
| "let"; fx = single_fix; "in"; c = operconstr LEVEL "200" ->
let fixp = mk_single_fix fx in
let (li,id) = match fixp with
CFix(_,id,_) -> id
| CCoFix(_,id,_) -> id
| _ -> assert false in
- CLetIn(!@loc,(li,Name id),fixp,c)
+ CLetIn(!@loc,(li,Name id),fixp,None,c)
| "let"; lb = ["("; l=LIST0 name SEP ","; ")" -> l | "()" -> []];
po = return_type;
":="; c1 = operconstr LEVEL "200"; "in";
@@ -412,11 +413,11 @@ GEXTEND Gram
impl_ident_tail:
[ [ "}" -> binder_of_name Implicit
| nal=LIST1 name; ":"; c=lconstr; "}" ->
- (fun na -> LocalRawAssum (na::nal,Default Implicit,c))
+ (fun na -> CLocalAssum (na::nal,Default Implicit,c))
| nal=LIST1 name; "}" ->
- (fun na -> LocalRawAssum (na::nal,Default Implicit,CHole (Loc.join_loc (fst na) !@loc, Some (Evar_kinds.BinderType (snd na)), IntroAnonymous, None)))
+ (fun na -> CLocalAssum (na::nal,Default Implicit,CHole (Loc.join_loc (fst na) !@loc, Some (Evar_kinds.BinderType (snd na)), IntroAnonymous, None)))
| ":"; c=lconstr; "}" ->
- (fun na -> LocalRawAssum ([na],Default Implicit,c))
+ (fun na -> CLocalAssum ([na],Default Implicit,c))
] ]
;
fixannot:
@@ -442,12 +443,12 @@ GEXTEND Gram
the latter is unique *)
[ [ (* open binder *)
id = name; idl = LIST0 name; ":"; c = lconstr ->
- [LocalRawAssum (id::idl,Default Explicit,c)]
+ [CLocalAssum (id::idl,Default Explicit,c)]
(* binders factorized with open binder *)
| id = name; idl = LIST0 name; bl = binders ->
binders_of_names (id::idl) @ bl
| id1 = name; ".."; id2 = name ->
- [LocalRawAssum ([id1;(!@loc,Name ldots_var);id2],
+ [CLocalAssum ([id1;(!@loc,Name ldots_var);id2],
Default Explicit,CHole (!@loc, None, IntroAnonymous, None))]
| bl = closed_binder; bl' = binders ->
bl@bl'
@@ -457,37 +458,39 @@ GEXTEND Gram
[ [ l = LIST0 binder -> List.flatten l ] ]
;
binder:
- [ [ id = name -> [LocalRawAssum ([id],Default Explicit,CHole (!@loc, None, IntroAnonymous, None))]
+ [ [ id = name -> [CLocalAssum ([id],Default Explicit,CHole (!@loc, None, IntroAnonymous, None))]
| bl = closed_binder -> bl ] ]
;
closed_binder:
[ [ "("; id=name; idl=LIST1 name; ":"; c=lconstr; ")" ->
- [LocalRawAssum (id::idl,Default Explicit,c)]
+ [CLocalAssum (id::idl,Default Explicit,c)]
| "("; id=name; ":"; c=lconstr; ")" ->
- [LocalRawAssum ([id],Default Explicit,c)]
+ [CLocalAssum ([id],Default Explicit,c)]
| "("; id=name; ":="; c=lconstr; ")" ->
- [LocalRawDef (id,c)]
+ (match c with
+ | CCast(_,c, CastConv t) -> [CLocalDef (id,c,Some t)]
+ | _ -> [CLocalDef (id,c,None)])
| "("; id=name; ":"; t=lconstr; ":="; c=lconstr; ")" ->
- [LocalRawDef (id,CCast (Loc.merge (constr_loc t) (!@loc),c, CastConv t))]
+ [CLocalDef (id,c,Some t)]
| "{"; id=name; "}" ->
- [LocalRawAssum ([id],Default Implicit,CHole (!@loc, None, IntroAnonymous, None))]
+ [CLocalAssum ([id],Default Implicit,CHole (!@loc, None, IntroAnonymous, None))]
| "{"; id=name; idl=LIST1 name; ":"; c=lconstr; "}" ->
- [LocalRawAssum (id::idl,Default Implicit,c)]
+ [CLocalAssum (id::idl,Default Implicit,c)]
| "{"; id=name; ":"; c=lconstr; "}" ->
- [LocalRawAssum ([id],Default Implicit,c)]
+ [CLocalAssum ([id],Default Implicit,c)]
| "{"; id=name; idl=LIST1 name; "}" ->
- List.map (fun id -> LocalRawAssum ([id],Default Implicit,CHole (!@loc, None, IntroAnonymous, None))) (id::idl)
+ List.map (fun id -> CLocalAssum ([id],Default Implicit,CHole (!@loc, None, IntroAnonymous, None))) (id::idl)
| "`("; tc = LIST1 typeclass_constraint SEP "," ; ")" ->
- List.map (fun (n, b, t) -> LocalRawAssum ([n], Generalized (Implicit, Explicit, b), t)) tc
+ List.map (fun (n, b, t) -> CLocalAssum ([n], Generalized (Implicit, Explicit, b), t)) tc
| "`{"; tc = LIST1 typeclass_constraint SEP "," ; "}" ->
- List.map (fun (n, b, t) -> LocalRawAssum ([n], Generalized (Implicit, Implicit, b), t)) tc
+ List.map (fun (n, b, t) -> CLocalAssum ([n], Generalized (Implicit, Implicit, b), t)) tc
| "'"; p = pattern LEVEL "0" ->
let (p, ty) =
match p with
| CPatCast (_, p, ty) -> (p, Some ty)
| _ -> (p, None)
in
- [LocalPattern (!@loc, p, ty)]
+ [CLocalPattern (!@loc, p, ty)]
] ]
;
typeclass_constraint:
diff --git a/parsing/g_prim.ml4 b/parsing/g_prim.ml4
index 820514b08a..2db91b8f87 100644
--- a/parsing/g_prim.ml4
+++ b/parsing/g_prim.ml4
@@ -34,7 +34,7 @@ GEXTEND Gram
GLOBAL:
bigint natural integer identref name ident var preident
fullyqualid qualid reference dirpath ne_lstring
- ne_string string pattern_ident pattern_identref by_notation smart_global;
+ ne_string string lstring pattern_ident pattern_identref by_notation smart_global;
preident:
[ [ s = IDENT -> s ] ]
;
@@ -106,6 +106,9 @@ GEXTEND Gram
string:
[ [ s = STRING -> s ] ]
;
+ lstring:
+ [ [ s = string -> (!@loc, s) ] ]
+ ;
integer:
[ [ i = INT -> my_int_of_string (!@loc) i
| "-"; i = INT -> - my_int_of_string (!@loc) i ] ]
diff --git a/parsing/g_vernac.ml4 b/parsing/g_vernac.ml4
index d46880831f..ded7a557cf 100644
--- a/parsing/g_vernac.ml4
+++ b/parsing/g_vernac.ml4
@@ -66,13 +66,7 @@ GEXTEND Gram
(* Stm backdoor *)
| IDENT "Stm"; IDENT "JoinDocument"; "." -> VernacStm JoinDocument
- | IDENT "Stm"; IDENT "Finish"; "." -> VernacStm Finish
| IDENT "Stm"; IDENT "Wait"; "." -> VernacStm Wait
- | IDENT "Stm"; IDENT "PrintDag"; "." -> VernacStm PrintDag
- | IDENT "Stm"; IDENT "Observe"; id = INT; "." ->
- VernacStm (Observe (Stateid.of_int (int_of_string id)))
- | IDENT "Stm"; IDENT "Command"; v = vernac_aux -> VernacStm (Command v)
- | IDENT "Stm"; IDENT "PGLast"; v = vernac_aux -> VernacStm (PGLast v)
| v = vernac_poly -> v ]
]
@@ -249,7 +243,7 @@ GEXTEND Gram
| _ -> DefineBody (bl, red, c, None))
| bl = binders; ":"; t = lconstr; ":="; red = reduce; c = lconstr ->
let ((bl, c), tyo) =
- if List.exists (function LocalPattern _ -> true | _ -> false) bl
+ if List.exists (function CLocalPattern _ -> true | _ -> false) bl
then
let c = CCast (!@loc, c, CastConv t) in
(expand_pattern_binders mkCLambdaN bl c, None)
@@ -340,8 +334,8 @@ GEXTEND Gram
binder_nodef:
[ [ b = binder_let ->
(match b with
- LocalRawAssum(l,ty) -> (l,ty)
- | LocalRawDef _ ->
+ CLocalAssum(l,ty) -> (l,ty)
+ | CLocalDef _ ->
Util.user_err_loc
(loc,"fix_param",Pp.str"defined binder not allowed here.")) ] ]
;
@@ -1112,7 +1106,7 @@ GEXTEND Gram
idl = LIST0 ident; ":="; c = constr; b = only_parsing ->
VernacSyntacticDefinition
(id,(idl,c),local,b)
- | IDENT "Notation"; local = obsolete_locality; s = ne_lstring; ":=";
+ | IDENT "Notation"; local = obsolete_locality; s = lstring; ":=";
c = constr;
modl = [ "("; l = LIST1 syntax_modifier SEP ","; ")" -> l | -> [] ];
sc = OPT [ ":"; sc = IDENT -> sc ] ->
diff --git a/parsing/pcoq.ml b/parsing/pcoq.ml
index c5823440ac..b8405ca8c5 100644
--- a/parsing/pcoq.ml
+++ b/parsing/pcoq.ml
@@ -267,6 +267,7 @@ module Prim =
let integer = gec_gen "integer"
let bigint = Gram.entry_create "Prim.bigint"
let string = gec_gen "string"
+ let lstring = Gram.entry_create "Prim.lstring"
let reference = make_gen_entry uprim "reference"
let by_notation = Gram.entry_create "by_notation"
let smart_global = Gram.entry_create "smart_global"
diff --git a/parsing/pcoq.mli b/parsing/pcoq.mli
index d987bb4557..6c148d3938 100644
--- a/parsing/pcoq.mli
+++ b/parsing/pcoq.mli
@@ -136,6 +136,7 @@ module Prim :
val bigint : Bigint.bigint Gram.entry
val integer : int Gram.entry
val string : string Gram.entry
+ val lstring : string located Gram.entry
val qualid : qualid located Gram.entry
val fullyqualid : Id.t list located Gram.entry
val reference : reference Gram.entry
@@ -161,11 +162,11 @@ module Constr :
val pattern : cases_pattern_expr Gram.entry
val constr_pattern : constr_expr Gram.entry
val lconstr_pattern : constr_expr Gram.entry
- val closed_binder : local_binder list Gram.entry
- val binder : local_binder list Gram.entry (* closed_binder or variable *)
- val binders : local_binder list Gram.entry (* list of binder *)
- val open_binders : local_binder list Gram.entry
- val binders_fixannot : (local_binder list * (Id.t located option * recursion_order_expr)) Gram.entry
+ val closed_binder : local_binder_expr list Gram.entry
+ val binder : local_binder_expr list Gram.entry (* closed_binder or variable *)
+ val binders : local_binder_expr list Gram.entry (* list of binder *)
+ val open_binders : local_binder_expr list Gram.entry
+ val binders_fixannot : (local_binder_expr list * (Id.t located option * recursion_order_expr)) Gram.entry
val typeclass_constraint : (Name.t located * bool * constr_expr) Gram.entry
val record_declaration : constr_expr Gram.entry
val appl_arg : (constr_expr * explicitation located option) Gram.entry
diff --git a/plugins/decl_mode/decl_expr.mli b/plugins/decl_mode/decl_expr.mli
deleted file mode 100644
index 29ecb94ca8..0000000000
--- a/plugins/decl_mode/decl_expr.mli
+++ /dev/null
@@ -1,102 +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 Tacexpr
-
-type 'it statement =
- {st_label:Name.t;
- st_it:'it}
-
-type thesis_kind =
- Plain
- | For of Id.t
-
-type 'this or_thesis =
- This of 'this
- | Thesis of thesis_kind
-
-type side = Lhs | Rhs
-
-type elim_type =
- ET_Case_analysis
- | ET_Induction
-
-type block_type =
- B_proof
- | B_claim
- | B_focus
- | B_elim of elim_type
-
-type ('it,'constr,'tac) cut =
- {cut_stat: 'it;
- cut_by: 'constr list option;
- cut_using: 'tac option}
-
-type ('var,'constr) hyp =
- Hvar of 'var
- | Hprop of 'constr statement
-
-type ('constr,'tac) casee =
- Real of 'constr
- | Virtual of ('constr statement,'constr,'tac) cut
-
-type ('var,'constr,'pat,'tac) bare_proof_instr =
- | Pthen of ('var,'constr,'pat,'tac) bare_proof_instr
- | Pthus of ('var,'constr,'pat,'tac) bare_proof_instr
- | Phence of ('var,'constr,'pat,'tac) bare_proof_instr
- | Pcut of ('constr or_thesis statement,'constr,'tac) cut
- | Prew of side * ('constr statement,'constr,'tac) cut
- | Psuffices of ((('var,'constr) hyp list * 'constr or_thesis),'constr,'tac) cut
- | Passume of ('var,'constr) hyp list
- | Plet of ('var,'constr) hyp list
- | Pgiven of ('var,'constr) hyp list
- | Pconsider of 'constr*('var,'constr) hyp list
- | Pclaim of 'constr statement
- | Pfocus of 'constr statement
- | Pdefine of Id.t * 'var list * 'constr
- | Pcast of Id.t or_thesis * 'constr
- | Psuppose of ('var,'constr) hyp list
- | Pcase of 'var list*'pat*(('var,'constr or_thesis) hyp list)
- | Ptake of 'constr list
- | Pper of elim_type * ('constr,'tac) casee
- | Pend of block_type
- | Pescape
-
-type emphasis = int
-
-type ('var,'constr,'pat,'tac) gen_proof_instr=
- {emph: emphasis;
- instr: ('var,'constr,'pat,'tac) bare_proof_instr }
-
-
-type raw_proof_instr =
- ((Id.t * (Constrexpr.constr_expr option)) Loc.located,
- Constrexpr.constr_expr,
- Constrexpr.cases_pattern_expr,
- raw_tactic_expr) gen_proof_instr
-
-type glob_proof_instr =
- ((Id.t * (Tacexpr.glob_constr_and_expr option)) Loc.located,
- Tacexpr.glob_constr_and_expr,
- Constrexpr.cases_pattern_expr,
- Tacexpr.glob_tactic_expr) gen_proof_instr
-
-type proof_pattern =
- {pat_vars: Term.types statement list;
- pat_aliases: (Term.constr*Term.types) statement list;
- pat_constr: Term.constr;
- pat_typ: Term.types;
- pat_pat: Glob_term.cases_pattern;
- pat_expr: Constrexpr.cases_pattern_expr}
-
-type proof_instr =
- (Term.constr statement,
- Term.constr,
- proof_pattern,
- Geninterp.Val.t) gen_proof_instr
diff --git a/plugins/decl_mode/decl_interp.ml b/plugins/decl_mode/decl_interp.ml
deleted file mode 100644
index 2b63ed6d6e..0000000000
--- a/plugins/decl_mode/decl_interp.ml
+++ /dev/null
@@ -1,474 +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 Ltac_plugin
-open CErrors
-open Util
-open Names
-open Constrexpr
-open Tacintern
-open Decl_expr
-open Decl_mode
-open Pretyping
-open Glob_term
-open Term
-open Vars
-open Pp
-open Decl_kinds
-open Misctypes
-
-(* INTERN *)
-
-let glob_app (loc,hd,args) = if List.is_empty args then hd else GApp(loc,hd,args)
-
-let intern_justification_items globs =
- Option.map (List.map (intern_constr globs))
-
-let intern_justification_method globs =
- Option.map (intern_pure_tactic globs)
-
-let intern_statement intern_it globs st =
- {st_label=st.st_label;
- st_it=intern_it globs st.st_it}
-
-let intern_no_bind intern_it globs x =
- globs,intern_it globs x
-
-let intern_constr_or_thesis globs = function
- Thesis n -> Thesis n
- | This c -> This (intern_constr globs c)
-
-let add_var id globs=
- {globs with ltacvars = Id.Set.add id globs.ltacvars}
-
-let add_name nam globs=
- match nam with
- Anonymous -> globs
- | Name id -> add_var id globs
-
-let intern_hyp iconstr globs = function
- Hvar (loc,(id,topt)) -> add_var id globs,
- Hvar (loc,(id,Option.map (intern_constr globs) topt))
- | Hprop st -> add_name st.st_label globs,
- Hprop (intern_statement iconstr globs st)
-
-let intern_hyps iconstr globs hyps =
- snd (List.fold_map (intern_hyp iconstr) globs hyps)
-
-let intern_cut intern_it globs cut=
- let nglobs,nstat=intern_it globs cut.cut_stat in
- {cut_stat=nstat;
- cut_by=intern_justification_items nglobs cut.cut_by;
- cut_using=intern_justification_method nglobs cut.cut_using}
-
-let intern_casee globs = function
- Real c -> Real (intern_constr globs c)
- | Virtual cut -> Virtual
- (intern_cut (intern_no_bind (intern_statement intern_constr)) globs cut)
-
-let intern_hyp_list args globs =
- let intern_one globs (loc,(id,opttyp)) =
- (add_var id globs),
- (loc,(id,Option.map (intern_constr globs) opttyp)) in
- List.fold_map intern_one globs args
-
-let intern_suffices_clause globs (hyps,c) =
- let nglobs,nhyps = List.fold_map (intern_hyp intern_constr) globs hyps in
- nglobs,(nhyps,intern_constr_or_thesis nglobs c)
-
-let intern_fundecl args body globs=
- let nglobs,nargs = intern_hyp_list args globs in
- nargs,intern_constr nglobs body
-
-let rec add_vars_of_simple_pattern globs = function
- CPatAlias (loc,p,id) ->
- add_vars_of_simple_pattern (add_var id globs) p
-(* Loc.raise loc
- (UserError ("simple_pattern",str "\"as\" is not allowed here"))*)
- | CPatOr (loc, _)->
- Loc.raise ~loc
- (UserError (Some "simple_pattern",str "\"(_ | _)\" is not allowed here"))
- | CPatDelimiters (_,_,p) ->
- add_vars_of_simple_pattern globs p
- | CPatCstr (_,_,pl1,pl2) ->
- List.fold_left add_vars_of_simple_pattern
- (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
- | _ -> globs
-
-let rec intern_bare_proof_instr globs = function
- Pthus i -> Pthus (intern_bare_proof_instr globs i)
- | Pthen i -> Pthen (intern_bare_proof_instr globs i)
- | Phence i -> Phence (intern_bare_proof_instr globs i)
- | Pcut c -> Pcut
- (intern_cut
- (intern_no_bind (intern_statement intern_constr_or_thesis)) globs c)
- | Psuffices c ->
- Psuffices (intern_cut intern_suffices_clause globs c)
- | Prew (s,c) -> Prew
- (s,intern_cut
- (intern_no_bind (intern_statement intern_constr)) globs c)
- | Psuppose hyps -> Psuppose (intern_hyps intern_constr globs hyps)
- | Pcase (params,pat,hyps) ->
- let nglobs,nparams = intern_hyp_list params globs in
- let nnglobs= add_vars_of_simple_pattern nglobs pat in
- let nhyps = intern_hyps intern_constr_or_thesis nnglobs hyps in
- Pcase (nparams,pat,nhyps)
- | Ptake witl -> Ptake (List.map (intern_constr globs) witl)
- | Pconsider (c,hyps) -> Pconsider (intern_constr globs c,
- intern_hyps intern_constr globs hyps)
- | Pper (et,c) -> Pper (et,intern_casee globs c)
- | Pend bt -> Pend bt
- | Pescape -> Pescape
- | Passume hyps -> Passume (intern_hyps intern_constr globs hyps)
- | Pgiven hyps -> Pgiven (intern_hyps intern_constr globs hyps)
- | Plet hyps -> Plet (intern_hyps intern_constr globs hyps)
- | Pclaim st -> Pclaim (intern_statement intern_constr globs st)
- | Pfocus st -> Pfocus (intern_statement intern_constr globs st)
- | Pdefine (id,args,body) ->
- let nargs,nbody = intern_fundecl args body globs in
- Pdefine (id,nargs,nbody)
- | Pcast (id,typ) ->
- Pcast (id,intern_constr globs typ)
-
-let intern_proof_instr globs instr=
- {emph = instr.emph;
- instr = intern_bare_proof_instr globs instr.instr}
-
-(* INTERP *)
-
-let interp_justification_items env sigma =
- Option.map (List.map (fun c -> fst (*FIXME*)(understand env sigma (fst c))))
-
-let interp_constr check_sort env sigma c =
- if check_sort then
- fst (understand env sigma ~expected_type:IsType (fst c) (* FIXME *))
- else
- fst (understand env sigma (fst c))
-
-let special_whd env =
- let infos=CClosure.create_clos_infos CClosure.all env in
- (fun t -> CClosure.whd_val infos (CClosure.inject t))
-
-let _eq = lazy (Universes.constr_of_global (Coqlib.glob_eq))
-
-let decompose_eq env id =
- let typ = Environ.named_type id env in
- let whd = special_whd env typ in
- match kind_of_term whd with
- App (f,args)->
- if eq_constr f (Lazy.force _eq) && Int.equal (Array.length args) 3
- then args.(0)
- else error "Previous step is not an equality."
- | _ -> error "Previous step is not an equality."
-
-let get_eq_typ info env =
- let typ = decompose_eq env (get_last env) in
- typ
-
-let interp_constr_in_type typ env sigma c =
- fst (understand env sigma (fst c) ~expected_type:(OfType typ))(*FIXME*)
-
-let interp_statement interp_it env sigma st =
- {st_label=st.st_label;
- st_it=interp_it env sigma st.st_it}
-
-let interp_constr_or_thesis check_sort env sigma = function
- Thesis n -> Thesis n
- | This c -> This (interp_constr check_sort env sigma c)
-
-let abstract_one_hyp inject h glob =
- match h with
- Hvar (loc,(id,None)) ->
- GProd (Loc.ghost,Name id, Explicit, GHole (loc,Evar_kinds.BinderType (Name id), Misctypes.IntroAnonymous, None), glob)
- | Hvar (loc,(id,Some typ)) ->
- GProd (Loc.ghost,Name id, Explicit, fst typ, glob)
- | Hprop st ->
- GProd (Loc.ghost,st.st_label, Explicit, inject st.st_it, glob)
-
-let glob_constr_of_hyps inject hyps head =
- List.fold_right (abstract_one_hyp inject) hyps head
-
-let glob_prop = GSort (Loc.ghost,GProp)
-
-let rec match_hyps blend names constr = function
- [] -> [],substl names constr
- | hyp::q ->
- let (name,typ,body)=destProd constr in
- let st= {st_label=name;st_it=substl names typ} in
- let qnames=
- match name with
- Anonymous -> mkMeta 0 :: names
- | Name id -> mkVar id :: names in
- let qhyp = match hyp with
- Hprop st' -> Hprop (blend st st')
- | Hvar _ -> Hvar st in
- let rhyps,head = match_hyps blend qnames body q in
- qhyp::rhyps,head
-
-let interp_hyps_gen inject blend env sigma hyps head =
- let constr= fst(*FIXME*) (understand env sigma (glob_constr_of_hyps inject hyps head)) in
- match_hyps blend [] constr hyps
-
-let interp_hyps env sigma hyps = fst (interp_hyps_gen fst (fun x _ -> x) env sigma hyps glob_prop)
-
-let dummy_prefix= Id.of_string "__"
-
-let rec deanonymize ids =
- function
- PatVar (loc,Anonymous) ->
- let (found,known) = !ids in
- let new_id=Namegen.next_ident_away dummy_prefix known in
- let _= ids:= (loc,new_id) :: found , new_id :: known in
- PatVar (loc,Name new_id)
- | PatVar (loc,Name id) as pat ->
- let (found,known) = !ids in
- let _= ids:= (loc,id) :: found , known in
- pat
- | PatCstr(loc,cstr,lpat,nam) ->
- PatCstr(loc,cstr,List.map (deanonymize ids) lpat,nam)
-
-let rec glob_of_pat =
- function
- PatVar (loc,Anonymous) -> anomaly (Pp.str "Anonymous pattern variable")
- | PatVar (loc,Name id) ->
- GVar (loc,id)
- | PatCstr(loc,((ind,_) as cstr),lpat,_) ->
- let mind= fst (Global.lookup_inductive ind) in
- let rec add_params n q =
- if n<=0 then q else
- add_params (pred n) (GHole(Loc.ghost,
- Evar_kinds.TomatchTypeParameter(ind,n), Misctypes.IntroAnonymous, None)::q) in
- let args = List.map glob_of_pat lpat in
- glob_app(loc,GRef(Loc.ghost,Globnames.ConstructRef cstr,None),
- add_params mind.Declarations.mind_nparams args)
-
-let prod_one_hyp = function
- (loc,(id,None)) ->
- (fun glob ->
- GProd (Loc.ghost,Name id, Explicit,
- GHole (loc,Evar_kinds.BinderType (Name id), Misctypes.IntroAnonymous, None), glob))
- | (loc,(id,Some typ)) ->
- (fun glob ->
- GProd (Loc.ghost,Name id, Explicit, fst typ, glob))
-
-let prod_one_id (loc,id) glob =
- GProd (Loc.ghost,Name id, Explicit,
- GHole (loc,Evar_kinds.BinderType (Name id), Misctypes.IntroAnonymous, None), glob)
-
-let let_in_one_alias (id,pat) glob =
- GLetIn (Loc.ghost,Name id, glob_of_pat pat, glob)
-
-let rec bind_primary_aliases map pat =
- match pat with
- PatVar (_,_) -> map
- | PatCstr(loc,_,lpat,nam) ->
- let map1 =
- match nam with
- Anonymous -> map
- | Name id -> (id,pat)::map
- in
- List.fold_left bind_primary_aliases map1 lpat
-
-let bind_secondary_aliases map subst =
- Id.Map.fold (fun ids idp map -> (ids,Id.List.assoc idp map)::map) subst map
-
-let bind_aliases patvars subst patt =
- let map = bind_primary_aliases [] patt in
- let map1 = bind_secondary_aliases map subst in
- List.rev map1
-
-let interp_pattern env pat_expr =
- let patvars,pats = Constrintern.intern_pattern env pat_expr in
- match pats with
- [] -> anomaly (Pp.str "empty pattern list")
- | [subst,patt] ->
- (patvars,bind_aliases patvars subst patt,patt)
- | _ -> anomaly (Pp.str "undetected disjunctive pattern")
-
-let rec match_args dest names constr = function
- [] -> [],names,substl names constr
- | _::q ->
- let (name,typ,body)=dest constr in
- let st={st_label=name;st_it=substl names typ} in
- let qnames=
- match name with
- Anonymous -> assert false
- | Name id -> mkVar id :: names in
- let args,bnames,body = match_args dest qnames body q in
- st::args,bnames,body
-
-let rec match_aliases names constr = function
- [] -> [],names,substl names constr
- | _::q ->
- let (name,c,typ,body)=destLetIn constr in
- let st={st_label=name;st_it=(substl names c,substl names typ)} in
- let qnames=
- match name with
- Anonymous -> assert false
- | Name id -> mkVar id :: names in
- let args,bnames,body = match_aliases qnames body q in
- st::args,bnames,body
-
-let detype_ground env c = Detyping.detype false [] env Evd.empty c
-
-let interp_cases info env sigma params (pat:cases_pattern_expr) hyps =
- let et,pinfo =
- match info.pm_stack with
- Per(et,pi,_,_)::_ -> et,pi
- | _ -> error "No proof per cases/induction/inversion in progress." in
- let mib,oib=Global.lookup_inductive pinfo.per_ind in
- let num_params = pinfo.per_nparams in
- let _ =
- let expected = mib.Declarations.mind_nparams - num_params in
- if not (Int.equal (List.length params) expected) then
- user_err ~hdr:"suppose it is"
- (str "Wrong number of extra arguments: " ++
- (if Int.equal expected 0 then str "none" else int expected) ++ spc () ++
- str "expected.") in
- let app_ind =
- let rind = GRef (Loc.ghost,Globnames.IndRef pinfo.per_ind,None) in
- let rparams = List.map (detype_ground env) pinfo.per_params in
- let rparams_rec =
- List.map
- (fun (loc,(id,_)) ->
- GVar (loc,id)) params in
- let dum_args=
- List.init oib.Declarations.mind_nrealargs
- (fun _ -> GHole (Loc.ghost,Evar_kinds.QuestionMark (Evar_kinds.Define false),Misctypes.IntroAnonymous, None)) in
- glob_app(Loc.ghost,rind,rparams@rparams_rec@dum_args) in
- let pat_vars,aliases,patt = interp_pattern env pat in
- let inject = function
- Thesis (Plain) -> Glob_term.GSort(Loc.ghost,GProp)
- | Thesis (For rec_occ) ->
- if not (Id.List.mem rec_occ pat_vars) then
- user_err ~hdr:"suppose it is"
- (str "Variable " ++ Nameops.pr_id rec_occ ++
- str " does not occur in pattern.");
- Glob_term.GSort(Loc.ghost,GProp)
- | This (c,_) -> c in
- let term1 = glob_constr_of_hyps inject hyps glob_prop in
- let loc_ids,npatt =
- let rids=ref ([],pat_vars) in
- let npatt= deanonymize rids patt in
- List.rev (fst !rids),npatt in
- let term2 =
- GLetIn(Loc.ghost,Anonymous,
- GCast(Loc.ghost,glob_of_pat npatt,
- CastConv app_ind),term1) in
- let term3=List.fold_right let_in_one_alias aliases term2 in
- let term4=List.fold_right prod_one_id loc_ids term3 in
- let term5=List.fold_right prod_one_hyp params term4 in
- let constr = fst (understand env sigma term5)(*FIXME*) in
- let tparams,nam4,rest4 = match_args destProd [] constr params in
- let tpatvars,nam3,rest3 = match_args destProd nam4 rest4 loc_ids in
- let taliases,nam2,rest2 = match_aliases nam3 rest3 aliases in
- let (_,pat_pat,pat_typ,rest1) = destLetIn rest2 in
- let blend st st' =
- match st'.st_it with
- Thesis nam -> {st_it=Thesis nam;st_label=st'.st_label}
- | This _ -> {st_it = This st.st_it;st_label=st.st_label} in
- let thyps = fst (match_hyps blend nam2 (Termops.pop rest1) hyps) in
- tparams,{pat_vars=tpatvars;
- pat_aliases=taliases;
- pat_constr=pat_pat;
- pat_typ=pat_typ;
- pat_pat=patt;
- pat_expr=pat},thyps
-
-let interp_cut interp_it env sigma cut=
- let nenv,nstat = interp_it env sigma cut.cut_stat in
- { cut_using=Option.map (Tacinterp.Value.of_closure (Tacinterp.default_ist ())) cut.cut_using;
- cut_stat=nstat;
- cut_by=interp_justification_items nenv sigma cut.cut_by}
-
-let interp_no_bind interp_it env sigma x =
- env,interp_it env sigma x
-
-let interp_suffices_clause env sigma (hyps,cot)=
- let (locvars,_) as res =
- match cot with
- This (c,_) ->
- let nhyps,nc = interp_hyps_gen fst (fun x _ -> x) env sigma hyps c in
- nhyps,This nc
- | Thesis Plain as th -> interp_hyps env sigma hyps,th
- | Thesis (For n) -> error "\"thesis for\" is not applicable here." in
- let push_one hyp env0 =
- match hyp with
- (Hprop st | Hvar st) ->
- match st.st_label with
- Name id -> Environ.push_named (Context.Named.Declaration.LocalAssum (id,st.st_it)) env0
- | _ -> env in
- let nenv = List.fold_right push_one locvars env in
- nenv,res
-
-let interp_casee env sigma = function
- Real c -> Real (fst (understand env sigma (fst c)))(*FIXME*)
- | Virtual cut -> Virtual (interp_cut (interp_no_bind (interp_statement (interp_constr true))) env sigma cut)
-
-let abstract_one_arg = function
- (loc,(id,None)) ->
- (fun glob ->
- GLambda (Loc.ghost,Name id, Explicit,
- GHole (loc,Evar_kinds.BinderType (Name id),Misctypes.IntroAnonymous,None), glob))
- | (loc,(id,Some typ)) ->
- (fun glob ->
- GLambda (Loc.ghost,Name id, Explicit, fst typ, glob))
-
-let glob_constr_of_fun args body =
- List.fold_right abstract_one_arg args (fst body)
-
-let interp_fun env sigma args body =
- let constr=fst (*FIXME*) (understand env sigma (glob_constr_of_fun args body)) in
- match_args destLambda [] constr args
-
-let rec interp_bare_proof_instr info env sigma = function
- Pthus i -> Pthus (interp_bare_proof_instr info env sigma i)
- | Pthen i -> Pthen (interp_bare_proof_instr info env sigma i)
- | Phence i -> Phence (interp_bare_proof_instr info env sigma i)
- | Pcut c -> Pcut (interp_cut
- (interp_no_bind (interp_statement
- (interp_constr_or_thesis true)))
- env sigma c)
- | Psuffices c ->
- Psuffices (interp_cut interp_suffices_clause env sigma c)
- | Prew (s,c) -> Prew (s,interp_cut
- (interp_no_bind (interp_statement
- (interp_constr_in_type (get_eq_typ info env))))
- env sigma c)
-
- | Psuppose hyps -> Psuppose (interp_hyps env sigma hyps)
- | Pcase (params,pat,hyps) ->
- let tparams,tpat,thyps = interp_cases info env sigma params pat hyps in
- Pcase (tparams,tpat,thyps)
- | Ptake witl ->
- Ptake (List.map (fun c -> fst (*FIXME*) (understand env sigma (fst c))) witl)
- | Pconsider (c,hyps) -> Pconsider (interp_constr false env sigma c,
- interp_hyps env sigma hyps)
- | Pper (et,c) -> Pper (et,interp_casee env sigma c)
- | Pend bt -> Pend bt
- | Pescape -> Pescape
- | Passume hyps -> Passume (interp_hyps env sigma hyps)
- | Pgiven hyps -> Pgiven (interp_hyps env sigma hyps)
- | Plet hyps -> Plet (interp_hyps env sigma hyps)
- | Pclaim st -> Pclaim (interp_statement (interp_constr true) env sigma st)
- | Pfocus st -> Pfocus (interp_statement (interp_constr true) env sigma st)
- | Pdefine (id,args,body) ->
- let nargs,_,nbody = interp_fun env sigma args body in
- Pdefine (id,nargs,nbody)
- | Pcast (id,typ) ->
- Pcast(id,interp_constr true env sigma typ)
-
-let interp_proof_instr info env sigma instr=
- {emph = instr.emph;
- instr = interp_bare_proof_instr info env sigma instr.instr}
-
-
-
diff --git a/plugins/decl_mode/decl_mode.ml b/plugins/decl_mode/decl_mode.ml
deleted file mode 100644
index 92d4089015..0000000000
--- a/plugins/decl_mode/decl_mode.ml
+++ /dev/null
@@ -1,136 +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 Term
-open Evd
-open CErrors
-open Util
-
-let daimon_flag = ref false
-
-let set_daimon_flag () = daimon_flag:=true
-let clear_daimon_flag () = daimon_flag:=false
-let get_daimon_flag () = !daimon_flag
-
-
-
-
-type split_tree=
- Skip_patt of Id.Set.t * split_tree
- | Split_patt of Id.Set.t * inductive *
- (bool array * (Id.Set.t * split_tree) option) array
- | Close_patt of split_tree
- | End_patt of (Id.t * (int * int))
-
-type elim_kind =
- EK_dep of split_tree
- | EK_nodep
- | EK_unknown
-
-type recpath = int option*Declarations.wf_paths
-
-type per_info =
- {per_casee:constr;
- per_ctype:types;
- per_ind:inductive;
- per_pred:constr;
- per_args:constr list;
- per_params:constr list;
- per_nparams:int;
- per_wf:recpath}
-
-type stack_info =
- Per of Decl_expr.elim_type * per_info * elim_kind * Id.t list
- | Suppose_case
- | Claim
- | Focus_claim
-
-type pm_info =
- { pm_stack : stack_info list}
-let info = Store.field ()
-
-
-(* Current proof mode *)
-
-type command_mode =
- Mode_tactic
- | Mode_proof
- | Mode_none
-
-let mode_of_pftreestate pts =
- (* spiwack: it used to be "top_goal_..." but this should be fine *)
- let { it = goals ; sigma = sigma } = Proof.V82.subgoals pts in
- let goal = List.hd goals in
- match Store.get (Goal.V82.extra sigma goal) info with
- | None -> Mode_tactic
- | Some _ -> Mode_proof
-
-let get_current_mode () =
- try
- mode_of_pftreestate (Pfedit.get_pftreestate ())
- with Proof_global.NoCurrentProof -> Mode_none
-
-let check_not_proof_mode str =
- match get_current_mode () with
- | Mode_proof -> error str
- | _ -> ()
-
-let get_info sigma gl=
- match Store.get (Goal.V82.extra sigma gl) info with
- | None -> invalid_arg "get_info"
- | Some pm -> pm
-
-let try_get_info sigma gl =
- Store.get (Goal.V82.extra sigma gl) info
-
-let get_goal_stack pts =
- let { it = goals ; sigma = sigma } = Proof.V82.subgoals pts in
- let info = get_info sigma (List.hd goals) in
- info.pm_stack
-
-
-let proof_focus = Proof.new_focus_kind ()
-let proof_cond = Proof.done_cond proof_focus
-
-let focus p =
- let inf = get_goal_stack p in
- Proof_global.simple_with_current_proof (fun _ -> Proof.focus proof_cond inf 1)
-
-let unfocus () =
- Proof_global.simple_with_current_proof (fun _ p -> Proof.unfocus proof_focus p ())
-
-let get_top_stack pts =
- try
- Proof.get_at_focus proof_focus pts
- with Proof.NoSuchFocus ->
- let { it = gl ; sigma = sigma } = Proof.V82.top_goal pts in
- let info = get_info sigma gl in
- info.pm_stack
-
-let get_stack pts = Proof.get_at_focus proof_focus pts
-
-let get_last env = match Environ.named_context env with
- | decl :: _ -> Context.Named.Declaration.get_id decl
- | [] -> error "no previous statement to use"
-
-
-let get_end_command pts =
- match get_top_stack pts with
- | [] -> "\"end proof\""
- | Claim::_ -> "\"end claim\""
- | Focus_claim::_-> "\"end focus\""
- | Suppose_case :: Per (et,_,_,_) :: _ | Per (et,_,_,_) :: _ ->
- begin
- match et with
- Decl_expr.ET_Case_analysis ->
- "\"end cases\" or start a new case"
- | Decl_expr.ET_Induction ->
- "\"end induction\" or start a new case"
- end
- | _ -> anomaly (Pp.str"lonely suppose")
diff --git a/plugins/decl_mode/decl_mode.mli b/plugins/decl_mode/decl_mode.mli
deleted file mode 100644
index dfeee833cb..0000000000
--- a/plugins/decl_mode/decl_mode.mli
+++ /dev/null
@@ -1,79 +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 Term
-open Evd
-
-val set_daimon_flag : unit -> unit
-val clear_daimon_flag : unit -> unit
-val get_daimon_flag : unit -> bool
-
-type command_mode =
- Mode_tactic
- | Mode_proof
- | Mode_none
-
-val mode_of_pftreestate : Proof.proof -> command_mode
-
-val get_current_mode : unit -> command_mode
-
-val check_not_proof_mode : string -> unit
-
-type split_tree=
- Skip_patt of Id.Set.t * split_tree
- | Split_patt of Id.Set.t * inductive *
- (bool array * (Id.Set.t * split_tree) option) array
- | Close_patt of split_tree
- | End_patt of (Id.t * (int * int))
-
-type elim_kind =
- EK_dep of split_tree
- | EK_nodep
- | EK_unknown
-
-type recpath = int option*Declarations.wf_paths
-
-type per_info =
- {per_casee:constr;
- per_ctype:types;
- per_ind:inductive;
- per_pred:constr;
- per_args:constr list;
- per_params:constr list;
- per_nparams:int;
- per_wf:recpath}
-
-type stack_info =
- Per of Decl_expr.elim_type * per_info * elim_kind * Names.Id.t list
- | Suppose_case
- | Claim
- | Focus_claim
-
-type pm_info =
- {pm_stack : stack_info list }
-
-val info : pm_info Store.field
-
-val get_info : Evd.evar_map -> Proof_type.goal -> pm_info
-
-val try_get_info : Evd.evar_map -> Proof_type.goal -> pm_info option
-
-val get_stack : Proof.proof -> stack_info list
-
-val get_top_stack : Proof.proof -> stack_info list
-
-val get_last: Environ.env -> Id.t
-(** [get_last] raises a [UserError] when it cannot find a previous
- statement in the environment. *)
-
-val get_end_command : Proof.proof -> string
-
-val focus : Proof.proof -> unit
-
-val unfocus : unit -> unit
diff --git a/plugins/decl_mode/decl_mode_plugin.mlpack b/plugins/decl_mode/decl_mode_plugin.mlpack
deleted file mode 100644
index 1b84a0790f..0000000000
--- a/plugins/decl_mode/decl_mode_plugin.mlpack
+++ /dev/null
@@ -1,5 +0,0 @@
-Decl_mode
-Decl_interp
-Decl_proof_instr
-Ppdecl_proof
-G_decl_mode
diff --git a/plugins/decl_mode/decl_proof_instr.ml b/plugins/decl_mode/decl_proof_instr.ml
deleted file mode 100644
index deb2ede1d5..0000000000
--- a/plugins/decl_mode/decl_proof_instr.ml
+++ /dev/null
@@ -1,1554 +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 Ltac_plugin
-open CErrors
-open Util
-open Pp
-open Evd
-
-open Tacmach
-open Tacintern
-open Decl_expr
-open Decl_mode
-open Decl_interp
-open Glob_term
-open Glob_ops
-open Names
-open Nameops
-open Declarations
-open Tactics
-open Tacticals
-open Term
-open Vars
-open Termops
-open Namegen
-open Goptions
-open Misctypes
-open Sigma.Notations
-open Context.Named.Declaration
-
-module RelDecl = Context.Rel.Declaration
-module NamedDecl = 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, _) ->
- user_err (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 =
- let strictness = ref false in
- (fun () -> (!strictness)),(fun b -> strictness:=b)
-
-let _ =
- declare_bool_option
- { optsync = true;
- optdepr = false;
- optname = "strict proofs";
- optkey = ["Strict";"Proofs"];
- optread = get_strictness;
- optwrite = set_strictness }
-
-let tcl_change_info_gen info_gen =
- (fun gls ->
- let it = sig_it gls in
- let concl = pf_concl gls in
- let hyps = Goal.V82.hyps (project gls) it in
- let extra = Goal.V82.extra (project gls) it in
- let (gl,ev,sigma) = Goal.V82.mk_goal (project gls) hyps concl (info_gen extra) in
- let sigma = Goal.V82.partial_solution sigma it ev in
- { it = [gl] ; sigma= sigma; } )
-
-let tcl_change_info info gls =
- let info_gen s = Store.set s Decl_mode.info info in
- tcl_change_info_gen info_gen gls
-
-let tcl_erase_info gls =
- let info_gen s = Store.remove s Decl_mode.info in
- tcl_change_info_gen info_gen gls
-
-let special_whd gl=
- let infos=CClosure.create_clos_infos CClosure.all (pf_env gl) in
- (fun t -> CClosure.whd_val infos (CClosure.inject t))
-
-let special_nf gl=
- let infos=CClosure.create_clos_infos CClosure.betaiotazeta (pf_env gl) in
- (fun t -> CClosure.norm_val infos (CClosure.inject t))
-
-let is_good_inductive env ind =
- let mib,oib = Inductive.lookup_mind_specif env ind in
- Int.equal oib.mind_nrealargs 0 && not (Inductiveops.mis_is_recursive (ind,mib,oib))
-
-let check_not_per pts =
- if not (Proof.is_done pts) then
- match get_stack pts with
- Per (_,_,_,_)::_ ->
- error "You are inside a proof per cases/induction.\n\
-Please \"suppose\" something or \"end\" it now."
- | _ -> ()
-
-let mk_evd metalist gls =
- let evd0= clear_metas (sig_sig gls) in
- let add_one (meta,typ) evd =
- meta_declare meta typ evd in
- List.fold_right add_one metalist evd0
-
-let is_tmp id = (Id.to_string id).[0] == '_'
-
-let tmp_ids gls =
- let ctx = pf_hyps gls in
- match ctx with
- [] -> []
- | _::q -> List.filter is_tmp (ids_of_named_context q)
-
-let clean_tmp gls =
- let clean_id id0 gls0 =
- tclTRY (clear [id0]) gls0 in
- let rec clean_all = function
- [] -> tclIDTAC
- | id :: rest -> tclTHEN (clean_id id) (clean_all rest)
- in
- clean_all (tmp_ids gls) gls
-
-let assert_postpone id t =
- assert_before (Name id) t
-
-(* start a proof *)
-
-
-let start_proof_tac gls=
- let info={pm_stack=[]} in
- tcl_change_info info gls
-
-let go_to_proof_mode () =
- ignore (Pfedit.by (Proofview.V82.tactic start_proof_tac));
- let p = Proof_global.give_me_the_proof () in
- Decl_mode.focus p
-
-(* closing gaps *)
-
-(* spiwack: should use [Proofview.give_up] but that would require
- moving the whole declarative mode into the new proof engine. It
- will eventually have to be done.
-
- As far as I can tell, [daimon_tac] is used after a [thus thesis],
- it will leave uninstantiated variables instead of giving a relevant
- message at [Qed]. *)
-let daimon_tac gls =
- set_daimon_flag ();
- {it=[];sigma=sig_sig gls;}
-
-let daimon_instr env p =
- let (p,(status,_)) =
- Proof.run_tactic env begin
- Proofview.tclINDEPENDENT Proofview.give_up
- end p
- in
- p,status
-
-let do_daimon () =
- let env = Global.env () in
- let status =
- Proof_global.with_current_proof begin fun _ p ->
- daimon_instr env p
- end
- in
- if not status then Feedback.feedback Feedback.AddedAxiom else ()
-
-(* post-instruction focus management *)
-
-let goto_current_focus () =
- Decl_mode.unfocus ()
-
-(* spiwack: used to catch errors indicating lack of "focusing command"
- in the proof tree. In the current implementation, however, entering
- the declarative mode puts a focus first, there should, therefore,
- never be exception raised here. *)
-let goto_current_focus_or_top () =
- goto_current_focus ()
-
-(* return *)
-
-let close_tactic_mode () =
- try do_daimon ();goto_current_focus ()
- with Not_found ->
- error "\"return\" cannot be used outside of Declarative Proof Mode."
-
-let return_from_tactic_mode () =
- close_tactic_mode ()
-
-(* end proof/claim *)
-
-let close_block bt pts =
- if Proof.no_focused_goal pts then
- goto_current_focus ()
- else
- let stack =
- if Proof.is_done pts then
- get_top_stack pts
- else
- get_stack pts
- in
- match bt,stack with
- B_claim, Claim::_ | B_focus, Focus_claim::_ | B_proof, [] ->
- do_daimon ();goto_current_focus ()
- | _, Claim::_ ->
- error "\"end claim\" expected."
- | _, Focus_claim::_ ->
- error "\"end focus\" expected."
- | _, [] ->
- error "\"end proof\" expected."
- | _, (Per (et,_,_,_)::_|Suppose_case::Per (et,_,_,_)::_) ->
- begin
- match et with
- ET_Case_analysis -> error "\"end cases\" expected."
- | ET_Induction -> error "\"end induction\" expected."
- end
- | _,_ -> anomaly (Pp.str "Lonely suppose on stack.")
-
-
-(* utility for suppose / suppose it is *)
-
-let close_previous_case pts =
- if
- Proof.is_done pts
- then
- match get_top_stack pts with
- Per (et,_,_,_) :: _ -> anomaly (Pp.str "Weird case occurred ...")
- | Suppose_case :: Per (et,_,_,_) :: _ ->
- goto_current_focus ()
- | _ -> error "Not inside a proof per cases or induction."
- else
- match get_stack pts with
- Per (et,_,_,_) :: _ -> ()
- | Suppose_case :: Per (et,_,_,_) :: _ ->
- do_daimon ();goto_current_focus ()
- | _ -> error "Not inside a proof per cases or induction."
-
-(* Proof instructions *)
-
-(* automation *)
-
-let filter_hyps f gls =
- let filter_aux id =
- let id = NamedDecl.get_id id in
- if f id then
- tclIDTAC
- else
- tclTRY (clear [id]) in
- tclMAP filter_aux (pf_hyps gls) gls
-
-let local_hyp_prefix = Id.of_string "___"
-
-let add_justification_hyps keep items gls =
- let add_aux c gls=
- match kind_of_term c with
- Var id ->
- keep:=Id.Set.add id !keep;
- tclIDTAC gls
- | _ ->
- let id=pf_get_new_id local_hyp_prefix gls in
- keep:=Id.Set.add id !keep;
- tclTHEN (Proofview.V82.of_tactic (letin_tac None (Names.Name id) c None Locusops.nowhere))
- (Proofview.V82.of_tactic (clear_body [id])) gls in
- tclMAP add_aux items gls
-
-let prepare_goal items gls =
- let tokeep = ref Id.Set.empty in
- let auxres = add_justification_hyps tokeep items gls in
- tclTHENLIST
- [ (fun _ -> auxres);
- filter_hyps (let keep = !tokeep in fun id -> Id.Set.mem id keep)] gls
-
-let my_automation_tac = ref
- (Proofview.tclZERO (CErrors.make_anomaly (Pp.str"No automation registered")))
-
-let register_automation_tac tac = my_automation_tac:= tac
-
-let automation_tac = Proofview.tclBIND (Proofview.tclUNIT ()) (fun () -> !my_automation_tac)
-
-let warn_insufficient_justification =
- CWarnings.create ~name:"declmode-insufficient-justification" ~category:"declmode"
- (fun () -> strbrk "Insufficient justification.")
-
-let justification tac gls=
- tclORELSE
- (tclSOLVE [tclTHEN tac (Proofview.V82.of_tactic assumption)])
- (fun gls ->
- if get_strictness () then
- error "Insufficient justification."
- else
- begin
- warn_insufficient_justification ();
- daimon_tac gls
- end) gls
-
-let default_justification elems gls=
- justification (tclTHEN (prepare_goal elems) (Proofview.V82.of_tactic automation_tac)) gls
-
-(* code for conclusion refining *)
-
-let constant dir s = lazy (Coqlib.gen_constant "Declarative" dir s)
-
-let _and = constant ["Init";"Logic"] "and"
-
-let _and_rect = constant ["Init";"Logic"] "and_rect"
-
-let _prod = constant ["Init";"Datatypes"] "prod"
-
-let _prod_rect = constant ["Init";"Datatypes"] "prod_rect"
-
-let _ex = constant ["Init";"Logic"] "ex"
-
-let _ex_ind = constant ["Init";"Logic"] "ex_ind"
-
-let _sig = constant ["Init";"Specif"] "sig"
-
-let _sig_rect = constant ["Init";"Specif"] "sig_rect"
-
-let _sigT = constant ["Init";"Specif"] "sigT"
-
-let _sigT_rect = constant ["Init";"Specif"] "sigT_rect"
-
-type stackd_elt =
-{se_meta:metavariable;
- se_type:types;
- se_last_meta:metavariable;
- se_meta_list:(metavariable*types) list;
- se_evd: evar_map}
-
-let rec replace_in_list m l = function
- [] -> raise Not_found
- | c::q -> if Int.equal m (fst c) then l@q else c::replace_in_list m l q
-
-let enstack_subsubgoals env se stack gls=
- let hd,params = decompose_app (special_whd gls se.se_type) in
- match kind_of_term hd with
- Ind (ind,u as indu) when is_good_inductive env ind -> (* MS: FIXME *)
- let mib,oib=
- Inductive.lookup_mind_specif env ind in
- let gentypes=
- Inductive.arities_of_constructors indu (mib,oib) in
- let process i gentyp =
- let constructor = mkConstructU ((ind,succ i),u)
- (* constructors numbering*) in
- let appterm = applist (constructor,params) in
- let apptype = prod_applist gentyp params in
- let rc,_ = Reduction.dest_prod env apptype in
- let rec meta_aux last lenv = function
- [] -> (last,lenv,[])
- | decl::q ->
- let nlast=succ last in
- let (llast,holes,metas) =
- meta_aux nlast (mkMeta nlast :: lenv) q in
- (llast,holes,(nlast,special_nf gls (substl lenv (RelDecl.get_type decl)))::metas) in
- let (nlast,holes,nmetas) =
- meta_aux se.se_last_meta [] (List.rev rc) in
- let refiner = applist (appterm,List.rev holes) in
- let evd = meta_assign se.se_meta
- (refiner,(Conv,TypeProcessed (* ? *))) se.se_evd in
- let ncreated = replace_in_list
- se.se_meta nmetas se.se_meta_list in
- let evd0 = List.fold_left
- (fun evd (m,typ) -> meta_declare m typ evd) evd nmetas in
- List.iter (fun (m,typ) ->
- Stack.push
- {se_meta=m;
- se_type=typ;
- se_evd=evd0;
- se_meta_list=ncreated;
- se_last_meta=nlast} stack) (List.rev nmetas)
- in
- Array.iteri process gentypes
- | _ -> ()
-
-let rec nf_list evd =
- function
- [] -> []
- | (m,typ)::others ->
- if meta_defined evd m then
- nf_list evd others
- else
- (m,Reductionops.nf_meta evd typ)::nf_list evd others
-
-let find_subsubgoal c ctyp skip submetas gls =
- let env= pf_env gls in
- let concl = pf_concl gls in
- let evd = mk_evd ((0,concl)::submetas) gls in
- let stack = Stack.create () in
- let max_meta =
- List.fold_left (fun a (m,_) -> max a m) 0 submetas in
- let _ = Stack.push
- {se_meta=0;
- se_type=concl;
- se_last_meta=max_meta;
- se_meta_list=[0,concl];
- se_evd=evd} stack in
- let rec dfs n =
- let se = Stack.pop stack in
- try
- let unifier =
- Unification.w_unify env se.se_evd Reduction.CUMUL
- ~flags:(Unification.elim_flags ()) ctyp se.se_type in
- if n <= 0 then
- {se with
- se_evd=meta_assign se.se_meta
- (c,(Conv,TypeNotProcessed (* ?? *))) unifier;
- se_meta_list=replace_in_list
- se.se_meta submetas se.se_meta_list}
- else
- dfs (pred n)
- with e when CErrors.noncritical e ->
- begin
- enstack_subsubgoals env se stack gls;
- dfs n
- end in
- let nse= try dfs skip with Stack.Empty -> raise Not_found in
- nf_list nse.se_evd nse.se_meta_list,Reductionops.nf_meta nse.se_evd (mkMeta 0)
-
-let concl_refiner metas body gls =
- let concl = pf_concl gls in
- let evd = sig_sig gls in
- let env = pf_env gls in
- let sort = family_of_sort (Typing.e_sort_of env (ref evd) concl) in
- let rec aux env avoid subst = function
- [] -> anomaly ~label:"concl_refiner" (Pp.str "cannot happen")
- | (n,typ)::rest ->
- let _A = subst_meta subst typ in
- let x = id_of_name_using_hdchar env _A Anonymous in
- let _x = fresh_id avoid x gls in
- let nenv = Environ.push_named (LocalAssum (_x,_A)) env in
- let asort = family_of_sort (Typing.e_sort_of nenv (ref evd) _A) in
- let nsubst = (n,mkVar _x)::subst in
- if List.is_empty rest then
- asort,_A,mkNamedLambda _x _A (subst_meta nsubst body)
- else
- let bsort,_B,nbody =
- aux nenv (_x::avoid) ((n,mkVar _x)::subst) rest in
- let body = mkNamedLambda _x _A nbody in
- if occur_term (mkVar _x) _B then
- begin
- let _P = mkNamedLambda _x _A _B in
- match bsort,sort with
- InProp,InProp ->
- let _AxB = mkApp(Lazy.force _ex,[|_A;_P|]) in
- InProp,_AxB,
- mkApp(Lazy.force _ex_ind,[|_A;_P;concl;body|])
- | InProp,_ ->
- let _AxB = mkApp(Lazy.force _sig,[|_A;_P|]) in
- let _P0 = mkLambda(Anonymous,_AxB,concl) in
- InType,_AxB,
- mkApp(Lazy.force _sig_rect,[|_A;_P;_P0;body|])
- | _,_ ->
- let _AxB = mkApp(Lazy.force _sigT,[|_A;_P|]) in
- let _P0 = mkLambda(Anonymous,_AxB,concl) in
- InType,_AxB,
- mkApp(Lazy.force _sigT_rect,[|_A;_P;_P0;body|])
- end
- else
- begin
- match asort,bsort with
- InProp,InProp ->
- let _AxB = mkApp(Lazy.force _and,[|_A;_B|]) in
- InProp,_AxB,
- mkApp(Lazy.force _and_rect,[|_A;_B;concl;body|])
- |_,_ ->
- let _AxB = mkApp(Lazy.force _prod,[|_A;_B|]) in
- let _P0 = mkLambda(Anonymous,_AxB,concl) in
- InType,_AxB,
- mkApp(Lazy.force _prod_rect,[|_A;_B;_P0;body|])
- end
- in
- let (_,_,prf) = aux env [] [] metas in
- mkApp(prf,[|mkMeta 1|])
-
-let thus_tac c ctyp submetas gls =
- let list,proof =
- try
- find_subsubgoal c ctyp 0 submetas gls
- with Not_found ->
- error "I could not relate this statement to the thesis." in
- if List.is_empty list then
- Proofview.V82.of_tactic (exact_check proof) gls
- else
- let refiner = concl_refiner list proof gls in
- Tacmach.refine refiner gls
-
-(* general forward step *)
-
-let mk_stat_or_thesis info gls = function
- This c -> c
- | Thesis (For _ ) ->
- error "\"thesis for ...\" is not applicable here."
- | Thesis Plain -> pf_concl gls
-
-let just_tac _then cut info gls0 =
- let last_item =
- if _then then
- try [mkVar (get_last (pf_env gls0))]
- with UserError _ ->
- error "\"then\" and \"hence\" require at least one previous fact"
- else []
- in
- let items_tac gls =
- match cut.cut_by with
- None -> tclIDTAC gls
- | Some items -> prepare_goal (last_item@items) gls in
- let method_tac gls =
- match cut.cut_using with
- None ->
- Proofview.V82.of_tactic automation_tac gls
- | Some tac ->
- Proofview.V82.of_tactic (Tacinterp.tactic_of_value (Tacinterp.default_ist ()) tac) gls in
- justification (tclTHEN items_tac method_tac) gls0
-
-let instr_cut mkstat _thus _then cut gls0 =
- let info = get_its_info gls0 in
- let stat = cut.cut_stat in
- let (c_id,_) = match stat.st_label with
- Anonymous ->
- pf_get_new_id (Id.of_string "_fact") gls0,false
- | Name id -> id,true in
- let c_stat = mkstat info gls0 stat.st_it in
- let thus_tac gls=
- if _thus then
- thus_tac (mkVar c_id) c_stat [] gls
- else tclIDTAC gls in
- tclTHENS (Proofview.V82.of_tactic (assert_postpone c_id c_stat))
- [tclTHEN tcl_erase_info (just_tac _then cut info);
- thus_tac] gls0
-
-
-(* iterated equality *)
-let _eq = lazy (Universes.constr_of_global (Coqlib.glob_eq))
-
-let decompose_eq id gls =
- let typ = pf_get_hyp_typ gls id in
- let whd = (special_whd gls typ) in
- match kind_of_term whd with
- App (f,args)->
- if eq_constr f (Lazy.force _eq) && Int.equal (Array.length args) 3
- then (args.(0),
- args.(1),
- args.(2))
- else error "Previous step is not an equality."
- | _ -> error "Previous step is not an equality."
-
-let instr_rew _thus rew_side cut gls0 =
- let last_id =
- try get_last (pf_env gls0)
- with UserError _ -> error "No previous equality."
- in
- let typ,lhs,rhs = decompose_eq last_id gls0 in
- let items_tac gls =
- match cut.cut_by with
- None -> tclIDTAC gls
- | Some items -> prepare_goal items gls in
- let method_tac gls =
- match cut.cut_using with
- None ->
- Proofview.V82.of_tactic automation_tac gls
- | Some tac ->
- Proofview.V82.of_tactic (Tacinterp.tactic_of_value (Tacinterp.default_ist ()) tac) gls in
- let just_tac gls =
- justification (tclTHEN items_tac method_tac) gls in
- let (c_id,_) = match cut.cut_stat.st_label with
- Anonymous ->
- pf_get_new_id (Id.of_string "_eq") gls0,false
- | Name id -> id,true in
- let thus_tac new_eq gls=
- if _thus then
- thus_tac (mkVar c_id) new_eq [] gls
- else tclIDTAC gls in
- match rew_side with
- Lhs ->
- let new_eq = mkApp(Lazy.force _eq,[|typ;cut.cut_stat.st_it;rhs|]) in
- tclTHENS (Proofview.V82.of_tactic (assert_postpone c_id new_eq))
- [tclTHEN tcl_erase_info
- (tclTHENS (Proofview.V82.of_tactic (transitivity lhs))
- [just_tac;Proofview.V82.of_tactic (exact_check (mkVar last_id))]);
- thus_tac new_eq] gls0
- | Rhs ->
- let new_eq = mkApp(Lazy.force _eq,[|typ;lhs;cut.cut_stat.st_it|]) in
- tclTHENS (Proofview.V82.of_tactic (assert_postpone c_id new_eq))
- [tclTHEN tcl_erase_info
- (tclTHENS (Proofview.V82.of_tactic (transitivity rhs))
- [Proofview.V82.of_tactic (exact_check (mkVar last_id));just_tac]);
- thus_tac new_eq] gls0
-
-
-(* tactics for claim/focus *)
-
-let instr_claim _thus st gls0 =
- let info = get_its_info gls0 in
- let (id,_) = match st.st_label with
- Anonymous -> pf_get_new_id (Id.of_string "_claim") gls0,false
- | Name id -> id,true in
- let thus_tac gls=
- if _thus then
- thus_tac (mkVar id) st.st_it [] gls
- else tclIDTAC gls in
- let ninfo1 = {pm_stack=
- (if _thus then Focus_claim else Claim)::info.pm_stack} in
- tclTHENS (Proofview.V82.of_tactic (assert_postpone id st.st_it))
- [thus_tac;
- tcl_change_info ninfo1] gls0
-
-(* tactics for assume *)
-
-let push_intro_tac coerce nam gls =
- let (hid,_) =
- match nam with
- Anonymous -> pf_get_new_id (Id.of_string "_hyp") gls,false
- | Name id -> id,true in
- tclTHENLIST
- [Proofview.V82.of_tactic (intro_mustbe_force hid);
- coerce hid]
- gls
-
-let assume_tac hyps gls =
- List.fold_right
- (fun (Hvar st | Hprop st) ->
- tclTHEN
- (push_intro_tac
- (fun id ->
- Proofview.V82.of_tactic (convert_hyp (LocalAssum (id,st.st_it)))) st.st_label))
- hyps tclIDTAC gls
-
-let assume_hyps_or_theses hyps gls =
- List.fold_right
- (function
- (Hvar {st_label=nam;st_it=c} | Hprop {st_label=nam;st_it=This c}) ->
- tclTHEN
- (push_intro_tac
- (fun id ->
- Proofview.V82.of_tactic (convert_hyp (LocalAssum (id,c)))) nam)
- | Hprop {st_label=nam;st_it=Thesis (tk)} ->
- tclTHEN
- (push_intro_tac
- (fun id -> tclIDTAC) nam))
- hyps tclIDTAC gls
-
-let assume_st hyps gls =
- List.fold_right
- (fun st ->
- tclTHEN
- (push_intro_tac
- (fun id -> Proofview.V82.of_tactic (convert_hyp (LocalAssum (id,st.st_it)))) st.st_label))
- hyps tclIDTAC gls
-
-let assume_st_letin hyps gls =
- List.fold_right
- (fun st ->
- tclTHEN
- (push_intro_tac
- (fun id ->
- Proofview.V82.of_tactic (convert_hyp (LocalDef (id, fst st.st_it, snd st.st_it)))) st.st_label))
- hyps tclIDTAC gls
-
-(* suffices *)
-
-let rec metas_from n hyps =
- match hyps with
- _ :: q -> n :: metas_from (succ n) q
- | [] -> []
-
-let rec build_product args body =
- match args with
- (Hprop st| Hvar st )::rest ->
- let pprod= lift 1 (build_product rest body) in
- let lbody =
- match st.st_label with
- Anonymous -> pprod
- | Name id -> subst_term (mkVar id) pprod in
- mkProd (st.st_label, st.st_it, lbody)
- | [] -> body
-
-let rec build_applist prod = function
- [] -> [],prod
- | n::q ->
- let (_,typ,_) = destProd prod in
- let ctx,head = build_applist (prod_applist prod [mkMeta n]) q in
- (n,typ)::ctx,head
-
-let instr_suffices _then cut gls0 =
- let info = get_its_info gls0 in
- let c_id = pf_get_new_id (Id.of_string "_cofact") gls0 in
- let ctx,hd = cut.cut_stat in
- let c_stat = build_product ctx (mk_stat_or_thesis info gls0 hd) in
- let metas = metas_from 1 ctx in
- let c_ctx,c_head = build_applist c_stat metas in
- let c_term = applist (mkVar c_id,List.map mkMeta metas) in
- let thus_tac gls=
- thus_tac c_term c_head c_ctx gls in
- tclTHENS (Proofview.V82.of_tactic (assert_postpone c_id c_stat))
- [tclTHENLIST
- [ assume_tac ctx;
- tcl_erase_info;
- just_tac _then cut info];
- thus_tac] gls0
-
-(* tactics for consider/given *)
-
-let conjunction_arity id gls =
- let typ = pf_get_hyp_typ gls id in
- let hd,params = decompose_app (special_whd gls typ) in
- let env =pf_env gls in
- match kind_of_term hd with
- Ind (ind,u as indu) when is_good_inductive env ind ->
- let mib,oib=
- Inductive.lookup_mind_specif env ind in
- let gentypes=
- Inductive.arities_of_constructors indu (mib,oib) in
- let _ = if not (Int.equal (Array.length gentypes) 1) then raise Not_found in
- let apptype = prod_applist gentypes.(0) params in
- let rc,_ = Reduction.dest_prod env apptype in
- List.length rc
- | _ -> raise Not_found
-
-let rec intron_then n ids ltac gls =
- if n<=0 then
- ltac ids gls
- else
- let id = pf_get_new_id (Id.of_string "_tmp") gls in
- tclTHEN
- (Proofview.V82.of_tactic (intro_mustbe_force id))
- (intron_then (pred n) (id::ids) ltac) gls
-
-
-let rec consider_match may_intro introduced available expected gls =
- match available,expected with
- [],[] ->
- tclIDTAC gls
- | _,[] -> error "Last statements do not match a complete hypothesis."
- (* should tell which ones *)
- | [],hyps ->
- if may_intro then
- begin
- let id = pf_get_new_id (Id.of_string "_tmp") gls in
- tclIFTHENELSE
- (Proofview.V82.of_tactic (intro_mustbe_force id))
- (consider_match true [] [id] hyps)
- (fun _ ->
- error "Not enough sub-hypotheses to match statements.")
- gls
- end
- else
- error "Not enough sub-hypotheses to match statements."
- (* should tell which ones *)
- | id::rest_ids,(Hvar st | Hprop st)::rest ->
- tclIFTHENELSE (Proofview.V82.of_tactic (convert_hyp (LocalAssum (id,st.st_it))))
- begin
- match st.st_label with
- Anonymous ->
- consider_match may_intro ((id,false)::introduced) rest_ids rest
- | Name hid ->
- tclTHENLIST
- [Proofview.V82.of_tactic (rename_hyp [id,hid]);
- consider_match may_intro ((hid,true)::introduced) rest_ids rest]
- end
- begin
- (fun gls ->
- let nhyps =
- try conjunction_arity id gls with
- Not_found -> error "Matching hypothesis not found." in
- tclTHENLIST
- [Proofview.V82.of_tactic (simplest_case (mkVar id));
- intron_then nhyps []
- (fun l -> consider_match may_intro introduced
- (List.rev_append l rest_ids) expected)] gls)
- end
- gls
-
-let consider_tac c hyps gls =
- match kind_of_term (strip_outer_cast c) with
- Var id ->
- consider_match false [] [id] hyps gls
- | _ ->
- let id = pf_get_new_id (Id.of_string "_tmp") gls in
- tclTHEN
- (Proofview.V82.of_tactic (pose_proof (Name id) c))
- (consider_match false [] [id] hyps) gls
-
-
-let given_tac hyps gls =
- consider_match true [] [] hyps gls
-
-(* tactics for take *)
-
-let rec take_tac wits gls =
- match wits with
- [] -> tclIDTAC gls
- | wit::rest ->
- let typ = pf_unsafe_type_of gls wit in
- tclTHEN (thus_tac wit typ []) (take_tac rest) gls
-
-
-(* tactics for define *)
-
-let rec build_function args body =
- match args with
- st::rest ->
- let pfun= lift 1 (build_function rest body) in
- let id = match st.st_label with
- Anonymous -> assert false
- | Name id -> id in
- mkLambda (Name id, st.st_it, subst_term (mkVar id) pfun)
- | [] -> body
-
-let define_tac id args body gls =
- let t = build_function args body in
- Proofview.V82.of_tactic (letin_tac None (Name id) t None Locusops.nowhere) gls
-
-(* tactics for reconsider *)
-
-let cast_tac id_or_thesis typ gls =
- match id_or_thesis with
- | This id ->
- Proofview.V82.of_tactic (id |> pf_get_hyp gls |> NamedDecl.set_id id |> NamedDecl.set_type typ |> convert_hyp) gls
- | Thesis (For _ ) ->
- error "\"thesis for ...\" is not applicable here."
- | Thesis Plain ->
- Proofview.V82.of_tactic (convert_concl typ DEFAULTcast) gls
-
-(* per cases *)
-
-let is_rec_pos (main_ind,wft) =
- match main_ind with
- None -> false
- | Some index ->
- match fst (Rtree.dest_node wft) with
- Mrec (_,i) when Int.equal i index -> true
- | _ -> false
-
-let rec constr_trees (main_ind,wft) ind =
- match Rtree.dest_node wft with
- Norec,_ ->
- let itree =
- (snd (Global.lookup_inductive ind)).mind_recargs in
- constr_trees (None,itree) ind
- | _,constrs -> main_ind,constrs
-
-let ind_args rp ind =
- let main_ind,constrs = constr_trees rp ind in
- let args ctree =
- Array.map (fun t -> main_ind,t) (snd (Rtree.dest_node ctree)) in
- Array.map args constrs
-
-let init_tree ids ind rp nexti =
- let indargs = ind_args rp ind in
- let do_i i arp = (Array.map is_rec_pos arp),nexti i arp in
- Split_patt (ids,ind,Array.mapi do_i indargs)
-
-let map_tree_rp rp id_fun mapi = function
- Split_patt (ids,ind,branches) ->
- let indargs = ind_args rp ind in
- let do_i i (recargs,bri) = recargs,mapi i indargs.(i) bri in
- Split_patt (id_fun ids,ind,Array.mapi do_i branches)
- | _ -> failwith "map_tree_rp: not a splitting node"
-
-let map_tree id_fun mapi = function
- Split_patt (ids,ind,branches) ->
- let do_i i (recargs,bri) = recargs,mapi i bri in
- Split_patt (id_fun ids,ind,Array.mapi do_i branches)
- | _ -> failwith "map_tree: not a splitting node"
-
-
-let start_tree env ind rp =
- init_tree Id.Set.empty ind rp (fun _ _ -> None)
-
-let build_per_info etype casee gls =
- let concl=pf_concl gls in
- let env=pf_env gls in
- let ctyp=pf_unsafe_type_of gls casee in
- let is_dep = dependent casee concl in
- let hd,args = decompose_app (special_whd gls ctyp) in
- let (ind,u) =
- try
- destInd hd
- with DestKO ->
- error "Case analysis must be done on an inductive object." in
- let mind,oind = Global.lookup_inductive ind in
- let nparams,index =
- match etype with
- ET_Induction -> mind.mind_nparams_rec,Some (snd ind)
- | _ -> mind.mind_nparams,None in
- let params,real_args = List.chop nparams args in
- let abstract_obj c body =
- let typ=pf_unsafe_type_of gls c in
- lambda_create env (typ,subst_term c body) in
- let pred= List.fold_right abstract_obj
- real_args (lambda_create env (ctyp,subst_term casee concl)) in
- is_dep,
- {per_casee=casee;
- per_ctype=ctyp;
- per_ind=ind;
- per_pred=pred;
- per_args=real_args;
- per_params=params;
- per_nparams=nparams;
- per_wf=index,oind.mind_recargs}
-
-let per_tac etype casee gls=
- let env=pf_env gls in
- let info = get_its_info gls in
- match casee with
- Real c ->
- let is_dep,per_info = build_per_info etype c gls in
- let ek =
- if is_dep then
- EK_dep (start_tree env per_info.per_ind per_info.per_wf)
- else EK_unknown in
- tcl_change_info
- {pm_stack=
- Per(etype,per_info,ek,[])::info.pm_stack} gls
- | Virtual cut ->
- assert (cut.cut_stat.st_label == Anonymous);
- let id = pf_get_new_id (Id.of_string "anonymous_matched") gls in
- let c = mkVar id in
- let modified_cut =
- {cut with cut_stat={cut.cut_stat with st_label=Name id}} in
- tclTHEN
- (instr_cut (fun _ _ c -> c) false false modified_cut)
- (fun gls0 ->
- let is_dep,per_info = build_per_info etype c gls0 in
- assert (not is_dep);
- tcl_change_info
- {pm_stack=
- Per(etype,per_info,EK_unknown,[])::info.pm_stack} gls0)
- gls
-
-(* suppose *)
-
-let register_nodep_subcase id= function
- Per(et,pi,ek,clauses)::s ->
- begin
- match ek with
- EK_unknown -> clauses,Per(et,pi,EK_nodep,id::clauses)::s
- | EK_nodep -> clauses,Per(et,pi,EK_nodep,id::clauses)::s
- | EK_dep _ -> error "Do not mix \"suppose\" with \"suppose it is\"."
- end
- | _ -> anomaly (Pp.str "wrong stack state")
-
-let suppose_tac hyps gls0 =
- let info = get_its_info gls0 in
- let thesis = pf_concl gls0 in
- let id = pf_get_new_id (Id.of_string "subcase_") gls0 in
- let clause = build_product hyps thesis in
- let ninfo1 = {pm_stack=Suppose_case::info.pm_stack} in
- let old_clauses,stack = register_nodep_subcase id info.pm_stack in
- let ninfo2 = {pm_stack=stack} in
- tclTHENS (Proofview.V82.of_tactic (assert_postpone id clause))
- [tclTHENLIST [tcl_change_info ninfo1;
- assume_tac hyps;
- clear old_clauses];
- tcl_change_info ninfo2] gls0
-
-(* suppose it is ... *)
-
-(* pattern matching compiling *)
-
-let rec skip_args rest ids n =
- if n <= 0 then
- Close_patt rest
- else
- Skip_patt (ids,skip_args rest ids (pred n))
-
-let rec tree_of_pats ((id,_) as cpl) pats =
- match pats with
- [] -> End_patt cpl
- | args::stack ->
- match args with
- [] -> Close_patt (tree_of_pats cpl stack)
- | (patt,rp) :: rest_args ->
- match patt with
- PatVar (_,v) ->
- Skip_patt (Id.Set.singleton id,
- tree_of_pats cpl (rest_args::stack))
- | PatCstr (_,(ind,cnum),args,nam) ->
- let nexti i ati =
- if Int.equal i (pred cnum) then
- let nargs =
- List.map_i (fun j a -> (a,ati.(j))) 0 args in
- Some (Id.Set.singleton id,
- tree_of_pats cpl (nargs::rest_args::stack))
- else None
- in init_tree Id.Set.empty ind rp nexti
-
-let rec add_branch ((id,_) as cpl) pats tree=
- match pats with
- [] ->
- begin
- match tree with
- End_patt cpl0 -> End_patt cpl0
- (* this ensures precedence for overlapping patterns *)
- | _ -> anomaly (Pp.str "tree is expected to end here")
- end
- | args::stack ->
- match args with
- [] ->
- begin
- match tree with
- Close_patt t ->
- Close_patt (add_branch cpl stack t)
- | _ -> anomaly (Pp.str "we should pop here")
- end
- | (patt,rp) :: rest_args ->
- match patt with
- PatVar (_,v) ->
- begin
- match tree with
- Skip_patt (ids,t) ->
- Skip_patt (Id.Set.add id ids,
- add_branch cpl (rest_args::stack) t)
- | Split_patt (_,_,_) ->
- map_tree (Id.Set.add id)
- (fun i bri ->
- append_branch cpl 1 (rest_args::stack) bri)
- tree
- | _ -> anomaly (Pp.str "No pop/stop expected here")
- end
- | PatCstr (_,(ind,cnum),args,nam) ->
- match tree with
- Skip_patt (ids,t) ->
- let nexti i ati =
- if Int.equal i (pred cnum) then
- let nargs =
- List.map_i (fun j a -> (a,ati.(j))) 0 args in
- Some (Id.Set.add id ids,
- add_branch cpl (nargs::rest_args::stack)
- (skip_args t ids (Array.length ati)))
- else
- Some (ids,
- skip_args t ids (Array.length ati))
- in init_tree ids ind rp nexti
- | Split_patt (_,ind0,_) ->
- if (not (eq_ind ind ind0)) then error
- (* this can happen with coercions *)
- "Case pattern belongs to wrong inductive type.";
- let mapi i ati bri =
- if Int.equal i (pred cnum) then
- let nargs =
- List.map_i (fun j a -> (a,ati.(j))) 0 args in
- append_branch cpl 0
- (nargs::rest_args::stack) bri
- else bri in
- map_tree_rp rp (fun ids -> ids) mapi tree
- | _ -> anomaly (Pp.str "No pop/stop expected here")
-and append_branch ((id,_) as cpl) depth pats = function
- Some (ids,tree) ->
- Some (Id.Set.add id ids,append_tree cpl depth pats tree)
- | None ->
- Some (Id.Set.singleton id,tree_of_pats cpl pats)
-and append_tree ((id,_) as cpl) depth pats tree =
- if depth<=0 then add_branch cpl pats tree
- else match tree with
- Close_patt t ->
- Close_patt (append_tree cpl (pred depth) pats t)
- | Skip_patt (ids,t) ->
- Skip_patt (Id.Set.add id ids,append_tree cpl depth pats t)
- | End_patt _ -> anomaly (Pp.str "Premature end of branch")
- | Split_patt (_,_,_) ->
- map_tree (Id.Set.add id)
- (fun i bri -> append_branch cpl (succ depth) pats bri) tree
-
-(* suppose it is *)
-
-let rec st_assoc id = function
- [] -> raise Not_found
- | st::_ when Name.equal st.st_label id -> st.st_it
- | _ :: rest -> st_assoc id rest
-
-let thesis_for obj typ per_info env=
- let rc,hd1=decompose_prod typ in
- let cind,all_args=decompose_app typ in
- let ind,u = destInd cind in
- let _ = if not (eq_ind ind per_info.per_ind) then
- user_err ~hdr:"thesis_for"
- ((Printer.pr_constr_env env Evd.empty obj) ++ spc () ++
- str"cannot give an induction hypothesis (wrong inductive type).") in
- let params,args = List.chop per_info.per_nparams all_args in
- let _ = if not (List.for_all2 eq_constr params per_info.per_params) then
- user_err ~hdr:"thesis_for"
- ((Printer.pr_constr_env env Evd.empty obj) ++ spc () ++
- str "cannot give an induction hypothesis (wrong parameters).") in
- let hd2 = (applist ((lift (List.length rc) per_info.per_pred),args@[obj])) in
- compose_prod rc (Reductionops.whd_beta Evd.empty hd2)
-
-let rec build_product_dep pat_info per_info args body gls =
- match args with
- (Hprop {st_label=nam;st_it=This c}
- | Hvar {st_label=nam;st_it=c})::rest ->
- let pprod=
- lift 1 (build_product_dep pat_info per_info rest body gls) in
- let lbody =
- match nam with
- Anonymous -> body
- | Name id -> subst_var id pprod in
- mkProd (nam,c,lbody)
- | Hprop ({st_it=Thesis tk} as st)::rest ->
- let pprod=
- lift 1 (build_product_dep pat_info per_info rest body gls) in
- let lbody =
- match st.st_label with
- Anonymous -> body
- | Name id -> subst_var id pprod in
- let ptyp =
- match tk with
- For id ->
- let obj = mkVar id in
- let typ =
- try st_assoc (Name id) pat_info.pat_vars
- with Not_found ->
- snd (st_assoc (Name id) pat_info.pat_aliases) in
- thesis_for obj typ per_info (pf_env gls)
- | Plain -> pf_concl gls in
- mkProd (st.st_label,ptyp,lbody)
- | [] -> body
-
-let build_dep_clause params pat_info per_info hyps gls =
- let concl=
- thesis_for pat_info.pat_constr pat_info.pat_typ per_info (pf_env gls) in
- let open_clause =
- build_product_dep pat_info per_info hyps concl gls in
- let prod_one st body =
- match st.st_label with
- Anonymous -> mkProd(Anonymous,st.st_it,lift 1 body)
- | Name id -> mkNamedProd id st.st_it (lift 1 body) in
- let let_one_in st body =
- match st.st_label with
- Anonymous -> mkLetIn(Anonymous,fst st.st_it,snd st.st_it,lift 1 body)
- | Name id ->
- mkNamedLetIn id (fst st.st_it) (snd st.st_it) (lift 1 body) in
- let aliased_clause =
- List.fold_right let_one_in pat_info.pat_aliases open_clause in
- List.fold_right prod_one (params@pat_info.pat_vars) aliased_clause
-
-let rec register_dep_subcase id env per_info pat = function
- EK_nodep -> error "Only \"suppose it is\" can be used here."
- | EK_unknown ->
- register_dep_subcase id env per_info pat
- (EK_dep (start_tree env per_info.per_ind per_info.per_wf))
- | EK_dep tree -> EK_dep (add_branch id [[pat,per_info.per_wf]] tree)
-
-let case_tac params pat_info hyps gls0 =
- let info = get_its_info gls0 in
- let id = pf_get_new_id (Id.of_string "subcase_") gls0 in
- let et,per_info,ek,old_clauses,rest =
- match info.pm_stack with
- Per (et,pi,ek,old_clauses)::rest -> (et,pi,ek,old_clauses,rest)
- | _ -> anomaly (Pp.str "wrong place for cases") in
- let clause = build_dep_clause params pat_info per_info hyps gls0 in
- let ninfo1 = {pm_stack=Suppose_case::info.pm_stack} in
- let nek =
- register_dep_subcase (id,(List.length params,List.length hyps))
- (pf_env gls0) per_info pat_info.pat_pat ek in
- let ninfo2 = {pm_stack=Per(et,per_info,nek,id::old_clauses)::rest} in
- tclTHENS (Proofview.V82.of_tactic (assert_postpone id clause))
- [tclTHENLIST
- [tcl_change_info ninfo1;
- assume_st (params@pat_info.pat_vars);
- assume_st_letin pat_info.pat_aliases;
- assume_hyps_or_theses hyps;
- clear old_clauses];
- tcl_change_info ninfo2] gls0
-
-(* end cases *)
-
-type ('a, 'b) instance_stack =
- ('b * (('a option * constr list) list)) list
-
-let initial_instance_stack ids : (_, _) instance_stack =
- List.map (fun id -> id,[None,[]]) ids
-
-let push_one_arg arg = function
- [] -> anomaly (Pp.str "impossible")
- | (head,args) :: ctx ->
- ((head,(arg::args)) :: ctx)
-
-let push_arg arg stacks =
- List.map (fun (id,stack) -> (id,push_one_arg arg stack)) stacks
-
-
-let push_one_head c ids (id,stack) =
- let head = if Id.Set.mem id ids then Some c else None in
- id,(head,[]) :: stack
-
-let push_head c ids stacks =
- List.map (push_one_head c ids) stacks
-
-let pop_one (id,stack) =
- let nstack=
- match stack with
- [] -> anomaly (Pp.str "impossible")
- | [c] as l -> l
- | (Some head,args)::(head0,args0)::ctx ->
- let arg = applist (head,(List.rev args)) in
- (head0,(arg::args0))::ctx
- | (None,args)::(head0,args0)::ctx ->
- (head0,(args@args0))::ctx
- in id,nstack
-
-let pop_stacks stacks =
- List.map pop_one stacks
-
-let hrec_for fix_id per_info gls obj_id =
- let obj=mkVar obj_id in
- let typ=pf_get_hyp_typ gls obj_id in
- let rc,hd1=decompose_prod typ in
- let cind,all_args=decompose_app typ in
- let ind,u = destInd cind in assert (eq_ind ind per_info.per_ind);
- let params,args= List.chop per_info.per_nparams all_args in
- assert begin
- try List.for_all2 eq_constr params per_info.per_params with
- Invalid_argument _ -> false end;
- let hd2 = applist (mkVar fix_id,args@[obj]) in
- compose_lam rc (Reductionops.whd_beta gls.sigma hd2)
-
-let warn_missing_case =
- CWarnings.create ~name:"declmode-missing-case" ~category:"declmode"
- (fun () -> strbrk "missing case")
-
-let rec execute_cases fix_name per_info tacnext args objs nhrec tree gls =
- match tree, objs with
- Close_patt t,_ ->
- let args0 = pop_stacks args in
- execute_cases fix_name per_info tacnext args0 objs nhrec t gls
- | Skip_patt (_,t),skipped::next_objs ->
- let args0 = push_arg skipped args in
- execute_cases fix_name per_info tacnext args0 next_objs nhrec t gls
- | End_patt (id,(nparams,nhyps)),[] ->
- begin
- match Id.List.assoc id args with
- [None,br_args] ->
- let all_metas =
- List.init (nparams + nhyps) (fun n -> mkMeta (succ n)) in
- let param_metas,hyp_metas = List.chop nparams all_metas in
- tclTHEN
- (tclDO nhrec (Proofview.V82.of_tactic introf))
- (tacnext
- (applist (mkVar id,
- List.append param_metas
- (List.rev_append br_args hyp_metas)))) gls
- | _ -> anomaly (Pp.str "wrong stack size")
- end
- | Split_patt (ids,ind,br), casee::next_objs ->
- let (mind,oind) as spec = Global.lookup_inductive ind in
- let nparams = mind.mind_nparams in
- let concl=pf_concl gls in
- let env=pf_env gls in
- let ctyp=pf_unsafe_type_of gls casee in
- let hd,all_args = decompose_app (special_whd gls ctyp) in
- let ind', u = destInd hd in
- let _ = assert (eq_ind ind' ind) in (* just in case *)
- let params,real_args = List.chop nparams all_args in
- let abstract_obj c body =
- let typ=pf_unsafe_type_of gls c in
- lambda_create env (typ,subst_term c body) in
- let elim_pred = List.fold_right abstract_obj
- real_args (lambda_create env (ctyp,subst_term casee concl)) in
- let case_info = Inductiveops.make_case_info env ind RegularStyle in
- let gen_arities = Inductive.arities_of_constructors (ind,u) spec in
- let f_ids typ =
- let sign =
- (prod_assum (prod_applist typ params)) in
- find_intro_names sign gls in
- let constr_args_ids = Array.map f_ids gen_arities in
- let case_term =
- mkCase(case_info,elim_pred,casee,
- Array.mapi (fun i _ -> mkMeta (succ i)) constr_args_ids) in
- let branch_tac i (recargs,bro) gls0 =
- let args_ids = constr_args_ids.(i) in
- let rec aux n = function
- [] ->
- assert (Int.equal n (Array.length recargs));
- next_objs,[],nhrec
- | id :: q ->
- let objs,recs,nrec = aux (succ n) q in
- if recargs.(n)
- then (mkVar id::objs),(id::recs),succ nrec
- else (mkVar id::objs),recs,nrec in
- let objs,recs,nhrec = aux 0 args_ids in
- tclTHENLIST
- [tclMAP (fun id -> Proofview.V82.of_tactic (intro_mustbe_force id)) args_ids;
- begin
- fun gls1 ->
- let hrecs =
- List.map
- (fun id ->
- hrec_for (out_name fix_name) per_info gls1 id)
- recs in
- Proofview.V82.of_tactic (generalize hrecs) gls1
- end;
- match bro with
- None ->
- warn_missing_case ();
- tacnext (mkMeta 1)
- | Some (sub_ids,tree) ->
- let br_args =
- List.filter
- (fun (id,_) -> Id.Set.mem id sub_ids) args in
- let construct =
- applist (mkConstruct(ind,succ i),params) in
- let p_args =
- push_head construct ids br_args in
- execute_cases fix_name per_info tacnext
- p_args objs nhrec tree] gls0 in
- tclTHENSV
- (refine case_term)
- (Array.mapi branch_tac br) gls
- | Split_patt (_, _, _) , [] ->
- anomaly ~label:"execute_cases " (Pp.str "Nothing to split")
- | Skip_patt _ , [] ->
- anomaly ~label:"execute_cases " (Pp.str "Nothing to skip")
- | End_patt (_,_) , _ :: _ ->
- anomaly ~label:"execute_cases " (Pp.str "End of branch with garbage left")
-
-let understand_my_constr env sigma c concl =
- let env = env in
- let rawc = Detyping.detype false [] env Evd.empty c in
- let rec frob = function
- | GEvar _ -> GHole (Loc.ghost,Evar_kinds.QuestionMark Evar_kinds.Expand,Misctypes.IntroAnonymous,None)
- | rc -> map_glob_constr frob rc
- in
- Pretyping.understand_tcc env sigma ~expected_type:(Pretyping.OfType concl) (frob rawc)
-
-let my_refine c gls =
- let oc = { run = begin fun sigma ->
- let sigma = Sigma.to_evar_map sigma in
- let (sigma, c) = understand_my_constr (pf_env gls) sigma c (pf_concl gls) in
- Sigma.Unsafe.of_pair (c, sigma)
- end } in
- Proofview.V82.of_tactic (Tactics.New.refine oc) gls
-
-(* end focus/claim *)
-
-let end_tac et2 gls =
- let info = get_its_info gls in
- let et1,pi,ek,clauses =
- match info.pm_stack with
- Suppose_case::_ ->
- anomaly (Pp.str "This case should already be trapped")
- | Claim::_ ->
- error "\"end claim\" expected."
- | Focus_claim::_ ->
- error "\"end focus\" expected."
- | Per(et',pi,ek,clauses)::_ -> (et',pi,ek,clauses)
- | [] ->
- anomaly (Pp.str "This case should already be trapped") in
- let et = match et1, et2 with
- | ET_Case_analysis, ET_Case_analysis -> et1
- | ET_Induction, ET_Induction -> et1
- | ET_Case_analysis, _ -> error "\"end cases\" expected."
- | ET_Induction, _ -> error "\"end induction\" expected."
- in
- tclTHEN
- tcl_erase_info
- begin
- match et,ek with
- _,EK_unknown ->
- tclSOLVE [Proofview.V82.of_tactic (simplest_elim pi.per_casee)]
- | ET_Case_analysis,EK_nodep ->
- tclTHEN
- (Proofview.V82.of_tactic (simplest_case pi.per_casee))
- (default_justification (List.map mkVar clauses))
- | ET_Induction,EK_nodep ->
- tclTHENLIST
- [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 ->
- execute_cases Anonymous pi
- (fun c -> tclTHENLIST
- [my_refine c;
- clear clauses;
- justification (Proofview.V82.of_tactic assumption)])
- (initial_instance_stack clauses) [pi.per_casee] 0 tree
- | ET_Induction,EK_dep tree ->
- let nargs = (List.length pi.per_args) in
- tclTHEN (Proofview.V82.of_tactic (generalize (pi.per_args@[pi.per_casee])))
- begin
- fun gls0 ->
- let fix_id =
- pf_get_new_id (Id.of_string "_fix") gls0 in
- let c_id =
- pf_get_new_id (Id.of_string "_main_arg") gls0 in
- tclTHENLIST
- [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
- (fun c ->
- tclTHENLIST
- [clear [fix_id];
- my_refine c;
- clear clauses;
- justification (Proofview.V82.of_tactic assumption)])
- (initial_instance_stack clauses)
- [mkVar c_id] 0 tree] gls0
- end
- end gls
-
-(* escape *)
-
-let escape_tac gls =
- (* spiwack: sets an empty info stack to avoid interferences.
- We could erase the info altogether, but that doesn't play
- well with the Decl_mode.focus (used in post_processing). *)
- let info={pm_stack=[]} in
- tcl_change_info info gls
-
-(* General instruction engine *)
-
-let rec do_proof_instr_gen _thus _then instr =
- match instr with
- Pthus i ->
- assert (not _thus);
- do_proof_instr_gen true _then i
- | Pthen i ->
- assert (not _then);
- do_proof_instr_gen _thus true i
- | Phence i ->
- assert (not (_then || _thus));
- do_proof_instr_gen true true i
- | Pcut c ->
- instr_cut mk_stat_or_thesis _thus _then c
- | Psuffices c ->
- instr_suffices _then c
- | Prew (s,c) ->
- assert (not _then);
- instr_rew _thus s c
- | Pconsider (c,hyps) -> consider_tac c hyps
- | Pgiven hyps -> given_tac hyps
- | Passume hyps -> assume_tac hyps
- | Plet hyps -> assume_tac hyps
- | Pclaim st -> instr_claim false st
- | Pfocus st -> instr_claim true st
- | Ptake witl -> take_tac witl
- | Pdefine (id,args,body) -> define_tac id args body
- | Pcast (id,typ) -> cast_tac id typ
- | Pper (et,cs) -> per_tac et cs
- | Psuppose hyps -> suppose_tac hyps
- | Pcase (params,pat_info,hyps) -> case_tac params pat_info hyps
- | Pend (B_elim et) -> end_tac et
- | Pend _ -> anomaly (Pp.str "Not applicable")
- | Pescape -> escape_tac
-
-let eval_instr {instr=instr} =
- do_proof_instr_gen false false instr
-
-let rec preprocess pts instr =
- match instr with
- Phence i |Pthus i | Pthen i -> preprocess pts i
- | Psuffices _ | Pcut _ | Passume _ | Plet _ | Pclaim _ | Pfocus _
- | Pconsider (_,_) | Pcast (_,_) | Pgiven _ | Ptake _
- | Pdefine (_,_,_) | Pper _ | Prew _ ->
- check_not_per pts;
- true
- | Pescape ->
- check_not_per pts;
- true
- | Pcase _ | Psuppose _ | Pend (B_elim _) ->
- close_previous_case pts ;
- true
- | Pend bt ->
- close_block bt pts ;
- false
-
-let rec postprocess pts instr =
- match instr with
- Phence i | Pthus i | Pthen i -> postprocess pts i
- | Pcut _ | Psuffices _ | Passume _ | Plet _ | Pconsider (_,_) | Pcast (_,_)
- | Pgiven _ | Ptake _ | Pdefine (_,_,_) | Prew (_,_) -> ()
- | Pclaim _ | Pfocus _ | Psuppose _ | Pcase _ | Pper _ ->
- Decl_mode.focus pts
- | Pescape ->
- Decl_mode.focus pts;
- Proof_global.set_proof_mode "Classic"
- | Pend (B_elim ET_Induction) ->
- begin
- let pfterm = List.hd (Proof.partial_proof pts) in
- let { it = gls ; sigma = sigma } = Proof.V82.subgoals pts in
- let env = try
- Goal.V82.env sigma (List.hd gls)
- with Failure "hd" ->
- Global.env ()
- in
- try
- Inductiveops.control_only_guard env pfterm;
- goto_current_focus_or_top ()
- with
- Type_errors.TypeError(env,
- Type_errors.IllFormedRecBody(_,_,_,_,_)) ->
- anomaly (Pp.str "\"end induction\" generated an ill-formed fixpoint")
- end
- | Pend (B_elim ET_Case_analysis) -> goto_current_focus ()
- | Pend B_proof -> Proof_global.set_proof_mode "Classic"
- | Pend _ -> ()
-
-let do_instr raw_instr pts =
- let has_tactic = preprocess pts raw_instr.instr in
- (* spiwack: hack! [preprocess] assumes that the [pts] is indeed the
- current proof (and, actually so does [do_instr] later one, so
- it's ok to do the same here. Ideally the proof should be properly
- threaded through the commands here, but since the are interleaved
- with actions on the proof mode, which is attached to the global
- proof environment, it is not possible without heavy lifting. *)
- let pts = Proof_global.give_me_the_proof () in
- let pts =
- if has_tactic then
- let { it=gls ; sigma=sigma; } = Proof.V82.subgoals pts in
- let gl = { it=List.hd gls ; sigma=sigma; } in
- let env= pf_env gl in
- let ist = {ltacvars = Id.Set.empty; genv = env} in
- let glob_instr = intern_proof_instr ist raw_instr in
- let instr =
- interp_proof_instr (get_its_info gl) env sigma glob_instr in
- let (pts',_) = Proof.run_tactic (Global.env())
- (Proofview.V82.tactic (tclTHEN (eval_instr instr) clean_tmp)) pts in
- pts'
- else pts
- in
- Proof_global.simple_with_current_proof (fun _ _ -> pts);
- postprocess pts raw_instr.instr
-
-let proof_instr raw_instr =
- let p = Proof_global.give_me_the_proof () in
- do_instr raw_instr p
-
-(*
-
-(* STUFF FOR ITERATED RELATIONS *)
-let decompose_bin_app t=
- let hd,args = destApp
-
-let identify_transitivity_lemma c =
- let varx,tx,c1 = destProd c in
- let vary,ty,c2 = destProd (pop c1) in
- let varz,tz,c3 = destProd (pop c2) in
- let _,p1,c4 = destProd (pop c3) in
- let _,lp2,lp3 = destProd (pop c4) in
- let p2=pop lp2 in
- let p3=pop lp3 in
-*)
-
diff --git a/plugins/decl_mode/decl_proof_instr.mli b/plugins/decl_mode/decl_proof_instr.mli
deleted file mode 100644
index 325969dadb..0000000000
--- a/plugins/decl_mode/decl_proof_instr.mli
+++ /dev/null
@@ -1,108 +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 Term
-open Tacmach
-open Decl_mode
-
-val go_to_proof_mode: unit -> unit
-val return_from_tactic_mode: unit -> unit
-
-val register_automation_tac: unit Proofview.tactic -> unit
-
-val automation_tac : unit Proofview.tactic
-
-val concl_refiner:
- Termops.meta_type_map -> constr -> Proof_type.goal sigma -> constr
-
-val do_instr: Decl_expr.raw_proof_instr -> Proof.proof -> unit
-val proof_instr: Decl_expr.raw_proof_instr -> unit
-
-val tcl_change_info : Decl_mode.pm_info -> tactic
-
-val execute_cases :
- Name.t ->
- Decl_mode.per_info ->
- (Term.constr -> Proof_type.tactic) ->
- (Id.Set.elt * (Term.constr option * Term.constr list) list) list ->
- Term.constr list -> int -> Decl_mode.split_tree -> Proof_type.tactic
-
-val tree_of_pats :
- Id.t * (int * int) -> (Glob_term.cases_pattern*recpath) list list ->
- split_tree
-
-val add_branch :
- Id.t * (int * int) -> (Glob_term.cases_pattern*recpath) list list ->
- split_tree -> split_tree
-
-val append_branch :
- Id.t *(int * int) -> int -> (Glob_term.cases_pattern*recpath) list list ->
- (Id.Set.t * Decl_mode.split_tree) option ->
- (Id.Set.t * Decl_mode.split_tree) option
-
-val append_tree :
- Id.t * (int * int) -> int -> (Glob_term.cases_pattern*recpath) list list ->
- split_tree -> split_tree
-
-val build_dep_clause : Term.types Decl_expr.statement list ->
- Decl_expr.proof_pattern ->
- Decl_mode.per_info ->
- (Term.types Decl_expr.statement, Term.types Decl_expr.or_thesis)
- Decl_expr.hyp list -> Proof_type.goal Tacmach.sigma -> Term.types
-
-val register_dep_subcase :
- Id.t * (int * int) ->
- Environ.env ->
- Decl_mode.per_info ->
- Glob_term.cases_pattern -> Decl_mode.elim_kind -> Decl_mode.elim_kind
-
-val thesis_for : Term.constr ->
- Term.constr -> Decl_mode.per_info -> Environ.env -> Term.constr
-
-val close_previous_case : Proof.proof -> unit
-
-val pop_stacks :
- (Id.t *
- (Term.constr option * Term.constr list) list) list ->
- (Id.t *
- (Term.constr option * Term.constr list) list) list
-
-val push_head : Term.constr ->
- Id.Set.t ->
- (Id.t *
- (Term.constr option * Term.constr list) list) list ->
- (Id.t *
- (Term.constr option * Term.constr list) list) list
-
-val push_arg : Term.constr ->
- (Id.t *
- (Term.constr option * Term.constr list) list) list ->
- (Id.t *
- (Term.constr option * Term.constr list) list) list
-
-val hrec_for:
- Id.t ->
- Decl_mode.per_info -> Proof_type.goal Tacmach.sigma ->
- Id.t -> Term.constr
-
-val consider_match :
- bool ->
- (Id.Set.elt*bool) list ->
- Id.Set.elt list ->
- (Term.types Decl_expr.statement, Term.types) Decl_expr.hyp list ->
- Proof_type.tactic
-
-val init_tree:
- Id.Set.t ->
- inductive ->
- int option * Declarations.wf_paths ->
- (int ->
- (int option * Declarations.recarg Rtree.t) array ->
- (Id.Set.t * Decl_mode.split_tree) option) ->
- Decl_mode.split_tree
diff --git a/plugins/decl_mode/g_decl_mode.ml4 b/plugins/decl_mode/g_decl_mode.ml4
deleted file mode 100644
index a71d20f0dc..0000000000
--- a/plugins/decl_mode/g_decl_mode.ml4
+++ /dev/null
@@ -1,387 +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: "grammar/grammar.cma" i*)
-
-DECLARE PLUGIN "decl_mode_plugin"
-
-open Ltac_plugin
-open Compat
-open Pp
-open Decl_expr
-open Names
-open Pcoq
-open Vernacexpr
-open Tok (* necessary for camlp4 *)
-
-open Pcoq.Constr
-open Pltac
-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 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
- | [goal] when pr_first ->
- pr_goal { Evd.it = goal ; sigma = sigma }
- | _ ->
- (* spiwack: it's not very nice to have to call proof global
- here, a more robust solution would be to add a hook for
- [Printer.pr_open_subgoals] in proof modes, in order to
- compute the end command. Yet a more robust solution would be
- to have focuses give explanations of their unfocusing
- behaviour. *)
- let p = Proof_global.give_me_the_proof () in
- let close_cmd = Decl_mode.get_end_command p in
- str "Subproof completed, now type " ++ str close_cmd ++ str "."
-
-let interp_proof_instr _ { Evd.it = gl ; sigma = sigma }=
- Decl_interp.interp_proof_instr
- (Decl_mode.get_info sigma gl)
- (Goal.V82.env sigma gl)
- (sigma)
-
-let vernac_decl_proof () =
- let pf = Proof_global.give_me_the_proof () in
- if Proof.is_done pf then
- CErrors.error "Nothing left to prove here."
- else
- begin
- Decl_proof_instr.go_to_proof_mode () ;
- Proof_global.set_proof_mode "Declarative"
- end
-
-(* spiwack: some bureaucracy is not performed here *)
-let vernac_return () =
- begin
- Decl_proof_instr.return_from_tactic_mode () ;
- Proof_global.set_proof_mode "Declarative"
- end
-
-let vernac_proof_instr instr =
- Decl_proof_instr.proof_instr instr
-
-(* Before we can write an new toplevel command (see below)
- which takes a [proof_instr] as argument, we need to declare
- how to parse it, print it, globalise it and interprete it.
- Normally we could do that easily through ARGUMENT EXTEND,
- but as the parsing is fairly complicated we will do it manually to
- indirect through the [proof_instr] grammar entry. *)
-(* spiwack: proposal: doing that directly from argextend.ml4, maybe ? *)
-
-(* 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 "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. *)
-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 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
- | _ -> 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.
- The "-" indicates that the rule does not start with a distinguished
- string. *)
-VERNAC proof_mode EXTEND ProofInstr
- [ - proof_instr(instr) ] => [classify_proof_instr instr] -> [ vernac_proof_instr instr ]
-END
-
-(* It is useful to use GEXTEND directly to call grammar entries that have been
- defined previously VERNAC EXTEND. In this case we allow, in proof mode,
- the use of commands like Check or Print. VERNAC EXTEND does quite a bit of
- bureaucracy for us, but it is not needed in this sort of case, and it would require
- to have an ARGUMENT EXTEND version of the "proof_mode" grammar entry. *)
-GEXTEND Gram
- GLOBAL: proof_mode ;
-
- proof_mode: LAST
- [ [ c=G_vernac.subgoal_command -> c (Some (Vernacexpr.SelectNth 1)) ] ]
- ;
-END
-
-(* We register a new proof mode here *)
-
-let _ =
- Proof_global.register_proof_mode { Proof_global.
- name = "Declarative" ; (* name for identifying and printing *)
- (* function [set] goes from No Proof Mode to
- Declarative Proof Mode performing side effects *)
- set = begin fun () ->
- (* We set the command non terminal to
- [proof_mode] (which we just defined). *)
- 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
- Printer.pr_goal = pr_goal;
- pr_subgoals = pr_subgoals; }
- end ;
- (* function [reset] goes back to No Proof Mode from
- Declarative Proof Mode *)
- reset = begin fun () ->
- (* We restore the command non terminal to
- [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
- }
-
-VERNAC COMMAND EXTEND DeclProof
-[ "proof" ] => [ VtProofMode "Declarative", VtNow ] -> [ vernac_decl_proof () ]
-END
-VERNAC COMMAND EXTEND DeclReturn
-[ "return" ] => [ VtProofMode "Declarative", VtNow ] -> [ vernac_return () ]
-END
-
-let none_is_empty = function
- None -> []
- | Some l -> l
-
-GEXTEND Gram
-GLOBAL: proof_instr;
- thesis :
- [[ "thesis" -> Plain
- | "thesis"; "for"; i=ident -> (For i)
- ]];
- statement :
- [[ i=ident ; ":" ; c=constr -> {st_label=Name i;st_it=c}
- | i=ident -> {st_label=Anonymous;
- st_it=Constrexpr.CRef (Libnames.Ident (!@loc, i), None)}
- | c=constr -> {st_label=Anonymous;st_it=c}
- ]];
- constr_or_thesis :
- [[ t=thesis -> Thesis t ] |
- [ c=constr -> This c
- ]];
- statement_or_thesis :
- [
- [ t=thesis -> {st_label=Anonymous;st_it=Thesis t} ]
- |
- [ i=ident ; ":" ; cot=constr_or_thesis -> {st_label=Name i;st_it=cot}
- | i=ident -> {st_label=Anonymous;
- st_it=This (Constrexpr.CRef (Libnames.Ident (!@loc, i), None))}
- | c=constr -> {st_label=Anonymous;st_it=This c}
- ]
- ];
- justification_items :
- [[ -> Some []
- | "by"; l=LIST1 constr SEP "," -> Some l
- | "by"; "*" -> None ]]
- ;
- justification_method :
- [[ -> None
- | "using"; tac = tactic -> Some tac ]]
- ;
- simple_cut_or_thesis :
- [[ ls = statement_or_thesis;
- j = justification_items;
- taco = justification_method
- -> {cut_stat=ls;cut_by=j;cut_using=taco} ]]
- ;
- simple_cut :
- [[ ls = statement;
- j = justification_items;
- taco = justification_method
- -> {cut_stat=ls;cut_by=j;cut_using=taco} ]]
- ;
- elim_type:
- [[ IDENT "induction" -> ET_Induction
- | IDENT "cases" -> ET_Case_analysis ]]
- ;
- block_type :
- [[ IDENT "claim" -> B_claim
- | IDENT "focus" -> B_focus
- | IDENT "proof" -> B_proof
- | et=elim_type -> B_elim et ]]
- ;
- elim_obj:
- [[ IDENT "on"; c=constr -> Real c
- | IDENT "of"; c=simple_cut -> Virtual c ]]
- ;
- elim_step:
- [[ IDENT "consider" ;
- h=consider_vars ; IDENT "from" ; c=constr -> Pconsider (c,h)
- | IDENT "per"; et=elim_type; obj=elim_obj -> Pper (et,obj)
- | IDENT "suffices"; ls=suff_clause;
- j = justification_items;
- taco = justification_method
- -> Psuffices {cut_stat=ls;cut_by=j;cut_using=taco} ]]
- ;
- rew_step :
- [[ "~=" ; c=simple_cut -> (Rhs,c)
- | "=~" ; c=simple_cut -> (Lhs,c)]]
- ;
- cut_step:
- [[ "then"; tt=elim_step -> Pthen tt
- | "then"; c=simple_cut_or_thesis -> Pthen (Pcut c)
- | IDENT "thus"; tt=rew_step -> Pthus (let s,c=tt in Prew (s,c))
- | IDENT "thus"; c=simple_cut_or_thesis -> Pthus (Pcut c)
- | IDENT "hence"; c=simple_cut_or_thesis -> Phence (Pcut c)
- | tt=elim_step -> tt
- | tt=rew_step -> let s,c=tt in Prew (s,c);
- | IDENT "have"; c=simple_cut_or_thesis -> Pcut c;
- | IDENT "claim"; c=statement -> Pclaim c;
- | IDENT "focus"; IDENT "on"; c=statement -> Pfocus c;
- | "end"; bt = block_type -> Pend bt;
- | IDENT "escape" -> Pescape ]]
- ;
- (* examiner s'il est possible de faire R _ et _ R pour R une relation qcq*)
- loc_id:
- [[ id=ident -> fun x -> (!@loc,(id,x)) ]];
- hyp:
- [[ id=loc_id -> id None ;
- | id=loc_id ; ":" ; c=constr -> id (Some c)]]
- ;
- consider_vars:
- [[ name=hyp -> [Hvar name]
- | name=hyp; ","; v=consider_vars -> (Hvar name) :: v
- | name=hyp;
- IDENT "such"; IDENT "that"; h=consider_hyps -> (Hvar name)::h
- ]]
- ;
- consider_hyps:
- [[ st=statement; IDENT "and"; h=consider_hyps -> Hprop st::h
- | st=statement; IDENT "and";
- IDENT "consider" ; v=consider_vars -> Hprop st::v
- | st=statement -> [Hprop st]
- ]]
- ;
- assume_vars:
- [[ name=hyp -> [Hvar name]
- | name=hyp; ","; v=assume_vars -> (Hvar name) :: v
- | name=hyp;
- IDENT "such"; IDENT "that"; h=assume_hyps -> (Hvar name)::h
- ]]
- ;
- assume_hyps:
- [[ st=statement; IDENT "and"; h=assume_hyps -> Hprop st::h
- | st=statement; IDENT "and";
- IDENT "we"; IDENT "have" ; v=assume_vars -> Hprop st::v
- | st=statement -> [Hprop st]
- ]]
- ;
- assume_clause:
- [[ IDENT "we" ; IDENT "have" ; v=assume_vars -> v
- | h=assume_hyps -> h ]]
- ;
- suff_vars:
- [[ name=hyp; IDENT "to"; IDENT "show" ; c = constr_or_thesis ->
- [Hvar name],c
- | name=hyp; ","; v=suff_vars ->
- let (q,c) = v in ((Hvar name) :: q),c
- | name=hyp;
- IDENT "such"; IDENT "that"; h=suff_hyps ->
- let (q,c) = h in ((Hvar name) :: q),c
- ]];
- suff_hyps:
- [[ st=statement; IDENT "and"; h=suff_hyps ->
- let (q,c) = h in (Hprop st::q),c
- | st=statement; IDENT "and";
- IDENT "to" ; IDENT "have" ; v=suff_vars ->
- let (q,c) = v in (Hprop st::q),c
- | st=statement; IDENT "to"; IDENT "show" ; c = constr_or_thesis ->
- [Hprop st],c
- ]]
- ;
- suff_clause:
- [[ IDENT "to" ; IDENT "have" ; v=suff_vars -> v
- | h=suff_hyps -> h ]]
- ;
- let_vars:
- [[ name=hyp -> [Hvar name]
- | name=hyp; ","; v=let_vars -> (Hvar name) :: v
- | name=hyp; IDENT "be";
- IDENT "such"; IDENT "that"; h=let_hyps -> (Hvar name)::h
- ]]
- ;
- let_hyps:
- [[ st=statement; IDENT "and"; h=let_hyps -> Hprop st::h
- | st=statement; IDENT "and"; "let"; v=let_vars -> Hprop st::v
- | st=statement -> [Hprop st]
- ]];
- given_vars:
- [[ name=hyp -> [Hvar name]
- | name=hyp; ","; v=given_vars -> (Hvar name) :: v
- | name=hyp; IDENT "such"; IDENT "that"; h=given_hyps -> (Hvar name)::h
- ]]
- ;
- given_hyps:
- [[ st=statement; IDENT "and"; h=given_hyps -> Hprop st::h
- | st=statement; IDENT "and"; IDENT "given"; v=given_vars -> Hprop st::v
- | st=statement -> [Hprop st]
- ]];
- suppose_vars:
- [[name=hyp -> [Hvar name]
- |name=hyp; ","; v=suppose_vars -> (Hvar name) :: v
- |name=hyp; OPT[IDENT "be"];
- IDENT "such"; IDENT "that"; h=suppose_hyps -> (Hvar name)::h
- ]]
- ;
- suppose_hyps:
- [[ st=statement_or_thesis; IDENT "and"; h=suppose_hyps -> Hprop st::h
- | st=statement_or_thesis; IDENT "and"; IDENT "we"; IDENT "have";
- v=suppose_vars -> Hprop st::v
- | st=statement_or_thesis -> [Hprop st]
- ]]
- ;
- suppose_clause:
- [[ IDENT "we"; IDENT "have"; v=suppose_vars -> v;
- | h=suppose_hyps -> h ]]
- ;
- intro_step:
- [[ IDENT "suppose" ; h=assume_clause -> Psuppose h
- | IDENT "suppose" ; IDENT "it"; IDENT "is" ; c=pattern LEVEL "0" ;
- po=OPT[ "with"; p=LIST1 hyp SEP ","-> p ] ;
- ho=OPT[ IDENT "and" ; h=suppose_clause -> h ] ->
- Pcase (none_is_empty po,c,none_is_empty ho)
- | "let" ; v=let_vars -> Plet v
- | IDENT "take"; witnesses = LIST1 constr SEP "," -> Ptake witnesses
- | IDENT "assume"; h=assume_clause -> Passume h
- | IDENT "given"; h=given_vars -> Pgiven h
- | IDENT "define"; id=ident; args=LIST0 hyp;
- "as"; body=constr -> Pdefine(id,args,body)
- | IDENT "reconsider"; id=ident; "as" ; typ=constr -> Pcast (This id,typ)
- | IDENT "reconsider"; t=thesis; "as" ; typ=constr -> Pcast (Thesis t ,typ)
- ]]
- ;
- emphasis :
- [[ -> 0
- | "*" -> 1
- | "**" -> 2
- | "***" -> 3
- ]]
- ;
- bare_proof_instr:
- [[ c = cut_step -> c ;
- | i = intro_step -> i ]]
- ;
- proof_instr :
- [[ e=emphasis;i=bare_proof_instr;"." -> {emph=e;instr=i}]]
- ;
-END;;
diff --git a/plugins/decl_mode/ppdecl_proof.ml b/plugins/decl_mode/ppdecl_proof.ml
deleted file mode 100644
index f5de638ed2..0000000000
--- a/plugins/decl_mode/ppdecl_proof.ml
+++ /dev/null
@@ -1,216 +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 Ltac_plugin
-open CErrors
-open Pp
-open Decl_expr
-open Names
-open Nameops
-
-let pr_label = function
- Anonymous -> mt ()
- | Name id -> pr_id id ++ spc () ++ str ":" ++ spc ()
-
-let pr_justification_items pr_constr = function
- Some [] -> mt ()
- | Some (_::_ as l) ->
- spc () ++ str "by" ++ spc () ++
- prlist_with_sep (fun () -> str ",") pr_constr l
- | None -> spc () ++ str "by *"
-
-let pr_justification_method pr_tac = function
- None -> mt ()
- | Some tac ->
- spc () ++ str "using" ++ spc () ++ pr_tac tac
-
-let pr_statement pr_constr st =
- pr_label st.st_label ++ pr_constr st.st_it
-
-let pr_or_thesis pr_this = function
- Thesis Plain -> str "thesis"
- | Thesis (For id) ->
- str "thesis" ++ spc() ++ str "for" ++ spc () ++ pr_id id
- | This c -> pr_this c
-
-let pr_cut pr_constr pr_tac pr_it c =
- hov 1 (pr_it c.cut_stat) ++
- pr_justification_items pr_constr c.cut_by ++
- pr_justification_method pr_tac c.cut_using
-
-let type_or_thesis = function
- Thesis _ -> Term.mkProp
- | This c -> c
-
-let _I x = x
-
-let rec pr_hyps pr_var pr_constr gtyp sep _be _have hyps =
- let pr_sep = if sep then str "and" ++ spc () else mt () in
- match hyps with
- (Hvar _ ::_) as rest ->
- spc () ++ pr_sep ++ str _have ++
- pr_vars pr_var pr_constr gtyp false _be _have rest
- | Hprop st :: rest ->
- begin
- (* let npr_constr env = pr_constr (Environ.push_named (id,None,gtyp st.st_it) env)*)
- spc() ++ pr_sep ++ pr_statement pr_constr st ++
- pr_hyps pr_var pr_constr gtyp true _be _have rest
- end
- | [] -> mt ()
-
-and pr_vars pr_var pr_constr gtyp sep _be _have vars =
- match vars with
- Hvar st :: rest ->
- begin
- (* let npr_constr env = pr_constr (Environ.push_named (id,None,gtyp st.st_it) env)*)
- let pr_sep = if sep then pr_comma () else mt () in
- spc() ++ pr_sep ++
- pr_var st ++
- pr_vars pr_var pr_constr gtyp true _be _have rest
- end
- | (Hprop _ :: _) as rest ->
- let _st = if _be then
- str "be such that"
- else
- str "such that" in
- spc() ++ _st ++ pr_hyps pr_var pr_constr gtyp false _be _have rest
- | [] -> mt ()
-
-let pr_suffices_clause pr_var pr_constr (hyps,c) =
- pr_hyps pr_var pr_constr _I false false "to have" hyps ++ spc () ++
- str "to show" ++ spc () ++ pr_or_thesis pr_constr c
-
-let pr_elim_type = function
- ET_Case_analysis -> str "cases"
- | ET_Induction -> str "induction"
-
-let pr_block_type = function
- B_elim et -> pr_elim_type et
- | B_proof -> str "proof"
- | B_claim -> str "claim"
- | B_focus -> str "focus"
-
-let pr_casee pr_constr pr_tac =function
- Real c -> str "on" ++ spc () ++ pr_constr c
- | Virtual cut -> str "of" ++ spc () ++ pr_cut pr_constr pr_tac (pr_statement pr_constr) cut
-
-let pr_side = function
- Lhs -> str "=~"
- | Rhs -> str "~="
-
-let rec pr_bare_proof_instr pr_var pr_constr pr_pat pr_tac _then _thus = function
- | Pescape -> str "escape"
- | Pthen i -> pr_bare_proof_instr pr_var pr_constr pr_pat pr_tac true _thus i
- | Pthus i -> pr_bare_proof_instr pr_var pr_constr pr_pat pr_tac _then true i
- | Phence i -> pr_bare_proof_instr pr_var pr_constr pr_pat pr_tac true true i
- | Pcut c ->
- begin
- match _then,_thus with
- false,false -> str "have" ++ spc () ++
- pr_cut pr_constr pr_tac (pr_statement (pr_or_thesis pr_constr)) c
- | false,true -> str "thus" ++ spc () ++
- pr_cut pr_constr pr_tac (pr_statement (pr_or_thesis pr_constr)) c
- | true,false -> str "then" ++ spc () ++
- pr_cut pr_constr pr_tac (pr_statement (pr_or_thesis pr_constr)) c
- | true,true -> str "hence" ++ spc () ++
- pr_cut pr_constr pr_tac (pr_statement (pr_or_thesis pr_constr)) c
- end
- | Psuffices c ->
- str "suffices" ++ pr_cut pr_constr pr_tac (pr_suffices_clause pr_var pr_constr) c
- | Prew (sid,c) ->
- (if _thus then str "thus" else str " ") ++ spc () ++
- pr_side sid ++ spc () ++ pr_cut pr_constr pr_tac (pr_statement pr_constr) c
- | Passume hyps ->
- str "assume" ++ pr_hyps pr_var pr_constr _I false false "we have" hyps
- | Plet hyps ->
- str "let" ++ pr_vars pr_var pr_constr _I false true "let" hyps
- | Pclaim st ->
- str "claim" ++ spc () ++ pr_statement pr_constr st
- | Pfocus st ->
- str "focus on" ++ spc () ++ pr_statement pr_constr st
- | Pconsider (id,hyps) ->
- str "consider" ++ pr_vars pr_var pr_constr _I false false "consider" hyps
- ++ spc () ++ str "from " ++ pr_constr id
- | Pgiven hyps ->
- str "given" ++ pr_vars pr_var pr_constr _I false false "given" hyps
- | Ptake witl ->
- str "take" ++ spc () ++
- prlist_with_sep pr_comma pr_constr witl
- | Pdefine (id,args,body) ->
- str "define" ++ spc () ++ pr_id id ++ spc () ++
- prlist_with_sep spc
- (fun st -> str "(" ++
- pr_var st ++ str ")") args ++ spc () ++
- str "as" ++ (pr_constr body)
- | Pcast (id,typ) ->
- str "reconsider" ++ spc () ++
- pr_or_thesis pr_id id ++ spc () ++
- str "as" ++ spc () ++ (pr_constr typ)
- | Psuppose hyps ->
- str "suppose" ++
- pr_hyps pr_var pr_constr _I false false "we have" hyps
- | Pcase (params,pat,hyps) ->
- str "suppose it is" ++ spc () ++ pr_pat pat ++
- (if params = [] then mt () else
- (spc () ++ str "with" ++ spc () ++
- prlist_with_sep spc
- (fun st -> str "(" ++
- pr_var st ++ str ")") params ++ spc ()))
- ++
- (if hyps = [] then mt () else
- (spc () ++ str "and" ++
- pr_hyps pr_var (pr_or_thesis pr_constr) type_or_thesis
- false false "we have" hyps))
- | Pper (et,c) ->
- str "per" ++ spc () ++ pr_elim_type et ++ spc () ++
- pr_casee pr_constr pr_tac c
- | Pend blk -> str "end" ++ spc () ++ pr_block_type blk
-
-let pr_emph = function
- 0 -> str " "
- | 1 -> str "* "
- | 2 -> str "** "
- | 3 -> str "*** "
- | _ -> anomaly (Pp.str "unknown emphasis")
-
-let pr_gen_proof_instr pr_var pr_constr pr_pat pr_tac instr =
- pr_emph instr.emph ++ spc () ++
- pr_bare_proof_instr pr_var pr_constr pr_pat pr_tac false false instr.instr
-
-
-let pr_raw_proof_instr pconstr1 pconstr2 ptac (instr : raw_proof_instr) =
- pr_gen_proof_instr
- (fun (_,(id,otyp)) ->
- match otyp with
- None -> pr_id id
- | Some typ -> str "(" ++ pr_id id ++ str ":" ++ pconstr1 typ ++str ")"
- )
- pconstr2
- Ppconstr.pr_cases_pattern_expr
- (ptac Pptactic.ltop)
- instr
-
-let pr_glob_proof_instr pconstr1 pconstr2 ptac (instr : glob_proof_instr) =
- pr_gen_proof_instr
- (fun (_,(id,otyp)) ->
- match otyp with
- None -> pr_id id
- | Some typ -> str "(" ++ pr_id id ++ str ":" ++ pconstr1 typ ++str ")")
- pconstr2
- Ppconstr.pr_cases_pattern_expr
- (ptac Pptactic.ltop)
- instr
-
-let pr_proof_instr pconstr1 pconstr2 ptac (instr : proof_instr) =
- pr_gen_proof_instr
- (fun st -> pr_statement pconstr1 st)
- pconstr2
- (fun mpat -> Ppconstr.pr_cases_pattern_expr mpat.pat_expr)
- (ptac Pptactic.ltop)
- instr
-
diff --git a/plugins/decl_mode/ppdecl_proof.mli b/plugins/decl_mode/ppdecl_proof.mli
deleted file mode 100644
index 678fc07688..0000000000
--- a/plugins/decl_mode/ppdecl_proof.mli
+++ /dev/null
@@ -1,14 +0,0 @@
-
-open Decl_expr
-open Pptactic
-
-val pr_gen_proof_instr :
- ('var -> Pp.std_ppcmds) ->
- ('constr -> Pp.std_ppcmds) ->
- ('pat -> Pp.std_ppcmds) ->
- ('tac -> Pp.std_ppcmds) ->
- ('var,'constr,'pat,'tac) gen_proof_instr -> Pp.std_ppcmds
-
-val pr_raw_proof_instr : raw_proof_instr raw_extra_genarg_printer
-val pr_glob_proof_instr : glob_proof_instr glob_extra_genarg_printer
-val pr_proof_instr : proof_instr extra_genarg_printer
diff --git a/plugins/extraction/common.ml b/plugins/extraction/common.ml
index de97ba97c3..fc8d5356c8 100644
--- a/plugins/extraction/common.ml
+++ b/plugins/extraction/common.ml
@@ -67,7 +67,9 @@ let pp_boxed_tuple f = function
blocks is less that a line length. To avoid this awkward situation,
we attach a big virtual size to [fnl] newlines. *)
-let fnl () = stras (1000000,"") ++ fnl ()
+(* EG: This looks quite suspicious... but beware of bugs *)
+(* let fnl () = stras (1000000,"") ++ fnl () *)
+let fnl () = fnl ()
let fnl2 () = fnl () ++ fnl ()
@@ -91,10 +93,7 @@ let begins_with_CoqXX s =
let unquote s =
if lang () != Scheme then s
- else
- let s = String.copy s in
- for i=0 to String.length s - 1 do if s.[i] == '\'' then s.[i] <- '~' done;
- s
+ else String.map (fun c -> if c == '\'' then '~' else c) s
let rec qualify delim = function
| [] -> assert false
diff --git a/plugins/extraction/extract_env.ml b/plugins/extraction/extract_env.ml
index e019bb3c2a..2b12462ad5 100644
--- a/plugins/extraction/extract_env.ml
+++ b/plugins/extraction/extract_env.ml
@@ -472,13 +472,14 @@ let formatter dry file =
if dry then Format.make_formatter (fun _ _ _ -> ()) (fun _ -> ())
else
match file with
- | Some f -> Pp_control.with_output_to f
+ | Some f -> Topfmt.with_output_to f
| None -> Format.formatter_of_buffer buf
in
+ (* XXX: Fixme, this shouldn't depend on Topfmt *)
(* We never want to see ellipsis ... in extracted code *)
Format.pp_set_max_boxes ft max_int;
(* We reuse the width information given via "Set Printing Width" *)
- (match Pp_control.get_margin () with
+ (match Topfmt.get_margin () with
| None -> ()
| Some i ->
Format.pp_set_margin ft i;
@@ -518,8 +519,10 @@ let print_structure_to_file (fn,si,mo) dry struc =
set_phase Impl;
pp_with ft (d.preamble mo comment opened unsafe_needs);
pp_with ft (d.pp_struct struc);
+ Format.pp_print_flush ft ();
Option.iter close_out cout;
with reraise ->
+ Format.pp_print_flush ft ();
Option.iter close_out cout; raise reraise
end;
if not dry then Option.iter info_file fn;
@@ -532,8 +535,10 @@ let print_structure_to_file (fn,si,mo) dry struc =
set_phase Intf;
pp_with ft (d.sig_preamble mo comment opened unsafe_needs);
pp_with ft (d.pp_sig (signature_of_structure struc));
+ Format.pp_print_flush ft ();
close_out cout;
with reraise ->
+ Format.pp_print_flush ft ();
close_out cout; raise reraise
end;
info_file si)
diff --git a/plugins/extraction/ocaml.ml b/plugins/extraction/ocaml.ml
index d89bf95ee8..d8e3821557 100644
--- a/plugins/extraction/ocaml.ml
+++ b/plugins/extraction/ocaml.ml
@@ -66,7 +66,7 @@ let pp_header_comment = function
| None -> mt ()
| Some com -> pp_comment com ++ fnl2 ()
-let then_nl pp = if Pp.is_empty pp then mt () else pp ++ fnl ()
+let then_nl pp = if Pp.ismt pp then mt () else pp ++ fnl ()
let pp_tdummy usf =
if usf.tdummy || usf.tunknown then str "type __ = Obj.t" ++ fnl () else mt ()
@@ -618,7 +618,7 @@ and pp_module_type params = function
push_visible mp params;
let try_pp_specif l x =
let px = pp_specif x in
- if Pp.is_empty px then l else px::l
+ if Pp.ismt px then l else px::l
in
(* We cannot use fold_right here due to side effects in pp_specif *)
let l = List.fold_left try_pp_specif [] sign in
@@ -696,7 +696,7 @@ and pp_module_expr params = function
push_visible mp params;
let try_pp_structure_elem l x =
let px = pp_structure_elem x in
- if Pp.is_empty px then l else px::l
+ if Pp.ismt px then l else px::l
in
(* We cannot use fold_right here due to side effects in pp_structure_elem *)
let l = List.fold_left try_pp_structure_elem [] sel in
@@ -714,7 +714,7 @@ let rec prlist_sep_nonempty sep f = function
| h::t ->
let e = f h in
let r = prlist_sep_nonempty sep f t in
- if Pp.is_empty e then r
+ if Pp.ismt e then r
else e ++ sep () ++ r
let do_struct f s =
diff --git a/plugins/extraction/scheme.ml b/plugins/extraction/scheme.ml
index a6309e61f9..8d0cc4a0db 100644
--- a/plugins/extraction/scheme.ml
+++ b/plugins/extraction/scheme.ml
@@ -40,11 +40,7 @@ let preamble _ comment _ usf =
(if usf.mldummy then str "(define __ (lambda (_) __))\n\n" else mt ())
let pr_id id =
- let s = Id.to_string id in
- for i = 0 to String.length s - 1 do
- if s.[i] == '\'' then s.[i] <- '~'
- done;
- str s
+ str @@ String.map (fun c -> if c == '\'' then '~' else c) (Id.to_string id)
let paren = pp_par true
diff --git a/plugins/extraction/table.ml b/plugins/extraction/table.ml
index 5e7d810c93..d6a334c5fe 100644
--- a/plugins/extraction/table.ml
+++ b/plugins/extraction/table.ml
@@ -773,9 +773,7 @@ let file_of_modfile mp =
| MPfile f -> Id.to_string (List.hd (DirPath.repr f))
| _ -> assert false
in
- let s = String.copy (string_of_modfile mp) in
- if s.[0] != s0.[0] then s.[0] <- s0.[0];
- s
+ String.mapi (fun i c -> if i = 0 then s0.[0] else c) (string_of_modfile mp)
let add_blacklist_entries l =
blacklist_table :=
diff --git a/plugins/firstorder/g_ground.ml4 b/plugins/firstorder/g_ground.ml4
index e28d6aa626..3c03193196 100644
--- a/plugins/firstorder/g_ground.ml4
+++ b/plugins/firstorder/g_ground.ml4
@@ -159,21 +159,3 @@ END
open Proofview.Notations
open Cc_plugin
-open Decl_mode_plugin
-
-let default_declarative_automation =
- Proofview.tclUNIT () >>= fun () -> (* delay for [congruence_depth] *)
- Tacticals.New.tclORELSE
- (Tacticals.New.tclORELSE (Auto.h_trivial [] None)
- (Cctac.congruence_tac !congruence_depth []))
- (Proofview.V82.tactic (gen_ground_tac true
- (Some (Tacticals.New.tclTHEN
- (snd (default_solver ()))
- (Cctac.congruence_tac !congruence_depth [])))
- [] []))
-
-
-
-let () =
- Decl_proof_instr.register_automation_tac default_declarative_automation
-
diff --git a/plugins/fourier/Fourier.v b/plugins/fourier/Fourier.v
index 1d7ee93ea3..a962547131 100644
--- a/plugins/fourier/Fourier.v
+++ b/plugins/fourier/Fourier.v
@@ -13,6 +13,6 @@ Require Export DiscrR.
Require Export Fourier_util.
Declare ML Module "fourier_plugin".
-Ltac fourier := abstract (fourierz; field; discrR).
+Ltac fourier := abstract (compute [IZR IPR IPR_2] in *; fourierz; field; discrR).
Ltac fourier_eq := apply Rge_antisym; fourier.
diff --git a/plugins/funind/functional_principles_proofs.ml b/plugins/funind/functional_principles_proofs.ml
index 527f4f0b12..3199474dde 100644
--- a/plugins/funind/functional_principles_proofs.ml
+++ b/plugins/funind/functional_principles_proofs.ml
@@ -1217,7 +1217,7 @@ let prove_princ_for_struct (evd:Evd.evar_map ref) interactive_proof fun_num fnam
let mk_fixes : tactic =
let pre_info,infos = list_chop fun_num infos in
match pre_info,infos with
- | [],[] -> tclIDTAC
+ | _,[] -> tclIDTAC
| _, this_fix_info::others_infos ->
let other_fix_infos =
List.map
@@ -1233,7 +1233,6 @@ let prove_princ_for_struct (evd:Evd.evar_map ref) interactive_proof fun_num fnam
else
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 *)
tclTHENSEQ
diff --git a/plugins/funind/glob_term_to_relation.ml b/plugins/funind/glob_term_to_relation.ml
index de2e5ea4e2..084de31c09 100644
--- a/plugins/funind/glob_term_to_relation.ml
+++ b/plugins/funind/glob_term_to_relation.ml
@@ -42,7 +42,7 @@ let compose_glob_context =
match bt with
| Lambda n -> mkGLambda(n,t,acc)
| Prod n -> mkGProd(n,t,acc)
- | LetIn n -> mkGLetIn(n,t,acc)
+ | LetIn n -> mkGLetIn(n,t,None,acc)
in
List.fold_right compose_binder
@@ -489,7 +489,7 @@ let rec build_entry_lc env funnames avoid rt : glob_constr build_entry_return =
| u::l ->
match t with
| GLambda(loc,na,_,nat,b) ->
- GLetIn(Loc.ghost,na,u,aux b l)
+ GLetIn(Loc.ghost,na,u,None,aux b l)
| _ ->
GApp(Loc.ghost,t,l)
in
@@ -535,7 +535,7 @@ let rec build_entry_lc env funnames avoid rt : glob_constr build_entry_return =
args_res.result
}
| GApp _ -> assert false (* we have collected all the app in [glob_decompose_app] *)
- | GLetIn(_,n,t,b) ->
+ | GLetIn(_,n,v,t,b) ->
(* if we have [(let x := v in b) t1 ... tn] ,
we discard our work and compute the list of constructor for
[let x = v in (b t1 ... tn)] up to alpha conversion
@@ -559,7 +559,7 @@ let rec build_entry_lc env funnames avoid rt : glob_constr build_entry_return =
env
funnames
avoid
- (mkGLetIn(new_n,t,mkGApp(new_b,args)))
+ (mkGLetIn(new_n,v,t,mkGApp(new_b,args)))
| GCases _ | GIf _ | GLetTuple _ ->
(* we have [(match e1, ...., en with ..... end) t1 tn]
we first compute the result from the case and
@@ -603,12 +603,13 @@ let rec build_entry_lc env funnames avoid rt : glob_constr build_entry_return =
let new_env = raw_push_named (n,None,t) env in
let b_res = build_entry_lc new_env funnames avoid b in
combine_results (combine_prod n) t_res b_res
- | GLetIn(_,n,v,b) ->
+ | GLetIn(loc,n,v,typ,b) ->
(* we first compute the list of constructor
corresponding to the body of the function,
then the one corresponding to the value [t]
and combine the two result
*)
+ let v = match typ with None -> v | Some t -> GCast (loc,v,CastConv t) in
let v_res = build_entry_lc env funnames avoid v in
let v_as_constr,ctx = Pretyping.understand env (Evd.from_env env) v in
let v_type = Typing.unsafe_type_of env (Evd.from_env env) v_as_constr in
@@ -1115,8 +1116,9 @@ let rec rebuild_cons env nb_args relname args crossed_types depth rt =
(* We have renamed all the anonymous functions during alpha_renaming phase *)
end
- | GLetIn(_,n,t,b) ->
+ | GLetIn(loc,n,v,t,b) ->
begin
+ let t = match t with None -> v | Some t -> GCast (loc,v,CastConv t) in
let not_free_in_t id = not (is_free_in id t) in
let evd = (Evd.from_env env) in
let t',ctx = Pretyping.understand env evd t in
@@ -1131,7 +1133,7 @@ let rec rebuild_cons env nb_args relname args crossed_types depth rt =
match n with
| Name id when Id.Set.mem id id_to_exclude && depth >= nb_args ->
new_b,Id.Set.remove id (Id.Set.filter not_free_in_t id_to_exclude)
- | _ -> GLetIn(Loc.ghost,n,t,new_b),
+ | _ -> GLetIn(Loc.ghost,n,t,None,new_b), (* HOPING IT WOULD WORK *)
Id.Set.filter not_free_in_t id_to_exclude
end
| GLetTuple(_,nal,(na,rto),t,b) ->
@@ -1189,9 +1191,13 @@ let rec compute_cst_params relnames params = function
compute_cst_params_from_app [] (params,rtl)
| GApp(_,f,args) ->
List.fold_left (compute_cst_params relnames) params (f::args)
- | GLambda(_,_,_,t,b) | GProd(_,_,_,t,b) | GLetIn(_,_,t,b) | GLetTuple(_,_,_,t,b) ->
+ | GLambda(_,_,_,t,b) | GProd(_,_,_,t,b) | GLetTuple(_,_,_,t,b) ->
let t_params = compute_cst_params relnames params t in
compute_cst_params relnames t_params b
+ | GLetIn(_,_,v,t,b) ->
+ let v_params = compute_cst_params relnames params v in
+ let t_params = Option.fold_left (compute_cst_params relnames) v_params t in
+ compute_cst_params relnames t_params b
| GCases _ ->
params (* If there is still cases at this point they can only be
discrimination ones *)
@@ -1202,12 +1208,12 @@ let rec compute_cst_params relnames params = function
and compute_cst_params_from_app acc (params,rtl) =
match params,rtl with
| _::_,[] -> assert false (* the rel has at least nargs + 1 arguments ! *)
- | ((Name id,_,is_defined) as param)::params',(GVar(_,id'))::rtl'
- when Id.compare id id' == 0 && not is_defined ->
+ | ((Name id,_,None) as param)::params',(GVar(_,id'))::rtl'
+ when Id.compare id id' == 0 ->
compute_cst_params_from_app (param::acc) (params',rtl')
| _ -> List.rev acc
-let compute_params_name relnames (args : (Name.t * Glob_term.glob_constr * bool) list array) csts =
+let compute_params_name relnames (args : (Name.t * Glob_term.glob_constr * glob_constr option) list array) csts =
let rels_params =
Array.mapi
(fun i args ->
@@ -1222,11 +1228,11 @@ let compute_params_name relnames (args : (Name.t * Glob_term.glob_constr * bool)
let _ =
try
List.iteri
- (fun i ((n,nt,is_defined) as param) ->
+ (fun i ((n,nt,typ) as param) ->
if Array.for_all
(fun l ->
- let (n',nt',is_defined') = List.nth l i in
- Name.equal n n' && glob_constr_eq nt nt' && (is_defined : bool) == is_defined')
+ let (n',nt',typ') = List.nth l i in
+ Name.equal n n' && glob_constr_eq nt nt' && Option.equal glob_constr_eq typ typ')
rels_params
then
l := param::!l
@@ -1241,15 +1247,15 @@ let rec rebuild_return_type rt =
match rt with
| Constrexpr.CProdN(loc,n,t') ->
Constrexpr.CProdN(loc,n,rebuild_return_type t')
- | Constrexpr.CLetIn(loc,na,t,t') ->
- Constrexpr.CLetIn(loc,na,t,rebuild_return_type t')
+ | Constrexpr.CLetIn(loc,na,v,t,t') ->
+ Constrexpr.CLetIn(loc,na,v,t,rebuild_return_type t')
| _ -> Constrexpr.CProdN(Loc.ghost,[[Loc.ghost,Anonymous],
Constrexpr.Default Decl_kinds.Explicit,rt],
Constrexpr.CSort(Loc.ghost,GType []))
let do_build_inductive
- evd (funconstants: Term.pconstant list) (funsargs: (Name.t * glob_constr * bool) list list)
+ evd (funconstants: Term.pconstant list) (funsargs: (Name.t * glob_constr * glob_constr option) list list)
returned_types
(rtl:glob_constr list) =
let _time1 = System.get_time () in
@@ -1288,16 +1294,17 @@ let do_build_inductive
let resa = Array.map (build_entry_lc env funnames_as_set []) rta in
let env_with_graphs =
let rel_arity i funargs = (* Rebuilding arities (with parameters) *)
- let rel_first_args :(Name.t * Glob_term.glob_constr * bool ) list =
+ let rel_first_args :(Name.t * Glob_term.glob_constr * Glob_term.glob_constr option ) list =
funargs
in
List.fold_right
- (fun (n,t,is_defined) acc ->
- if is_defined
- then
+ (fun (n,t,typ) acc ->
+ match typ with
+ | Some typ ->
Constrexpr.CLetIn(Loc.ghost,(Loc.ghost, n),with_full_print (Constrextern.extern_glob_constr Id.Set.empty) t,
+ Some (with_full_print (Constrextern.extern_glob_constr Id.Set.empty) typ),
acc)
- else
+ | None ->
Constrexpr.CProdN
(Loc.ghost,
[[(Loc.ghost,n)],Constrexpr_ops.default_binder_kind,with_full_print (Constrextern.extern_glob_constr Id.Set.empty) t],
@@ -1355,16 +1362,17 @@ let do_build_inductive
rel_constructors
in
let rel_arity i funargs = (* Reduilding arities (with parameters) *)
- let rel_first_args :(Name.t * Glob_term.glob_constr * bool ) list =
+ let rel_first_args :(Name.t * Glob_term.glob_constr * Glob_term.glob_constr option ) list =
(snd (List.chop nrel_params funargs))
in
List.fold_right
- (fun (n,t,is_defined) acc ->
- if is_defined
- then
+ (fun (n,t,typ) acc ->
+ match typ with
+ | Some typ ->
Constrexpr.CLetIn(Loc.ghost,(Loc.ghost, n),with_full_print (Constrextern.extern_glob_constr Id.Set.empty) t,
+ Some (with_full_print (Constrextern.extern_glob_constr Id.Set.empty) typ),
acc)
- else
+ | None ->
Constrexpr.CProdN
(Loc.ghost,
[[(Loc.ghost,n)],Constrexpr_ops.default_binder_kind,with_full_print (Constrextern.extern_glob_constr Id.Set.empty) t],
@@ -1391,12 +1399,13 @@ let do_build_inductive
in
let rel_params =
List.map
- (fun (n,t,is_defined) ->
- if is_defined
- then
- Constrexpr.LocalRawDef((Loc.ghost,n), Constrextern.extern_glob_constr Id.Set.empty t)
- else
- Constrexpr.LocalRawAssum
+ (fun (n,t,typ) ->
+ match typ with
+ | Some typ ->
+ Constrexpr.CLocalDef((Loc.ghost,n), Constrextern.extern_glob_constr Id.Set.empty t,
+ Some (with_full_print (Constrextern.extern_glob_constr Id.Set.empty) typ))
+ | None ->
+ Constrexpr.CLocalAssum
([(Loc.ghost,n)], Constrexpr_ops.default_binder_kind, Constrextern.extern_glob_constr Id.Set.empty t)
)
rels_params
diff --git a/plugins/funind/glob_term_to_relation.mli b/plugins/funind/glob_term_to_relation.mli
index 5bb1376e26..0cab5a6d35 100644
--- a/plugins/funind/glob_term_to_relation.mli
+++ b/plugins/funind/glob_term_to_relation.mli
@@ -12,7 +12,7 @@ val build_inductive :
*)
Evd.evar_map ->
Term.pconstant list ->
- (Name.t*Glob_term.glob_constr*bool) list list -> (* The list of function args *)
+ (Name.t*Glob_term.glob_constr*Glob_term.glob_constr option) list list -> (* The list of function args *)
Constrexpr.constr_expr list -> (* The list of function returned type *)
Glob_term.glob_constr list -> (* the list of body *)
unit
diff --git a/plugins/funind/glob_termops.ml b/plugins/funind/glob_termops.ml
index 4e561fc7e5..99f50437b9 100644
--- a/plugins/funind/glob_termops.ml
+++ b/plugins/funind/glob_termops.ml
@@ -15,7 +15,7 @@ let mkGVar id = GVar(Loc.ghost,id)
let mkGApp(rt,rtl) = GApp(Loc.ghost,rt,rtl)
let mkGLambda(n,t,b) = GLambda(Loc.ghost,n,Explicit,t,b)
let mkGProd(n,t,b) = GProd(Loc.ghost,n,Explicit,t,b)
-let mkGLetIn(n,t,b) = GLetIn(Loc.ghost,n,t,b)
+let mkGLetIn(n,b,t,c) = GLetIn(Loc.ghost,n,b,t,c)
let mkGCases(rto,l,brl) = GCases(Loc.ghost,Term.RegularStyle,rto,l,brl)
let mkGSort s = GSort(Loc.ghost,s)
let mkGHole () = GHole(Loc.ghost,Evar_kinds.BinderType Anonymous,Misctypes.IntroAnonymous,None)
@@ -37,8 +37,8 @@ let glob_decompose_prod_or_letin =
let rec glob_decompose_prod args = function
| GProd(_,n,k,t,b) ->
glob_decompose_prod ((n,None,Some t)::args) b
- | GLetIn(_,n,t,b) ->
- glob_decompose_prod ((n,Some t,None)::args) b
+ | GLetIn(_,n,b,t,c) ->
+ glob_decompose_prod ((n,Some b,t)::args) c
| rt -> args,rt
in
glob_decompose_prod []
@@ -51,7 +51,7 @@ let glob_compose_prod_or_letin =
fun concl decl ->
match decl with
| (n,None,Some t) -> mkGProd(n,t,concl)
- | (n,Some bdy,None) -> mkGLetIn(n,bdy,concl)
+ | (n,Some bdy,t) -> mkGLetIn(n,bdy,t,concl)
| _ -> assert false)
let glob_decompose_prod_n n =
@@ -73,8 +73,8 @@ let glob_decompose_prod_or_letin_n n =
match c with
| GProd(_,n,_,t,b) ->
glob_decompose_prod (i-1) ((n,None,Some t)::args) b
- | GLetIn(_,n,t,b) ->
- glob_decompose_prod (i-1) ((n,Some t,None)::args) b
+ | GLetIn(_,n,b,t,c) ->
+ glob_decompose_prod (i-1) ((n,Some b,t)::args) c
| rt -> args,rt
in
glob_decompose_prod n []
@@ -150,10 +150,11 @@ let change_vars =
change_vars mapping t,
change_vars (remove_name_from_mapping mapping name) b
)
- | GLetIn(loc,name,def,b) ->
+ | GLetIn(loc,name,def,typ,b) ->
GLetIn(loc,
name,
change_vars mapping def,
+ Option.map (change_vars mapping) typ,
change_vars (remove_name_from_mapping mapping name) b
)
| GLetTuple(loc,nal,(na,rto),b,e) ->
@@ -272,10 +273,11 @@ let rec alpha_rt excluded rt =
let new_t = alpha_rt excluded t in
let new_b = alpha_rt excluded b in
GProd(loc,Anonymous,k,new_t,new_b)
- | GLetIn(loc,Anonymous,t,b) ->
- let new_t = alpha_rt excluded t in
+ | GLetIn(loc,Anonymous,b,t,c) ->
let new_b = alpha_rt excluded b in
- GLetIn(loc,Anonymous,new_t,new_b)
+ let new_t = Option.map (alpha_rt excluded) t in
+ let new_c = alpha_rt excluded c in
+ GLetIn(loc,Anonymous,new_b,new_t,new_c)
| GLambda(loc,Name id,k,t,b) ->
let new_id = Namegen.next_ident_away id excluded in
let t,b =
@@ -302,19 +304,17 @@ let rec alpha_rt excluded rt =
let new_t = alpha_rt new_excluded t in
let new_b = alpha_rt new_excluded b in
GProd(loc,Name new_id,k,new_t,new_b)
- | GLetIn(loc,Name id,t,b) ->
+ | GLetIn(loc,Name id,b,t,c) ->
let new_id = Namegen.next_ident_away id excluded in
- let t,b =
- if Id.equal new_id id
- then t,b
- else
- let replace = change_vars (Id.Map.add id new_id Id.Map.empty) in
- (t,replace b)
+ let c =
+ if Id.equal new_id id then c
+ else change_vars (Id.Map.add id new_id Id.Map.empty) c
in
let new_excluded = new_id::excluded in
- let new_t = alpha_rt new_excluded t in
let new_b = alpha_rt new_excluded b in
- GLetIn(loc,Name new_id,new_t,new_b)
+ let new_t = Option.map (alpha_rt new_excluded) t in
+ let new_c = alpha_rt new_excluded c in
+ GLetIn(loc,Name new_id,new_b,new_t,new_c)
| GLetTuple(loc,nal,(na,rto),t,b) ->
@@ -388,13 +388,20 @@ let is_free_in id =
| GEvar _ -> false
| GPatVar _ -> false
| GApp(_,rt,rtl) -> List.exists is_free_in (rt::rtl)
- | GLambda(_,n,_,t,b) | GProd(_,n,_,t,b) | GLetIn(_,n,t,b) ->
+ | GLambda(_,n,_,t,b) | GProd(_,n,_,t,b) ->
let check_in_b =
match n with
| Name id' -> not (Id.equal id' id)
| _ -> true
in
is_free_in t || (check_in_b && is_free_in b)
+ | GLetIn(_,n,b,t,c) ->
+ let check_in_c =
+ match n with
+ | Name id' -> not (Id.equal id' id)
+ | _ -> true
+ in
+ is_free_in b || Option.cata is_free_in true t || (check_in_c && is_free_in c)
| GCases(_,_,_,el,brl) ->
(List.exists (fun (e,_) -> is_free_in e) el) ||
List.exists is_free_in_br brl
@@ -473,11 +480,12 @@ let replace_var_by_term x_id term =
replace_var_by_pattern t,
replace_var_by_pattern b
)
- | GLetIn(_,Name id,_,_) when Id.compare id x_id == 0 -> rt
- | GLetIn(loc,name,def,b) ->
+ | GLetIn(_,Name id,_,_,_) when Id.compare id x_id == 0 -> rt
+ | GLetIn(loc,name,def,typ,b) ->
GLetIn(loc,
name,
replace_var_by_pattern def,
+ Option.map (replace_var_by_pattern) typ,
replace_var_by_pattern b
)
| GLetTuple(_,nal,_,_,_)
@@ -589,7 +597,7 @@ let ids_of_glob_constr c =
ids_of_glob_constr [] g @ List.flatten (List.map (ids_of_glob_constr []) args) @ acc
| GLambda (loc,na,k,ty,c) -> idof na :: ids_of_glob_constr [] ty @ ids_of_glob_constr [] c @ acc
| GProd (loc,na,k,ty,c) -> idof na :: ids_of_glob_constr [] ty @ ids_of_glob_constr [] c @ acc
- | GLetIn (loc,na,b,c) -> idof na :: ids_of_glob_constr [] b @ ids_of_glob_constr [] c @ acc
+ | GLetIn (loc,na,b,t,c) -> idof na :: ids_of_glob_constr [] b @ Option.cata (ids_of_glob_constr []) [] t @ ids_of_glob_constr [] c @ acc
| GCast (loc,c,(CastConv t|CastVM t|CastNative t)) -> ids_of_glob_constr [] c @ ids_of_glob_constr [] t @ acc
| GCast (loc,c,CastCoerce) -> ids_of_glob_constr [] c @ acc
| GIf (loc,c,(na,po),b1,b2) -> ids_of_glob_constr [] c @ ids_of_glob_constr [] b1 @ ids_of_glob_constr [] b2 @ acc
@@ -633,9 +641,9 @@ let zeta_normalize =
zeta_normalize_term t,
zeta_normalize_term b
)
- | GLetIn(_,Name id,def,b) ->
+ | GLetIn(_,Name id,def,typ,b) ->
zeta_normalize_term (replace_var_by_term id def b)
- | GLetIn(loc,Anonymous,def,b) -> zeta_normalize_term b
+ | GLetIn(loc,Anonymous,def,typ,b) -> zeta_normalize_term b
| GLetTuple(loc,nal,(na,rto),def,b) ->
GLetTuple(loc,
nal,
@@ -690,7 +698,7 @@ let expand_as =
| GApp(loc,f,args) -> GApp(loc,expand_as map f,List.map (expand_as map) args)
| GLambda(loc,na,k,t,b) -> GLambda(loc,na,k,expand_as map t, expand_as map b)
| GProd(loc,na,k,t,b) -> GProd(loc,na,k,expand_as map t, expand_as map b)
- | GLetIn(loc,na,v,b) -> GLetIn(loc,na, expand_as map v,expand_as map b)
+ | GLetIn(loc,na,v,typ,b) -> GLetIn(loc,na, expand_as map v,Option.map (expand_as map) typ,expand_as map b)
| GLetTuple(loc,nal,(na,po),v,b) ->
GLetTuple(loc,nal,(na,Option.map (expand_as map) po),
expand_as map v, expand_as map b)
diff --git a/plugins/funind/glob_termops.mli b/plugins/funind/glob_termops.mli
index 179e8fe8d9..84359a36b7 100644
--- a/plugins/funind/glob_termops.mli
+++ b/plugins/funind/glob_termops.mli
@@ -19,7 +19,7 @@ val mkGVar : Id.t -> glob_constr
val mkGApp : glob_constr*(glob_constr list) -> glob_constr
val mkGLambda : Name.t * glob_constr * glob_constr -> glob_constr
val mkGProd : Name.t * glob_constr * glob_constr -> glob_constr
-val mkGLetIn : Name.t * glob_constr * glob_constr -> glob_constr
+val mkGLetIn : Name.t * glob_constr * glob_constr option * glob_constr -> glob_constr
val mkGCases : glob_constr option * tomatch_tuples * cases_clauses -> glob_constr
val mkGSort : glob_sort -> glob_constr
val mkGHole : unit -> glob_constr (* we only build Evd.BinderType Anonymous holes *)
diff --git a/plugins/funind/indfun.ml b/plugins/funind/indfun.ml
index 99b04898ba..d394fe313e 100644
--- a/plugins/funind/indfun.ml
+++ b/plugins/funind/indfun.ml
@@ -129,11 +129,11 @@ let functional_induction with_clean c princl pat =
let rec abstract_glob_constr c = function
| [] -> c
- | Constrexpr.LocalRawDef (x,b)::bl -> Constrexpr_ops.mkLetInC(x,b,abstract_glob_constr c bl)
- | Constrexpr.LocalRawAssum (idl,k,t)::bl ->
+ | Constrexpr.CLocalDef (x,b,t)::bl -> Constrexpr_ops.mkLetInC(x,b,t,abstract_glob_constr c bl)
+ | Constrexpr.CLocalAssum (idl,k,t)::bl ->
List.fold_right (fun x b -> Constrexpr_ops.mkLambdaC([x],k,t,b)) idl
(abstract_glob_constr c bl)
- | Constrexpr.LocalPattern _::bl -> assert false
+ | Constrexpr.CLocalPattern _::bl -> assert false
let interp_casted_constr_with_implicits env sigma impls c =
Constrintern.intern_gen Pretyping.WithoutTypeConstraint env ~impls
@@ -192,8 +192,10 @@ let is_rec names =
| GRec _ -> error "GRec not handled"
| GIf(_,b,_,lhs,rhs) ->
(lookup names b) || (lookup names lhs) || (lookup names rhs)
- | GLetIn(_,na,t,b) | GLambda(_,na,_,t,b) | GProd(_,na,_,t,b) ->
+ | GProd(_,na,_,t,b) | GLambda(_,na,_,t,b) ->
lookup names t || lookup (Nameops.name_fold Id.Set.remove na names) b
+ | GLetIn(_,na,b,t,c) ->
+ lookup names b || Option.cata (lookup names) true t || lookup (Nameops.name_fold Id.Set.remove na names) c
| GLetTuple(_,nal,_,t,b) -> lookup names t ||
lookup
(List.fold_left
@@ -215,9 +217,9 @@ let is_rec names =
let rec local_binders_length = function
(* Assume that no `{ ... } contexts occur *)
| [] -> 0
- | Constrexpr.LocalRawDef _::bl -> 1 + local_binders_length bl
- | Constrexpr.LocalRawAssum (idl,_,_)::bl -> List.length idl + local_binders_length bl
- | Constrexpr.LocalPattern _::bl -> assert false
+ | Constrexpr.CLocalDef _::bl -> 1 + local_binders_length bl
+ | Constrexpr.CLocalAssum (idl,_,_)::bl -> List.length idl + local_binders_length bl
+ | Constrexpr.CLocalPattern _::bl -> assert false
let prepare_body ((name,_,args,types,_),_) rt =
let n = local_binders_length args in
@@ -496,7 +498,7 @@ let register_mes fname rec_impls wf_mes_expr wf_rel_expr_opt wf_arg using_lemmas
| None ->
begin
match args with
- | [Constrexpr.LocalRawAssum ([(_,Name x)],k,t)] -> t,x
+ | [Constrexpr.CLocalAssum ([(_,Name x)],k,t)] -> t,x
| _ -> error "Recursive argument must be specified"
end
| Some wf_args ->
@@ -504,7 +506,7 @@ let register_mes fname rec_impls wf_mes_expr wf_rel_expr_opt wf_arg using_lemmas
match
List.find
(function
- | Constrexpr.LocalRawAssum(l,k,t) ->
+ | Constrexpr.CLocalAssum(l,k,t) ->
List.exists
(function (_,Name id) -> Id.equal id wf_args | _ -> false)
l
@@ -512,7 +514,7 @@ let register_mes fname rec_impls wf_mes_expr wf_rel_expr_opt wf_arg using_lemmas
)
args
with
- | Constrexpr.LocalRawAssum(_,k,t) -> t,wf_args
+ | Constrexpr.CLocalAssum(_,k,t) -> t,wf_args
| _ -> assert false
with Not_found -> assert false
in
@@ -570,10 +572,10 @@ let make_assoc assoc l1 l2 =
let rec rebuild_bl (aux,assoc) bl typ =
match bl,typ with
| [], _ -> (List.rev aux,replace_vars_constr_expr assoc typ,assoc)
- | (Constrexpr.LocalRawAssum(nal,bk,_))::bl',typ ->
+ | (Constrexpr.CLocalAssum(nal,bk,_))::bl',typ ->
rebuild_nal (aux,assoc) bk bl' nal (List.length nal) typ
- | (Constrexpr.LocalRawDef(na,_))::bl',Constrexpr.CLetIn(_,_,nat,typ') ->
- rebuild_bl ((Constrexpr.LocalRawDef(na,replace_vars_constr_expr assoc nat)::aux),assoc)
+ | (Constrexpr.CLocalDef(na,_,_))::bl',Constrexpr.CLetIn(_,_,nat,ty,typ') ->
+ rebuild_bl ((Constrexpr.CLocalDef(na,replace_vars_constr_expr assoc nat,Option.map (replace_vars_constr_expr assoc) ty (* ??? *))::aux),assoc)
bl' typ'
| _ -> assert false
and rebuild_nal (aux,assoc) bk bl' nal lnal typ =
@@ -586,7 +588,7 @@ let rec rebuild_bl (aux,assoc) bl typ =
then
let old_nal',new_nal' = List.chop lnal nal' in
let nassoc = make_assoc assoc old_nal' nal in
- let assum = LocalRawAssum(nal,bk,replace_vars_constr_expr assoc nal't) in
+ let assum = CLocalAssum(nal,bk,replace_vars_constr_expr assoc nal't) in
rebuild_bl ((assum :: aux), nassoc) bl'
(if List.is_empty new_nal' && List.is_empty rest
then typ'
@@ -596,7 +598,7 @@ let rec rebuild_bl (aux,assoc) bl typ =
else
let captured_nal,non_captured_nal = List.chop lnal' nal in
let nassoc = make_assoc assoc nal' captured_nal in
- let assum = LocalRawAssum(captured_nal,bk,replace_vars_constr_expr assoc nal't) in
+ let assum = CLocalAssum(captured_nal,bk,replace_vars_constr_expr assoc nal't) in
rebuild_nal ((assum :: aux), nassoc)
bk bl' non_captured_nal (lnal - lnal') (CProdN(Loc.ghost,rest,typ'))
| _ -> assert false
@@ -726,8 +728,8 @@ let rec add_args id new_args b =
CLambdaN(loc,
List.map (fun (nal,k,b2) -> (nal,k,add_args id new_args b2)) nal,
add_args id new_args b1)
- | CLetIn(loc,na,b1,b2) ->
- CLetIn(loc,na,add_args id new_args b1,add_args id new_args b2)
+ | CLetIn(loc,na,b1,t,b2) ->
+ CLetIn(loc,na,add_args id new_args b1,Option.map (add_args id new_args) t,add_args id new_args b2)
| CAppExpl(loc,(pf,r,us),exprl) ->
begin
match r with
@@ -813,7 +815,7 @@ let rec chop_n_arrow n t =
| _ -> anomaly (Pp.str "Not enough products")
-let rec get_args b t : Constrexpr.local_binder list *
+let rec get_args b t : Constrexpr.local_binder_expr list *
Constrexpr.constr_expr * Constrexpr.constr_expr =
match b with
| Constrexpr.CLambdaN (loc, (nal_ta), b') ->
@@ -824,7 +826,7 @@ let rec get_args b t : Constrexpr.local_binder list *
in
let nal_tas,b'',t'' = get_args b' (chop_n_arrow n t) in
(List.map (fun (nal,k,ta) ->
- (Constrexpr.LocalRawAssum (nal,k,ta))) nal_ta)@nal_tas, b'',t''
+ (Constrexpr.CLocalAssum (nal,k,ta))) nal_ta)@nal_tas, b'',t''
end
| _ -> [],b,t
@@ -865,13 +867,13 @@ let make_graph (f_ref:global_reference) =
List.flatten
(List.map
(function
- | Constrexpr.LocalRawDef (na,_)-> []
- | Constrexpr.LocalRawAssum (nal,_,_) ->
+ | Constrexpr.CLocalDef (na,_,_)-> []
+ | Constrexpr.CLocalAssum (nal,_,_) ->
List.map
(fun (loc,n) ->
CRef(Libnames.Ident(loc, Nameops.out_name n),None))
nal
- | Constrexpr.LocalPattern _ -> assert false
+ | Constrexpr.CLocalPattern _ -> assert false
)
nal_tas
)
diff --git a/plugins/funind/indfun_common.ml b/plugins/funind/indfun_common.ml
index a45effb167..aed0fa331c 100644
--- a/plugins/funind/indfun_common.ml
+++ b/plugins/funind/indfun_common.ml
@@ -70,8 +70,8 @@ let chop_rlambda_n =
then List.rev acc,rt
else
match rt with
- | Glob_term.GLambda(_,name,k,t,b) -> chop_lambda_n ((name,t,false)::acc) (n-1) b
- | Glob_term.GLetIn(_,name,v,b) -> chop_lambda_n ((name,v,true)::acc) (n-1) b
+ | Glob_term.GLambda(_,name,k,t,b) -> chop_lambda_n ((name,t,None)::acc) (n-1) b
+ | Glob_term.GLetIn(_,name,v,t,b) -> chop_lambda_n ((name,v,t)::acc) (n-1) b
| _ ->
raise (CErrors.UserError(Some "chop_rlambda_n",
str "chop_rlambda_n: Not enough Lambdas"))
diff --git a/plugins/funind/indfun_common.mli b/plugins/funind/indfun_common.mli
index e5c756f564..2aabfa003e 100644
--- a/plugins/funind/indfun_common.mli
+++ b/plugins/funind/indfun_common.mli
@@ -34,7 +34,7 @@ val list_add_set_eq :
('a -> 'a -> bool) -> 'a -> 'a list -> 'a list
val chop_rlambda_n : int -> Glob_term.glob_constr ->
- (Name.t*Glob_term.glob_constr*bool) list * Glob_term.glob_constr
+ (Name.t*Glob_term.glob_constr*Glob_term.glob_constr option) list * Glob_term.glob_constr
val chop_rprod_n : int -> Glob_term.glob_constr ->
(Name.t*Glob_term.glob_constr) list * Glob_term.glob_constr
diff --git a/plugins/funind/merge.ml b/plugins/funind/merge.ml
index 19c2ed4178..9c23be68ae 100644
--- a/plugins/funind/merge.ml
+++ b/plugins/funind/merge.ml
@@ -510,14 +510,14 @@ let rec merge_app c1 c2 id1 id2 shift filter_shift_stable =
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) , _ ->
+ | GLetIn(_,nme,bdy,typ,trm) , _ ->
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) ->
+ GLetIn(Loc.ghost,nme,bdy,typ,newtrm)
+ | _, GLetIn(_,nme,bdy,typ,trm) ->
let _ = prstr "\nICI3!\n" in
let newtrm = merge_app c1 trm id1 id2 shift filter_shift_stable in
- GLetIn(Loc.ghost,nme,bdy,newtrm)
+ GLetIn(Loc.ghost,nme,bdy,typ,newtrm)
| _ -> let _ = prstr "\nICI4!\n" in
raise NoMerge
@@ -528,14 +528,14 @@ let rec merge_app_unsafe c1 c2 shift filter_shift_stable =
let args = filter_shift_stable lnk (arr1 @ arr2) in
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) , _ ->
+ | GLetIn(_,nme,bdy,typ,trm) , _ ->
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) ->
+ GLetIn(Loc.ghost,nme,bdy,typ,newtrm)
+ | _, GLetIn(_,nme,bdy,typ,trm) ->
let _ = prstr "\nICI3 '!\n" in
let newtrm = merge_app_unsafe c1 trm shift filter_shift_stable in
- GLetIn(Loc.ghost,nme,bdy,newtrm)
+ GLetIn(Loc.ghost,nme,bdy,typ,newtrm)
| _ -> let _ = prstr "\nICI4 '!\n" in raise NoMerge
@@ -822,7 +822,7 @@ let merge_rec_params_and_arity prms1 prms2 shift (concl:constr) =
let _ = prNamedRConstr (string_of_name nme) tp in
let _ = prstr " ; " in
let typ = glob_constr_to_constr_expr tp in
- LocalRawAssum ([(Loc.ghost,nme)], Constrexpr_ops.default_binder_kind, typ) :: acc)
+ CLocalAssum ([(Loc.ghost,nme)], Constrexpr_ops.default_binder_kind, typ) :: acc)
[] params in
let concl = Constrextern.extern_constr false (Global.env()) Evd.empty concl in
let arity,_ =
diff --git a/plugins/ltac/extratactics.ml4 b/plugins/ltac/extratactics.ml4
index 1223f6eb4b..7a9fc6657e 100644
--- a/plugins/ltac/extratactics.ml4
+++ b/plugins/ltac/extratactics.ml4
@@ -38,7 +38,7 @@ let with_delayed_uconstr ist c tac =
let flags = {
Pretyping.use_typeclasses = false;
solve_unification_constraints = true;
- use_hook = Some Pfedit.solve_by_implicit_tactic;
+ use_hook = Pfedit.solve_by_implicit_tactic ();
fail_evar = false;
expand_evars = true
} in
@@ -341,10 +341,10 @@ END
(**********************************************************************)
(* Refine *)
-let constr_flags = {
+let constr_flags () = {
Pretyping.use_typeclasses = true;
Pretyping.solve_unification_constraints = true;
- Pretyping.use_hook = Some Pfedit.solve_by_implicit_tactic;
+ Pretyping.use_hook = Pfedit.solve_by_implicit_tactic ();
Pretyping.fail_evar = false;
Pretyping.expand_evars = true }
@@ -353,7 +353,7 @@ let refine_tac ist simple with_classes c =
let concl = Proofview.Goal.concl gl in
let env = Proofview.Goal.env gl in
let flags =
- { constr_flags with Pretyping.use_typeclasses = with_classes } in
+ { constr_flags () with Pretyping.use_typeclasses = with_classes } in
let expected_type = Pretyping.OfType concl in
let c = Pretyping.type_uconstr ~flags ~expected_type ist c in
let update = { run = fun sigma -> c.delayed env sigma } in
diff --git a/plugins/ltac/g_auto.ml4 b/plugins/ltac/g_auto.ml4
index fcc2b86a91..f75ea70872 100644
--- a/plugins/ltac/g_auto.ml4
+++ b/plugins/ltac/g_auto.ml4
@@ -45,7 +45,7 @@ let eval_uconstrs ist cs =
let flags = {
Pretyping.use_typeclasses = false;
solve_unification_constraints = true;
- use_hook = Some Pfedit.solve_by_implicit_tactic;
+ use_hook = Pfedit.solve_by_implicit_tactic ();
fail_evar = false;
expand_evars = true
} in
diff --git a/plugins/ltac/g_ltac.ml4 b/plugins/ltac/g_ltac.ml4
index aab5687465..fd33a779dc 100644
--- a/plugins/ltac/g_ltac.ml4
+++ b/plugins/ltac/g_ltac.ml4
@@ -8,6 +8,8 @@
(*i camlp4deps: "grammar/grammar.cma" i*)
+DECLARE PLUGIN "ltac_plugin"
+
open Util
open Pp
open Compat
diff --git a/plugins/ltac/g_obligations.ml4 b/plugins/ltac/g_obligations.ml4
index d286a58708..3e6e2db605 100644
--- a/plugins/ltac/g_obligations.ml4
+++ b/plugins/ltac/g_obligations.ml4
@@ -70,7 +70,7 @@ GEXTEND Gram
Constr.closed_binder:
[[ "("; id=Prim.name; ":"; t=Constr.lconstr; "|"; c=Constr.lconstr; ")" ->
let typ = mkAppC (sigref, [mkLambdaC ([id], default_binder_kind, t, c)]) in
- [LocalRawAssum ([id], default_binder_kind, typ)]
+ [CLocalAssum ([id], default_binder_kind, typ)]
] ];
END
diff --git a/plugins/ltac/g_rewrite.ml4 b/plugins/ltac/g_rewrite.ml4
index b1c4f58eb8..c50100bf55 100644
--- a/plugins/ltac/g_rewrite.ml4
+++ b/plugins/ltac/g_rewrite.ml4
@@ -183,7 +183,7 @@ VERNAC COMMAND EXTEND AddRelation3 CLASSIFIED AS SIDEFF
[ declare_relation a aeq n None None (Some lemma3) ]
END
-type binders_argtype = local_binder list
+type binders_argtype = local_binder_expr list
let wit_binders =
(Genarg.create_arg "binders" : binders_argtype Genarg.uniform_genarg_type)
diff --git a/plugins/ltac/pptactic.ml b/plugins/ltac/pptactic.ml
index 6f4ef37b44..dc418d530e 100644
--- a/plugins/ltac/pptactic.ml
+++ b/plugins/ltac/pptactic.ml
@@ -27,6 +27,26 @@ open Pputils
open Ppconstr
open Printer
+module Tag =
+struct
+
+ let keyword = "tactic.keyword"
+ let primitive = "tactic.primitive"
+ let string = "tactic.string"
+
+end
+
+let tag t s = Pp.tag t s
+let do_not_tag _ x = x
+let tag_keyword = tag Tag.keyword
+let tag_primitive = tag Tag.primitive
+let tag_string = tag Tag.string
+let tag_glob_tactic_expr = do_not_tag
+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_atomic_tactic_expr = do_not_tag
+
let pr_global x = Nametab.pr_global_env Id.Set.empty x
type 'a grammar_tactic_prod_item_expr =
@@ -64,30 +84,6 @@ type 'a extra_genarg_printer =
(tolerability -> Val.t -> std_ppcmds) ->
'a -> std_ppcmds
-module Make
- (Ppconstr : Ppconstrsig.Pp)
- (Taggers : sig
- val tag_keyword
- : std_ppcmds -> std_ppcmds
- val tag_primitive
- : std_ppcmds -> std_ppcmds
- val tag_string
- : std_ppcmds -> std_ppcmds
- val tag_glob_tactic_expr
- : glob_tactic_expr -> std_ppcmds -> std_ppcmds
- val tag_glob_atomic_tactic_expr
- : glob_atomic_tactic_expr -> std_ppcmds -> std_ppcmds
- val tag_raw_tactic_expr
- : raw_tactic_expr -> std_ppcmds -> std_ppcmds
- val tag_raw_atomic_tactic_expr
- : raw_atomic_tactic_expr -> std_ppcmds -> std_ppcmds
- val tag_atomic_tactic_expr
- : atomic_tactic_expr -> std_ppcmds -> std_ppcmds
- end)
-= struct
-
- open Taggers
-
let keyword x = tag_keyword (str x)
let primitive x = tag_primitive (str x)
@@ -1206,37 +1202,6 @@ module Make
let pr_atomic_tactic env = pr_atomic_tactic_level env ltop
-end
-
-module Tag =
-struct
- let keyword =
- let style = Terminal.make ~bold:true () in
- Ppstyle.make ~style ["tactic"; "keyword"]
-
- let primitive =
- let style = Terminal.make ~fg_color:`LIGHT_GREEN () in
- Ppstyle.make ~style ["tactic"; "primitive"]
-
- let string =
- let style = Terminal.make ~fg_color:`LIGHT_RED () in
- Ppstyle.make ~style ["tactic"; "string"]
-
-end
-
-include Make (Ppconstr) (struct
- let tag t s = Pp.tag (Pp.Tag.inj t Ppstyle.tag) s
- let do_not_tag _ x = x
- let tag_keyword = tag Tag.keyword
- let tag_primitive = tag Tag.primitive
- let tag_string = tag Tag.string
- let tag_glob_tactic_expr = do_not_tag
- 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_atomic_tactic_expr = do_not_tag
-end)
-
let declare_extra_genarg_pprule wit
(f : 'a raw_extra_genarg_printer)
(g : 'b glob_extra_genarg_printer)
@@ -1338,22 +1303,3 @@ 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
-
- include Make (Ppconstr.Richpp) (struct
- open Ppannotation
- open Genarg
- let do_not_tag _ x = x
- let tag e s = Pp.tag (Pp.Tag.inj e tag) s
- let tag_keyword = tag AKeyword
- let tag_primitive = tag AKeyword
- let tag_string = do_not_tag ()
- let tag_glob_tactic_expr e = tag (AGlbGenArg (in_gen (glbwit wit_ltac) e))
- let tag_glob_atomic_tactic_expr = do_not_tag
- let tag_raw_tactic_expr e = tag (ARawGenArg (in_gen (rawwit wit_ltac) e))
- let tag_raw_atomic_tactic_expr = do_not_tag
- let tag_atomic_tactic_expr = do_not_tag
- end)
-
-end
diff --git a/plugins/ltac/pptactic.mli b/plugins/ltac/pptactic.mli
index 86e3ea5484..43e22dba3f 100644
--- a/plugins/ltac/pptactic.mli
+++ b/plugins/ltac/pptactic.mli
@@ -13,6 +13,8 @@ open Pp
open Genarg
open Geninterp
open Names
+open Misctypes
+open Environ
open Constrexpr
open Tacexpr
open Ppextend
@@ -54,14 +56,66 @@ type pp_tactic = {
val declare_notation_tactic_pprule : KerName.t -> pp_tactic -> unit
-(** The default pretty-printers produce {!Pp.std_ppcmds} that are
- interpreted as raw strings. *)
-include Pptacticsig.Pp
+val pr_with_occurrences :
+ ('a -> std_ppcmds) -> 'a Locus.with_occurrences -> std_ppcmds
+val pr_red_expr :
+ ('a -> std_ppcmds) * ('a -> std_ppcmds) * ('b -> std_ppcmds) * ('c -> std_ppcmds) ->
+ ('a,'b,'c) Genredexpr.red_expr_gen -> std_ppcmds
+val pr_may_eval :
+ ('a -> std_ppcmds) -> ('a -> std_ppcmds) -> ('b -> std_ppcmds) ->
+ ('c -> std_ppcmds) -> ('a,'b,'c) Genredexpr.may_eval -> std_ppcmds
+
+val pr_and_short_name : ('a -> std_ppcmds) -> 'a and_short_name -> std_ppcmds
+val pr_or_by_notation : ('a -> std_ppcmds) -> 'a or_by_notation -> std_ppcmds
+
+val pr_in_clause :
+ ('a -> Pp.std_ppcmds) -> 'a Locus.clause_expr -> Pp.std_ppcmds
+
+val pr_clauses : bool option ->
+ ('a -> Pp.std_ppcmds) -> 'a Locus.clause_expr -> Pp.std_ppcmds
+
+val pr_raw_generic : env -> rlevel generic_argument -> std_ppcmds
+
+val pr_glb_generic : env -> glevel generic_argument -> std_ppcmds
+
+val pr_raw_extend: env -> int ->
+ ml_tactic_entry -> raw_tactic_arg list -> std_ppcmds
+
+val pr_glob_extend: env -> int ->
+ ml_tactic_entry -> glob_tactic_arg list -> std_ppcmds
+
+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_ltac_constant : Nametab.ltac_constant -> std_ppcmds
+
+val pr_raw_tactic : raw_tactic_expr -> std_ppcmds
+
+val pr_raw_tactic_level : tolerability -> raw_tactic_expr -> std_ppcmds
+
+val pr_glob_tactic : env -> glob_tactic_expr -> std_ppcmds
+
+val pr_atomic_tactic : env -> atomic_tactic_expr -> std_ppcmds
+
+val pr_hintbases : string list option -> std_ppcmds
+
+val pr_auto_using : ('constr -> std_ppcmds) -> 'constr list -> std_ppcmds
+
+val pr_bindings :
+ ('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
-(** The rich pretty-printers produce {!Pp.std_ppcmds} that are
- interpreted as annotated strings. The annotations can be
- retrieved using {!RichPp.rich_pp}. Their definitions are
- located in {!Ppannotation.t}. *)
-module Richpp : Pptacticsig.Pp
val ltop : tolerability
diff --git a/plugins/ltac/pptacticsig.mli b/plugins/ltac/pptacticsig.mli
deleted file mode 100644
index 74ddd377ad..0000000000
--- a/plugins/ltac/pptacticsig.mli
+++ /dev/null
@@ -1,81 +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 Pp
-open Genarg
-open Geninterp
-open Tacexpr
-open Ppextend
-open Environ
-open Misctypes
-
-module type Pp = sig
-
- val pr_with_occurrences :
- ('a -> std_ppcmds) -> 'a Locus.with_occurrences -> std_ppcmds
- val pr_red_expr :
- ('a -> std_ppcmds) * ('a -> std_ppcmds) * ('b -> std_ppcmds) * ('c -> std_ppcmds) ->
- ('a,'b,'c) Genredexpr.red_expr_gen -> std_ppcmds
- val pr_may_eval :
- ('a -> std_ppcmds) -> ('a -> std_ppcmds) -> ('b -> std_ppcmds) ->
- ('c -> std_ppcmds) -> ('a,'b,'c) Genredexpr.may_eval -> std_ppcmds
-
- val pr_and_short_name : ('a -> std_ppcmds) -> 'a and_short_name -> std_ppcmds
-
- val pr_in_clause :
- ('a -> Pp.std_ppcmds) -> 'a Locus.clause_expr -> Pp.std_ppcmds
-
- val pr_clauses : bool option ->
- ('a -> Pp.std_ppcmds) -> 'a Locus.clause_expr -> Pp.std_ppcmds
-
- val pr_raw_generic : env -> rlevel generic_argument -> std_ppcmds
-
- val pr_glb_generic : env -> glevel generic_argument -> std_ppcmds
-
- val pr_raw_extend: env -> int ->
- ml_tactic_entry -> raw_tactic_arg list -> std_ppcmds
-
- val pr_glob_extend: env -> int ->
- ml_tactic_entry -> glob_tactic_arg list -> std_ppcmds
-
- 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
-
- val pr_raw_tactic_level : tolerability -> raw_tactic_expr -> std_ppcmds
-
- val pr_glob_tactic : env -> glob_tactic_expr -> std_ppcmds
-
- val pr_atomic_tactic : env -> atomic_tactic_expr -> std_ppcmds
-
- val pr_hintbases : string list option -> std_ppcmds
-
- val pr_auto_using : ('constr -> std_ppcmds) -> 'constr list -> std_ppcmds
-
- val pr_bindings :
- ('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/plugins/ltac/profile_ltac.ml b/plugins/ltac/profile_ltac.ml
index 2514ededb0..58123f63ef 100644
--- a/plugins/ltac/profile_ltac.ml
+++ b/plugins/ltac/profile_ltac.ml
@@ -257,7 +257,7 @@ let string_of_call ck =
(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 = String.map (fun c -> if c = '\n' then ' ' else c) s in
let s = try String.sub s 0 (CString.string_index_from s 0 "(*") with Not_found -> s in
CString.strip s
diff --git a/plugins/ltac/rewrite.mli b/plugins/ltac/rewrite.mli
index 35c4483513..4fdce0c84f 100644
--- a/plugins/ltac/rewrite.mli
+++ b/plugins/ltac/rewrite.mli
@@ -77,17 +77,17 @@ val is_applied_rewrite_relation :
env -> evar_map -> Context.Rel.t -> constr -> types option
val declare_relation :
- ?binders:local_binder list -> constr_expr -> constr_expr -> Id.t ->
+ ?binders:local_binder_expr list -> constr_expr -> constr_expr -> Id.t ->
constr_expr option -> constr_expr option -> constr_expr option -> unit
val add_setoid :
- bool -> local_binder list -> constr_expr -> constr_expr -> constr_expr ->
+ bool -> local_binder_expr list -> constr_expr -> constr_expr -> constr_expr ->
Id.t -> unit
val add_morphism_infer : bool -> constr_expr -> Id.t -> unit
val add_morphism :
- bool -> local_binder list -> constr_expr -> constr_expr -> Id.t -> unit
+ bool -> local_binder_expr list -> constr_expr -> constr_expr -> Id.t -> unit
val get_reflexive_proof : env -> evar_map -> constr -> constr -> evar_map * constr
diff --git a/plugins/ltac/tacentries.ml b/plugins/ltac/tacentries.ml
index 75edf150e3..cd8c9e471e 100644
--- a/plugins/ltac/tacentries.ml
+++ b/plugins/ltac/tacentries.ml
@@ -302,9 +302,9 @@ let cons_production_parameter = function
| TacTerm _ -> None
| TacNonTerm (_, _, id) -> Some id
-let add_glob_tactic_notation local n prods forml ids tac =
+let add_glob_tactic_notation local ~level prods forml ids tac =
let parule = {
- tacgram_level = n;
+ tacgram_level = level;
tacgram_prods = prods;
} in
let tacobj = {
@@ -360,7 +360,7 @@ let extend_atomic_tactic name entries =
in
List.iteri add_atomic entries
-let add_ml_tactic_notation name prods =
+let add_ml_tactic_notation name ~level prods =
let len = List.length prods in
let iter i prods =
let open Tacexpr in
@@ -372,10 +372,12 @@ let add_ml_tactic_notation name prods =
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
+ add_glob_tactic_notation false ~level prods true ids tac
in
List.iteri iter (List.rev prods);
- extend_atomic_tactic name prods
+ (** We call [extend_atomic_tactic] only for "basic tactics" (the ones at
+ tactic_expr level 0) *)
+ if Int.equal level 0 then extend_atomic_tactic name prods
(**********************************************************************)
(** Ltac quotations *)
diff --git a/plugins/ltac/tacentries.mli b/plugins/ltac/tacentries.mli
index 969c118fb5..0695044736 100644
--- a/plugins/ltac/tacentries.mli
+++ b/plugins/ltac/tacentries.mli
@@ -45,7 +45,7 @@ val register_tactic_notation_entry : string -> ('a, 'b, 'c) Genarg.genarg_type -
to finding an argument by name (as in {!Genarg}) if there is none
matching. *)
-val add_ml_tactic_notation : ml_tactic_name ->
+val add_ml_tactic_notation : ml_tactic_name -> level:int ->
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. *)
diff --git a/plugins/ltac/tacinterp.ml b/plugins/ltac/tacinterp.ml
index 61a70d712d..fe10f0c313 100644
--- a/plugins/ltac/tacinterp.ml
+++ b/plugins/ltac/tacinterp.ml
@@ -642,32 +642,32 @@ let interp_gen kind ist allow_patvar flags env sigma (c,ce) =
Proofview.NonLogical.run (db_constr (curr_debug ist) env c);
(evd,c)
-let constr_flags = {
+let constr_flags () = {
use_typeclasses = true;
solve_unification_constraints = true;
- use_hook = Some solve_by_implicit_tactic;
+ use_hook = solve_by_implicit_tactic ();
fail_evar = true;
expand_evars = true }
(* Interprets a constr; expects evars to be solved *)
let interp_constr_gen kind ist env sigma c =
- interp_gen kind ist false constr_flags env sigma c
+ interp_gen kind ist false (constr_flags ()) env sigma c
let interp_constr = interp_constr_gen WithoutTypeConstraint
let interp_type = interp_constr_gen IsType
-let open_constr_use_classes_flags = {
+let open_constr_use_classes_flags () = {
use_typeclasses = true;
solve_unification_constraints = true;
- use_hook = Some solve_by_implicit_tactic;
+ use_hook = solve_by_implicit_tactic ();
fail_evar = false;
expand_evars = true }
-let open_constr_no_classes_flags = {
+let open_constr_no_classes_flags () = {
use_typeclasses = false;
solve_unification_constraints = true;
- use_hook = Some solve_by_implicit_tactic;
+ use_hook = solve_by_implicit_tactic ();
fail_evar = false;
expand_evars = true }
@@ -679,11 +679,11 @@ let pure_open_constr_flags = {
expand_evars = false }
(* Interprets an open constr *)
-let interp_open_constr ?(expected_type=WithoutTypeConstraint) ist =
+let interp_open_constr ?(expected_type=WithoutTypeConstraint) ist env sigma c =
let flags =
- if expected_type == WithoutTypeConstraint then open_constr_no_classes_flags
- else open_constr_use_classes_flags in
- interp_gen expected_type ist false flags
+ if expected_type == WithoutTypeConstraint then open_constr_no_classes_flags ()
+ else open_constr_use_classes_flags () in
+ interp_gen expected_type ist false flags env sigma c
let interp_pure_open_constr ist =
interp_gen WithoutTypeConstraint ist false pure_open_constr_flags
@@ -1422,7 +1422,14 @@ and tactic_of_value ist vle =
extra = TacStore.set ist.extra f_trace []; } in
let tac = name_if_glob appl (eval_tactic ist t) in
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.")
+ | VFun (_, _, _,vars,_) ->
+ let numargs = List.length vars in
+ Tacticals.New.tclZEROMSG
+ (str "A fully applied tactic is expected:" ++ spc() ++ Pp.str "missing " ++
+ Pp.str (String.plural numargs "argument") ++ Pp.str " for " ++
+ Pp.str (String.plural numargs "variable") ++ Pp.str " " ++
+ pr_enum pr_name vars ++ Pp.str ".")
+ | 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
tactic_of_value ist tac
@@ -1780,7 +1787,7 @@ and interp_atomic ist tac : unit Proofview.tactic =
(TacLetTac(na,c,clp,b,eqpat))
(Tacticals.New.tclWITHHOLES false (*in hope of a future "eset/epose"*)
(let_pat_tac b (interp_name ist env sigma na)
- ((sigma,sigma'),c) clp eqpat) sigma')
+ (sigma,c) clp eqpat) sigma')
end }
(* Derived basic tactics *)
diff --git a/plugins/micromega/RMicromega.v b/plugins/micromega/RMicromega.v
index 2352d78d63..30e475b710 100644
--- a/plugins/micromega/RMicromega.v
+++ b/plugins/micromega/RMicromega.v
@@ -18,7 +18,7 @@ Require Import Refl.
Require Import Raxioms RIneq Rpow_def DiscrR.
Require Import QArith.
Require Import Qfield.
-
+Require Import Qreals.
Require Setoid.
(*Declare ML Module "micromega_plugin".*)
@@ -38,15 +38,8 @@ Proof.
exact Rplus_opp_r.
Qed.
-Add Ring Rring : Rsrt.
Open Scope R_scope.
-Lemma Rmult_neutral : forall x:R , 0 * x = 0.
-Proof.
- intro ; ring.
-Qed.
-
-
Lemma Rsor : SOR R0 R1 Rplus Rmult Rminus Ropp (@eq R) Rle Rlt.
Proof.
constructor; intros ; subst ; try (intuition (subst; try ring ; auto with real)).
@@ -59,142 +52,41 @@ Proof.
apply (Rlt_irrefl m) ; auto.
apply Rnot_le_lt. auto with real.
destruct (total_order_T n m) as [ [H1 | H1] | H1] ; auto.
- intros.
- rewrite <- (Rmult_neutral m).
- apply (Rmult_lt_compat_r) ; auto.
-Qed.
-
-Definition IQR := fun x : Q => (IZR (Qnum x) * / IZR (' Qden x))%R.
-
-
-Lemma Rinv_elim : forall x y z,
- y <> 0 -> (z * y = x <-> x * / y = z).
-Proof.
- intros.
- split ; intros.
- subst.
- rewrite Rmult_assoc.
- rewrite Rinv_r; auto.
- ring.
- subst.
- rewrite Rmult_assoc.
- rewrite (Rmult_comm (/ y)).
- rewrite Rinv_r ; auto.
- ring.
-Qed.
-
-Ltac INR_nat_of_P :=
- match goal with
- | H : context[INR (Pos.to_nat ?X)] |- _ =>
- revert H ;
- let HH := fresh in
- assert (HH := pos_INR_nat_of_P X) ; revert HH ; generalize (INR (Pos.to_nat X))
- | |- context[INR (Pos.to_nat ?X)] =>
- let HH := fresh in
- assert (HH := pos_INR_nat_of_P X) ; revert HH ; generalize (INR (Pos.to_nat X))
- end.
-
-Ltac add_eq expr val := set (temp := expr) ;
- generalize (eq_refl temp) ;
- unfold temp at 1 ; generalize temp ; intro val ; clear temp.
-
-Ltac Rinv_elim :=
- match goal with
- | |- context[?x * / ?y] =>
- let z := fresh "v" in
- add_eq (x * / y) z ;
- let H := fresh in intro H ; rewrite <- Rinv_elim in H
- end.
-
-Lemma Rlt_neq : forall r , 0 < r -> r <> 0.
-Proof.
- red. intros.
- subst.
- apply (Rlt_irrefl 0 H).
+ now apply Rmult_lt_0_compat.
Qed.
+Notation IQR := Q2R (only parsing).
Lemma Rinv_1 : forall x, x * / 1 = x.
Proof.
intro.
- Rinv_elim.
- subst ; ring.
- apply R1_neq_R0.
+ rewrite Rinv_1.
+ apply Rmult_1_r.
Qed.
-Lemma Qeq_true : forall x y,
- Qeq_bool x y = true ->
- IQR x = IQR y.
+Lemma Qeq_true : forall x y, Qeq_bool x y = true -> IQR x = IQR y.
Proof.
- unfold IQR.
- simpl.
- intros.
- apply Qeq_bool_eq in H.
- unfold Qeq in H.
- assert (IZR (Qnum x * ' Qden y) = IZR (Qnum y * ' Qden x))%Z.
- rewrite H. reflexivity.
- repeat rewrite mult_IZR in H0.
- simpl in H0.
- revert H0.
- repeat INR_nat_of_P.
intros.
- apply Rinv_elim in H2 ; [| apply Rlt_neq ; auto].
- rewrite <- H2.
- field.
- split ; apply Rlt_neq ; auto.
+ now apply Qeq_eqR, Qeq_bool_eq.
Qed.
Lemma Qeq_false : forall x y, Qeq_bool x y = false -> IQR x <> IQR y.
Proof.
intros.
- apply Qeq_bool_neq in H.
- intro. apply H. clear H.
- unfold Qeq,IQR in *.
- simpl in *.
- revert H0.
- repeat Rinv_elim.
- intros.
- subst.
- assert (IZR (Qnum x * ' Qden y)%Z = IZR (Qnum y * ' Qden x)%Z).
- repeat rewrite mult_IZR.
- simpl.
- rewrite <- H0. rewrite <- H.
- ring.
- apply eq_IZR ; auto.
- INR_nat_of_P; intros; apply Rlt_neq ; auto.
- INR_nat_of_P; intros ; apply Rlt_neq ; auto.
+ apply Qeq_bool_neq in H.
+ contradict H.
+ now apply eqR_Qeq.
Qed.
-
-
Lemma Qle_true : forall x y : Q, Qle_bool x y = true -> IQR x <= IQR y.
Proof.
intros.
- apply Qle_bool_imp_le in H.
- unfold Qle in H.
- unfold IQR.
- simpl in *.
- apply IZR_le in H.
- repeat rewrite mult_IZR in H.
- simpl in H.
- repeat INR_nat_of_P; intros.
- assert (Hr := Rlt_neq r H).
- assert (Hr0 := Rlt_neq r0 H0).
- replace (IZR (Qnum x) * / r) with ((IZR (Qnum x) * r0) * (/r * /r0)).
- replace (IZR (Qnum y) * / r0) with ((IZR (Qnum y) * r) * (/r * /r0)).
- apply Rmult_le_compat_r ; auto.
- apply Rmult_le_pos.
- unfold Rle. left. apply Rinv_0_lt_compat ; auto.
- unfold Rle. left. apply Rinv_0_lt_compat ; auto.
- field ; intuition.
- field ; intuition.
+ now apply Qle_Rle, Qle_bool_imp_le.
Qed.
-
-
Lemma IQR_0 : IQR 0 = 0.
Proof.
- compute. apply Rinv_1.
+ apply Rmult_0_l.
Qed.
Lemma IQR_1 : IQR 1 = 1.
@@ -202,160 +94,6 @@ Proof.
compute. apply Rinv_1.
Qed.
-Lemma IQR_plus : forall x y, IQR (x + y) = IQR x + IQR y.
-Proof.
- intros.
- unfold IQR.
- simpl in *.
- rewrite plus_IZR in *.
- rewrite mult_IZR in *.
- simpl.
- rewrite Pos2Nat.inj_mul.
- rewrite mult_INR.
- rewrite mult_IZR.
- simpl.
- repeat INR_nat_of_P.
- intros. field.
- split ; apply Rlt_neq ; auto.
-Qed.
-
-Lemma IQR_opp : forall x, IQR (- x) = - IQR x.
-Proof.
- intros.
- unfold IQR.
- simpl.
- rewrite opp_IZR.
- ring.
-Qed.
-
-Lemma IQR_minus : forall x y, IQR (x - y) = IQR x - IQR y.
-Proof.
- intros.
- unfold Qminus.
- rewrite IQR_plus.
- rewrite IQR_opp.
- ring.
-Qed.
-
-
-Lemma IQR_mult : forall x y, IQR (x * y) = IQR x * IQR y.
-Proof.
- unfold IQR ; intros.
- simpl.
- repeat rewrite mult_IZR.
- rewrite Pos2Nat.inj_mul.
- rewrite mult_INR.
- repeat INR_nat_of_P.
- intros. field ; split ; apply Rlt_neq ; auto.
-Qed.
-
-Lemma IQR_inv_lt : forall x, (0 < x)%Q ->
- IQR (/ x) = / IQR x.
-Proof.
- unfold IQR ; simpl.
- intros.
- unfold Qlt in H.
- revert H.
- simpl.
- intros.
- unfold Qinv.
- destruct x.
- destruct Qnum ; simpl in *.
- exfalso. auto with zarith.
- clear H.
- repeat INR_nat_of_P.
- intros.
- assert (HH := Rlt_neq _ H).
- assert (HH0 := Rlt_neq _ H0).
- rewrite Rinv_mult_distr ; auto.
- rewrite Rinv_involutive ; auto.
- ring.
- apply Rinv_0_lt_compat in H0.
- apply Rlt_neq ; auto.
- simpl in H.
- exfalso.
- rewrite Pos.mul_comm in H.
- compute in H.
- discriminate.
-Qed.
-
-Lemma Qinv_opp : forall x, (- (/ x) = / ( -x))%Q.
-Proof.
- destruct x ; destruct Qnum ; reflexivity.
-Qed.
-
-Lemma Qopp_involutive_strong : forall x, (- - x = x)%Q.
-Proof.
- intros.
- destruct x.
- unfold Qopp.
- simpl.
- rewrite Z.opp_involutive.
- reflexivity.
-Qed.
-
-Lemma Ropp_0 : forall r , - r = 0 -> r = 0.
-Proof.
- intros.
- rewrite <- (Ropp_involutive r).
- apply Ropp_eq_0_compat ; auto.
-Qed.
-
-Lemma IQR_x_0 : forall x, IQR x = 0 -> x == 0%Q.
-Proof.
- destruct x ; simpl.
- unfold IQR.
- simpl.
- INR_nat_of_P.
- intros.
- apply Rmult_integral in H0.
- destruct H0.
- apply eq_IZR_R0 in H0.
- subst.
- reflexivity.
- exfalso.
- apply Rinv_0_lt_compat in H.
- rewrite <- H0 in H.
- apply Rlt_irrefl in H. auto.
-Qed.
-
-
-Lemma IQR_inv_gt : forall x, (0 > x)%Q ->
- IQR (/ x) = / IQR x.
-Proof.
- intros.
- rewrite <- (Qopp_involutive_strong x).
- rewrite <- Qinv_opp.
- rewrite IQR_opp.
- rewrite IQR_inv_lt.
- repeat rewrite IQR_opp.
- rewrite Ropp_inv_permute.
- auto.
- intro.
- apply Ropp_0 in H0.
- apply IQR_x_0 in H0.
- rewrite H0 in H.
- compute in H. discriminate.
- unfold Qlt in *.
- destruct x ; simpl in *.
- auto with zarith.
-Qed.
-
-Lemma IQR_inv : forall x, ~ x == 0 ->
- IQR (/ x) = / IQR x.
-Proof.
- intros.
- assert ( 0 > x \/ 0 < x)%Q.
- destruct x ; unfold Qlt, Qeq in * ; simpl in *.
- rewrite Z.mul_1_r in *.
- destruct Qnum ; simpl in * ; intuition auto.
- right. reflexivity.
- left ; reflexivity.
- destruct H0.
- apply IQR_inv_gt ; auto.
- apply IQR_inv_lt ; auto.
-Qed.
-
Lemma IQR_inv_ext : forall x,
IQR (/ x) = (if Qeq_bool x 0 then 0 else / IQR x).
Proof.
@@ -366,18 +104,13 @@ Proof.
destruct x ; simpl.
unfold Qeq in H.
simpl in H.
- replace Qnum with 0%Z.
- compute. rewrite Rinv_1.
- reflexivity.
- rewrite <- H. ring.
+ rewrite Zmult_1_r in H.
+ rewrite H.
+ apply Rmult_0_l.
intros.
- apply IQR_inv.
- intro.
- rewrite <- Qeq_bool_iff in H0.
- congruence.
+ now apply Q2R_inv, Qeq_bool_neq.
Qed.
-
Notation to_nat := N.to_nat.
Lemma QSORaddon :
@@ -391,10 +124,10 @@ Proof.
constructor ; intros ; try reflexivity.
apply IQR_0.
apply IQR_1.
- apply IQR_plus.
- apply IQR_minus.
- apply IQR_mult.
- apply IQR_opp.
+ apply Q2R_plus.
+ apply Q2R_minus.
+ apply Q2R_mult.
+ apply Q2R_opp.
apply Qeq_true ; auto.
apply R_power_theory.
apply Qeq_false.
@@ -453,13 +186,13 @@ Proof.
apply IQR_1.
reflexivity.
unfold IQR. simpl. rewrite Rinv_1. reflexivity.
- apply IQR_plus.
- apply IQR_minus.
- apply IQR_mult.
+ apply Q2R_plus.
+ apply Q2R_minus.
+ apply Q2R_mult.
rewrite <- IHc.
apply IQR_inv_ext.
rewrite <- IHc.
- apply IQR_opp.
+ apply Q2R_opp.
Qed.
Require Import EnvRing.
diff --git a/plugins/micromega/coq_micromega.ml b/plugins/micromega/coq_micromega.ml
index 97f29df823..6051cb3d3c 100644
--- a/plugins/micromega/coq_micromega.ml
+++ b/plugins/micromega/coq_micromega.ml
@@ -364,6 +364,7 @@ struct
[["Coq";"Reals" ; "Rdefinitions"];
["Coq";"Reals" ; "Rpow_def"] ;
["Coq";"Reals" ; "Raxioms"] ;
+ ["Coq";"QArith"; "Qreals"] ;
]
let z_modules = [["Coq";"ZArith";"BinInt"]]
@@ -479,7 +480,7 @@ struct
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_IQR = lazy (r_constant "Q2R")
let coq_PEX = lazy (constant "PEX" )
diff --git a/plugins/rtauto/proof_search.ml b/plugins/rtauto/proof_search.ml
index 8b92611136..1ad4d622b2 100644
--- a/plugins/rtauto/proof_search.ml
+++ b/plugins/rtauto/proof_search.ml
@@ -505,12 +505,12 @@ let pp_mapint map =
pp_form obj ++ str " => " ++
pp_list (fun (i,f) -> pp_form f) l ++
cut ()) ) map;
- str "{ " ++ vb 0 ++ (!pp) ++ str " }" ++ close ()
+ str "{ " ++ hv 0 (!pp ++ str " }")
let pp_connect (i,j,f1,f2) = pp_form f1 ++ str " => " ++ pp_form f2
let pp_gl gl= cut () ++
- str "{ " ++ vb 0 ++
+ str "{ " ++ hv 0 (
begin
match gl.abs with
None -> str ""
@@ -520,7 +520,7 @@ let pp_gl gl= cut () ++
str "norev =" ++ pp_intmap gl.norev_hyps ++ cut () ++
str "arrows=" ++ pp_mapint gl.right ++ cut () ++
str "cnx =" ++ pp_list pp_connect gl.cnx ++ cut () ++
- str "goal =" ++ pp_form gl.gl ++ str " }" ++ close ()
+ str "goal =" ++ pp_form gl.gl ++ str " }")
let pp =
function
diff --git a/plugins/setoid_ring/RealField.v b/plugins/setoid_ring/RealField.v
index 293722125b..facd2e0625 100644
--- a/plugins/setoid_ring/RealField.v
+++ b/plugins/setoid_ring/RealField.v
@@ -59,11 +59,12 @@ Notation Rset := (Eqsth R).
Notation Rext := (Eq_ext Rplus Rmult Ropp).
Lemma Rlt_0_2 : 0 < 2.
+Proof.
apply Rlt_trans with (0 + 1).
apply Rlt_n_Sn.
rewrite Rplus_comm.
apply Rplus_lt_compat_l.
- replace 1 with (0 + 1).
+ replace R1 with (0 + 1).
apply Rlt_n_Sn.
apply Rplus_0_l.
Qed.
@@ -126,9 +127,17 @@ Ltac Rpow_tac t :=
| _ => constr:(N.of_nat t)
end.
-Add Field RField : Rfield
- (completeness Zeq_bool_complete, power_tac R_power_theory [Rpow_tac]).
-
-
-
+Ltac IZR_tac t :=
+ match t with
+ | R0 => constr:(0%Z)
+ | R1 => constr:(1%Z)
+ | IZR ?u =>
+ match isZcst u with
+ | true => u
+ | _ => constr:(InitialRing.NotConstant)
+ end
+ | _ => constr:(InitialRing.NotConstant)
+ end.
+Add Field RField : Rfield
+ (completeness Zeq_bool_complete, constants [IZR_tac], power_tac R_power_theory [Rpow_tac]).
diff --git a/plugins/setoid_ring/newring.ml b/plugins/setoid_ring/newring.ml
index eb35d3f806..87ee666605 100644
--- a/plugins/setoid_ring/newring.ml
+++ b/plugins/setoid_ring/newring.ml
@@ -323,14 +323,16 @@ let _ = add_map "ring"
(map_with_eq
[coq_cons,(function -1->Eval|2->Rec|_->Prot);
coq_nil, (function -1->Eval|_ -> Prot);
+ my_reference "IDphi", (function _->Eval);
+ my_reference "gen_phiZ", (function _->Eval);
(* Pphi_dev: evaluate polynomial and coef operations, protect
ring operations and make recursive call on the var map *)
pol_cst "Pphi_dev", (function -1|8|9|10|11|12|14->Eval|13->Rec|_->Prot);
pol_cst "Pphi_pow",
- (function -1|8|9|10|11|13|15|17->Eval|16->Rec|_->Prot);
+ (function -1|8|9|10|13|15|17->Eval|11|16->Rec|_->Prot);
(* PEeval: evaluate morphism and polynomial, protect ring
operations and make recursive call on the var map *)
- pol_cst "PEeval", (function -1|7|9|12->Eval|11->Rec|_->Prot)])
+ pol_cst "PEeval", (function -1|8|10|13->Eval|12->Rec|_->Prot)])
(****************************************************************************)
(* Ring database *)
@@ -756,12 +758,14 @@ let _ = add_map "field"
(map_with_eq
[coq_cons,(function -1->Eval|2->Rec|_->Prot);
coq_nil, (function -1->Eval|_ -> Prot);
+ my_reference "IDphi", (function _->Eval);
+ my_reference "gen_phiZ", (function _->Eval);
(* display_linear: evaluate polynomials and coef operations, protect
field operations and make recursive call on the var map *)
my_reference "display_linear",
(function -1|9|10|11|12|13|15|16->Eval|14->Rec|_->Prot);
my_reference "display_pow_linear",
- (function -1|9|10|11|12|13|14|16|18|19->Eval|17->Rec|_->Prot);
+ (function -1|9|10|11|14|16|18|19->Eval|12|17->Rec|_->Prot);
(* Pphi_dev: evaluate polynomial and coef operations, protect
ring operations and make recursive call on the var map *)
pol_cst "Pphi_dev", (function -1|8|9|10|11|12|14->Eval|13->Rec|_->Prot);
@@ -769,19 +773,20 @@ let _ = add_map "field"
(function -1|8|9|10|11|13|15|17->Eval|16->Rec|_->Prot);
(* PEeval: evaluate morphism and polynomial, protect ring
operations and make recursive call on the var map *)
- pol_cst "PEeval", (function -1|7|9|12->Eval|11->Rec|_->Prot);
+ pol_cst "PEeval", (function -1|8|10|13->Eval|12->Rec|_->Prot);
(* FEeval: evaluate morphism, protect field
operations and make recursive call on the var map *)
- my_reference "FEeval", (function -1|8|9|10|11|14->Eval|13->Rec|_->Prot)]);;
+ my_reference "FEeval", (function -1|10|12|15->Eval|14->Rec|_->Prot)]);;
let _ = add_map "field_cond"
(map_without_eq
[coq_cons,(function -1->Eval|2->Rec|_->Prot);
coq_nil, (function -1->Eval|_ -> Prot);
- (* PCond: evaluate morphism and denum list, protect ring
+ my_reference "IDphi", (function _->Eval);
+ my_reference "gen_phiZ", (function _->Eval);
+ (* PCond: evaluate denum list, protect ring
operations and make recursive call on the var map *)
- my_reference "PCond", (function -1|9|11|14->Eval|13->Rec|_->Prot)]);;
-(* (function -1|9|11->Eval|10->Rec|_->Prot)]);;*)
+ my_reference "PCond", (function -1|11|14->Eval|9|13->Rec|_->Prot)]);;
let _ = Redexpr.declare_reduction "simpl_field_expr"
diff --git a/plugins/ssrmatching/ssrmatching.ml4 b/plugins/ssrmatching/ssrmatching.ml4
index 03c4ae47dd..4d55946336 100644
--- a/plugins/ssrmatching/ssrmatching.ml4
+++ b/plugins/ssrmatching/ssrmatching.ml4
@@ -156,7 +156,7 @@ let mkCHole loc = CHole (loc, None, IntroAnonymous, None)
let mkCLambda loc name ty t =
CLambdaN (loc, [[loc, name], Default Explicit, ty], t)
let mkCLetIn loc name bo t =
- CLetIn (loc, (loc, name), bo, t)
+ CLetIn (loc, (loc, name), bo, None, t)
let mkCCast loc t ty = CCast (loc,t, dC ty)
(** Constructors for rawconstr *)
let mkRHole = GHole (dummy_loc, InternalHole, IntroAnonymous, None)
@@ -1193,7 +1193,7 @@ let interp_pattern ?wit_ssrpatternarg ist gl red redty =
pp(lazy(str"typed as: " ++ pr_pattern_w_ids red));
let mkXLetIn loc x (a,(g,c)) = match c with
| Some b -> a,(g,Some (mkCLetIn loc x (mkCHole loc) b))
- | None -> a,(GLetIn (loc,x,(GHole (loc, BinderType x, IntroAnonymous, None)), g), None) in
+ | None -> a,(GLetIn (loc,x,(GHole (loc, BinderType x, IntroAnonymous, None)), None, g), None) in
match red with
| T t -> let sigma, t = interp_term ist gl t in sigma, T t
| In_T t -> let sigma, t = interp_term ist gl t in sigma, In_T t
diff --git a/plugins/syntax/r_syntax.ml b/plugins/syntax/r_syntax.ml
index 3ae2d45f32..8f065f5282 100644
--- a/plugins/syntax/r_syntax.ml
+++ b/plugins/syntax/r_syntax.ml
@@ -9,6 +9,8 @@
open Util
open Names
open Globnames
+open Glob_term
+open Bigint
(* Poor's man DECLARE PLUGIN *)
let __coq_plugin_name = "r_syntax_plugin"
@@ -17,95 +19,105 @@ let () = Mltop.add_known_module __coq_plugin_name
exception Non_closed_number
(**********************************************************************)
-(* Parsing R via scopes *)
+(* Parsing positive via scopes *)
(**********************************************************************)
-open Glob_term
-open Bigint
+let binnums = ["Coq";"Numbers";"BinNums"]
let make_dir l = DirPath.make (List.rev_map Id.of_string l)
-let rdefinitions = make_dir ["Coq";"Reals";"Rdefinitions"]
-let make_path dir id = Libnames.make_path dir (Id.of_string id)
+let make_path dir id = Libnames.make_path (make_dir dir) (Id.of_string id)
+
+let positive_path = make_path binnums "positive"
+
+(* TODO: temporary hack *)
+let make_kn dir id = Globnames.encode_mind dir id
+
+let positive_kn = make_kn (make_dir binnums) (Id.of_string "positive")
+let glob_positive = IndRef (positive_kn,0)
+let path_of_xI = ((positive_kn,0),1)
+let path_of_xO = ((positive_kn,0),2)
+let path_of_xH = ((positive_kn,0),3)
+let glob_xI = ConstructRef path_of_xI
+let glob_xO = ConstructRef path_of_xO
+let glob_xH = ConstructRef path_of_xH
+
+let pos_of_bignat dloc x =
+ let ref_xI = GRef (dloc, glob_xI, None) in
+ let ref_xH = GRef (dloc, glob_xH, None) in
+ let ref_xO = GRef (dloc, glob_xO, None) in
+ let rec pos_of x =
+ match div2_with_rest x with
+ | (q,false) -> GApp (dloc, ref_xO,[pos_of q])
+ | (q,true) when not (Bigint.equal q zero) -> GApp (dloc,ref_xI,[pos_of q])
+ | (q,true) -> ref_xH
+ in
+ pos_of x
+
+(**********************************************************************)
+(* Printing positive via scopes *)
+(**********************************************************************)
+
+let rec bignat_of_pos = function
+ | GApp (_, GRef (_,b,_),[a]) when Globnames.eq_gr b glob_xO -> mult_2(bignat_of_pos a)
+ | GApp (_, GRef (_,b,_),[a]) when Globnames.eq_gr b glob_xI -> add_1(mult_2(bignat_of_pos a))
+ | GRef (_, a, _) when Globnames.eq_gr a glob_xH -> Bigint.one
+ | _ -> raise Non_closed_number
+
+(**********************************************************************)
+(* Parsing Z via scopes *)
+(**********************************************************************)
+let z_path = make_path binnums "Z"
+let z_kn = make_kn (make_dir binnums) (Id.of_string "Z")
+let glob_z = IndRef (z_kn,0)
+let path_of_ZERO = ((z_kn,0),1)
+let path_of_POS = ((z_kn,0),2)
+let path_of_NEG = ((z_kn,0),3)
+let glob_ZERO = ConstructRef path_of_ZERO
+let glob_POS = ConstructRef path_of_POS
+let glob_NEG = ConstructRef path_of_NEG
+
+let z_of_int dloc n =
+ if not (Bigint.equal n zero) then
+ let sgn, n =
+ if is_pos_or_zero n then glob_POS, n else glob_NEG, Bigint.neg n in
+ GApp(dloc, GRef (dloc,sgn,None), [pos_of_bignat dloc n])
+ else
+ GRef (dloc, glob_ZERO, None)
+
+(**********************************************************************)
+(* Printing Z via scopes *)
+(**********************************************************************)
+
+let bigint_of_z = function
+ | GApp (_, GRef (_,b,_),[a]) when Globnames.eq_gr b glob_POS -> bignat_of_pos a
+ | GApp (_, GRef (_,b,_),[a]) when Globnames.eq_gr b glob_NEG -> Bigint.neg (bignat_of_pos a)
+ | GRef (_, a, _) when Globnames.eq_gr a glob_ZERO -> Bigint.zero
+ | _ -> raise Non_closed_number
+
+(**********************************************************************)
+(* Parsing R via scopes *)
+(**********************************************************************)
+
+let rdefinitions = ["Coq";"Reals";"Rdefinitions"]
let r_path = make_path rdefinitions "R"
(* TODO: temporary hack *)
let make_path dir id = Globnames.encode_con dir (Id.of_string id)
-let r_kn = make_path rdefinitions "R"
-let glob_R = ConstRef r_kn
-let glob_R1 = ConstRef (make_path rdefinitions "R1")
-let glob_R0 = ConstRef (make_path rdefinitions "R0")
-let glob_Ropp = ConstRef (make_path rdefinitions "Ropp")
-let glob_Rplus = ConstRef (make_path rdefinitions "Rplus")
-let glob_Rmult = ConstRef (make_path rdefinitions "Rmult")
-
-let two = mult_2 one
-let three = add_1 two
-let four = mult_2 two
-
-(* Unary representation of strictly positive numbers *)
-let rec small_r dloc n =
- if equal one n then GRef (dloc, glob_R1, None)
- else GApp(dloc,GRef (dloc,glob_Rplus, None),
- [GRef (dloc, glob_R1, None);small_r dloc (sub_1 n)])
-
-let r_of_posint dloc n =
- let r1 = GRef (dloc, glob_R1, None) in
- let r2 = small_r dloc two in
- let rec r_of_pos n =
- if less_than n four then small_r dloc n
- else
- let (q,r) = div2_with_rest n in
- let b = GApp(dloc,GRef(dloc,glob_Rmult,None),[r2;r_of_pos q]) in
- if r then GApp(dloc,GRef(dloc,glob_Rplus,None),[r1;b]) else b in
- if not (Bigint.equal n zero) then r_of_pos n else GRef(dloc,glob_R0,None)
+let glob_IZR = ConstRef (make_path (make_dir rdefinitions) "IZR")
let r_of_int dloc z =
- if is_strictly_neg z then
- GApp (dloc, GRef(dloc,glob_Ropp,None), [r_of_posint dloc (neg z)])
- else
- r_of_posint dloc z
+ GApp (dloc, GRef(dloc,glob_IZR,None), [z_of_int dloc z])
(**********************************************************************)
(* Printing R via scopes *)
(**********************************************************************)
-let bignat_of_r =
-(* for numbers > 1 *)
-let rec bignat_of_pos = function
- (* 1+1 *)
- | GApp (_,GRef (_,p,_), [GRef (_,o1,_); GRef (_,o2,_)])
- when Globnames.eq_gr p glob_Rplus && Globnames.eq_gr o1 glob_R1 && Globnames.eq_gr o2 glob_R1 -> two
- (* 1+(1+1) *)
- | GApp (_,GRef (_,p1,_), [GRef (_,o1,_);
- GApp(_,GRef (_,p2,_),[GRef(_,o2,_);GRef(_,o3,_)])])
- when Globnames.eq_gr p1 glob_Rplus && Globnames.eq_gr p2 glob_Rplus &&
- Globnames.eq_gr o1 glob_R1 && Globnames.eq_gr o2 glob_R1 && Globnames.eq_gr o3 glob_R1 -> three
- (* (1+1)*b *)
- | GApp (_,GRef (_,p,_), [a; b]) when Globnames.eq_gr p glob_Rmult ->
- if not (Bigint.equal (bignat_of_pos a) two) then raise Non_closed_number;
- mult_2 (bignat_of_pos b)
- (* 1+(1+1)*b *)
- | GApp (_,GRef (_,p1,_), [GRef (_,o,_); GApp (_,GRef (_,p2,_),[a;b])])
- when Globnames.eq_gr p1 glob_Rplus && Globnames.eq_gr p2 glob_Rmult && Globnames.eq_gr o glob_R1 ->
- if not (Bigint.equal (bignat_of_pos a) two) then raise Non_closed_number;
- add_1 (mult_2 (bignat_of_pos b))
- | _ -> raise Non_closed_number
-in
-let bignat_of_r = function
- | GRef (_,a,_) when Globnames.eq_gr a glob_R0 -> zero
- | GRef (_,a,_) when Globnames.eq_gr a glob_R1 -> one
- | r -> bignat_of_pos r
-in
-bignat_of_r
-
let bigint_of_r = function
- | GApp (_,GRef (_,o,_), [a]) when Globnames.eq_gr o glob_Ropp ->
- let n = bignat_of_r a in
- if Bigint.equal n zero then raise Non_closed_number;
- neg n
- | a -> bignat_of_r a
+ | GApp (_,GRef (_,o,_), [a]) when Globnames.eq_gr o glob_IZR ->
+ bigint_of_z a
+ | _ -> raise Non_closed_number
let uninterp_r p =
try
@@ -113,12 +125,9 @@ let uninterp_r p =
with Non_closed_number ->
None
-let mkGRef gr = GRef (Loc.ghost,gr,None)
-
let _ = Notation.declare_numeral_interpreter "R_scope"
(r_path,["Coq";"Reals";"Rdefinitions"])
r_of_int
- (List.map mkGRef
- [glob_Ropp;glob_R0;glob_Rplus;glob_Rmult;glob_R1],
+ ([GRef (Loc.ghost,glob_IZR,None)],
uninterp_r,
false)
diff --git a/pretyping/constr_matching.ml b/pretyping/constr_matching.ml
index 5ec44a68d8..1cae8d16de 100644
--- a/pretyping/constr_matching.ml
+++ b/pretyping/constr_matching.ml
@@ -264,7 +264,11 @@ let matches_core env sigma convert allow_partial_app allow_bound_rels
sorec ((na1,na2,c2)::ctx) (Environ.push_rel (LocalAssum (na2,c2)) env)
(add_binders na1 na2 binding_vars (sorec ctx env subst c1 c2)) d1 d2
- | PLetIn (na1,c1,d1), LetIn(na2,c2,t2,d2) ->
+ | PLetIn (na1,c1,Some t1,d1), LetIn(na2,c2,t2,d2) ->
+ sorec ((na1,na2,t2)::ctx) (Environ.push_rel (LocalDef (na2,c2,t2)) env)
+ (add_binders na1 na2 binding_vars (sorec ctx env (sorec ctx env subst c1 c2) t1 t2)) d1 d2
+
+ | PLetIn (na1,c1,None,d1), LetIn(na2,c2,t2,d2) ->
sorec ((na1,na2,t2)::ctx) (Environ.push_rel (LocalDef (na2,c2,t2)) env)
(add_binders na1 na2 binding_vars (sorec ctx env subst c1 c2)) d1 d2
diff --git a/pretyping/detyping.ml b/pretyping/detyping.ml
index cad5551c15..5a296de84b 100644
--- a/pretyping/detyping.ml
+++ b/pretyping/detyping.ml
@@ -331,7 +331,7 @@ let extract_nondep_branches test c b l =
match r,l with
| r, [] -> r
| GLambda (_,_,_,_,t), false::l -> strip l t
- | GLetIn (_,_,_,t), true::l -> strip l t
+ | GLetIn (_,_,_,_,t), true::l -> strip l t
(* FIXME: do we need adjustment? *)
| _,_ -> assert false in
if test c l then Some (strip l b) else None
@@ -341,7 +341,7 @@ let it_destRLambda_or_LetIn_names l c =
match c, l with
| _, [] -> (List.rev nal,c)
| GLambda (_,na,_,_,c), false::l -> aux l (na::nal) c
- | GLetIn (_,na,_,c), true::l -> aux l (na::nal) c
+ | GLetIn (_,na,_,_,c), true::l -> aux l (na::nal) c
| _, true::l -> (* let-expansion *) aux l (Anonymous :: nal) c
| _, false::l ->
(* eta-expansion *)
@@ -690,9 +690,8 @@ and detype_binder (lax,isgoal as flags) bk avoid env sigma na body ty c =
let c = detype (lax,false) avoid env sigma (Option.get body) in
(* Heuristic: we display the type if in Prop *)
let s = try Retyping.get_sort_family_of (snd env) sigma ty with _ when !Flags.in_debugger || !Flags.in_toplevel -> InType (* Can fail because of sigma missing in debugger *) in
- let c = if s != InProp then c else
- GCast (dl, c, CastConv (detype (lax,false) avoid env sigma ty)) in
- GLetIn (dl, na', c, r)
+ let t = if s != InProp then None else Some (detype (lax,false) avoid env sigma ty) in
+ GLetIn (dl, na', c, t, r)
let detype_rel_context ?(lax=false) where avoid env sigma sign =
let where = Option.map (fun c -> it_mkLambda_or_LetIn c sign) where in
@@ -764,9 +763,9 @@ let detype_closed_glob ?lax isgoal avoid env sigma t =
| GProd (loc,id,k,t,c) ->
let id = convert_name cl id in
GProd(loc,id,k,detype_closed_glob cl t, detype_closed_glob cl c)
- | GLetIn (loc,id,b,e) ->
+ | GLetIn (loc,id,b,t,e) ->
let id = convert_name cl id in
- GLetIn(loc,id,detype_closed_glob cl b, detype_closed_glob cl e)
+ GLetIn(loc,id,detype_closed_glob cl b, Option.map (detype_closed_glob cl) t, detype_closed_glob cl e)
| GLetTuple (loc,ids,(n,r),b,e) ->
let ids = List.map (convert_name cl) ids in
let n = convert_name cl n in
@@ -825,10 +824,12 @@ let rec subst_glob_constr subst raw =
if r1' == r1 && r2' == r2 then raw else
GProd (loc,n,bk,r1',r2')
- | GLetIn (loc,n,r1,r2) ->
- let r1' = subst_glob_constr subst r1 and r2' = subst_glob_constr subst r2 in
- if r1' == r1 && r2' == r2 then raw else
- GLetIn (loc,n,r1',r2')
+ | GLetIn (loc,n,r1,t,r2) ->
+ let r1' = subst_glob_constr subst r1 in
+ let t' = Option.smartmap (subst_glob_constr subst) t in
+ let r2' = subst_glob_constr subst r2 in
+ if r1' == r1 && t == t' && r2' == r2 then raw else
+ GLetIn (loc,n,r1',t',r2')
| GCases (loc,sty,rtno,rl,branches) ->
let rtno' = Option.smartmap (subst_glob_constr subst) rtno
diff --git a/pretyping/evarconv.ml b/pretyping/evarconv.ml
index a2ffe12e93..d18b437a33 100644
--- a/pretyping/evarconv.ml
+++ b/pretyping/evarconv.ml
@@ -500,8 +500,7 @@ and evar_eqappr_x ?(rhs_is_already_stuck = false) ts env evd pbty
(* Evar must be undefined since we have flushed evars *)
let () = if !debug_unification then
let open Pp in
- Feedback.msg_notice (v 0 (pr_state appr1 ++ cut () ++ pr_state appr2 ++ cut ())
- ++ fnl ()) in
+ Feedback.msg_notice (v 0 (pr_state appr1 ++ cut () ++ pr_state appr2 ++ cut ())) in
match (flex_kind_of_term (fst ts) env evd term1 sk1,
flex_kind_of_term (fst ts) env evd term2 sk2) with
| Flexible (sp1,al1 as ev1), Flexible (sp2,al2 as ev2) ->
@@ -1129,6 +1128,10 @@ let apply_conversion_problem_heuristic ts env evd pbty t1 t2 =
let t2 = apprec_nohdbeta ts env evd (whd_head_evar evd t2) in
let (term1,l1 as appr1) = try destApp t1 with DestKO -> (t1, [||]) in
let (term2,l2 as appr2) = try destApp t2 with DestKO -> (t2, [||]) in
+ let () = if !debug_unification then
+ let open Pp in
+ Feedback.msg_notice (v 0 (str "Heuristic:" ++ spc () ++ print_constr t1
+ ++ cut () ++ print_constr t2 ++ cut ())) in
let app_empty = Array.is_empty l1 && Array.is_empty l2 in
match kind_of_term term1, kind_of_term term2 with
| Evar (evk1,args1), (Rel _|Var _) when app_empty
@@ -1193,20 +1196,22 @@ let check_problems_are_solved env evd =
| (pbty,env,t1,t2) as pb::_ -> error_cannot_unify env evd pb t1 t2
| _ -> ()
+exception MaxUndefined of (Evar.t * evar_info * constr list)
+
let max_undefined_with_candidates evd =
- (* If evar were ordered with highest index first, fold_undefined
- would be going decreasingly and we could use fold_undefined to
- find the undefined evar of maximum index (alternatively,
- max_bindings from ocaml 3.12 could be used); instead we traverse
- the whole map *)
- let l = Evd.fold_undefined
- (fun evk ev_info evars ->
- match ev_info.evar_candidates with
- | None -> evars
- | Some l -> (evk,ev_info,l)::evars) evd [] in
- match l with
- | [] -> None
- | a::l -> Some (List.last (a::l))
+ let fold evk evi () = match evi.evar_candidates with
+ | None -> ()
+ | Some l -> raise (MaxUndefined (evk, evi, l))
+ in
+ (** [fold_right] traverses the undefined map in decreasing order of indices.
+ The evar with candidates of maximum index is thus the first evar with
+ candidates found by a [fold_right] traversal. This has a significant impact on
+ performance. *)
+ try
+ let () = Evar.Map.fold_right fold (Evd.undefined_map evd) () in
+ None
+ with MaxUndefined ans ->
+ Some ans
let rec solve_unconstrained_evars_with_candidates ts evd =
(* max_undefined is supposed to return the most recent, hence
diff --git a/pretyping/glob_ops.ml b/pretyping/glob_ops.ml
index 51660818f4..ebbfa195f0 100644
--- a/pretyping/glob_ops.ml
+++ b/pretyping/glob_ops.ml
@@ -77,8 +77,8 @@ let rec glob_constr_eq c1 c2 = match c1, c2 with
| GProd (_, na1, bk1, t1, c1), GProd (_, na2, bk2, t2, c2) ->
Name.equal na1 na2 && binding_kind_eq bk1 bk2 &&
glob_constr_eq t1 t2 && glob_constr_eq c1 c2
-| GLetIn (_, na1, t1, c1), GLetIn (_, na2, t2, c2) ->
- Name.equal na1 na2 && glob_constr_eq t1 t2 && glob_constr_eq c1 c2
+| GLetIn (_, na1, b1, t1, c1), GLetIn (_, na2, b2, t2, c2) ->
+ Name.equal na1 na2 && glob_constr_eq b1 b2 && Option.equal glob_constr_eq t1 t2 && glob_constr_eq c1 c2
| GCases (_, st1, c1, tp1, cl1), GCases (_, st2, c2, tp2, cl2) ->
case_style_eq st1 st2 && Option.equal glob_constr_eq c1 c2 &&
List.equal tomatch_tuple_eq tp1 tp2 &&
@@ -152,10 +152,11 @@ let map_glob_constr_left_to_right f = function
let comp1 = f ty in
let comp2 = f c in
GProd (loc,na,bk,comp1,comp2)
- | GLetIn (loc,na,b,c) ->
+ | GLetIn (loc,na,b,t,c) ->
let comp1 = f b in
+ let compt = Option.map f t in
let comp2 = f c in
- GLetIn (loc,na,comp1,comp2)
+ GLetIn (loc,na,comp1,compt,comp2)
| GCases (loc,sty,rtntypopt,tml,pl) ->
let comp1 = Option.map f rtntypopt in
let comp2 = Util.List.map_left (fun (tm,x) -> (f tm,x)) tml in
@@ -189,8 +190,10 @@ let fold_return_type f acc (na,tyopt) = Option.fold_left f acc tyopt
let fold_glob_constr f acc = function
| GVar _ -> acc
| GApp (_,c,args) -> List.fold_left f (f acc c) args
- | GLambda (_,_,_,b,c) | GProd (_,_,_,b,c) | GLetIn (_,_,b,c) ->
+ | GLambda (_,_,_,b,c) | GProd (_,_,_,b,c) ->
f (f acc b) c
+ | GLetIn (_,_,b,t,c) ->
+ f (Option.fold_left f (f acc b) t) c
| GCases (_,_,rtntypopt,tml,pl) ->
let fold_pattern acc (_,idl,p,c) = f acc c in
List.fold_left fold_pattern
@@ -225,8 +228,8 @@ let occur_glob_constr id =
(occur ty) || (not (same_id na id) && (occur c))
| GProd (loc,na,bk,ty,c) ->
(occur ty) || (not (same_id na id) && (occur c))
- | GLetIn (loc,na,b,c) ->
- (occur b) || (not (same_id na id) && (occur c))
+ | GLetIn (loc,na,b,t,c) ->
+ (Option.fold_left (fun b t -> occur t || b) (occur b) t) || (not (same_id na id) && (occur c))
| GCases (loc,sty,rtntypopt,tml,pl) ->
(occur_option rtntypopt)
|| (List.exists (fun (tm,_) -> occur tm) tml)
@@ -270,10 +273,15 @@ 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)
- | GLambda (loc,na,_,ty,c) | GProd (loc,na,_,ty,c) | GLetIn (loc,na,ty,c) ->
+ | GLambda (loc,na,_,ty,c) | GProd (loc,na,_,ty,c) ->
let vs' = vars bounded vs ty in
let bounded' = add_name_to_ids bounded na in
vars bounded' vs' c
+ | GLetIn (loc,na,b,ty,c) ->
+ let vs' = vars bounded vs b in
+ let vs'' = Option.fold_left (vars bounded) vs' ty in
+ let bounded' = add_name_to_ids bounded na in
+ vars bounded' vs'' c
| GCases (loc,sty,rtntypopt,tml,pl) ->
let vs1 = vars_option bounded vs rtntypopt in
let vs2 = List.fold_left (fun vs (tm,_) -> vars bounded vs tm) vs1 tml in
@@ -346,7 +354,7 @@ let add_and_check_ident id set =
let bound_glob_vars =
let rec vars bound = function
- | GLambda (_,na,_,_,_) | GProd (_,na,_,_,_) | GLetIn (_,na,_,_) as c ->
+ | GLambda (_,na,_,_,_) | GProd (_,na,_,_,_) | GLetIn (_,na,_,_,_) as c ->
let bound = name_fold add_and_check_ident na bound in
fold_glob_constr vars bound c
| GCases (loc,sty,rtntypopt,tml,pl) ->
@@ -460,7 +468,7 @@ let loc_of_glob_constr = function
| GApp (loc,_,_) -> loc
| GLambda (loc,_,_,_,_) -> loc
| GProd (loc,_,_,_,_) -> loc
- | GLetIn (loc,_,_,_) -> loc
+ | GLetIn (loc,_,_,_,_) -> loc
| GCases (loc,_,_,_,_) -> loc
| GLetTuple (loc,_,_,_,_) -> loc
| GIf (loc,_,_,_,_) -> loc
@@ -512,9 +520,9 @@ let rec rename_glob_vars l = function
| GLambda (loc,na,bk,t,c) ->
let na',l' = update_subst na l in
GLambda (loc,na',bk,rename_glob_vars l t,rename_glob_vars l' c)
- | GLetIn (loc,na,b,c) ->
+ | GLetIn (loc,na,b,t,c) ->
let na',l' = update_subst na l in
- GLetIn (loc,na',rename_glob_vars l b,rename_glob_vars l' c)
+ GLetIn (loc,na',rename_glob_vars l b,Option.map (rename_glob_vars l) t,rename_glob_vars l' c)
(* Lazy strategy: we fail if a collision with renaming occurs, rather than renaming further *)
| GCases (loc,ci,po,tomatchl,cls) ->
let test_pred_pat (na,ino) =
diff --git a/pretyping/patternops.ml b/pretyping/patternops.ml
index 9dcb5d2a57..79765a4938 100644
--- a/pretyping/patternops.ml
+++ b/pretyping/patternops.ml
@@ -44,8 +44,9 @@ let rec constr_pattern_eq p1 p2 = match p1, p2 with
Name.equal v1 v2 && constr_pattern_eq t1 t2 && constr_pattern_eq b1 b2
| PProd (v1, t1, b1), PProd (v2, t2, b2) ->
Name.equal v1 v2 && constr_pattern_eq t1 t2 && constr_pattern_eq b1 b2
-| PLetIn (v1, t1, b1), PLetIn (v2, t2, b2) ->
- Name.equal v1 v2 && constr_pattern_eq t1 t2 && constr_pattern_eq b1 b2
+| PLetIn (v1, b1, t1, c1), PLetIn (v2, b2, t2, c2) ->
+ Name.equal v1 v2 && constr_pattern_eq b1 b2 &&
+ Option.equal constr_pattern_eq t1 t2 && constr_pattern_eq c1 c2
| PSort s1, PSort s2 -> Miscops.glob_sort_eq s1 s2
| PMeta m1, PMeta m2 -> Option.equal Id.equal m1 m2
| PIf (t1, l1, r1), PIf (t2, l2, r2) ->
@@ -85,7 +86,8 @@ let rec occur_meta_pattern = function
| PProj (_,arg) -> occur_meta_pattern arg
| PLambda (na,t,c) -> (occur_meta_pattern t) || (occur_meta_pattern c)
| PProd (na,t,c) -> (occur_meta_pattern t) || (occur_meta_pattern c)
- | PLetIn (na,t,c) -> (occur_meta_pattern t) || (occur_meta_pattern c)
+ | PLetIn (na,b,t,c) ->
+ Option.fold_left (fun b t -> b || occur_meta_pattern t) (occur_meta_pattern b) t || (occur_meta_pattern c)
| PIf (c,c1,c2) ->
(occur_meta_pattern c) ||
(occur_meta_pattern c1) || (occur_meta_pattern c2)
@@ -101,7 +103,7 @@ exception BoundPattern;;
let rec head_pattern_bound t =
match t with
| PProd (_,_,b) -> head_pattern_bound b
- | PLetIn (_,_,b) -> head_pattern_bound b
+ | PLetIn (_,_,_,b) -> head_pattern_bound b
| PApp (c,args) -> head_pattern_bound c
| PIf (c,_,_) -> head_pattern_bound c
| PCase (_,p,c,br) -> head_pattern_bound c
@@ -132,7 +134,7 @@ let pattern_of_constr env sigma t =
| Sort (Prop Pos) -> PSort GSet
| Sort (Type _) -> PSort (GType [])
| Cast (c,_,_) -> pattern_of_constr env c
- | LetIn (na,c,t,b) -> PLetIn (na,pattern_of_constr env c,
+ | LetIn (na,c,t,b) -> PLetIn (na,pattern_of_constr env c,Some (pattern_of_constr env t),
pattern_of_constr (push_rel (LocalDef (na,c,t)) env) b)
| Prod (na,c,b) -> PProd (na,pattern_of_constr env c,
pattern_of_constr (push_rel (LocalAssum (na, c)) env) b)
@@ -189,7 +191,7 @@ let map_pattern_with_binders g f l = function
| PSoApp (n,pl) -> PSoApp (n, List.map (f l) pl)
| PLambda (n,a,b) -> PLambda (n,f l a,f (g n l) b)
| PProd (n,a,b) -> PProd (n,f l a,f (g n l) b)
- | PLetIn (n,a,b) -> PLetIn (n,f l a,f (g n l) b)
+ | PLetIn (n,a,t,b) -> PLetIn (n,f l a,Option.map (f l) t,f (g n l) b)
| PIf (c,b1,b2) -> PIf (f l c,f l b1,f l b2)
| PCase (ci,po,p,pl) ->
PCase (ci,f l po,f l p, List.map (fun (i,n,c) -> (i,n,f l c)) pl)
@@ -274,11 +276,12 @@ let rec subst_pattern subst pat =
let c2' = subst_pattern subst c2 in
if c1' == c1 && c2' == c2 then pat else
PProd (name,c1',c2')
- | PLetIn (name,c1,c2) ->
+ | PLetIn (name,c1,t,c2) ->
let c1' = subst_pattern subst c1 in
+ let t' = Option.smartmap (subst_pattern subst) t in
let c2' = subst_pattern subst c2 in
- if c1' == c1 && c2' == c2 then pat else
- PLetIn (name,c1',c2')
+ if c1' == c1 && t' == t && c2' == c2 then pat else
+ PLetIn (name,c1',t',c2')
| PSort _
| PMeta _ -> pat
| PIf (c,c1,c2) ->
@@ -343,9 +346,10 @@ let rec pat_of_raw metas vars = function
name_iter (fun n -> metas := n::!metas) na;
PProd (na, pat_of_raw metas vars c1,
pat_of_raw metas (na::vars) c2)
- | GLetIn (_,na,c1,c2) ->
+ | GLetIn (_,na,c1,t,c2) ->
name_iter (fun n -> metas := n::!metas) na;
PLetIn (na, pat_of_raw metas vars c1,
+ Option.map (pat_of_raw metas vars) t,
pat_of_raw metas (na::vars) c2)
| GSort (_,s) ->
PSort s
@@ -404,7 +408,9 @@ let rec pat_of_raw metas vars = function
and pats_of_glob_branches loc metas vars ind brs =
let get_arg = function
- | PatVar(_,na) -> na
+ | PatVar(_,na) ->
+ name_iter (fun n -> metas := n::!metas) na;
+ na
| PatCstr(loc,_,_,_) -> err ~loc (Pp.str "Non supported pattern.")
in
let rec get_pat indexes = function
diff --git a/pretyping/pretyping.ml b/pretyping/pretyping.ml
index f92110ea56..27144b279f 100644
--- a/pretyping/pretyping.ml
+++ b/pretyping/pretyping.ml
@@ -257,16 +257,36 @@ type inference_flags = {
[sigma'] into those already in [sigma] or deriving from an evar in
[sigma] by restriction, and the evars properly created in [sigma'] *)
+type frozen =
+| FrozenId of evar_info Evar.Map.t
+ (** No pending evars. We do not put a set here not to reallocate like crazy,
+ but the actual data of the map is not used, only keys matter. All
+ functions operating on this type must have the same behaviour on
+ [FrozenId map] and [FrozenProgress (Evar.Map.domain map, Evar.Set.empty)] *)
+| FrozenProgress of (Evar.Set.t * Evar.Set.t) Lazy.t
+ (** Proper partition of the evar map as described above. *)
+
let frozen_and_pending_holes (sigma, sigma') =
- let add_derivative_of evk evi acc =
- match advance sigma' evk with None -> acc | Some evk' -> Evar.Set.add evk' acc in
- let frozen = Evd.fold_undefined add_derivative_of sigma Evar.Set.empty in
- let fold evk _ accu = if not (Evar.Set.mem evk frozen) then Evar.Set.add evk accu else accu in
- let pending = Evd.fold_undefined fold sigma' Evar.Set.empty in
- (frozen,pending)
+ let undefined0 = Evd.undefined_map sigma in
+ (** Fast path when the undefined evars where not modified *)
+ if undefined0 == Evd.undefined_map sigma' then
+ FrozenId undefined0
+ else
+ let data = lazy begin
+ let add_derivative_of evk evi acc =
+ match advance sigma' evk with None -> acc | Some evk' -> Evar.Set.add evk' acc in
+ let frozen = Evar.Map.fold add_derivative_of undefined0 Evar.Set.empty in
+ let fold evk _ accu = if not (Evar.Set.mem evk frozen) then Evar.Set.add evk accu else accu in
+ let pending = Evd.fold_undefined fold sigma' Evar.Set.empty in
+ (frozen, pending)
+ end in
+ FrozenProgress data
let apply_typeclasses env evdref frozen fail_evar =
- let filter_frozen evk = Evar.Set.mem evk frozen in
+ let filter_frozen = match frozen with
+ | FrozenId map -> fun evk -> Evar.Map.mem evk map
+ | FrozenProgress (lazy (frozen, _)) -> fun evk -> Evar.Set.mem evk 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))
@@ -276,7 +296,9 @@ let apply_typeclasses env evdref frozen fail_evar =
evdref := Typeclasses.resolve_typeclasses
~filter:(fun evk evi -> Typeclasses.all_evars evk evi && not (filter_frozen evk)) ~split:true ~fail:false env !evdref
-let apply_inference_hook hook evdref pending =
+let apply_inference_hook hook evdref frozen = match frozen with
+| FrozenId _ -> ()
+| FrozenProgress (lazy (_, pending)) ->
evdref := Evar.Set.fold (fun evk sigma ->
if Evd.is_undefined sigma evk (* in particular not defined by side-effect *)
then
@@ -299,7 +321,9 @@ let check_typeclasses_instances_are_solved env current_sigma frozen =
(* Naive way, call resolution again with failure flag *)
apply_typeclasses env (ref current_sigma) frozen true
-let check_extra_evars_are_solved env current_sigma pending =
+let check_extra_evars_are_solved env current_sigma frozen = match frozen with
+| FrozenId _ -> ()
+| FrozenProgress (lazy (_, pending)) ->
Evar.Set.iter
(fun evk ->
if not (Evd.is_defined current_sigma evk) then
@@ -326,29 +350,29 @@ let check_evars env initial_sigma sigma c =
| _ -> Constr.iter proc_rec c
in proc_rec c
-let check_evars_are_solved env current_sigma frozen pending =
+let check_evars_are_solved env current_sigma frozen =
check_typeclasses_instances_are_solved env current_sigma frozen;
check_problems_are_solved env current_sigma;
- check_extra_evars_are_solved env current_sigma pending
+ check_extra_evars_are_solved env current_sigma frozen
(* Try typeclasses, hooks, unification heuristics ... *)
-let solve_remaining_evars flags env current_sigma pending =
- let frozen,pending = frozen_and_pending_holes pending in
+let solve_remaining_evars flags env current_sigma init_sigma =
+ let frozen = frozen_and_pending_holes (init_sigma, current_sigma) in
let evdref = ref current_sigma in
if flags.use_typeclasses then apply_typeclasses env evdref frozen false;
if Option.has_some flags.use_hook then
- apply_inference_hook (Option.get flags.use_hook env) evdref pending;
+ apply_inference_hook (Option.get flags.use_hook env) evdref frozen;
if flags.solve_unification_constraints then apply_heuristics env evdref false;
- if flags.fail_evar then check_evars_are_solved env !evdref frozen pending;
+ if flags.fail_evar then check_evars_are_solved env !evdref frozen;
!evdref
-let check_evars_are_solved env current_sigma pending =
- let frozen,pending = frozen_and_pending_holes pending in
- check_evars_are_solved env current_sigma frozen pending
+let check_evars_are_solved env current_sigma init_sigma =
+ let frozen = frozen_and_pending_holes (init_sigma, current_sigma) in
+ check_evars_are_solved env current_sigma frozen
let process_inference_flags flags env initial_sigma (sigma,c) =
- let sigma = solve_remaining_evars flags env sigma (initial_sigma, sigma) in
+ let sigma = solve_remaining_evars flags env sigma initial_sigma in
let c = if flags.expand_evars then nf_evar sigma c else c in
sigma,c
@@ -810,14 +834,14 @@ let rec pretype k0 resolve_tc (tycon : type_constraint) (env : ExtraEnv.t) evdre
iraise (e, info) in
inh_conv_coerce_to_tycon loc env evdref resj tycon
- | GLetIn(loc,name,c1,c2) ->
- let j =
- match c1 with
- | GCast (loc, c, CastConv t) ->
- let tj = pretype_type empty_valcon env evdref lvar t in
- pretype (mk_tycon tj.utj_val) env evdref lvar c
- | _ -> pretype empty_tycon env evdref lvar c1
- in
+ | GLetIn(loc,name,c1,t,c2) ->
+ let tycon1 =
+ match t with
+ | Some t ->
+ mk_tycon (pretype_type empty_valcon env evdref lvar t).utj_val
+ | None ->
+ empty_tycon in
+ let j = pretype tycon1 env evdref lvar c1 in
let t = evd_comb1 (Evarsolve.refresh_universes
~onlyalg:true ~status:Evd.univ_flexible (Some false) env.ExtraEnv.env)
evdref j.uj_type in
diff --git a/pretyping/pretyping.mli b/pretyping/pretyping.mli
index 2c6aa7a21b..23957d5575 100644
--- a/pretyping/pretyping.mli
+++ b/pretyping/pretyping.mli
@@ -129,13 +129,13 @@ val type_uconstr :
[pending], however, it can contain more evars than the pending ones. *)
val solve_remaining_evars : inference_flags ->
- env -> (* initial map *) evar_map -> (* map to solve *) pending -> evar_map
+ env -> (* current map *) evar_map -> (* initial map *) evar_map -> evar_map
(** Checking evars and pending conversion problems are all solved,
reporting an appropriate error message *)
val check_evars_are_solved :
- env -> (* current map: *) evar_map -> (* map to check: *) pending -> unit
+ env -> (* current map: *) evar_map -> (* initial map: *) evar_map -> unit
(** [check_evars env initial_sigma extended_sigma c] fails if some
new unresolved evar remains in [c] *)
diff --git a/pretyping/unification.ml b/pretyping/unification.ml
index a91c30df6f..11771f7bac 100644
--- a/pretyping/unification.ml
+++ b/pretyping/unification.ml
@@ -1520,7 +1520,7 @@ let default_matching_merge_flags sigma =
use_pattern_unification = true;
}
-let default_matching_flags (sigma,_) =
+let default_matching_flags sigma =
let flags = default_matching_core_flags sigma in {
core_unify_flags = flags;
merge_unify_flags = default_matching_merge_flags sigma;
@@ -1658,7 +1658,7 @@ let make_abstraction_core name (test,out) env sigma c ty occs check_occs concl =
type prefix_of_inductive_support_flag = bool
type abstraction_request =
-| AbstractPattern of prefix_of_inductive_support_flag * (types -> bool) * Name.t * pending_constr * clause * bool
+| AbstractPattern of prefix_of_inductive_support_flag * (types -> bool) * Name.t * (evar_map * constr) * clause * bool
| AbstractExact of Name.t * constr * types option * clause * bool
type 'r abstraction_result =
diff --git a/pretyping/unification.mli b/pretyping/unification.mli
index 0ad882a9ff..c63502eae1 100644
--- a/pretyping/unification.mli
+++ b/pretyping/unification.mli
@@ -71,11 +71,11 @@ exception PatternNotFound
type prefix_of_inductive_support_flag = bool
type abstraction_request =
-| AbstractPattern of prefix_of_inductive_support_flag * (types -> bool) * Names.Name.t * pending_constr * Locus.clause * bool
+| AbstractPattern of prefix_of_inductive_support_flag * (types -> bool) * Names.Name.t * (evar_map * constr) * Locus.clause * bool
| AbstractExact of Names.Name.t * constr * types option * Locus.clause * bool
val finish_evar_resolution : ?flags:Pretyping.inference_flags ->
- env -> 'r Sigma.t -> pending_constr -> (constr, 'r) Sigma.sigma
+ env -> 'r Sigma.t -> (evar_map * constr) -> (constr, 'r) Sigma.sigma
type 'r abstraction_result =
Names.Id.t * named_context_val *
diff --git a/printing/ppannotation.ml b/printing/ppannotation.ml
deleted file mode 100644
index 726c0ffcf1..0000000000
--- a/printing/ppannotation.ml
+++ /dev/null
@@ -1,33 +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 Ppextend
-open Constrexpr
-open Vernacexpr
-open Genarg
-
-type t =
- | AKeyword
- | AUnparsing of unparsing
- | AConstrExpr of constr_expr
- | AVernac of vernac_expr
- | AGlbGenArg of glob_generic_argument
- | ARawGenArg of raw_generic_argument
-
-let tag_of_annotation = function
- | AKeyword -> "keyword"
- | AUnparsing _ -> "unparsing"
- | AConstrExpr _ -> "constr_expr"
- | AVernac _ -> "vernac_expr"
- | AGlbGenArg _ -> "glob_generic_argument"
- | ARawGenArg _ -> "raw_generic_argument"
-
-let attributes_of_annotation a =
- []
-
-let tag = Pp.Tag.create "ppannotation"
diff --git a/printing/ppannotation.mli b/printing/ppannotation.mli
deleted file mode 100644
index b0e0facef6..0000000000
--- a/printing/ppannotation.mli
+++ /dev/null
@@ -1,29 +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 module defines the annotations that are attached to
- semi-structured pretty-printing of Coq syntactic objects. *)
-
-open Ppextend
-open Constrexpr
-open Vernacexpr
-open Genarg
-
-type t =
- | AKeyword
- | AUnparsing of unparsing
- | AConstrExpr of constr_expr
- | AVernac of vernac_expr
- | AGlbGenArg of glob_generic_argument
- | ARawGenArg of raw_generic_argument
-
-val tag_of_annotation : t -> string
-
-val attributes_of_annotation : t -> (string * string) list
-
-val tag : t Pp.Tag.key
diff --git a/printing/ppconstr.ml b/printing/ppconstr.ml
index 80ddd669f4..38eeda9b96 100644
--- a/printing/ppconstr.ml
+++ b/printing/ppconstr.ml
@@ -21,18 +21,31 @@ open Decl_kinds
open Misctypes
(*i*)
-module Make (Taggers : sig
- val tag_keyword : std_ppcmds -> std_ppcmds
- val tag_evar : std_ppcmds -> std_ppcmds
- val tag_type : std_ppcmds -> std_ppcmds
- val tag_path : std_ppcmds -> std_ppcmds
- val tag_ref : std_ppcmds -> std_ppcmds
- val tag_var : std_ppcmds -> std_ppcmds
- val tag_constr_expr : constr_expr -> std_ppcmds -> std_ppcmds
- val tag_unparsing : unparsing -> std_ppcmds -> std_ppcmds
-end) = struct
-
- open Taggers
+module Tag =
+struct
+ let keyword = "constr.keyword"
+ let evar = "constr.evar"
+ let univ = "constr.type"
+ let notation = "constr.notation"
+ let variable = "constr.variable"
+ let reference = "constr.reference"
+ let path = "constr.path"
+
+end
+
+let do_not_tag _ x = x
+let tag t s = Pp.tag t s
+let tag_keyword = tag Tag.keyword
+let tag_evar = tag Tag.evar
+let tag_type = tag Tag.univ
+let tag_unparsing = function
+| UnpTerminal s -> tag Tag.notation
+| _ -> do_not_tag ()
+let tag_constr_expr = do_not_tag
+let tag_path = tag Tag.path
+let tag_ref = tag Tag.reference
+let tag_var = tag Tag.variable
+
let keyword s = tag_keyword (str s)
let sep_v = fun _ -> str"," ++ spc()
@@ -304,9 +317,9 @@ end) = struct
pr_sep_com spc (pr ltop) rhs))
let begin_of_binder = function
- LocalRawDef((loc,_),_) -> fst (Loc.unloc loc)
- | LocalRawAssum((loc,_)::_,_,_) -> fst (Loc.unloc loc)
- | LocalPattern(loc,_,_) -> fst (Loc.unloc loc)
+ | CLocalDef((loc,_),_,_) -> fst (Loc.unloc loc)
+ | CLocalAssum((loc,_)::_,_,_) -> fst (Loc.unloc loc)
+ | CLocalPattern(loc,_,_) -> fst (Loc.unloc loc)
| _ -> assert false
let begin_of_binders = function
@@ -347,15 +360,13 @@ end) = struct
hov 1 (if many then surround_impl b s else surround_implicit b s)
let pr_binder_among_many pr_c = function
- | LocalRawAssum (nal,k,t) ->
+ | CLocalAssum (nal,k,t) ->
pr_binder true pr_c (nal,k,t)
- | LocalRawDef (na,c) ->
- let c,topt = match c with
- | CCast(_,c, (CastConv t|CastVM t|CastNative t)) -> c, t
- | _ -> c, CHole (Loc.ghost, None, Misctypes.IntroAnonymous, None) in
- surround (pr_lname na ++ pr_opt_type pr_c topt ++
- str":=" ++ cut() ++ pr_c c)
- | LocalPattern (loc,p,tyo) ->
+ | CLocalDef (na,c,topt) ->
+ surround (pr_lname na ++
+ pr_opt_no_spc (fun t -> str " :" ++ ws 1 ++ pr_c t) topt ++
+ str" :=" ++ spc() ++ pr_c c)
+ | CLocalPattern (loc,p,tyo) ->
let p = pr_patt lsimplepatt p in
match tyo with
| None ->
@@ -369,9 +380,9 @@ end) = struct
let pr_delimited_binders kw sep pr_c bl =
let n = begin_of_binders bl in
match bl with
- | [LocalRawAssum (nal,k,t)] ->
+ | [CLocalAssum (nal,k,t)] ->
kw n ++ pr_binder false pr_c (nal,k,t)
- | (LocalRawAssum _ | LocalPattern _) :: _ as bdl ->
+ | (CLocalAssum _ | CLocalPattern _) :: _ as bdl ->
kw n ++ pr_undelimited_binders sep pr_c bdl
| _ -> assert false
@@ -382,33 +393,33 @@ end) = struct
let rec extract_prod_binders = function
(* | CLetIn (loc,na,b,c) as x ->
let bl,c = extract_prod_binders c in
- if bl = [] then [], x else LocalRawDef (na,b) :: bl, c*)
+ if bl = [] then [], x else CLocalDef (na,b) :: bl, c*)
| CProdN (loc,[],c) ->
extract_prod_binders c
| CProdN (loc,[[_,Name id],bk,t],
CCases (_,LetPatternStyle,None, [CRef (Ident (_,id'),None),None,None],[(_,[_,[p]],b)]))
when Id.equal id id' && not (Id.Set.mem id (Topconstr.free_vars_of_constr_expr b)) ->
let bl,c = extract_prod_binders b in
- LocalPattern (loc,p,None) :: bl, c
+ CLocalPattern (loc,p,None) :: bl, c
| CProdN (loc,(nal,bk,t)::bl,c) ->
let bl,c = extract_prod_binders (CProdN(loc,bl,c)) in
- LocalRawAssum (nal,bk,t) :: bl, c
+ CLocalAssum (nal,bk,t) :: bl, c
| c -> [], c
let rec extract_lam_binders = function
(* | CLetIn (loc,na,b,c) as x ->
let bl,c = extract_lam_binders c in
- if bl = [] then [], x else LocalRawDef (na,b) :: bl, c*)
+ if bl = [] then [], x else CLocalDef (na,b) :: bl, c*)
| CLambdaN (loc,[],c) ->
extract_lam_binders c
| CLambdaN (loc,[[_,Name id],bk,t],
CCases (_,LetPatternStyle,None, [CRef (Ident (_,id'),None),None,None],[(_,[_,[p]],b)]))
when Id.equal id id' && not (Id.Set.mem id (Topconstr.free_vars_of_constr_expr b)) ->
let bl,c = extract_lam_binders b in
- LocalPattern (loc,p,None) :: bl, c
+ CLocalPattern (loc,p,None) :: bl, c
| CLambdaN (loc,(nal,bk,t)::bl,c) ->
let bl,c = extract_lam_binders (CLambdaN(loc,bl,c)) in
- LocalRawAssum (nal,bk,t) :: bl, c
+ CLocalAssum (nal,bk,t) :: bl, c
| c -> [], c
let split_lambda = function
@@ -437,7 +448,7 @@ end) = struct
let (na,_,def) = split_lambda def in
let (na,t,typ) = split_product na typ in
let (bl,typ,def) = split_fix (n-1) typ def in
- (LocalRawAssum ([na],default_binder_kind,t)::bl,typ,def)
+ (CLocalAssum ([na],default_binder_kind,t)::bl,typ,def)
let pr_recursive_decl pr pr_dangling dangling_with_for id bl annot t c =
let pr_body =
@@ -454,9 +465,9 @@ end) = struct
match (ro : Constrexpr.recursion_order_expr) with
| CStructRec ->
let names_of_binder = function
- | LocalRawAssum (nal,_,_) -> nal
- | LocalRawDef (_,_) -> []
- | LocalPattern _ -> assert false
+ | CLocalAssum (nal,_,_) -> nal
+ | CLocalDef (_,_,_) -> []
+ | CLocalPattern _ -> assert false
in let ids = List.flatten (List.map names_of_binder bl) in
if List.length ids > 1 then
spc() ++ str "{" ++ keyword "struct" ++ spc () ++ pr_id id ++ str"}"
@@ -575,7 +586,7 @@ end) = struct
pr_fun_sep ++ pr spc ltop a),
llambda
)
- | CLetIn (_,(_,Name x),(CFix(_,(_,x'),[_])|CCoFix(_,(_,x'),[_]) as fx), b)
+ | CLetIn (_,(_,Name x),(CFix(_,(_,x'),[_])|CCoFix(_,(_,x'),[_]) as fx), t, b)
when Id.equal x x' ->
return (
hv 0 (
@@ -585,11 +596,12 @@ end) = struct
pr spc ltop b),
lletin
)
- | CLetIn (_,x,a,b) ->
+ | CLetIn (_,x,a,t,b) ->
return (
hv 0 (
- hov 2 (keyword "let" ++ spc () ++ pr_lname x ++ str " :="
- ++ pr spc ltop a ++ spc ()
+ hov 2 (keyword "let" ++ spc () ++ pr_lname x
+ ++ pr_opt_no_spc (fun t -> str " :" ++ ws 1 ++ pr mt ltop t) t
+ ++ str " :=" ++ pr spc ltop a ++ spc ()
++ keyword "in") ++
pr spc ltop b),
lletin
@@ -690,7 +702,7 @@ end) = struct
| CEvar (_,n,l) ->
return (pr_evar (pr mt) n l, latom)
| CPatVar (_,p) ->
- return (str "?" ++ pr_patvar p, latom)
+ return (str "@?" ++ pr_patvar p, latom)
| CSort (_,s) ->
return (pr_glob_sort s, latom)
| CCast (_,a,b) ->
@@ -764,86 +776,3 @@ end) = struct
let pr_binders = pr_undelimited_binders spc (pr ltop)
-end
-
-module Tag =
-struct
- let keyword =
- let style = Terminal.make ~bold:true () in
- Ppstyle.make ~style ["constr"; "keyword"]
-
- let evar =
- let style = Terminal.make ~fg_color:`LIGHT_BLUE () in
- Ppstyle.make ~style ["constr"; "evar"]
-
- let univ =
- let style = Terminal.make ~bold:true ~fg_color:`YELLOW () in
- Ppstyle.make ~style ["constr"; "type"]
-
- let notation =
- let style = Terminal.make ~fg_color:`WHITE () in
- Ppstyle.make ~style ["constr"; "notation"]
-
- let variable =
- Ppstyle.make ["constr"; "variable"]
-
- let reference =
- let style = Terminal.make ~fg_color:`LIGHT_GREEN () in
- Ppstyle.make ~style ["constr"; "reference"]
-
- let path =
- let style = Terminal.make ~fg_color:`LIGHT_MAGENTA () in
- Ppstyle.make ~style ["constr"; "path"]
-
-end
-
-let do_not_tag _ x = x
-
-let split_token tag s =
- let len = String.length s in
- let rec parse_string off i =
- if Int.equal i len then
- if Int.equal off i then mt () else tag (str (String.sub s off (i - off)))
- else if s.[i] == ' ' then
- if Int.equal off i then parse_space 1 (succ i)
- else tag (str (String.sub s off (i - off))) ++ parse_space 1 (succ i)
- else parse_string off (succ i)
- and parse_space spc i =
- if Int.equal i len then str (String.make spc ' ')
- else if s.[i] == ' ' then parse_space (succ spc) (succ i)
- else str (String.make spc ' ') ++ parse_string i (succ i)
- in
- parse_string 0 0
-
-(** Instantiating Make with tagging functions that only add style
- information. *)
-include Make (struct
- let tag t s = Pp.tag (Pp.Tag.inj t Ppstyle.tag) s
- let tag_keyword = tag Tag.keyword
- let tag_evar = tag Tag.evar
- let tag_type = tag Tag.univ
- let tag_unparsing = function
- | UnpTerminal s -> fun _ -> split_token (fun pp -> tag Tag.notation pp) s
- | _ -> do_not_tag ()
- let tag_constr_expr = do_not_tag
- let tag_path = tag Tag.path
- let tag_ref = tag Tag.reference
- let tag_var = tag Tag.variable
-end)
-
-module Richpp = struct
-
- include Make (struct
- open Ppannotation
- let tag_keyword = Pp.tag (Pp.Tag.inj AKeyword tag)
- let tag_type = Pp.tag (Pp.Tag.inj AKeyword tag)
- let tag_evar = do_not_tag ()
- let tag_unparsing unp = Pp.tag (Pp.Tag.inj (AUnparsing unp) tag)
- let tag_constr_expr e = Pp.tag (Pp.Tag.inj (AConstrExpr e) tag)
- let tag_path = do_not_tag ()
- let tag_ref = do_not_tag ()
- let tag_var = do_not_tag ()
- end)
-
-end
-
diff --git a/printing/ppconstr.mli b/printing/ppconstr.mli
index 0241633c61..f92caf426e 100644
--- a/printing/ppconstr.mli
+++ b/printing/ppconstr.mli
@@ -11,11 +11,85 @@
(** The default pretty-printers produce {!Pp.std_ppcmds} that are
interpreted as raw strings. *)
-include Ppconstrsig.Pp
+open Loc
+open Pp
+open Libnames
+open Constrexpr
+open Names
+open Misctypes
-(** The rich pretty-printers produce {!Pp.std_ppcmds} that are
- interpreted as annotated strings. The annotations can be
- retrieved using {!RichPp.rich_pp}. Their definitions are
- located in {!Ppannotation.t}. *)
+val extract_lam_binders :
+ constr_expr -> local_binder_expr list * constr_expr
+val extract_prod_binders :
+ constr_expr -> local_binder_expr list * constr_expr
+val split_fix :
+ int -> constr_expr -> constr_expr ->
+ local_binder_expr list * constr_expr * constr_expr
-module Richpp : Ppconstrsig.Pp
+val prec_less : int -> int * Ppextend.parenRelation -> bool
+
+val pr_tight_coma : unit -> std_ppcmds
+
+val pr_or_var : ('a -> std_ppcmds) -> 'a or_var -> std_ppcmds
+
+val pr_lident : Id.t located -> std_ppcmds
+val pr_lname : Name.t located -> std_ppcmds
+
+val pr_with_comments : Loc.t -> std_ppcmds -> std_ppcmds
+val pr_com_at : int -> std_ppcmds
+val pr_sep_com :
+ (unit -> std_ppcmds) ->
+ (constr_expr -> std_ppcmds) ->
+ constr_expr -> std_ppcmds
+
+val pr_id : Id.t -> std_ppcmds
+val pr_name : Name.t -> std_ppcmds
+val pr_qualid : qualid -> std_ppcmds
+val pr_patvar : patvar -> std_ppcmds
+
+val pr_glob_level : glob_level -> std_ppcmds
+val pr_glob_sort : glob_sort -> std_ppcmds
+val pr_guard_annot : (constr_expr -> std_ppcmds) ->
+ local_binder_expr list ->
+ ('a * Names.Id.t) option * recursion_order_expr ->
+ std_ppcmds
+
+val pr_record_body : (reference * constr_expr) list -> std_ppcmds
+val pr_binders : local_binder_expr list -> std_ppcmds
+val pr_constr_pattern_expr : constr_pattern_expr -> std_ppcmds
+val pr_lconstr_pattern_expr : constr_pattern_expr -> std_ppcmds
+val pr_constr_expr : constr_expr -> std_ppcmds
+val pr_lconstr_expr : constr_expr -> std_ppcmds
+val pr_cases_pattern_expr : cases_pattern_expr -> std_ppcmds
+
+type term_pr = {
+ pr_constr_expr : constr_expr -> std_ppcmds;
+ pr_lconstr_expr : constr_expr -> std_ppcmds;
+ pr_constr_pattern_expr : constr_pattern_expr -> std_ppcmds;
+ pr_lconstr_pattern_expr : constr_pattern_expr -> std_ppcmds
+}
+
+val set_term_pr : term_pr -> unit
+val default_term_pr : term_pr
+
+(* The modular constr printer.
+ [modular_constr_pr pr s p t] prints the head of the term [t] and calls
+ [pr] on its subterms.
+ [s] is typically {!Pp.mt} and [p] is [lsimpleconstr] for "constr" printers
+ and [ltop] for "lconstr" printers (spiwack: we might need more
+ specification here).
+ We can make a new modular constr printer by overriding certain branches,
+ for instance if we want to build a printer which prints "Prop" as "Omega"
+ instead we can proceed as follows:
+ let my_modular_constr_pr pr s p = function
+ | CSort (_,GProp Null) -> str "Omega"
+ | t -> modular_constr_pr pr s p t
+ Which has the same type. We can turn a modular printer into a printer by
+ taking its fixpoint. *)
+
+type precedence
+val lsimpleconstr : precedence
+val ltop : precedence
+val modular_constr_pr :
+ ((unit->std_ppcmds) -> precedence -> constr_expr -> std_ppcmds) ->
+ (unit->std_ppcmds) -> precedence -> constr_expr -> std_ppcmds
diff --git a/printing/ppconstrsig.mli b/printing/ppconstrsig.mli
deleted file mode 100644
index 3de0d805c4..0000000000
--- a/printing/ppconstrsig.mli
+++ /dev/null
@@ -1,95 +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 Loc
-open Pp
-open Libnames
-open Constrexpr
-open Names
-open Misctypes
-
-module type Pp = sig
-
- val extract_lam_binders :
- constr_expr -> local_binder list * constr_expr
- val extract_prod_binders :
- constr_expr -> local_binder list * constr_expr
- val split_fix :
- int -> constr_expr -> constr_expr ->
- local_binder list * constr_expr * constr_expr
-
- val prec_less : int -> int * Ppextend.parenRelation -> bool
-
- val pr_tight_coma : unit -> std_ppcmds
-
- val pr_or_var : ('a -> std_ppcmds) -> 'a or_var -> std_ppcmds
-
- val pr_lident : Id.t located -> std_ppcmds
- val pr_lname : Name.t located -> std_ppcmds
-
- val pr_with_comments : Loc.t -> std_ppcmds -> std_ppcmds
- val pr_com_at : int -> std_ppcmds
- val pr_sep_com :
- (unit -> std_ppcmds) ->
- (constr_expr -> std_ppcmds) ->
- constr_expr -> std_ppcmds
-
- val pr_id : Id.t -> std_ppcmds
- val pr_name : Name.t -> std_ppcmds
- val pr_qualid : qualid -> std_ppcmds
- val pr_patvar : patvar -> std_ppcmds
-
- val pr_glob_level : glob_level -> std_ppcmds
- val pr_glob_sort : glob_sort -> std_ppcmds
- val pr_guard_annot : (constr_expr -> std_ppcmds) ->
- local_binder list ->
- ('a * Names.Id.t) option * recursion_order_expr ->
- std_ppcmds
-
- val pr_record_body : (reference * constr_expr) list -> std_ppcmds
- val pr_binders : local_binder list -> std_ppcmds
- val pr_constr_pattern_expr : constr_pattern_expr -> std_ppcmds
- val pr_lconstr_pattern_expr : constr_pattern_expr -> std_ppcmds
- val pr_constr_expr : constr_expr -> std_ppcmds
- val pr_lconstr_expr : constr_expr -> std_ppcmds
- val pr_cases_pattern_expr : cases_pattern_expr -> std_ppcmds
-
- type term_pr = {
- pr_constr_expr : constr_expr -> std_ppcmds;
- pr_lconstr_expr : constr_expr -> std_ppcmds;
- pr_constr_pattern_expr : constr_pattern_expr -> std_ppcmds;
- pr_lconstr_pattern_expr : constr_pattern_expr -> std_ppcmds
- }
-
- val set_term_pr : term_pr -> unit
- val default_term_pr : term_pr
-
-(** The modular constr printer.
- [modular_constr_pr pr s p t] prints the head of the term [t] and calls
- [pr] on its subterms.
- [s] is typically {!Pp.mt} and [p] is [lsimpleconstr] for "constr" printers
- and [ltop] for "lconstr" printers (spiwack: we might need more
- specification here).
- We can make a new modular constr printer by overriding certain branches,
- for instance if we want to build a printer which prints "Prop" as "Omega"
- instead we can proceed as follows:
- let my_modular_constr_pr pr s p = function
- | CSort (_,GProp Null) -> str "Omega"
- | t -> modular_constr_pr pr s p t
- Which has the same type. We can turn a modular printer into a printer by
- taking its fixpoint. *)
-
- type precedence
- val lsimpleconstr : precedence
- val ltop : precedence
- val modular_constr_pr :
- ((unit->std_ppcmds) -> precedence -> constr_expr -> std_ppcmds) ->
- (unit->std_ppcmds) -> precedence -> constr_expr -> std_ppcmds
-
-end
-
diff --git a/printing/ppvernac.ml b/printing/ppvernac.ml
index ff72be90c5..cfc2e48d11 100644
--- a/printing/ppvernac.ml
+++ b/printing/ppvernac.ml
@@ -19,17 +19,12 @@ open Constrexpr
open Constrexpr_ops
open Decl_kinds
-module Make
- (Ppconstr : Ppconstrsig.Pp)
- (Taggers : sig
- val tag_keyword : std_ppcmds -> std_ppcmds
- val tag_vernac : vernac_expr -> std_ppcmds -> std_ppcmds
- end)
-= struct
-
- open Taggers
open Ppconstr
+ let do_not_tag _ x = x
+ let tag_keyword = do_not_tag ()
+ let tag_vernac = do_not_tag
+
let keyword s = tag_keyword (str s)
let pr_constr = pr_constr_expr
@@ -526,7 +521,7 @@ module Make
let pr_using e = str (Proof_using.to_string e)
let rec pr_vernac_body v =
- let return = Taggers.tag_vernac v in
+ let return = tag_vernac v in
match v with
| VernacPolymorphic (poly, v) ->
let s = if poly then keyword "Polymorphic" else keyword "Monomorphic" in
@@ -539,18 +534,8 @@ module Make
(* Stm *)
| VernacStm JoinDocument ->
return (keyword "Stm JoinDocument")
- | VernacStm PrintDag ->
- return (keyword "Stm PrintDag")
- | VernacStm Finish ->
- return (keyword "Stm Finish")
| VernacStm Wait ->
return (keyword "Stm Wait")
- | VernacStm (Observe id) ->
- return (keyword "Stm Observe " ++ str(Stateid.to_string id))
- | VernacStm (Command v) ->
- return (keyword "Stm Command " ++ pr_vernac_body v)
- | VernacStm (PGLast v) ->
- return (keyword "Stm PGLast " ++ pr_vernac_body v)
(* Proof management *)
| VernacAbortAll ->
@@ -1244,23 +1229,3 @@ module Make
let pr_vernac v =
try pr_vernac_body v ++ sep_end v
with e -> CErrors.print e
-
-end
-
-include Make (Ppconstr) (struct
- let do_not_tag _ x = x
- let tag_keyword = do_not_tag ()
- let tag_vernac = do_not_tag
-end)
-
-module Richpp = struct
-
- include Make
- (Ppconstr.Richpp)
- (struct
- open Ppannotation
- let tag_keyword s = Pp.tag (Pp.Tag.inj AKeyword tag) s
- let tag_vernac v s = Pp.tag (Pp.Tag.inj (AVernac v) tag) s
- end)
-
-end
diff --git a/printing/ppvernac.mli b/printing/ppvernac.mli
index d3d4a5ceb7..836b05e0e4 100644
--- a/printing/ppvernac.mli
+++ b/printing/ppvernac.mli
@@ -9,12 +9,11 @@
(** This module implements pretty-printers for vernac_expr syntactic
objects and their subcomponents. *)
-(** The default pretty-printers produce {!Pp.std_ppcmds} that are
- interpreted as raw strings. *)
-include Ppvernacsig.Pp
+(** Prints a fixpoint body *)
+val pr_rec_definition : (Vernacexpr.fixpoint_expr * Vernacexpr.decl_notation list) -> Pp.std_ppcmds
-(** The rich pretty-printers produce {!Pp.std_ppcmds} that are
- interpreted as annotated strings. The annotations can be
- retrieved using {!RichPp.rich_pp}. Their definitions are
- located in {!Ppannotation.t}. *)
-module Richpp : Ppvernacsig.Pp
+(** Prints a vernac expression *)
+val pr_vernac_body : Vernacexpr.vernac_expr -> Pp.std_ppcmds
+
+(** Prints a vernac expression and closes it with a dot. *)
+val pr_vernac : Vernacexpr.vernac_expr -> Pp.std_ppcmds
diff --git a/printing/ppvernacsig.mli b/printing/ppvernacsig.mli
deleted file mode 100644
index 5e5e4bcf49..0000000000
--- a/printing/ppvernacsig.mli
+++ /dev/null
@@ -1,20 +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 *)
-(************************************************************************)
-
-module type Pp = sig
-
- (** Prints a fixpoint body *)
- val pr_rec_definition : (Vernacexpr.fixpoint_expr * Vernacexpr.decl_notation list) -> Pp.std_ppcmds
-
- (** Prints a vernac expression *)
- val pr_vernac_body : Vernacexpr.vernac_expr -> Pp.std_ppcmds
-
- (** Prints a vernac expression and closes it with a dot. *)
- val pr_vernac : Vernacexpr.vernac_expr -> Pp.std_ppcmds
-
-end
diff --git a/printing/prettyp.ml b/printing/prettyp.ml
index 8fabb70536..5963d45ef9 100644
--- a/printing/prettyp.ml
+++ b/printing/prettyp.ml
@@ -204,6 +204,11 @@ let print_opacity ref =
str "transparent (with minimal expansion weight)"]
(*******************)
+
+let print_if_is_coercion ref =
+ if Classops.coercion_exists ref then [pr_global ref ++ str " is a coercion"] else []
+
+(*******************)
(* *)
let print_polymorphism ref =
@@ -257,7 +262,8 @@ let print_name_infos ref =
type_info_for_implicit @
print_renames_list (mt()) renames @
print_impargs_list (mt()) impls @
- print_argument_scopes (mt()) scopes
+ print_argument_scopes (mt()) scopes @
+ print_if_is_coercion ref
let print_id_args_data test pr id l =
if List.exists test l then
diff --git a/printing/printer.ml b/printing/printer.ml
index 00c2b636b0..5e7e9ce548 100644
--- a/printing/printer.ml
+++ b/printing/printer.ml
@@ -722,7 +722,7 @@ let pr_open_subgoals ?(proof=Proof_global.give_me_the_proof ()) () =
let end_cmd =
str "This subproof is complete, but there are some unfocused goals." ++
(let s = Proof_global.Bullet.suggest p in
- if Pp.is_empty s then s else fnl () ++ s) ++
+ if Pp.ismt s then s else fnl () ++ s) ++
fnl ()
in
pr_subgoals ~pr_first:false (Some end_cmd) bsigma seeds shelf [] bgoals
diff --git a/printing/printing.mllib b/printing/printing.mllib
index b0141b6d37..86b68d8fb0 100644
--- a/printing/printing.mllib
+++ b/printing/printing.mllib
@@ -1,6 +1,5 @@
Genprint
Pputils
-Ppannotation
Ppconstr
Printer
Printmod
diff --git a/printing/printmod.ml b/printing/printmod.ml
index dfa66d4376..baa1b8d791 100644
--- a/printing/printmod.ml
+++ b/printing/printmod.ml
@@ -26,6 +26,18 @@ open Goptions
the "short" mode or (Some env) in the "rich" one.
*)
+module Tag =
+struct
+
+ let definition = "module.definition"
+ let keyword = "module.keyword"
+
+end
+
+let tag t s = Pp.tag t s
+let tag_definition s = tag Tag.definition s
+let tag_keyword s = tag Tag.keyword s
+
let short = ref false
let _ =
@@ -44,14 +56,8 @@ let mk_fake_top =
let r = ref 0 in
fun () -> incr r; Id.of_string ("FAKETOP"^(string_of_int !r))
-module Make (Taggers : sig
- val tag_definition : std_ppcmds -> std_ppcmds
- val tag_keyword : std_ppcmds -> std_ppcmds
-end) =
-struct
-
-let def s = Taggers.tag_definition (str s)
-let keyword s = Taggers.tag_keyword (str s)
+let def s = tag_definition (str s)
+let keyword s = tag_keyword (str s)
let get_new_id locals id =
let rec get_id l id =
@@ -397,11 +403,11 @@ let rec printable_body dir =
let print_expression' is_type env mp me =
States.with_state_protection
- (fun e -> eval_ppcmds (print_expression is_type env mp [] e)) me
+ (fun e -> print_expression is_type env mp [] e) me
let print_signature' is_type env mp me =
States.with_state_protection
- (fun e -> eval_ppcmds (print_signature is_type env mp [] e)) me
+ (fun e -> print_signature is_type env mp [] e) me
let unsafe_print_module env mp with_body mb =
let name = print_modpath [] mp in
@@ -441,20 +447,4 @@ let print_modtype kn =
with e when CErrors.noncritical e ->
print_signature' true None kn mtb.mod_type))
-end
-
-module Tag =
-struct
- let definition =
- let style = Terminal.make ~bold:true ~fg_color:`LIGHT_RED () in
- Ppstyle.make ~style ["module"; "definition"]
- let keyword =
- let style = Terminal.make ~bold:true () in
- Ppstyle.make ~style ["module"; "keyword"]
-end
-include Make(struct
- let tag t s = Pp.tag (Pp.Tag.inj t Ppstyle.tag) s
- let tag_definition s = tag Tag.definition s
- let tag_keyword s = tag Tag.keyword s
-end)
diff --git a/printing/printmod.mli b/printing/printmod.mli
index 7f7d343927..f3079d5b6b 100644
--- a/printing/printmod.mli
+++ b/printing/printmod.mli
@@ -6,9 +6,12 @@
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
+open Pp
open Names
(** false iff the module is an element of an open module type *)
val printable_body : DirPath.t -> bool
-include Printmodsig.Pp
+val pr_mutual_inductive_body : Environ.env -> mutual_inductive -> Declarations.mutual_inductive_body -> std_ppcmds
+val print_module : bool -> module_path -> std_ppcmds
+val print_modtype : module_path -> std_ppcmds
diff --git a/proofs/pfedit.ml b/proofs/pfedit.ml
index b06ea43bdd..9995a9394a 100644
--- a/proofs/pfedit.ml
+++ b/proofs/pfedit.ml
@@ -233,10 +233,10 @@ let declare_implicit_tactic tac = implicit_tactic := Some tac
let clear_implicit_tactic () = implicit_tactic := None
-let solve_by_implicit_tactic env sigma evk =
+let apply_implicit_tactic tac = (); fun env sigma evk ->
let evi = Evd.find_undefined sigma evk in
- match (!implicit_tactic, snd (evar_source evk sigma)) with
- | Some tac, (Evar_kinds.ImplicitArg _ | Evar_kinds.QuestionMark _)
+ match snd (evar_source evk sigma) with
+ | (Evar_kinds.ImplicitArg _ | Evar_kinds.QuestionMark _)
when
Context.Named.equal (Environ.named_context_of_val evi.evar_hyps)
(Environ.named_context env) ->
@@ -250,3 +250,9 @@ let solve_by_implicit_tactic env sigma evk =
sigma, ans
with e when Logic.catchable_exception e -> raise Exit)
| _ -> raise Exit
+
+let solve_by_implicit_tactic () = match !implicit_tactic with
+| None -> None
+| Some tac -> Some (apply_implicit_tactic tac)
+
+
diff --git a/proofs/pfedit.mli b/proofs/pfedit.mli
index 7458109fa1..aad719db49 100644
--- a/proofs/pfedit.mli
+++ b/proofs/pfedit.mli
@@ -190,4 +190,4 @@ val declare_implicit_tactic : unit Proofview.tactic -> unit
val clear_implicit_tactic : unit -> unit
(* Raise Exit if cannot solve *)
-val solve_by_implicit_tactic : env -> Evd.evar_map -> Evd.evar -> Evd.evar_map * constr
+val solve_by_implicit_tactic : unit -> (env -> Evd.evar_map -> Evd.evar -> Evd.evar_map * constr) option
diff --git a/proofs/proof_global.ml b/proofs/proof_global.ml
index 120cde5e55..ca7330fdb6 100644
--- a/proofs/proof_global.ml
+++ b/proofs/proof_global.ml
@@ -195,9 +195,9 @@ let check_no_pending_proof () =
if not (there_are_pending_proofs ()) then
()
else begin
- CErrors.error (Pp.string_of_ppcmds
+ CErrors.user_err
(str"Proof editing in progress" ++ msg_proofs () ++ fnl() ++
- str"Use \"Abort All\" first or complete proof(s)."))
+ str"Use \"Abort All\" first or complete proof(s).")
end
let discard_gen id =
diff --git a/proofs/proof_using.ml b/proofs/proof_using.ml
index a125fb10db..2c489d6ded 100644
--- a/proofs/proof_using.ml
+++ b/proofs/proof_using.ml
@@ -108,7 +108,7 @@ let remove_ids_and_lets env s ids =
let suggest_Proof_using name env vars ids_typ context_ids =
let module S = Id.Set in
let open Pp in
- let print x = prerr_endline (string_of_ppcmds x) in
+ let print x = Feedback.msg_debug x in
let pr_set parens s =
let wrap ppcmds =
if parens && S.cardinal s > 1 then str "(" ++ ppcmds ++ str ")"
diff --git a/stm/asyncTaskQueue.ml b/stm/asyncTaskQueue.ml
index 8acc3c233a..1254919880 100644
--- a/stm/asyncTaskQueue.ml
+++ b/stm/asyncTaskQueue.ml
@@ -10,9 +10,9 @@ open CErrors
open Pp
open Util
-let pr_err s = Printf.eprintf "%s] %s\n" (System.process_id ()) s; flush stderr
+let stm_pr_err pp = Format.eprintf "%s] @[%a@]%!\n" (System.process_id ()) Pp.pp_with pp
-let prerr_endline s = if !Flags.debug then begin pr_err s end else ()
+let stm_prerr_endline s = if !Flags.debug then begin stm_pr_err (str s) end else ()
type 'a worker_status = [ `Fresh | `Old of 'a ]
@@ -147,23 +147,23 @@ module Make(T : Task) = struct
let stop_waiting = ref false in
let expiration_date = ref (ref false) in
let pick_task () =
- prerr_endline "waiting for a task";
+ stm_prerr_endline "waiting for a task";
let pick age (t, c) = not !c && T.task_match age t in
let task, task_expiration =
TQueue.pop ~picky:(pick !worker_age) ~destroy:stop_waiting queue in
expiration_date := task_expiration;
last_task := Some task;
- prerr_endline ("got task: "^T.name_of_task task);
+ stm_prerr_endline ("got task: " ^ T.name_of_task task);
task in
let add_tasks l =
List.iter (fun t -> TQueue.push queue (t,!expiration_date)) l in
let get_exec_token () =
ignore(CoqworkmgrApi.get 1);
got_token := true;
- prerr_endline ("got execution token") in
+ stm_prerr_endline ("got execution token") in
let kill proc =
Worker.kill proc;
- prerr_endline ("Worker exited: " ^
+ stm_prerr_endline ("Worker exited: " ^
match Worker.wait proc with
| Unix.WEXITED 0x400 -> "exit code unavailable"
| Unix.WEXITED i -> Printf.sprintf "exit(%d)" i
@@ -196,7 +196,7 @@ module Make(T : Task) = struct
report_status ~id "Idle";
let task = pick_task () in
match T.request_of_task !worker_age task with
- | None -> prerr_endline ("Task expired: " ^ T.name_of_task task)
+ | None -> stm_prerr_endline ("Task expired: " ^ T.name_of_task task)
| Some req ->
try
get_exec_token ();
@@ -222,8 +222,7 @@ module Make(T : Task) = struct
raise e (* we pass the exception to the external handler *)
| MarshalError s -> T.on_marshal_error s task; raise Die
| e ->
- pr_err ("Uncaught exception in worker manager: "^
- string_of_ppcmds (print e));
+ stm_pr_err Pp.(seq [str "Uncaught exception in worker manager: "; print e]);
flush_all (); raise Die
done with
| (Die | TQueue.BeingDestroyed) ->
@@ -261,7 +260,7 @@ module Make(T : Task) = struct
let broadcast { queue } = TQueue.broadcast queue
let enqueue_task { queue; active } (t, _ as item) =
- prerr_endline ("Enqueue task "^T.name_of_task t);
+ stm_prerr_endline ("Enqueue task "^T.name_of_task t);
TQueue.push queue item
let cancel_worker { active } n = Pool.cancel n active
@@ -298,18 +297,11 @@ module Make(T : Task) = struct
let slave_handshake () =
Pool.worker_handshake (Option.get !slave_ic) (Option.get !slave_oc)
- let pp_pid pp =
- (* Breaking all abstraction barriers... very nice *)
- let get_xml pp = match Richpp.repr pp with
- | Xml_datatype.Element("_", [], xml) -> xml
- | _ -> assert false in
- Richpp.richpp_of_xml (Xml_datatype.Element("_", [],
- get_xml (Richpp.richpp_of_pp Pp.(str (System.process_id ()^ " "))) @
- get_xml pp))
+ let pp_pid pp = Pp.(str (System.process_id () ^ " ") ++ pp)
let debug_with_pid = Feedback.(function
| { contents = Message(Debug, loc, pp) } as fb ->
- { fb with contents = Message(Debug,loc,pp_pid pp) }
+ { fb with contents = Message(Debug,loc, pp_pid pp) }
| x -> x)
let main_loop () =
@@ -317,7 +309,6 @@ module Make(T : Task) = struct
let slave_feeder oc fb =
Marshal.to_channel oc (RespFeedback (debug_with_pid fb)) []; flush oc in
Feedback.add_feeder (fun x -> slave_feeder (Option.get !slave_oc) x);
- Feedback.set_logger Feedback.feedback_logger;
(* We ask master to allocate universe identifiers *)
Universes.set_remote_new_univ_level (bufferize (fun () ->
marshal_response (Option.get !slave_oc) RespGetCounterNewUnivLevel;
@@ -337,11 +328,11 @@ module Make(T : Task) = struct
CEphemeron.clear ()
with
| MarshalError s ->
- pr_err ("Fatal marshal error: " ^ s); flush_all (); exit 2
+ stm_pr_err Pp.(prlist str ["Fatal marshal error: "; s]); flush_all (); exit 2
| End_of_file ->
- prerr_endline "connection lost"; flush_all (); exit 2
+ stm_prerr_endline "connection lost"; flush_all (); exit 2
| e ->
- pr_err ("Slave: critical exception: " ^ Pp.string_of_ppcmds (print e));
+ stm_pr_err Pp.(seq [str "Slave: critical exception: "; print e]);
flush_all (); exit 1
done
diff --git a/stm/proofworkertop.ml b/stm/proofworkertop.ml
index 23538a467e..0d2f9cb747 100644
--- a/stm/proofworkertop.ml
+++ b/stm/proofworkertop.ml
@@ -8,11 +8,7 @@
module W = AsyncTaskQueue.MakeWorker(Stm.ProofTask)
-let () = Coqtop.toploop_init := (fun args ->
- Flags.make_silent true;
- W.init_stdout ();
- CoqworkmgrApi.init !Flags.async_proofs_worker_priority;
- args)
+let () = Coqtop.toploop_init := WorkerLoop.loop W.init_stdout
let () = Coqtop.toploop_run := W.main_loop
diff --git a/stm/queryworkertop.ml b/stm/queryworkertop.ml
index fff6d55434..9d30473739 100644
--- a/stm/queryworkertop.ml
+++ b/stm/queryworkertop.ml
@@ -8,11 +8,7 @@
module W = AsyncTaskQueue.MakeWorker(Stm.QueryTask)
-let () = Coqtop.toploop_init := (fun args ->
- Flags.make_silent true;
- W.init_stdout ();
- CoqworkmgrApi.init !Flags.async_proofs_worker_priority;
- args)
+let () = Coqtop.toploop_init := WorkerLoop.loop W.init_stdout
let () = Coqtop.toploop_run := W.main_loop
diff --git a/stm/stm.ml b/stm/stm.ml
index e698d1c72e..b0ad3f8790 100644
--- a/stm/stm.ml
+++ b/stm/stm.ml
@@ -6,14 +6,13 @@
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
-let pr_err s = Printf.eprintf "%s] %s\n" (System.process_id ()) s; flush stderr
+let stm_pr_err s = Printf.eprintf "%s] %s\n" (System.process_id ()) s; flush stderr
+let stm_pp_err pp = Format.eprintf "%s] @[%a@]\n" (System.process_id ()) Pp.pp_with pp; 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 stm_prerr_endline s = if false then begin stm_pr_err (s ()) end else ()
+let stm_prerr_debug s = if !Flags.debug then begin stm_pr_err (s ()) end else ()
-(* Opening ppvernac below aliases Richpp, see PR#185 *)
-let pp_to_richpp = Richpp.richpp_of_pp
-let str_to_richpp = Richpp.richpp_of_string
+let stm_pperr_endline s = if false then begin stm_pp_err (s ()) end else ()
open Vernacexpr
open CErrors
@@ -26,7 +25,7 @@ open Feedback
let execution_error state_id loc msg =
feedback ~id:(State state_id)
- (Message (Error, Some loc, pp_to_richpp msg))
+ (Message (Error, Some loc, msg))
module Hooks = struct
@@ -48,7 +47,7 @@ let forward_feedback, forward_feedback_hook =
let parse_error, parse_error_hook = Hook.make
~default:(fun id loc msg ->
- feedback ~id (Message(Error, Some loc, pp_to_richpp msg))) ()
+ feedback ~id (Message(Error, Some loc, msg))) ()
let unreachable_state, unreachable_state_hook = Hook.make
~default:(fun _ _ -> ()) ()
@@ -544,7 +543,7 @@ 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 (fun () -> "mode:" ^ mode);
+ stm_prerr_endline (fun () -> "mode:" ^ mode);
Proof_global.activate_proof_mode mode
with Failure _ ->
checkout Branch.master;
@@ -856,7 +855,7 @@ end = struct (* {{{ *)
if is_cached id && not redefine then
anomaly (str"defining state "++str str_id++str" twice");
try
- prerr_endline (fun () -> "defining "^str_id^" (cache="^
+ stm_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;
@@ -864,7 +863,7 @@ 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 (fun () -> "setting cur id to "^str_id);
+ stm_prerr_endline (fun () -> "setting cur id to "^str_id);
cur_id := id;
if feedback_processed then
Hooks.(call state_computed id ~in_cache:false);
@@ -998,11 +997,11 @@ let stm_vernac_interp ?proof id ?route { verbose; loc; expr } =
in
let aux_interp cmd =
if is_filtered_command cmd then
- prerr_endline (fun () -> "ignoring " ^ Pp.string_of_ppcmds(pr_vernac expr))
+ stm_pperr_endline Pp.(fun () -> str "ignoring " ++ pr_vernac expr)
else match cmd with
| VernacShow ShowScript -> ShowScript.show_script ()
| expr ->
- prerr_endline (fun () -> "interpreting " ^ Pp.string_of_ppcmds(pr_vernac expr));
+ stm_pperr_endline Pp.(fun () -> str "interpreting " ++ pr_vernac expr);
try Vernacentries.interp ?verbosely:(Some verbose) ?proof (loc, expr)
with e ->
let e = CErrors.push e in
@@ -1435,11 +1434,10 @@ end = struct (* {{{ *)
| Some (safe, err) -> err, safe
| None -> Stateid.dummy, Stateid.dummy in
let e_msg = iprint (e, info) in
- prerr_endline (fun () -> "failed with the following exception:");
- prerr_endline (fun () -> string_of_ppcmds e_msg);
+ stm_pperr_endline Pp.(fun () -> str "failed with the following exception: " ++ fnl () ++ 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 e = match classify_vernac e with
@@ -1618,9 +1616,9 @@ end = struct (* {{{ *)
Future.from_val (Option.get (Global.body_of_constant_body c)) in
let uc =
Future.chain
- ~greedy:true ~pure:true uc Univ.hcons_universe_context_set in
- let pr = Future.chain ~greedy:true ~pure:true pr discharge in
- let pr = Future.chain ~greedy:true ~pure:true pr Constr.hcons in
+ ~pure:true uc Univ.hcons_universe_context_set in
+ let pr = Future.chain ~pure:true pr discharge in
+ let pr = Future.chain ~pure:true pr Constr.hcons in
Future.sink pr;
let extra = Future.join uc in
u.(bucket) <- uc;
@@ -1701,7 +1699,7 @@ end = struct (* {{{ *)
| Some (ReqBuildProof (r, b, _)) -> Some(r, b)
| _ -> None)
tasks in
- prerr_endline (fun () -> Printf.sprintf "dumping %d tasks\n" (List.length reqs));
+ stm_prerr_endline (fun () -> Printf.sprintf "dumping %d tasks\n" (List.length reqs));
reqs
let reset_task_queue () = TaskQueue.clear (Option.get !queue)
@@ -1785,7 +1783,7 @@ end = struct (* {{{ *)
`Stay ((),[])
let on_marshal_error err { t_name } =
- pr_err ("Fatal marshal error: " ^ t_name );
+ stm_pr_err ("Fatal marshal error: " ^ t_name );
flush_all (); exit 1
let on_task_cancellation_or_expiration_or_slave_death = function
@@ -1884,10 +1882,10 @@ end = struct (* {{{ *)
let open Notations in
try
let pt, uc = Future.join f in
- prerr_endline (fun () -> string_of_ppcmds(hov 0 (
+ stm_pperr_endline (fun () -> hov 0 (
str"g=" ++ int (Evar.repr gid) ++ spc () ++
str"t=" ++ (Printer.pr_constr pt) ++ spc () ++
- str"uc=" ++ Evd.pr_evar_universe_context uc)));
+ str"uc=" ++ Evd.pr_evar_universe_context uc));
(if abstract then Tactics.tclABSTRACT None else (fun x -> x))
(V82.tactic (Refiner.tclPUSHEVARUNIVCONTEXT uc) <*>
Tactics.exact_no_check pt)
@@ -1929,7 +1927,7 @@ end = struct (* {{{ *)
let use_response _ _ _ = `End
let on_marshal_error _ _ =
- pr_err ("Fatal marshal error in query");
+ stm_pr_err ("Fatal marshal error in query");
flush_all (); exit 1
let on_task_cancellation_or_expiration_or_slave_death _ = ()
@@ -1945,7 +1943,7 @@ end = struct (* {{{ *)
feedback ~id:(State r_for) Processed
with e when CErrors.noncritical e ->
let e = CErrors.push e in
- let msg = pp_to_richpp (iprint e) in
+ let msg = iprint e in
feedback ~id:(State r_for) (Message (Error, None, msg))
let name_of_task { t_what } = string_of_ppcmds (pr_ast t_what)
@@ -2004,7 +2002,7 @@ let warn_deprecated_nested_proofs =
"stop working in a future Coq version"))
let collect_proof keep cur hd brkind id =
- prerr_endline (fun () -> "Collecting proof ending at "^Stateid.to_string id);
+ stm_prerr_endline (fun () -> "Collecting proof ending at "^Stateid.to_string id);
let no_name = "" in
let name = function
| [] -> no_name
@@ -2104,7 +2102,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 (fun () -> "STM: " ^ s)
+let log_string s = stm_prerr_debug (fun () -> "STM: " ^ s)
let log_processing_async id name = log_string Printf.(sprintf
"%s: proof %s: asynch" (Stateid.to_string id) name
)
@@ -2191,16 +2189,16 @@ 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 safe_id id = Future.purify (fun id ->
- prerr_endline (fun () -> "cherry-pick non pstate " ^ Stateid.to_string id);
+ stm_prerr_endline (fun () -> "cherry-pick non pstate " ^ Stateid.to_string id);
reach ~safe_id id;
cherry_pick_non_pstate ()) id
(* traverses the dag backward from nodes being already calculated *)
and reach ?safe_id ?(redefine_qed=false) ?(cache=cache) id =
- prerr_endline (fun () -> "reaching: " ^ Stateid.to_string id);
+ stm_prerr_endline (fun () -> "reaching: " ^ Stateid.to_string id);
if not redefine_qed && State.is_cached ~cache id then begin
Hooks.(call state_computed id ~in_cache:true);
- prerr_endline (fun () -> "reached (cache)");
+ stm_prerr_endline (fun () -> "reached (cache)");
State.install_cached id
end else
let step, cache_step, feedback_processed =
@@ -2234,10 +2232,13 @@ let known_state ?(redefine_qed=false) ~cache id =
if eff then update_global_env ()
), (if eff then `Yes else cache), true
| `Cmd { cast = x; ceff = eff } -> (fun () ->
- resilient_command reach view.next;
- stm_vernac_interp id x;
- if eff then update_global_env ()
- ), (if eff then `Yes else cache), true
+ (match !Flags.async_proofs_mode with
+ | Flags.APon | Flags.APonLazy ->
+ resilient_command reach view.next
+ | Flags.APoff -> reach view.next);
+ stm_vernac_interp id x;
+ if eff then update_global_env ()
+ ), (if eff then `Yes else cache), true
| `Fork ((x,_,_,_), None) -> (fun () ->
resilient_command reach view.next;
stm_vernac_interp id x;
@@ -2352,7 +2353,7 @@ let known_state ?(redefine_qed=false) ~cache id =
else cache_step in
State.define ?safe_id
~cache:cache_step ~redefine:redefine_qed ~feedback_processed step id;
- prerr_endline (fun () -> "reached: "^ Stateid.to_string id) in
+ stm_prerr_endline (fun () -> "reached: "^ Stateid.to_string id) in
reach ~redefine_qed id
end (* }}} *)
@@ -2367,7 +2368,7 @@ let init () =
Backtrack.record ();
Slaves.init ();
if Flags.async_proofs_is_master () then begin
- prerr_endline (fun () -> "Initializing workers");
+ stm_prerr_endline (fun () -> "Initializing workers");
Query.init ();
let opts = match !Flags.async_proofs_private_flags with
| None -> []
@@ -2419,9 +2420,9 @@ let rec join_admitted_proofs id =
let join () =
finish ();
wait ();
- prerr_endline (fun () -> "Joining the environment");
+ stm_prerr_endline (fun () -> "Joining the environment");
Global.join_safe_environment ();
- prerr_endline (fun () -> "Joining Admitted proofs");
+ stm_prerr_endline (fun () -> "Joining Admitted proofs");
join_admitted_proofs (VCS.get_branch_pos (VCS.current_branch ()));
VCS.print ();
VCS.print ()
@@ -2495,7 +2496,7 @@ let handle_failure (e, info) vcs tty =
anomaly(str"error with no safe_id attached:" ++ spc() ++
CErrors.iprint_no_report (e, info))
| Some (safe_id, id) ->
- prerr_endline (fun () -> "Failed at state " ^ Stateid.to_string id);
+ stm_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 *)
@@ -2518,29 +2519,21 @@ let reset_task_queue = Slaves.reset_task_queue
(* Document building *)
let process_transaction ?(newtip=Stateid.fresh ()) ~tty
({ verbose; loc; expr } as x) c =
- prerr_endline (fun () -> "{{{ processing: "^ string_of_ppcmds (pr_ast x));
+ stm_pperr_endline (fun () -> str "{{{ processing: " ++ pr_ast x);
let vcs = VCS.backup () in
try
let head = VCS.current_branch () in
VCS.checkout head;
let rc = begin
- prerr_endline (fun () ->
+ stm_prerr_endline (fun () ->
" classified as: " ^ string_of_vernac_classification c);
match c with
- (* PG stuff *)
- | VtStm(VtPG,false), VtNow -> stm_vernac_interp Stateid.dummy x; `Ok
- | VtStm(VtPG,_), _ -> anomaly(str "PG command in script or VtLater")
(* Joining various parts of the document *)
| VtStm (VtJoinDocument, b), VtNow -> join (); `Ok
- | VtStm (VtFinish, b), VtNow -> finish (); `Ok
- | VtStm (VtWait, b), VtNow -> finish (); wait (); `Ok
- | VtStm (VtPrintDag, b), VtNow ->
- VCS.print ~now:true (); `Ok
- | VtStm (VtObserve id, b), VtNow -> observe id; `Ok
- | VtStm ((VtObserve _ | VtFinish | VtJoinDocument
- |VtPrintDag |VtWait),_), VtLater ->
+ | VtStm (VtWait, b), VtNow -> finish (); wait (); `Ok
+ | VtStm ((VtJoinDocument|VtWait),_), VtLater ->
anomaly(str"classifier: join actions cannot be classified as VtLater")
-
+
(* Back *)
| VtStm (VtBack oid, true), w ->
let id = VCS.new_node ~id:newtip () in
@@ -2562,7 +2555,7 @@ let process_transaction ?(newtip=Stateid.fresh ()) ~tty
VCS.commit id (Alias (oid,x));
Backtrack.record (); if w == VtNow then finish (); `Ok
| VtStm (VtBack id, false), VtNow ->
- prerr_endline (fun () -> "undo to state " ^ Stateid.to_string id);
+ stm_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
@@ -2703,16 +2696,7 @@ let process_transaction ?(newtip=Stateid.fresh ()) ~tty
| VtUnknown, VtLater ->
anomaly(str"classifier: VtUnknown must imply VtNow")
end in
- (* Proof General *)
- begin match expr with
- | VernacStm (PGLast _) ->
- if not (VCS.Branch.equal head VCS.Branch.master) then
- stm_vernac_interp Stateid.dummy
- { verbose = true; loc = Loc.ghost; indentation = 0; strlen = 0;
- expr = VernacShow (ShowGoal OpenSubgoals) }
- | _ -> ()
- end;
- prerr_endline (fun () -> "processed }}}");
+ stm_prerr_endline (fun () -> "processed }}}");
VCS.print ();
rc
with e ->
@@ -2898,7 +2882,7 @@ let edit_at id =
anomaly (str ("edit_at "^Stateid.to_string id^": ") ++
CErrors.print_no_report e)
| Some (_, id) ->
- prerr_endline (fun () -> "Failed at state " ^ Stateid.to_string id);
+ stm_prerr_endline (fun () -> "Failed at state " ^ Stateid.to_string id);
VCS.restore vcs;
VCS.print ();
iraise (e, info)
diff --git a/stm/stm.mllib b/stm/stm.mllib
index 4b254e8113..72b5380162 100644
--- a/stm/stm.mllib
+++ b/stm/stm.mllib
@@ -5,6 +5,7 @@ TQueue
WorkerPool
Vernac_classifier
CoqworkmgrApi
+WorkerLoop
AsyncTaskQueue
Stm
ProofBlockDelimiter
diff --git a/stm/tacworkertop.ml b/stm/tacworkertop.ml
index d5333d1077..256532c6b6 100644
--- a/stm/tacworkertop.ml
+++ b/stm/tacworkertop.ml
@@ -8,11 +8,7 @@
module W = AsyncTaskQueue.MakeWorker(Stm.TacTask)
-let () = Coqtop.toploop_init := (fun args ->
- Flags.make_silent true;
- W.init_stdout ();
- CoqworkmgrApi.init !Flags.async_proofs_worker_priority;
- args)
+let () = Coqtop.toploop_init := WorkerLoop.loop W.init_stdout
let () = Coqtop.toploop_run := W.main_loop
diff --git a/stm/vernac_classifier.ml b/stm/vernac_classifier.ml
index dc5be08a37..5908c09d08 100644
--- a/stm/vernac_classifier.ml
+++ b/stm/vernac_classifier.ml
@@ -33,9 +33,7 @@ let string_of_vernac_type = function
| VtQuery (b,(id,route)) ->
"Query " ^ string_of_in_script b ^ " report " ^ Stateid.to_string id ^
" route " ^ string_of_int route
- | VtStm ((VtFinish|VtJoinDocument|VtObserve _|VtPrintDag|VtWait), b) ->
- "Stm " ^ string_of_in_script b
- | VtStm (VtPG, b) -> "Stm PG " ^ string_of_in_script b
+ | VtStm ((VtJoinDocument|VtWait), b) -> "Stm " ^ string_of_in_script b
| VtStm (VtBack _, b) -> "Stm Back " ^ string_of_in_script b
let string_of_vernac_when = function
@@ -52,12 +50,6 @@ let declare_vernac_classifier
=
classifiers := !classifiers @ [s,f]
-let elide_part_of_script_and_now (a, _) =
- match a with
- | VtQuery (_,id) -> VtQuery (false,id), VtNow
- | VtStm (x, _) -> VtStm (x, false), VtNow
- | x -> x, VtNow
-
let make_polymorphic (a, b as x) =
match a with
| VtStartProof (x, _, ids) ->
@@ -69,23 +61,14 @@ let set_undo_classifier f = undo_classifier := f
let rec classify_vernac e =
let static_classifier e = match e with
- (* PG compatibility *)
- | VernacUnsetOption (["Silent"]|["Undo"]|["Printing";"Depth"])
- | VernacSetOption ((["Silent"]|["Undo"]|["Printing";"Depth"]),_)
- when !Flags.print_emacs -> VtStm(VtPG,false), VtNow
(* Univ poly compatibility: we run it now, so that we can just
* look at Flags in stm.ml. Would be nicer to have the stm
* look at the entire dag to detect this option. *)
| VernacSetOption (["Universe"; "Polymorphism"],_)
| VernacUnsetOption (["Universe"; "Polymorphism"]) -> VtSideff [], VtNow
(* Stm *)
- | VernacStm Finish -> VtStm (VtFinish, true), VtNow
- | VernacStm Wait -> VtStm (VtWait, true), VtNow
+ | VernacStm Wait -> VtStm (VtWait, true), VtNow
| VernacStm JoinDocument -> VtStm (VtJoinDocument, true), VtNow
- | VernacStm PrintDag -> VtStm (VtPrintDag, true), VtNow
- | VernacStm (Observe id) -> VtStm (VtObserve id, true), VtNow
- | VernacStm (Command x) -> elide_part_of_script_and_now (classify_vernac x)
- | VernacStm (PGLast x) -> fst (classify_vernac x), VtNow
(* Nested vernac exprs *)
| VernacProgram e -> classify_vernac e
| VernacLocal (_,e) -> classify_vernac e
diff --git a/printing/printmodsig.mli b/stm/workerLoop.ml
index f71fffdcec..50b42512cb 100644
--- a/printing/printmodsig.mli
+++ b/stm/workerLoop.ml
@@ -6,12 +6,14 @@
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
-open Pp
-open Names
+let rec parse = function
+ | "--xml_format=Ppcmds" :: rest -> parse rest
+ | x :: rest -> x :: parse rest
+ | [] -> []
-module type Pp =
-sig
- val pr_mutual_inductive_body : Environ.env -> mutual_inductive -> Declarations.mutual_inductive_body -> std_ppcmds
- val print_module : bool -> module_path -> std_ppcmds
- val print_modtype : module_path -> std_ppcmds
-end
+let loop init args =
+ let args = parse args in
+ Flags.make_silent true;
+ init ();
+ CoqworkmgrApi.init !Flags.async_proofs_worker_priority;
+ args
diff --git a/plugins/decl_mode/decl_interp.mli b/stm/workerLoop.mli
index 4303ecdb42..dcbf9c88d6 100644
--- a/plugins/decl_mode/decl_interp.mli
+++ b/stm/workerLoop.mli
@@ -6,10 +6,4 @@
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
-open Tacintern
-open Decl_expr
-
-
-val intern_proof_instr : glob_sign -> raw_proof_instr -> glob_proof_instr
-val interp_proof_instr : Decl_mode.pm_info ->
- Environ.env -> Evd.evar_map -> glob_proof_instr -> proof_instr
+val loop : (unit -> unit) -> string list -> string list
diff --git a/tactics/class_tactics.ml b/tactics/class_tactics.ml
index a85afcbf09..edfe21d34b 100644
--- a/tactics/class_tactics.ml
+++ b/tactics/class_tactics.ml
@@ -1613,10 +1613,16 @@ let is_ground c gl =
else tclFAIL 0 (str"Not ground") gl
let autoapply c i gl =
+ let open Proofview.Notations in
let flags = auto_unif_flags Evar.Set.empty
(Hints.Hint_db.transparent_state (Hints.searchtable_map i)) in
let cty = pf_unsafe_type_of gl c in
let ce = mk_clenv_from gl (c,cty) in
- let tac = { enter = fun gl -> (unify_e_resolve false flags).enter gl
- ((c,cty,Univ.ContextSet.empty),0,ce) } in
- Proofview.V82.of_tactic (Proofview.Goal.nf_enter tac) gl
+ let enter gl =
+ (unify_e_resolve false flags).enter gl
+ ((c,cty,Univ.ContextSet.empty),0,ce) <*>
+ Proofview.tclEVARMAP >>= (fun sigma ->
+ let sigma = Typeclasses.mark_unresolvables ~filter:Typeclasses.all_goals sigma in
+ Proofview.Unsafe.tclEVARS sigma)
+ in
+ Proofview.V82.of_tactic (Proofview.Goal.nf_enter { enter }) gl
diff --git a/tactics/tactics.ml b/tactics/tactics.ml
index 84d09d8330..0aab773140 100644
--- a/tactics/tactics.ml
+++ b/tactics/tactics.ml
@@ -1146,7 +1146,7 @@ let run_delayed env sigma c =
let tactic_infer_flags with_evar = {
Pretyping.use_typeclasses = true;
Pretyping.solve_unification_constraints = true;
- Pretyping.use_hook = Some solve_by_implicit_tactic;
+ Pretyping.use_hook = solve_by_implicit_tactic ();
Pretyping.fail_evar = not with_evar;
Pretyping.expand_evars = true }
@@ -1154,10 +1154,9 @@ let tactic_infer_flags with_evar = {
let onOpenInductionArg env sigma tac = function
| clear_flag,ElimOnConstr f ->
let (cbl, sigma') = run_delayed env sigma f in
- let pending = (sigma,sigma') in
Tacticals.New.tclTHEN
(Proofview.Unsafe.tclEVARS sigma')
- (tac clear_flag (pending,cbl))
+ (tac clear_flag (sigma,cbl))
| clear_flag,ElimOnAnonHyp n ->
Tacticals.New.tclTHEN
(intros_until_n n)
@@ -1165,8 +1164,7 @@ let onOpenInductionArg env sigma tac = function
(fun c ->
Proofview.Goal.enter { enter = begin fun gl ->
let sigma = Tacmach.New.project gl in
- let pending = (sigma,sigma) in
- tac clear_flag (pending,(c,NoBindings))
+ tac clear_flag (sigma,(c,NoBindings))
end }))
| clear_flag,ElimOnIdent (_,id) ->
(* A quantified hypothesis *)
@@ -1174,8 +1172,7 @@ let onOpenInductionArg env sigma tac = function
(try_intros_until_id_check id)
(Proofview.Goal.enter { enter = begin fun gl ->
let sigma = Tacmach.New.project gl in
- let pending = (sigma,sigma) in
- tac clear_flag (pending,(mkVar id,NoBindings))
+ tac clear_flag (sigma,(mkVar id,NoBindings))
end })
let onInductionArg tac = function
@@ -1198,10 +1195,9 @@ let map_destruction_arg f sigma = function
let finish_delayed_evar_resolution with_evars env sigma f =
let ((c, lbind), sigma') = run_delayed env sigma f in
- let pending = (sigma,sigma') in
let sigma' = Sigma.Unsafe.of_evar_map sigma' in
let flags = tactic_infer_flags with_evars in
- let Sigma (c, sigma', _) = finish_evar_resolution ~flags env sigma' (pending,c) in
+ let Sigma (c, sigma', _) = finish_evar_resolution ~flags env sigma' (sigma,c) in
(Sigma.to_evar_map sigma', (c, lbind))
let with_no_bindings (c, lbind) =
@@ -3023,7 +3019,7 @@ let warn_unused_intro_pattern =
(fun c -> Printer.pr_constr (fst (run_delayed (Global.env()) Evd.empty c)))) names)
let check_unused_names names =
- if not (List.is_empty names) && Flags.is_verbose () then
+ if not (List.is_empty names) then
warn_unused_intro_pattern names
let intropattern_of_name gl avoid = function
@@ -4525,11 +4521,11 @@ let induction_destruct isrec with_evars (lc,elim) =
let induction ev clr c l e =
induction_gen clr true ev e
- (((Evd.empty,Evd.empty),(c,NoBindings)),(None,l)) None
+ ((Evd.empty,(c,NoBindings)),(None,l)) None
let destruct ev clr c l e =
induction_gen clr false ev e
- (((Evd.empty,Evd.empty),(c,NoBindings)),(None,l)) None
+ ((Evd.empty,(c,NoBindings)),(None,l)) None
(* The registered tactic, which calls the default elimination
* if no elimination constant is provided. *)
diff --git a/tactics/tactics.mli b/tactics/tactics.mli
index 7acfb62864..354ac50b43 100644
--- a/tactics/tactics.mli
+++ b/tactics/tactics.mli
@@ -385,7 +385,7 @@ val letin_tac : (bool * intro_pattern_naming) option ->
(** Common entry point for user-level "set", "pose" and "remember" *)
val letin_pat_tac : (bool * intro_pattern_naming) option ->
- Name.t -> pending_constr -> clause -> unit Proofview.tactic
+ Name.t -> (evar_map * constr) -> clause -> unit Proofview.tactic
(** {6 Generalize tactics. } *)
diff --git a/test-suite/bugs/closed/2640.v b/test-suite/bugs/closed/2640.v
deleted file mode 100644
index da0cc68a4e..0000000000
--- a/test-suite/bugs/closed/2640.v
+++ /dev/null
@@ -1,17 +0,0 @@
-(* Testing consistency of globalization and interpretation in some
- extreme cases *)
-
-Section sect.
-
- (* Simplification of the initial example *)
- Hypothesis Other: True.
-
- Lemma C2 : True.
- proof.
- Fail have True using Other.
- Abort.
-
- (* Variant of the same problem *)
- Lemma C2 : True.
- Fail clear; Other.
- Abort.
diff --git a/test-suite/bugs/closed/4957.v b/test-suite/bugs/closed/4957.v
new file mode 100644
index 0000000000..0efd87ac0d
--- /dev/null
+++ b/test-suite/bugs/closed/4957.v
@@ -0,0 +1,6 @@
+Ltac get_value H := eval cbv delta [H] in H.
+
+Goal True.
+refine (let X := _ in _).
+let e := get_value X in unify e Prop.
+Abort.
diff --git a/test-suite/bugs/closed/4969.v b/test-suite/bugs/closed/4969.v
new file mode 100644
index 0000000000..4dee41e221
--- /dev/null
+++ b/test-suite/bugs/closed/4969.v
@@ -0,0 +1,11 @@
+Require Import Classes.Init.
+
+Class C A := c : A.
+Instance nat_C : C nat := 0.
+Instance bool_C : C bool := true.
+Lemma silly {A} `{C A} : 0 = 0 -> c = c -> True.
+Proof. auto. Qed.
+
+Goal True.
+ class_apply @silly; [reflexivity|].
+ reflexivity. Fail Qed.
diff --git a/test-suite/bugs/closed/5345.v b/test-suite/bugs/closed/5345.v
new file mode 100644
index 0000000000..d8448f35db
--- /dev/null
+++ b/test-suite/bugs/closed/5345.v
@@ -0,0 +1,7 @@
+Ltac break_tuple :=
+ match goal with
+ | [ H: context[match ?a with | pair n m => _ end] |- _ ] =>
+ let n := fresh n in
+ let m := fresh m in
+ destruct a as [n m]
+ end.
diff --git a/test-suite/bugs/closed/5372.v b/test-suite/bugs/closed/5372.v
new file mode 100644
index 0000000000..2dc78d4c7f
--- /dev/null
+++ b/test-suite/bugs/closed/5372.v
@@ -0,0 +1,7 @@
+(* coq bug 5372: https://coq.inria.fr/bugs/show_bug.cgi?id=5372 *)
+Function odd (n:nat) :=
+ match n with
+ | 0 => false
+ | S n => true
+ end
+with even (n:nat) := false.
diff --git a/test-suite/ide/undo.v b/test-suite/ide/undo.v
deleted file mode 100644
index ea3920551d..0000000000
--- a/test-suite/ide/undo.v
+++ /dev/null
@@ -1,103 +0,0 @@
-(* Here are a sequences of scripts to test interactively with undo and
- replay in coqide proof sessions *)
-
-(* Undoing arbitrary commands, as first step *)
-
-Theorem a : O=O. (* 2 *)
-Ltac f x := x. (* 1 * 3 *)
-assert True by trivial.
-trivial.
-Qed.
-
-(* Undoing arbitrary commands, as non-first step *)
-
-Theorem b : O=O.
-assert True by trivial.
-Ltac g x := x.
-assert True by trivial.
-trivial.
-Qed.
-
-(* Undoing declarations, as first step *)
-(* was bugged in 8.1 *)
-
-Theorem c : O=O.
-Inductive T : Type := I.
-trivial.
-Qed.
-
-(* Undoing declarations, as first step *)
-(* new in 8.2 *)
-
-Theorem d : O=O.
-Definition e := O.
-Definition f := O.
-assert True by trivial.
-trivial.
-Qed.
-
-(* Undoing declarations, as non-first step *)
-(* new in 8.2 *)
-
-Theorem h : O=O.
-assert True by trivial.
-Definition i := O.
-Definition j := O.
-assert True by trivial.
-trivial.
-Qed.
-
-(* Undoing declarations, interleaved with proof steps *)
-(* new in 8.2 *)
-
-Theorem k : O=O.
-assert True by trivial.
-Definition l := O.
-assert True by trivial.
-Definition m := O.
-assert True by trivial.
-trivial.
-Qed.
-
-(* Undoing declarations, interleaved with proof steps and commands *)
-(* new in 8.2 *)
-
-Theorem n : O=O.
-assert True by trivial.
-Definition o := O.
-Ltac h x := x.
-assert True by trivial.
-Focus.
-Definition p := O.
-assert True by trivial.
-trivial.
-Qed.
-
-(* Undoing declarations, not in proof *)
-
-Definition q := O.
-Definition r := O.
-
-(* Bug 2082 : Follow the numbers *)
-(* Broken due to proof engine rewriting *)
-
-Variable A : Prop.
-Variable B : Prop.
-
-Axiom OR : A \/ B.
-
-Lemma MyLemma2 : True.
-proof.
-per cases of (A \/ B) by OR.
-suppose A.
- then (1 = 1).
- then H1 : thesis. (* 4 *)
- thus thesis by H1. (* 2 *)
-suppose B. (* 1 *) (* 3 *)
- then (1 = 1).
- then H2 : thesis.
- thus thesis by H2.
-end cases.
-end proof.
-Qed. (* 5 if you made it here, there is no regression *)
-
diff --git a/test-suite/ide/undo011.fake b/test-suite/ide/undo011.fake
deleted file mode 100644
index 0be439b272..0000000000
--- a/test-suite/ide/undo011.fake
+++ /dev/null
@@ -1,34 +0,0 @@
-# Script simulating a dialog between coqide and coqtop -ideslave
-# Run it via fake_ide
-#
-# Bug 2082
-# Broken due to proof engine rewriting
-#
-ADD { Variable A : Prop. }
-ADD { Variable B : Prop. }
-ADD { Axiom OR : A \/ B. }
-ADD { Lemma MyLemma2 : True. }
-ADD { proof. }
-ADD { per cases of (A \/ B) by OR. }
-ADD { suppose A. }
-ADD { then (1 = 1). }
-ADD there { then H1 : thesis. }
-ADD here { thus thesis by H1. }
-ADD { suppose B. }
-QUERY { Show. }
-EDIT_AT here
-# <replay>
-ADD { suppose B. }
-# </replay>
-EDIT_AT there
-# <replay>
-ADD { thus thesis by H1. }
-ADD { suppose B. }
-# </replay>
-QUERY { Show. }
-ADD { then (1 = 1). }
-ADD { then H2 : thesis. }
-ADD { thus thesis by H2. }
-ADD { end cases. }
-ADD { end proof. }
-ADD { Qed. }
diff --git a/test-suite/output/Arguments.out b/test-suite/output/Arguments.out
index a2ee2d4c8e..979396969a 100644
--- a/test-suite/output/Arguments.out
+++ b/test-suite/output/Arguments.out
@@ -97,8 +97,8 @@ Expands to: Constant Top.f
forall w : r, w 3 true = tt
: Prop
The command has indeed failed with message:
-Error: Unknown interpretation for notation "$".
+Unknown interpretation for notation "$".
w 3 true = tt
: Prop
The command has indeed failed with message:
-Error: Extra arguments: _, _.
+Extra arguments: _, _.
diff --git a/test-suite/output/Arguments_renaming.out b/test-suite/output/Arguments_renaming.out
index b084ad4984..4df21ae353 100644
--- a/test-suite/output/Arguments_renaming.out
+++ b/test-suite/output/Arguments_renaming.out
@@ -1,5 +1,5 @@
The command has indeed failed with message:
-Error: To rename arguments the "rename" flag must be specified.
+To rename arguments the "rename" flag must be specified.
Argument A renamed to B.
File "stdin", line 2, characters 0-25:
Warning: This command is just asserting the names of arguments of identity.
@@ -103,15 +103,15 @@ Expands to: Constant Top.myplus
@myplus
: forall Z : Type, Z -> nat -> nat -> nat
The command has indeed failed with message:
-Error: Argument lists should agree on the names they provide.
+Argument lists should agree on the names they provide.
The command has indeed failed with message:
-Error: Sequences of implicit arguments must be of different lengths.
+Sequences of implicit arguments must be of different lengths.
The command has indeed failed with message:
-Error: Some argument names are duplicated: F
+Some argument names are duplicated: F
The command has indeed failed with message:
-Error: Argument z cannot be declared implicit.
+Argument z cannot be declared implicit.
The command has indeed failed with message:
-Error: Extra arguments: y.
+Extra arguments: y.
The command has indeed failed with message:
-Error: To rename arguments the "rename" flag must be specified.
+To rename arguments the "rename" flag must be specified.
Argument A renamed to R.
diff --git a/test-suite/output/ErrorInModule.out b/test-suite/output/ErrorInModule.out
new file mode 100644
index 0000000000..776dfeb550
--- /dev/null
+++ b/test-suite/output/ErrorInModule.out
@@ -0,0 +1,3 @@
+File "stdin", line 3, characters 20-31:
+Error: The reference nonexistent was not found in the current environment.
+
diff --git a/test-suite/output/ErrorInModule.v b/test-suite/output/ErrorInModule.v
new file mode 100644
index 0000000000..e69e23276b
--- /dev/null
+++ b/test-suite/output/ErrorInModule.v
@@ -0,0 +1,4 @@
+(* -*- mode: coq; coq-prog-args: ("-emacs" "-quick") -*- *)
+Module M.
+ Definition foo := nonexistent.
+End M.
diff --git a/test-suite/output/ErrorInSection.out b/test-suite/output/ErrorInSection.out
new file mode 100644
index 0000000000..776dfeb550
--- /dev/null
+++ b/test-suite/output/ErrorInSection.out
@@ -0,0 +1,3 @@
+File "stdin", line 3, characters 20-31:
+Error: The reference nonexistent was not found in the current environment.
+
diff --git a/test-suite/output/ErrorInSection.v b/test-suite/output/ErrorInSection.v
new file mode 100644
index 0000000000..3036f8f05b
--- /dev/null
+++ b/test-suite/output/ErrorInSection.v
@@ -0,0 +1,4 @@
+(* -*- mode: coq; coq-prog-args: ("-emacs" "-quick") -*- *)
+Section S.
+ Definition foo := nonexistent.
+End S.
diff --git a/test-suite/output/Errors.out b/test-suite/output/Errors.out
index 06a6b2d157..38d055b28e 100644
--- a/test-suite/output/Errors.out
+++ b/test-suite/output/Errors.out
@@ -7,4 +7,4 @@ In nested Ltac calls to "f" and "apply x", last call failed.
Unable to unify "nat" with "True".
The command has indeed failed with message:
Ltac call to "instantiate ( (ident) := (lglob) )" failed.
-Error: Instance is not well-typed in the environment of ?x.
+Instance is not well-typed in the environment of ?x.
diff --git a/test-suite/output/FunExt.out b/test-suite/output/FunExt.out
index c6786c72ff..8d2a125c1d 100644
--- a/test-suite/output/FunExt.out
+++ b/test-suite/output/FunExt.out
@@ -16,4 +16,4 @@ Tactic failure: Already an intensional equality.
The command has indeed failed with message:
In nested Ltac calls to "extensionality in (var)" and
"clearbody (ne_var_list)", last call failed.
-Error: Hypothesis e depends on the body of H'
+Hypothesis e depends on the body of H'
diff --git a/test-suite/output/Notations.out b/test-suite/output/Notations.out
index 26eaca8272..9d106d2dac 100644
--- a/test-suite/output/Notations.out
+++ b/test-suite/output/Notations.out
@@ -41,29 +41,29 @@ fun x : nat => ifn x is succ n then n else 0
-4
: Z
The command has indeed failed with message:
-Error: x should not be bound in a recursive pattern of the right-hand side.
+x should not be bound in a recursive pattern of the right-hand side.
The command has indeed failed with message:
-Error: in the right-hand side, y and z should appear in
+in the right-hand side, y and z should appear in
term position as part of a recursive pattern.
The command has indeed failed with message:
The reference w was not found in the current environment.
The command has indeed failed with message:
-Error: in the right-hand side, y and z should appear in
+in the right-hand side, y and z should appear in
term position as part of a recursive pattern.
The command has indeed failed with message:
-Error: z is expected to occur in binding position in the right-hand side.
+z is expected to occur in binding position in the right-hand side.
The command has indeed failed with message:
-Error: as y is a non-closed binder, no such "," is allowed to occur.
+as y is a non-closed binder, no such "," is allowed to occur.
The command has indeed failed with message:
-Error: Cannot find where the recursive pattern starts.
+Cannot find where the recursive pattern starts.
The command has indeed failed with message:
-Error: Cannot find where the recursive pattern starts.
+Cannot find where the recursive pattern starts.
The command has indeed failed with message:
-Error: Cannot find where the recursive pattern starts.
+Cannot find where the recursive pattern starts.
The command has indeed failed with message:
-Error: Cannot find where the recursive pattern starts.
+Cannot find where the recursive pattern starts.
The command has indeed failed with message:
-Error: Both ends of the recursive pattern are the same.
+Both ends of the recursive pattern are the same.
SUM (nat * nat) nat
: Set
FST (0; 1)
diff --git a/test-suite/output/Notations2.out b/test-suite/output/Notations2.out
index ad60aeccce..1ec701ae81 100644
--- a/test-suite/output/Notations2.out
+++ b/test-suite/output/Notations2.out
@@ -32,7 +32,7 @@ let d := 2 in ∃ z : nat, let e := 3 in let f := 4 in x + y = z + d
: Type -> Prop
λ A : Type, ∀ n p : A, n = p
: Type -> Prop
-let' f (x y : nat) (a:=0) (z : nat) (_ : bool) := x + y + z + 1 in f 0 1 2
+let' f (x y : nat) (a := 0) (z : nat) (_ : bool) := x + y + z + 1 in f 0 1 2
: bool -> nat
λ (f : nat -> nat) (x : nat), f(x) + S(x)
: (nat -> nat) -> nat -> nat
diff --git a/test-suite/output/UnivBinders.out b/test-suite/output/UnivBinders.out
new file mode 100644
index 0000000000..128bc77673
--- /dev/null
+++ b/test-suite/output/UnivBinders.out
@@ -0,0 +1,6 @@
+bar@{u} = nat
+ : Wrap@{u} Set
+(* u |= Set < u
+ *)
+
+bar is universe polymorphic
diff --git a/test-suite/output/UnivBinders.v b/test-suite/output/UnivBinders.v
new file mode 100644
index 0000000000..d9e89e43c6
--- /dev/null
+++ b/test-suite/output/UnivBinders.v
@@ -0,0 +1,7 @@
+Set Universe Polymorphism.
+Set Printing Universes.
+
+Class Wrap A := wrap : A.
+
+Instance bar@{u} : Wrap@{u} Set. Proof nat.
+Print bar.
diff --git a/test-suite/output/inference.out b/test-suite/output/inference.out
index 576fbd7c0b..e83e7176de 100644
--- a/test-suite/output/inference.out
+++ b/test-suite/output/inference.out
@@ -6,7 +6,7 @@ fun e : option L => match e with
: option L -> option L
fun (m n p : nat) (H : S m <= S n + p) => le_S_n m (n + p) H
: forall m n p : nat, S m <= S n + p -> m <= n + p
-fun n : nat => let x := A n : T n in ?y ?y0 : T n
+fun n : nat => let x : T n := A n in ?y ?y0 : T n
: forall n : nat, T n
where
?y : [n : nat x := A n : T n |- ?T -> T n]
diff --git a/test-suite/output/ltac.out b/test-suite/output/ltac.out
index 1ff09e3af6..35c3057d84 100644
--- a/test-suite/output/ltac.out
+++ b/test-suite/output/ltac.out
@@ -1,5 +1,4 @@
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
@@ -22,11 +21,11 @@ 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 "h" and "injection (destruction_arg)", last call
failed.
-Error: No primitive equality found.
+No primitive equality found.
The command has indeed failed with message:
In nested Ltac calls to "h" and "injection (destruction_arg)", last call
failed.
-Error: No primitive equality found.
+No primitive equality found.
Hx
nat
nat
diff --git a/test-suite/output/ltac_missing_args.out b/test-suite/output/ltac_missing_args.out
new file mode 100644
index 0000000000..172612405f
--- /dev/null
+++ b/test-suite/output/ltac_missing_args.out
@@ -0,0 +1,20 @@
+The command has indeed failed with message:
+A fully applied tactic is expected: missing argument for variable x.
+The command has indeed failed with message:
+A fully applied tactic is expected: missing argument for variable x.
+The command has indeed failed with message:
+A fully applied tactic is expected: missing arguments for variables y and _.
+The command has indeed failed with message:
+A fully applied tactic is expected: missing argument for variable x.
+The command has indeed failed with message:
+A fully applied tactic is expected: missing argument for variable x.
+The command has indeed failed with message:
+A fully applied tactic is expected: missing argument for variable _.
+The command has indeed failed with message:
+A fully applied tactic is expected: missing argument for variable _.
+The command has indeed failed with message:
+A fully applied tactic is expected: missing argument for variable _.
+The command has indeed failed with message:
+A fully applied tactic is expected: missing argument for variable x.
+The command has indeed failed with message:
+A fully applied tactic is expected: missing argument for variable x.
diff --git a/test-suite/output/ltac_missing_args.v b/test-suite/output/ltac_missing_args.v
new file mode 100644
index 0000000000..8ecd97aa56
--- /dev/null
+++ b/test-suite/output/ltac_missing_args.v
@@ -0,0 +1,19 @@
+Ltac foo x := idtac x.
+Ltac bar x := fun y _ => idtac x y.
+Ltac baz := foo.
+Ltac qux := bar.
+Ltac mydo tac := tac ().
+Ltac rec x := rec.
+
+Goal True.
+ Fail foo.
+ Fail bar.
+ Fail bar True.
+ Fail baz.
+ Fail qux.
+ Fail mydo ltac:(fun _ _ => idtac).
+ Fail let tac := (fun _ => idtac) in tac.
+ Fail (fun _ => idtac).
+ Fail rec True.
+ Fail let rec tac x := tac in tac True.
+Abort. \ No newline at end of file
diff --git a/test-suite/output/qualification.out b/test-suite/output/qualification.out
index 9300c3f546..e9c70d1efc 100644
--- a/test-suite/output/qualification.out
+++ b/test-suite/output/qualification.out
@@ -1,3 +1,4 @@
File "stdin", line 19, characters 0-7:
Error: Signature components for label test do not match: expected type
"Top.M2.t = Top.M2.M.t" but found type "Top.M2.t = Top.M2.t".
+
diff --git a/test-suite/success/Notations.v b/test-suite/success/Notations.v
index 07bbb60c40..52acad7460 100644
--- a/test-suite/success/Notations.v
+++ b/test-suite/success/Notations.v
@@ -128,3 +128,10 @@ Notation " |- {{ a }} b" := (a=b) (no associativity, at level 10).
Goal True.
{{ exact I. }}
Qed.
+
+(* Check that we can have notations without any symbol iff they are "only printing". *)
+Fail Notation "" := (@nil).
+Notation "" := (@nil) (only printing).
+
+(* Check that a notation cannot be neither parsing nor printing. *)
+Fail Notation "'foobarkeyword'" := (@nil) (only parsing, only printing).
diff --git a/test-suite/success/decl_mode.v b/test-suite/success/decl_mode.v
deleted file mode 100644
index 58f79d45ec..0000000000
--- a/test-suite/success/decl_mode.v
+++ /dev/null
@@ -1,182 +0,0 @@
-(* \sqrt 2 is irrationnal, (c) 2006 Pierre Corbineau *)
-
-Set Firstorder Depth 1.
-Require Import ArithRing Wf_nat Peano_dec Div2 Even Lt.
-
-Lemma double_div2: forall n, div2 (double n) = n.
-proof.
- assume n:nat.
- per induction on n.
- suppose it is 0.
- suffices (0=0) to show thesis.
- thus thesis.
- suppose it is (S m) and Hrec:thesis for m.
- have (div2 (double (S m))= div2 (S (S (double m)))).
- ~= (S (div2 (double m))).
- thus ~= (S m) by Hrec.
- end induction.
-end proof.
-Show Script.
-Qed.
-
-Lemma double_inv : forall n m, double n = double m -> n = m .
-proof.
- let n, m be such that H:(double n = double m).
-have (n = div2 (double n)) by double_div2,H.
- ~= (div2 (double m)) by H.
- thus ~= m by double_div2.
-end proof.
-Qed.
-
-Lemma double_mult_l : forall n m, (double (n * m)=n * double m).
-proof.
- assume n:nat and m:nat.
- have (double (n * m) = n*m + n * m).
- ~= (n * (m+m)) by * using ring.
- thus ~= (n * double m).
-end proof.
-Qed.
-
-Lemma double_mult_r : forall n m, (double (n * m)=double n * m).
-proof.
- assume n:nat and m:nat.
- have (double (n * m) = n*m + n * m).
- ~= ((n + n) * m) by * using ring.
- thus ~= (double n * m).
-end proof.
-Qed.
-
-Lemma even_is_even_times_even: forall n, even (n*n) -> even n.
-proof.
- let n be such that H:(even (n*n)).
- per cases of (even n \/ odd n) by even_or_odd.
- suppose (odd n).
- hence thesis by H,even_mult_inv_r.
- end cases.
-end proof.
-Qed.
-
-Lemma main_thm_aux: forall n,even n ->
-double (double (div2 n *div2 n))=n*n.
-proof.
- given n such that H:(even n).
- *** have (double (double (div2 n * div2 n))
- = double (div2 n) * double (div2 n))
- by double_mult_l,double_mult_r.
- thus ~= (n*n) by H,even_double.
-end proof.
-Qed.
-
-Require Import Omega.
-
-Lemma even_double_n: (forall m, even (double m)).
-proof.
- assume m:nat.
- per induction on m.
- suppose it is 0.
- thus thesis.
- suppose it is (S mm) and thesis for mm.
- then H:(even (S (S (mm+mm)))).
- have (S (S (mm + mm)) = S mm + S mm) using omega.
- hence (even (S mm +S mm)) by H.
- end induction.
-end proof.
-Qed.
-
-Theorem main_theorem: forall n p, n*n=double (p*p) -> p=0.
-proof.
- assume n0:nat.
- define P n as (forall p, n*n=double (p*p) -> p=0).
- claim rec_step: (forall n, (forall m,m<n-> P m) -> P n).
- let n be such that H:(forall m : nat, m < n -> P m) and p:nat .
- per cases of ({n=0}+{n<>0}) by eq_nat_dec.
- suppose H1:(n=0).
- per cases on p.
- suppose it is (S p').
- assume (n * n = double (S p' * S p')).
- =~ 0 by H1,mult_n_O.
- ~= (S ( p' + p' * S p' + S p'* S p'))
- by plus_n_Sm.
- hence thesis .
- suppose it is 0.
- thus thesis.
- end cases.
- suppose H1:(n<>0).
- assume H0:(n*n=double (p*p)).
- have (even (double (p*p))) by even_double_n .
- then (even (n*n)) by H0.
- then H2:(even n) by even_is_even_times_even.
- then (double (double (div2 n *div2 n))=n*n)
- by main_thm_aux.
- ~= (double (p*p)) by H0.
- then H':(double (div2 n *div2 n)= p*p) by double_inv.
- have (even (double (div2 n *div2 n))) by even_double_n.
- then (even (p*p)) by even_double_n,H'.
- then H3:(even p) by even_is_even_times_even.
- have (double(double (div2 n * div2 n)) = n*n)
- by H2,main_thm_aux.
- ~= (double (p*p)) by H0.
- ~= (double(double (double (div2 p * div2 p))))
- by H3,main_thm_aux.
- then H'':(div2 n * div2 n = double (div2 p * div2 p))
- by double_inv.
- then (div2 n < n) by lt_div2,neq_O_lt,H1.
- then H4:(div2 p=0) by (H (div2 n)),H''.
- then (double (div2 p) = double 0).
- =~ p by even_double,H3.
- thus ~= 0.
- end cases.
- end claim.
- hence thesis by (lt_wf_ind n0 P).
-end proof.
-Qed.
-
-Require Import Reals Field.
-(*Coercion INR: nat >->R.
-Coercion IZR: Z >->R.*)
-
-Open Scope R_scope.
-
-Lemma square_abs_square:
- forall p,(INR (Z.abs_nat p) * INR (Z.abs_nat p)) = (IZR p * IZR p).
-proof.
- assume p:Z.
- per cases on p.
- suppose it is (0%Z).
- thus thesis.
- suppose it is (Zpos z).
- thus thesis.
- suppose it is (Zneg z).
- have ((INR (Z.abs_nat (Zneg z)) * INR (Z.abs_nat (Zneg z))) =
- (IZR (Zpos z) * IZR (Zpos z))).
- ~= ((- IZR (Zpos z)) * (- IZR (Zpos z))).
- thus ~= (IZR (Zneg z) * IZR (Zneg z)).
- end cases.
-end proof.
-Qed.
-
-Definition irrational (x:R):Prop :=
- forall (p:Z) (q:nat),q<>0%nat -> x<> (IZR p/INR q).
-
-Theorem irrationnal_sqrt_2: irrational (sqrt (INR 2%nat)).
-proof.
- let p:Z,q:nat be such that H:(q<>0%nat)
- and H0:(sqrt (INR 2%nat)=(IZR p/INR q)).
- have H_in_R:(INR q<>0:>R) by H.
- have triv:((IZR p/INR q* INR q) =IZR p :>R) by * using field.
- have sqrt2:((sqrt (INR 2%nat) * sqrt (INR 2%nat))= INR 2%nat:>R) by sqrt_def.
- have (INR (Z.abs_nat p * Z.abs_nat p)
- = (INR (Z.abs_nat p) * INR (Z.abs_nat p)))
- by mult_INR.
- ~= (IZR p* IZR p) by square_abs_square.
- ~= ((IZR p/INR q*INR q)*(IZR p/INR q*INR q)) by triv. (* we have to factor because field is too weak *)
- ~= ((IZR p/INR q)*(IZR p/INR q)*(INR q*INR q)) using ring.
- ~= (sqrt (INR 2%nat) * sqrt (INR 2%nat)*(INR q*INR q)) by H0.
- ~= (INR (2%nat * (q*q))) by sqrt2,mult_INR.
- then (Z.abs_nat p * Z.abs_nat p = 2* (q * q))%nat.
- ~= ((q*q)+(q*q))%nat.
- ~= (Div2.double (q*q)).
- then (q=0%nat) by main_theorem.
- hence thesis by H.
-end proof.
-Qed.
diff --git a/test-suite/success/decl_mode2.v b/test-suite/success/decl_mode2.v
deleted file mode 100644
index 46174e4810..0000000000
--- a/test-suite/success/decl_mode2.v
+++ /dev/null
@@ -1,249 +0,0 @@
-Theorem this_is_trivial: True.
-proof.
- thus thesis.
-end proof.
-Qed.
-
-Theorem T: (True /\ True) /\ True.
- split. split.
-proof. (* first subgoal *)
- thus thesis.
-end proof.
-trivial. (* second subgoal *)
-proof. (* third subgoal *)
- thus thesis.
-end proof.
-Abort.
-
-Theorem this_is_not_so_trivial: False.
-proof.
-end proof. (* here a warning is issued *)
-Fail Qed. (* fails: the proof in incomplete *)
-Admitted. (* Oops! *)
-
-Theorem T: True.
-proof.
-escape.
-auto.
-return.
-Abort.
-
-Theorem T: let a:=false in let b:= true in ( if a then True else False -> if b then True else False).
-intros a b.
-proof.
-assume H:(if a then True else False).
-reconsider H as False.
-reconsider thesis as True.
-Abort.
-
-Theorem T: forall x, x=2 -> 2+x=4.
-proof.
-let x be such that H:(x=2).
-have H':(2+x=2+2) by H.
-Abort.
-
-Theorem T: forall x, x=2 -> 2+x=4.
-proof.
-let x be such that H:(x=2).
-then (2+x=2+2).
-Abort.
-
-Theorem T: forall x, x=2 -> x + x = x * x.
-proof.
-let x be such that H:(x=2).
-have (4 = 4).
- ~= (2 * 2).
- ~= (x * x) by H.
- =~ (2 + 2).
- =~ H':(x + x) by H.
-Abort.
-
-Theorem T: forall x, x + x = x * x -> x = 0 \/ x = 2.
-proof.
-let x be such that H:(x + x = x * x).
-claim H':((x - 2) * x = 0).
-thus thesis.
-end claim.
-Abort.
-
-Theorem T: forall (A B:Prop), A -> B -> A /\ B.
-intros A B HA HB.
-proof.
-hence B.
-Abort.
-
-Theorem T: forall (A B C:Prop), A -> B -> C -> A /\ B /\ C.
-intros A B C HA HB HC.
-proof.
-thus B by HB.
-Abort.
-
-Theorem T: forall (A B C:Prop), A -> B -> C -> A /\ B.
-intros A B C HA HB HC.
-proof.
-Fail hence C. (* fails *)
-Abort.
-
-Theorem T: forall (A B:Prop), B -> A \/ B.
-intros A B HB.
-proof.
-hence B.
-Abort.
-
-Theorem T: forall (A B C D:Prop), C -> D -> (A /\ B) \/ (C /\ D).
-intros A B C D HC HD.
-proof.
-thus C by HC.
-Abort.
-
-Theorem T: forall (P:nat -> Prop), P 2 -> exists x,P x.
-intros P HP.
-proof.
-take 2.
-Abort.
-
-Theorem T: forall (P:nat -> Prop), P 2 -> exists x,P x.
-intros P HP.
-proof.
-hence (P 2).
-Abort.
-
-Theorem T: forall (P:nat -> Prop) (R:nat -> nat -> Prop), P 2 -> R 0 2 -> exists x, exists y, P y /\ R x y.
-intros P R HP HR.
-proof.
-thus (P 2) by HP.
-Abort.
-
-Theorem T: forall (A B:Prop) (P:nat -> Prop), (forall x, P x -> B) -> A -> A /\ B.
-intros A B P HP HA.
-proof.
-suffices to have x such that HP':(P x) to show B by HP,HP'.
-Abort.
-
-Theorem T: forall (A:Prop) (P:nat -> Prop), P 2 -> A -> A /\ (forall x, x = 2 -> P x).
-intros A P HP HA.
-proof.
-(* BUG: the next line fails when it should succeed.
-Waiting for someone to investigate the bug.
-focus on (forall x, x = 2 -> P x).
-let x be such that (x = 2).
-hence thesis by HP.
-end focus.
-*)
-Abort.
-
-Theorem T: forall x, x = 0 -> x + x = x * x.
-proof.
-let x be such that H:(x = 0).
-define sqr x as (x * x).
-reconsider thesis as (x + x = sqr x).
-Abort.
-
-Theorem T: forall (P:nat -> Prop), forall x, P x -> P x.
-proof.
-let P:(nat -> Prop).
-let x:nat.
-assume HP:(P x).
-Abort.
-
-Theorem T: forall (P:nat -> Prop), forall x, P x -> P x.
-proof.
-let P:(nat -> Prop).
-Fail let x. (* fails because x's type is not clear *)
-let x be such that HP:(P x). (* here x's type is inferred from (P x) *)
-Abort.
-
-Theorem T: forall (P:nat -> Prop), forall x, P x -> P x -> P x.
-proof.
-let P:(nat -> Prop).
-let x:nat.
-assume (P x). (* temporary name created *)
-Abort.
-
-Theorem T: forall (P:nat -> Prop), forall x, P x -> P x.
-proof.
-let P:(nat -> Prop).
-let x be such that (P x). (* temporary name created *)
-Abort.
-
-Theorem T: forall (P:nat -> Prop) (A:Prop), (exists x, (P x /\ A)) -> A.
-proof.
-let P:(nat -> Prop),A:Prop be such that H:(exists x, P x /\ A).
-consider x such that HP:(P x) and HA:A from H.
-Abort.
-
-(* Here is an example with pairs: *)
-
-Theorem T: forall p:(nat * nat)%type, (fst p >= snd p) \/ (fst p < snd p).
-proof.
-let p:(nat * nat)%type.
-consider x:nat,y:nat from p.
-reconsider thesis as (x >= y \/ x < y).
-Abort.
-
-Theorem T: forall P:(nat -> Prop), (forall n, P n -> P (n - 1)) ->
-(exists m, P m) -> P 0.
-proof.
-let P:(nat -> Prop) be such that HP:(forall n, P n -> P (n - 1)).
-given m such that Hm:(P m).
-Abort.
-
-Theorem T: forall (A B C:Prop), (A -> C) -> (B -> C) -> (A \/ B) -> C.
-proof.
-let A:Prop,B:Prop,C:Prop be such that HAC:(A -> C) and HBC:(B -> C).
-assume HAB:(A \/ B).
-per cases on HAB.
-suppose A.
- hence thesis by HAC.
-suppose HB:B.
- thus thesis by HB,HBC.
-end cases.
-Abort.
-
-Section Coq.
-
-Hypothesis EM : forall P:Prop, P \/ ~ P.
-
-Theorem T: forall (A C:Prop), (A -> C) -> (~A -> C) -> C.
-proof.
-let A:Prop,C:Prop be such that HAC:(A -> C) and HNAC:(~A -> C).
-per cases of (A \/ ~A) by EM.
-suppose (~A).
- hence thesis by HNAC.
-suppose A.
- hence thesis by HAC.
-end cases.
-Abort.
-
-Theorem T: forall (A C:Prop), (A -> C) -> (~A -> C) -> C.
-proof.
-let A:Prop,C:Prop be such that HAC:(A -> C) and HNAC:(~A -> C).
-per cases on (EM A).
-suppose (~A).
-Abort.
-End Coq.
-
-Theorem T: forall (A B:Prop) (x:bool), (if x then A else B) -> A \/ B.
-proof.
-let A:Prop,B:Prop,x:bool.
-per cases on x.
-suppose it is true.
- assume A.
- hence A.
-suppose it is false.
- assume B.
- hence B.
-end cases.
-Abort.
-
-Theorem T: forall (n:nat), n + 0 = n.
-proof.
-let n:nat.
-per induction on n.
-suppose it is 0.
- thus (0 + 0 = 0).
-suppose it is (S m) and H:thesis for m.
- then (S (m + 0) = S m).
- thus =~ (S m + 0).
-end induction.
-Abort. \ No newline at end of file
diff --git a/test-suite/success/ltac_match_pattern_names.v b/test-suite/success/ltac_match_pattern_names.v
new file mode 100644
index 0000000000..7363294960
--- /dev/null
+++ b/test-suite/success/ltac_match_pattern_names.v
@@ -0,0 +1,28 @@
+(* example from bug 5345 *)
+Ltac break_tuple :=
+ match goal with
+ | [ H: context[let '(n, m) := ?a in _] |- _ ] =>
+ let n := fresh n in
+ let m := fresh m in
+ destruct a as [n m]
+ end.
+
+(* desugared version of break_tuple *)
+Ltac break_tuple' :=
+ match goal with
+ | [ H: context[match ?a with | pair n m => _ end] |- _ ] =>
+ let n := fresh n in
+ let m := fresh m in
+ idtac
+ end.
+
+Ltac multiple_branches :=
+ match goal with
+ | [ H: match _ with
+ | left P => _
+ | right Q => _
+ end |- _ ] =>
+ let P := fresh P in
+ let Q := fresh Q in
+ idtac
+ end. \ No newline at end of file
diff --git a/test-suite/success/univnames.v b/test-suite/success/univnames.v
index 048b53d26c..fe3b8c1d7c 100644
--- a/test-suite/success/univnames.v
+++ b/test-suite/success/univnames.v
@@ -21,6 +21,17 @@ Inductive bla@{l k} : Type@{k} := blaI : Type@{l} -> bla.
Inductive blacopy@{k l} : Type@{k} := blacopyI : Type@{l} -> blacopy.
+Class Wrap A := wrap : A.
+
+Fail Instance bad@{} : Wrap Type := Type.
+
+Instance bad@{} : Wrap Type.
+Fail Proof Type.
+Abort.
+
+Instance bar@{u} : Wrap@{u} Set. Proof nat.
+
+
Monomorphic Universe g.
-Inductive blacopy'@{l} : Type@{g} := blacopy'I : Type@{l} -> blacopy'. \ No newline at end of file
+Inductive blacopy'@{l} : Type@{g} := blacopy'I : Type@{l} -> blacopy'.
diff --git a/theories/Init/Logic.v b/theories/Init/Logic.v
index fb1a7ab1c1..9b58c524e4 100644
--- a/theories/Init/Logic.v
+++ b/theories/Init/Logic.v
@@ -572,7 +572,8 @@ Proof.
intros A P (x & Hp & Huniq); split.
- intro; exists x; auto.
- intros (x0 & HPx0 & HQx0) x1 HPx1.
- replace x1 with x0 by (transitivity x; [symmetry|]; auto).
+ assert (H : x0 = x1) by (transitivity x; [symmetry|]; auto).
+ destruct H.
assumption.
Qed.
diff --git a/theories/Init/Prelude.v b/theories/Init/Prelude.v
index 03f2328dec..c58d23dad0 100644
--- a/theories/Init/Prelude.v
+++ b/theories/Init/Prelude.v
@@ -19,7 +19,6 @@ Require Export Coq.Init.Tauto.
(* Initially available plugins
(+ nat_syntax_plugin loaded in Datatypes) *)
Declare ML Module "extraction_plugin".
-Declare ML Module "decl_mode_plugin".
Declare ML Module "cc_plugin".
Declare ML Module "ground_plugin".
Declare ML Module "recdef_plugin".
diff --git a/theories/Init/Specif.v b/theories/Init/Specif.v
index 9fc00e80c1..2cc2ecbc20 100644
--- a/theories/Init/Specif.v
+++ b/theories/Init/Specif.v
@@ -103,7 +103,7 @@ Definition sig_of_sig2 (A : Type) (P Q : A -> Prop) (X : sig2 P Q) : sig P
of an [a] of type [A], a of a proof [h] that [a] satisfies [P],
and a proof [h'] that [a] satisfies [Q]. Then
[(proj1_sig (sig_of_sig2 y))] is the witness [a],
- [(proj2_sig (sig_of_sig2 y))] is the proof of [(P a)], and
+ [(proj2_sig (sig_of_sig2 y))] is the proof of [(P a)], and
[(proj3_sig y)] is the proof of [(Q a)]. *)
Section Subset_projections2.
@@ -190,6 +190,23 @@ Definition sig2_of_sigT2 (A : Type) (P Q : A -> Prop) (X : sigT2 P Q) : sig2 P Q
Definition sigT2_of_sig2 (A : Type) (P Q : A -> Prop) (X : sig2 P Q) : sigT2 P Q
:= existT2 P Q (proj1_sig (sig_of_sig2 X)) (proj2_sig (sig_of_sig2 X)) (proj3_sig X).
+(** η Principles *)
+Definition sigT_eta {A P} (p : { a : A & P a })
+ : p = existT _ (projT1 p) (projT2 p).
+Proof. destruct p; reflexivity. Defined.
+
+Definition sig_eta {A P} (p : { a : A | P a })
+ : p = exist _ (proj1_sig p) (proj2_sig p).
+Proof. destruct p; reflexivity. Defined.
+
+Definition sigT2_eta {A P Q} (p : { a : A & P a & Q a })
+ : p = existT2 _ _ (projT1 (sigT_of_sigT2 p)) (projT2 (sigT_of_sigT2 p)) (projT3 p).
+Proof. destruct p; reflexivity. Defined.
+
+Definition sig2_eta {A P Q} (p : { a : A | P a & Q a })
+ : p = exist2 _ _ (proj1_sig (sig_of_sig2 p)) (proj2_sig (sig_of_sig2 p)) (proj3_sig p).
+Proof. destruct p; reflexivity. Defined.
+
(** [sumbool] is a boolean type equipped with the justification of
their value *)
@@ -263,10 +280,10 @@ Section Dependent_choice_lemmas.
(forall x:X, {y | R x y}) ->
forall x0, {f : nat -> X | f O = x0 /\ forall n, R (f n) (f (S n))}.
Proof.
- intros H x0.
+ intros H x0.
set (f:=fix f n := match n with O => x0 | S n' => proj1_sig (H (f n')) end).
exists f.
- split. reflexivity.
+ split. reflexivity.
induction n; simpl; apply proj2_sig.
Defined.
diff --git a/theories/Lists/List.v b/theories/Lists/List.v
index 30f1dec22c..1aece3f60b 100644
--- a/theories/Lists/List.v
+++ b/theories/Lists/List.v
@@ -419,7 +419,7 @@ Section Elts.
Proof.
unfold lt; induction n as [| n hn]; simpl.
- destruct l; simpl; [ inversion 2 | auto ].
- - destruct l as [| a l hl]; simpl.
+ - destruct l; simpl.
* inversion 2.
* intros d ie; right; apply hn; auto with arith.
Qed.
@@ -1280,7 +1280,7 @@ End Fold_Right_Recursor.
partition l = ([], []) <-> l = [].
Proof.
split.
- - destruct l as [|a l' _].
+ - destruct l as [|a l'].
* intuition.
* simpl. destruct (f a), (partition l'); now intros [= -> ->].
- now intros ->.
diff --git a/theories/Logic/JMeq.v b/theories/Logic/JMeq.v
index 2f95856b4b..86d05e8fb2 100644
--- a/theories/Logic/JMeq.v
+++ b/theories/Logic/JMeq.v
@@ -130,7 +130,7 @@ Qed.
is as strong as [eq_dep U P p x q y] (this uses [JMeq_eq]) *)
Lemma JMeq_eq_dep :
- forall U (P:U->Prop) p q (x:P p) (y:P q),
+ forall U (P:U->Type) p q (x:P p) (y:P q),
p = q -> JMeq x y -> eq_dep U P p x q y.
Proof.
intros.
diff --git a/theories/Logic/vo.itarget b/theories/Logic/vo.itarget
index ef2709b472..5eba0b6235 100644
--- a/theories/Logic/vo.itarget
+++ b/theories/Logic/vo.itarget
@@ -1,4 +1,5 @@
Berardi.vo
+PropExtensionalityFacts.vo
ChoiceFacts.vo
ClassicalChoice.vo
ClassicalDescription.vo
@@ -26,6 +27,7 @@ IndefiniteDescription.vo
JMeq.vo
ProofIrrelevanceFacts.vo
ProofIrrelevance.vo
+PropFacts.vo
PropExtensionality.vo
RelationalChoice.vo
SetIsType.vo
diff --git a/theories/QArith/Qreals.v b/theories/QArith/Qreals.v
index 048e409cde..5f04cf242e 100644
--- a/theories/QArith/Qreals.v
+++ b/theories/QArith/Qreals.v
@@ -15,7 +15,8 @@ Definition Q2R (x : Q) : R := (IZR (Qnum x) * / IZR (QDen x))%R.
Lemma IZR_nz : forall p : positive, IZR (Zpos p) <> 0%R.
Proof.
-intros; apply not_O_IZR; auto with qarith.
+intros.
+now apply not_O_IZR.
Qed.
Hint Resolve IZR_nz Rmult_integral_contrapositive.
@@ -48,8 +49,7 @@ assert ((X1 * Y2)%R = (Y1 * X2)%R).
apply IZR_eq; auto.
clear H.
field_simplify_eq; auto.
-ring_simplify X1 Y2 (Y2 * X1)%R.
-rewrite H0; ring.
+rewrite H0; ring.
Qed.
Lemma Rle_Qle : forall x y : Q, (Q2R x <= Q2R y)%R -> x<=y.
@@ -66,10 +66,8 @@ replace (X1 * Y2)%R with (X1 * / X2 * (X2 * Y2))%R; try (field; auto).
replace (Y1 * X2)%R with (Y1 * / Y2 * (X2 * Y2))%R; try (field; auto).
apply Rmult_le_compat_r; auto.
apply Rmult_le_pos.
-unfold X2; replace 0%R with (IZR 0); auto; apply IZR_le;
- auto with zarith.
-unfold Y2; replace 0%R with (IZR 0); auto; apply IZR_le;
- auto with zarith.
+now apply IZR_le.
+now apply IZR_le.
Qed.
Lemma Qle_Rle : forall x y : Q, x<=y -> (Q2R x <= Q2R y)%R.
@@ -88,10 +86,8 @@ replace (X1 * / X2)%R with (X1 * Y2 * (/ X2 * / Y2))%R; try (field; auto).
replace (Y1 * / Y2)%R with (Y1 * X2 * (/ X2 * / Y2))%R; try (field; auto).
apply Rmult_le_compat_r; auto.
apply Rmult_le_pos; apply Rlt_le; apply Rinv_0_lt_compat.
-unfold X2; replace 0%R with (IZR 0); auto; apply IZR_lt; red;
- auto with zarith.
-unfold Y2; replace 0%R with (IZR 0); auto; apply IZR_lt; red;
- auto with zarith.
+now apply IZR_lt.
+now apply IZR_lt.
Qed.
Lemma Rlt_Qlt : forall x y : Q, (Q2R x < Q2R y)%R -> x<y.
@@ -108,10 +104,8 @@ replace (X1 * Y2)%R with (X1 * / X2 * (X2 * Y2))%R; try (field; auto).
replace (Y1 * X2)%R with (Y1 * / Y2 * (X2 * Y2))%R; try (field; auto).
apply Rmult_lt_compat_r; auto.
apply Rmult_lt_0_compat.
-unfold X2; replace 0%R with (IZR 0); auto; apply IZR_lt; red;
- auto with zarith.
-unfold Y2; replace 0%R with (IZR 0); auto; apply IZR_lt; red;
- auto with zarith.
+now apply IZR_lt.
+now apply IZR_lt.
Qed.
Lemma Qlt_Rlt : forall x y : Q, x<y -> (Q2R x < Q2R y)%R.
@@ -130,10 +124,8 @@ replace (X1 * / X2)%R with (X1 * Y2 * (/ X2 * / Y2))%R; try (field; auto).
replace (Y1 * / Y2)%R with (Y1 * X2 * (/ X2 * / Y2))%R; try (field; auto).
apply Rmult_lt_compat_r; auto.
apply Rmult_lt_0_compat; apply Rinv_0_lt_compat.
-unfold X2; replace 0%R with (IZR 0); auto; apply IZR_lt; red;
- auto with zarith.
-unfold Y2; replace 0%R with (IZR 0); auto; apply IZR_lt; red;
- auto with zarith.
+now apply IZR_lt.
+now apply IZR_lt.
Qed.
Lemma Q2R_plus : forall x y : Q, Q2R (x+y) = (Q2R x + Q2R y)%R.
diff --git a/theories/QArith/Qround.v b/theories/QArith/Qround.v
index 0ed6d557c0..e94ef408db 100644
--- a/theories/QArith/Qround.v
+++ b/theories/QArith/Qround.v
@@ -141,7 +141,7 @@ Qed.
Lemma Zdiv_Qdiv (n m: Z): (n / m)%Z = Qfloor (n / m).
Proof.
unfold Qfloor. intros. simpl.
- destruct m as [?|?|p]; simpl.
+ destruct m as [ | | p]; simpl.
now rewrite Zdiv_0_r, Z.mul_0_r.
now rewrite Z.mul_1_r.
rewrite <- Z.opp_eq_mul_m1.
diff --git a/theories/Reals/Alembert.v b/theories/Reals/Alembert.v
index a98d529fa0..0e1608a32f 100644
--- a/theories/Reals/Alembert.v
+++ b/theories/Reals/Alembert.v
@@ -78,7 +78,7 @@ Proof.
ring.
discrR.
discrR.
- pattern 1 at 3; replace 1 with (/ 1);
+ replace 1 with (/ 1);
[ apply tech7; discrR | apply Rinv_1 ].
replace (An (S x)) with (An (S x + 0)%nat).
apply (tech6 (fun i:nat => An (S x + i)%nat) (/ 2)).
diff --git a/theories/Reals/AltSeries.v b/theories/Reals/AltSeries.v
index c3ab8edc5e..17ffc0fe32 100644
--- a/theories/Reals/AltSeries.v
+++ b/theories/Reals/AltSeries.v
@@ -339,51 +339,24 @@ Proof.
symmetry ; apply S_pred with 0%nat.
assumption.
apply Rle_lt_trans with (/ INR (2 * N)).
- apply Rmult_le_reg_l with (INR (2 * N)).
+ apply Rinv_le_contravar.
rewrite mult_INR; apply Rmult_lt_0_compat;
[ simpl; prove_sup0 | apply lt_INR_0; assumption ].
- rewrite <- Rinv_r_sym.
- apply Rmult_le_reg_l with (INR (2 * n)).
- rewrite mult_INR; apply Rmult_lt_0_compat;
- [ simpl; prove_sup0 | apply lt_INR_0; assumption ].
- rewrite (Rmult_comm (INR (2 * n))); rewrite Rmult_assoc;
- rewrite <- Rinv_l_sym.
- do 2 rewrite Rmult_1_r; apply le_INR.
- apply (fun m n p:nat => mult_le_compat_l p n m); assumption.
- replace n with (S (pred n)).
- apply not_O_INR; discriminate.
- symmetry ; apply S_pred with 0%nat.
- assumption.
- replace N with (S (pred N)).
- apply not_O_INR; discriminate.
- symmetry ; apply S_pred with 0%nat.
- assumption.
+ apply le_INR.
+ now apply mult_le_compat_l.
rewrite mult_INR.
- rewrite Rinv_mult_distr.
- replace (INR 2) with 2; [ idtac | reflexivity ].
- apply Rmult_lt_reg_l with 2.
- prove_sup0.
- rewrite <- Rmult_assoc; rewrite <- Rinv_r_sym; [ idtac | discrR ].
- rewrite Rmult_1_l; apply Rmult_lt_reg_l with (INR N).
- apply lt_INR_0; assumption.
- rewrite <- Rinv_r_sym.
- apply Rmult_lt_reg_l with (/ (2 * eps)).
- apply Rinv_0_lt_compat; assumption.
- rewrite Rmult_1_r;
- replace (/ (2 * eps) * (INR N * (2 * eps))) with
- (INR N * (2 * eps * / (2 * eps))); [ idtac | ring ].
- rewrite <- Rinv_r_sym.
- rewrite Rmult_1_r; replace (INR N) with (IZR (Z.of_nat N)).
- rewrite <- H4.
- elim H1; intros; assumption.
- symmetry ; apply INR_IZR_INZ.
- apply prod_neq_R0;
- [ discrR | red; intro; rewrite H8 in H; elim (Rlt_irrefl _ H) ].
- apply not_O_INR.
- red; intro; rewrite H8 in H5; elim (lt_irrefl _ H5).
- replace (INR 2) with 2; [ discrR | reflexivity ].
- apply not_O_INR.
- red; intro; rewrite H8 in H5; elim (lt_irrefl _ H5).
+ apply Rmult_lt_reg_l with (INR N / eps).
+ apply Rdiv_lt_0_compat with (2 := H).
+ now apply (lt_INR 0).
+ replace (_ */ _) with (/(2 * eps)).
+ replace (_ / _ * _) with (INR N).
+ rewrite INR_IZR_INZ.
+ now rewrite <- H4.
+ field.
+ now apply Rgt_not_eq.
+ simpl (INR 2); field; split.
+ now apply Rgt_not_eq, (lt_INR 0).
+ now apply Rgt_not_eq.
apply Rle_ge; apply PI_tg_pos.
apply lt_le_trans with N; assumption.
elim H1; intros H5 _.
@@ -395,7 +368,6 @@ Proof.
elim (Rlt_irrefl _ (Rlt_trans _ _ _ H6 H5)).
elim (lt_n_O _ H6).
apply le_IZR.
- simpl.
left; apply Rlt_trans with (/ (2 * eps)).
apply Rinv_0_lt_compat; assumption.
elim H1; intros; assumption.
diff --git a/theories/Reals/ArithProp.v b/theories/Reals/ArithProp.v
index 6fca9c8ad6..67584f7759 100644
--- a/theories/Reals/ArithProp.v
+++ b/theories/Reals/ArithProp.v
@@ -143,7 +143,7 @@ Proof.
assert (H0 := archimed (x / y)); rewrite <- Z_R_minus; simpl;
cut (0 < y).
intro; unfold Rminus;
- replace (- ((IZR (up (x / y)) + -1) * y)) with ((1 - IZR (up (x / y))) * y);
+ replace (- ((IZR (up (x / y)) + -(1)) * y)) with ((1 - IZR (up (x / y))) * y);
[ idtac | ring ].
split.
apply Rmult_le_reg_l with (/ y).
diff --git a/theories/Reals/Cos_plus.v b/theories/Reals/Cos_plus.v
index b14d807d2e..eb4a3b8047 100644
--- a/theories/Reals/Cos_plus.v
+++ b/theories/Reals/Cos_plus.v
@@ -289,11 +289,9 @@ Proof.
apply INR_fact_lt_0.
rewrite <- Rinv_r_sym.
rewrite Rmult_1_r.
- replace 1 with (INR 1).
- apply le_INR.
+ apply (le_INR 1).
apply lt_le_S.
apply INR_lt; apply INR_fact_lt_0.
- reflexivity.
apply INR_fact_neq_0.
apply Rmult_le_reg_l with (INR (fact (S (N + n)))).
apply INR_fact_lt_0.
@@ -576,11 +574,9 @@ Proof.
apply INR_fact_lt_0.
rewrite <- Rinv_r_sym.
rewrite Rmult_1_r.
- replace 1 with (INR 1).
- apply le_INR.
+ apply (le_INR 1).
apply lt_le_S.
apply INR_lt; apply INR_fact_lt_0.
- reflexivity.
apply INR_fact_neq_0.
apply Rmult_le_reg_l with (INR (fact (S (S (N + n))))).
apply INR_fact_lt_0.
diff --git a/theories/Reals/DiscrR.v b/theories/Reals/DiscrR.v
index 4e2a7c3c6e..05911cd539 100644
--- a/theories/Reals/DiscrR.v
+++ b/theories/Reals/DiscrR.v
@@ -31,9 +31,6 @@ Ltac discrR :=
try
match goal with
| |- (?X1 <> ?X2) =>
- change 2 with (IZR 2);
- change 1 with (IZR 1);
- change 0 with (IZR 0);
repeat
rewrite <- plus_IZR ||
rewrite <- mult_IZR ||
@@ -52,9 +49,6 @@ Ltac prove_sup0 :=
end.
Ltac omega_sup :=
- change 2 with (IZR 2);
- change 1 with (IZR 1);
- change 0 with (IZR 0);
repeat
rewrite <- plus_IZR ||
rewrite <- mult_IZR || rewrite <- Ropp_Ropp_IZR || rewrite Z_R_minus;
@@ -72,9 +66,6 @@ Ltac prove_sup :=
end.
Ltac Rcompute :=
- change 2 with (IZR 2);
- change 1 with (IZR 1);
- change 0 with (IZR 0);
repeat
rewrite <- plus_IZR ||
rewrite <- mult_IZR || rewrite <- Ropp_Ropp_IZR || rewrite Z_R_minus;
diff --git a/theories/Reals/Exp_prop.v b/theories/Reals/Exp_prop.v
index 569518f7b8..76f4e14495 100644
--- a/theories/Reals/Exp_prop.v
+++ b/theories/Reals/Exp_prop.v
@@ -439,20 +439,16 @@ Proof.
repeat rewrite <- Rmult_assoc.
rewrite <- Rinv_r_sym.
rewrite Rmult_1_l.
- replace (INR N * INR N) with (Rsqr (INR N)); [ idtac | reflexivity ].
- rewrite Rmult_assoc.
- rewrite Rmult_comm.
- replace 4 with (Rsqr 2); [ idtac | ring_Rsqr ].
+ change 4 with (Rsqr 2).
rewrite <- Rsqr_mult.
apply Rsqr_incr_1.
- replace 2 with (INR 2).
- rewrite <- mult_INR; apply H1.
- reflexivity.
+ change 2 with (INR 2).
+ rewrite Rmult_comm, <- mult_INR; apply H1.
left; apply lt_INR_0; apply H.
left; apply Rmult_lt_0_compat.
- prove_sup0.
apply lt_INR_0; apply div2_not_R0.
apply lt_n_S; apply H.
+ now apply IZR_lt.
cut (1 < S N)%nat.
intro; unfold Rsqr; apply prod_neq_R0; apply not_O_INR; intro;
assert (H4 := div2_not_R0 _ H2); rewrite H3 in H4;
@@ -536,7 +532,7 @@ Proof.
apply Rmult_le_reg_l with (INR (fact (div2 (pred n)))).
apply INR_fact_lt_0.
rewrite Rmult_1_r; rewrite <- Rinv_r_sym.
- replace 1 with (INR 1); [ apply le_INR | reflexivity ].
+ apply (le_INR 1).
apply lt_le_S.
apply INR_lt.
apply INR_fact_lt_0.
diff --git a/theories/Reals/Machin.v b/theories/Reals/Machin.v
index 19db476fde..2d2385703b 100644
--- a/theories/Reals/Machin.v
+++ b/theories/Reals/Machin.v
@@ -53,7 +53,7 @@ assert (-(PI/4) <= atan x).
destruct xm1 as [xm1 | xm1].
rewrite <- atan_1, <- atan_opp; apply Rlt_le, atan_increasing.
assumption.
- solve[rewrite <- xm1, atan_opp, atan_1; apply Rle_refl].
+ solve[rewrite <- xm1; change (-1) with (-(1)); rewrite atan_opp, atan_1; apply Rle_refl].
assert (-(PI/4) < atan y).
rewrite <- atan_1, <- atan_opp; apply atan_increasing.
assumption.
diff --git a/theories/Reals/RIneq.v b/theories/Reals/RIneq.v
index 379fee6f49..7e1cc3e036 100644
--- a/theories/Reals/RIneq.v
+++ b/theories/Reals/RIneq.v
@@ -1629,7 +1629,7 @@ Hint Resolve lt_INR: real.
Lemma lt_1_INR : forall n:nat, (1 < n)%nat -> 1 < INR n.
Proof.
- intros; replace 1 with (INR 1); auto with real.
+ apply lt_INR.
Qed.
Hint Resolve lt_1_INR: real.
@@ -1653,17 +1653,16 @@ Hint Resolve pos_INR: real.
Lemma INR_lt : forall n m:nat, INR n < INR m -> (n < m)%nat.
Proof.
- double induction n m; intros.
- simpl; exfalso; apply (Rlt_irrefl 0); auto.
- auto with arith.
- generalize (pos_INR (S n0)); intro; cut (INR 0 = 0);
- [ intro H2; rewrite H2 in H0; idtac | simpl; trivial ].
- generalize (Rle_lt_trans 0 (INR (S n0)) 0 H1 H0); intro; exfalso;
- apply (Rlt_irrefl 0); auto.
- do 2 rewrite S_INR in H1; cut (INR n1 < INR n0).
- intro H2; generalize (H0 n0 H2); intro; auto with arith.
- apply (Rplus_lt_reg_l 1 (INR n1) (INR n0)).
- rewrite Rplus_comm; rewrite (Rplus_comm 1 (INR n0)); trivial.
+ intros n m. revert n.
+ induction m ; intros n H.
+ - elim (Rlt_irrefl 0).
+ apply Rle_lt_trans with (2 := H).
+ apply pos_INR.
+ - destruct n as [|n].
+ apply Nat.lt_0_succ.
+ apply lt_n_S, IHm.
+ rewrite 2!S_INR in H.
+ apply Rplus_lt_reg_r with (1 := H).
Qed.
Hint Resolve INR_lt: real.
@@ -1707,14 +1706,10 @@ Hint Resolve not_INR: real.
Lemma INR_eq : forall n m:nat, INR n = INR m -> n = m.
Proof.
- intros; case (le_or_lt n m); intros H1.
- case (le_lt_or_eq _ _ H1); intros H2; auto.
- cut (n <> m).
- intro H3; generalize (not_INR n m H3); intro H4; exfalso; auto.
- omega.
- symmetry ; cut (m <> n).
- intro H3; generalize (not_INR m n H3); intro H4; exfalso; auto.
- omega.
+ intros n m HR.
+ destruct (dec_eq_nat n m) as [H|H].
+ exact H.
+ now apply not_INR in H.
Qed.
Hint Resolve INR_eq: real.
@@ -1728,7 +1723,8 @@ Hint Resolve INR_le: real.
Lemma not_1_INR : forall n:nat, n <> 1%nat -> INR n <> 1.
Proof.
- replace 1 with (INR 1); auto with real.
+ intros n.
+ apply not_INR.
Qed.
Hint Resolve not_1_INR: real.
@@ -1743,24 +1739,40 @@ Proof.
intros z; idtac; apply Z_of_nat_complete; assumption.
Qed.
+Lemma INR_IPR : forall p, INR (Pos.to_nat p) = IPR p.
+Proof.
+ assert (H: forall p, 2 * INR (Pos.to_nat p) = IPR_2 p).
+ induction p as [p|p|] ; simpl IPR_2.
+ rewrite Pos2Nat.inj_xI, S_INR, mult_INR, <- IHp.
+ now rewrite (Rplus_comm (2 * _)).
+ now rewrite Pos2Nat.inj_xO, mult_INR, <- IHp.
+ apply Rmult_1_r.
+ intros [p|p|] ; unfold IPR.
+ rewrite Pos2Nat.inj_xI, S_INR, mult_INR, <- H.
+ apply Rplus_comm.
+ now rewrite Pos2Nat.inj_xO, mult_INR, <- H.
+ easy.
+Qed.
+
(**********)
Lemma INR_IZR_INZ : forall n:nat, INR n = IZR (Z.of_nat n).
Proof.
- simple induction n; auto with real.
- intros; simpl; rewrite SuccNat2Pos.id_succ;
- auto with real.
+ intros [|n].
+ easy.
+ simpl Z.of_nat. unfold IZR.
+ now rewrite <- INR_IPR, SuccNat2Pos.id_succ.
Qed.
Lemma plus_IZR_NEG_POS :
forall p q:positive, IZR (Zpos p + Zneg q) = IZR (Zpos p) + IZR (Zneg q).
Proof.
intros p q; simpl. rewrite Z.pos_sub_spec.
- case Pos.compare_spec; intros H; simpl.
+ case Pos.compare_spec; intros H; unfold IZR.
subst. ring.
- rewrite Pos2Nat.inj_sub by trivial.
+ rewrite <- 3!INR_IPR, Pos2Nat.inj_sub by trivial.
rewrite minus_INR by (now apply lt_le_weak, Pos2Nat.inj_lt).
ring.
- rewrite Pos2Nat.inj_sub by trivial.
+ rewrite <- 3!INR_IPR, Pos2Nat.inj_sub by trivial.
rewrite minus_INR by (now apply lt_le_weak, Pos2Nat.inj_lt).
ring.
Qed.
@@ -1769,26 +1781,18 @@ Qed.
Lemma plus_IZR : forall n m:Z, IZR (n + m) = IZR n + IZR m.
Proof.
intro z; destruct z; intro t; destruct t; intros; auto with real.
- simpl; intros; rewrite Pos2Nat.inj_add; auto with real.
+ simpl. unfold IZR. rewrite <- 3!INR_IPR, Pos2Nat.inj_add. apply plus_INR.
apply plus_IZR_NEG_POS.
rewrite Z.add_comm; rewrite Rplus_comm; apply plus_IZR_NEG_POS.
- simpl; intros; rewrite Pos2Nat.inj_add; rewrite plus_INR;
- auto with real.
+ simpl. unfold IZR. rewrite <- 3!INR_IPR, Pos2Nat.inj_add, plus_INR.
+ apply Ropp_plus_distr.
Qed.
(**********)
Lemma mult_IZR : forall n m:Z, IZR (n * m) = IZR n * IZR m.
Proof.
- intros z t; case z; case t; simpl; auto with real.
- intros t1 z1; rewrite Pos2Nat.inj_mul; auto with real.
- intros t1 z1; rewrite Pos2Nat.inj_mul; auto with real.
- rewrite Rmult_comm.
- rewrite Ropp_mult_distr_l_reverse; auto with real.
- apply Ropp_eq_compat; rewrite mult_comm; auto with real.
- intros t1 z1; rewrite Pos2Nat.inj_mul; auto with real.
- rewrite Ropp_mult_distr_l_reverse; auto with real.
- intros t1 z1; rewrite Pos2Nat.inj_mul; auto with real.
- rewrite Rmult_opp_opp; auto with real.
+ intros z t; case z; case t; simpl; auto with real;
+ unfold IZR; intros m n; rewrite <- 3!INR_IPR, Pos2Nat.inj_mul, mult_INR; ring.
Qed.
Lemma pow_IZR : forall z n, pow (IZR z) n = IZR (Z.pow z (Z.of_nat n)).
@@ -1804,13 +1808,13 @@ Qed.
(**********)
Lemma succ_IZR : forall n:Z, IZR (Z.succ n) = IZR n + 1.
Proof.
- intro; change 1 with (IZR 1); unfold Z.succ; apply plus_IZR.
+ intro; unfold Z.succ; apply plus_IZR.
Qed.
(**********)
Lemma opp_IZR : forall n:Z, IZR (- n) = - IZR n.
Proof.
- intro z; case z; simpl; auto with real.
+ intros [|z|z]; unfold IZR; simpl; auto with real.
Qed.
Definition Ropp_Ropp_IZR := opp_IZR.
@@ -1833,10 +1837,12 @@ Qed.
Lemma lt_0_IZR : forall n:Z, 0 < IZR n -> (0 < n)%Z.
Proof.
intro z; case z; simpl; intros.
- absurd (0 < 0); auto with real.
- unfold Z.lt; simpl; trivial.
- case Rlt_not_le with (1 := H).
- replace 0 with (-0); auto with real.
+ elim (Rlt_irrefl _ H).
+ easy.
+ elim (Rlt_not_le _ _ H).
+ unfold IZR.
+ rewrite <- INR_IPR.
+ auto with real.
Qed.
(**********)
@@ -1852,9 +1858,12 @@ Qed.
Lemma eq_IZR_R0 : forall n:Z, IZR n = 0 -> n = 0%Z.
Proof.
intro z; destruct z; simpl; intros; auto with zarith.
- case (Rlt_not_eq 0 (INR (Pos.to_nat p))); auto with real.
- case (Rlt_not_eq (- INR (Pos.to_nat p)) 0); auto with real.
- apply Ropp_lt_gt_0_contravar. unfold Rgt; apply pos_INR_nat_of_P.
+ elim Rgt_not_eq with (2 := H).
+ unfold IZR. rewrite <- INR_IPR.
+ apply lt_0_INR, Pos2Nat.is_pos.
+ elim Rlt_not_eq with (2 := H).
+ unfold IZR. rewrite <- INR_IPR.
+ apply Ropp_lt_gt_0_contravar, lt_0_INR, Pos2Nat.is_pos.
Qed.
(**********)
@@ -1892,8 +1901,8 @@ Qed.
(**********)
Lemma le_IZR_R1 : forall n:Z, IZR n <= 1 -> (n <= 1)%Z.
Proof.
- pattern 1 at 1; replace 1 with (IZR 1); intros; auto.
- apply le_IZR; trivial.
+ intros n.
+ apply le_IZR.
Qed.
(**********)
@@ -1922,7 +1931,7 @@ Proof.
intros z [H1 H2].
apply Z.le_antisymm.
apply Z.lt_succ_r; apply lt_IZR; trivial.
- replace 0%Z with (Z.succ (-1)); trivial.
+ change 0%Z with (Z.succ (-1)).
apply Z.le_succ_l; apply lt_IZR; trivial.
Qed.
@@ -1999,10 +2008,34 @@ Lemma double_var : forall r1, r1 = r1 / 2 + r1 / 2.
Proof.
intro; rewrite <- double; unfold Rdiv; rewrite <- Rmult_assoc;
symmetry ; apply Rinv_r_simpl_m.
- replace 2 with (INR 2);
- [ apply not_0_INR; discriminate | unfold INR; ring ].
+ now apply not_0_IZR.
Qed.
+Lemma R_rm : ring_morph
+ 0%R 1%R Rplus Rmult Rminus Ropp eq
+ 0%Z 1%Z Zplus Zmult Zminus Zopp Zeq_bool IZR.
+Proof.
+constructor ; try easy.
+exact plus_IZR.
+exact minus_IZR.
+exact mult_IZR.
+exact opp_IZR.
+intros x y H.
+apply f_equal.
+now apply Zeq_bool_eq.
+Qed.
+
+Lemma Zeq_bool_IZR x y :
+ IZR x = IZR y -> Zeq_bool x y = true.
+Proof.
+intros H.
+apply Zeq_is_eq_bool.
+now apply eq_IZR.
+Qed.
+
+Add Field RField : Rfield
+ (completeness Zeq_bool_IZR, morphism R_rm, constants [IZR_tac], power_tac R_power_theory [Rpow_tac]).
+
(*********************************************************)
(** ** Other rules about < and <= *)
(*********************************************************)
@@ -2017,42 +2050,18 @@ Qed.
Lemma le_epsilon :
forall r1 r2, (forall eps:R, 0 < eps -> r1 <= r2 + eps) -> r1 <= r2.
Proof.
- intros x y; intros; elim (Rtotal_order x y); intro.
- left; assumption.
- elim H0; intro.
- right; assumption.
- clear H0; generalize (Rgt_minus x y H1); intro H2; change (0 < x - y) in H2.
- cut (0 < 2).
- intro.
- generalize (Rmult_lt_0_compat (x - y) (/ 2) H2 (Rinv_0_lt_compat 2 H0));
- intro H3; generalize (H ((x - y) * / 2) H3);
- replace (y + (x - y) * / 2) with ((y + x) * / 2).
- intro H4;
- generalize (Rmult_le_compat_l 2 x ((y + x) * / 2) (Rlt_le 0 2 H0) H4);
- rewrite <- (Rmult_comm ((y + x) * / 2)); rewrite Rmult_assoc;
- rewrite <- Rinv_l_sym.
- rewrite Rmult_1_r; replace (2 * x) with (x + x).
- rewrite (Rplus_comm y); intro H5; apply Rplus_le_reg_l with x; assumption.
- ring.
- replace 2 with (INR 2); [ apply not_0_INR; discriminate | reflexivity ].
- pattern y at 2; replace y with (y / 2 + y / 2).
- unfold Rminus, Rdiv.
- repeat rewrite Rmult_plus_distr_r.
- ring.
- cut (forall z:R, 2 * z = z + z).
- intro.
- rewrite <- (H4 (y / 2)).
- unfold Rdiv.
- rewrite <- Rmult_assoc; apply Rinv_r_simpl_m.
- replace 2 with (INR 2).
- apply not_0_INR.
- discriminate.
- unfold INR; reflexivity.
- intro; ring.
- cut (0%nat <> 2%nat);
- [ intro H0; generalize (lt_0_INR 2 (neq_O_lt 2 H0)); unfold INR;
- intro; assumption
- | discriminate ].
+ intros x y H.
+ destruct (Rle_or_lt x y) as [H1|H1].
+ exact H1.
+ apply Rplus_le_reg_r with x.
+ replace (y + x) with (2 * (y + (x - y) * / 2)) by field.
+ replace (x + x) with (2 * x) by ring.
+ apply Rmult_le_compat_l.
+ now apply (IZR_le 0 2).
+ apply H.
+ apply Rmult_lt_0_compat.
+ now apply Rgt_minus.
+ apply Rinv_0_lt_compat, Rlt_0_2.
Qed.
(**********)
diff --git a/theories/Reals/R_Ifp.v b/theories/Reals/R_Ifp.v
index b6d0728371..46583d374e 100644
--- a/theories/Reals/R_Ifp.v
+++ b/theories/Reals/R_Ifp.v
@@ -42,28 +42,23 @@ Qed.
Lemma up_tech :
forall (r:R) (z:Z), IZR z <= r -> r < IZR (z + 1) -> (z + 1)%Z = up r.
Proof.
- intros; generalize (Rplus_le_compat_l 1 (IZR z) r H); intro; clear H;
- rewrite (Rplus_comm 1 (IZR z)) in H1; rewrite (Rplus_comm 1 r) in H1;
- cut (1 = IZR 1); auto with zarith real.
- intro; generalize H1; pattern 1 at 1; rewrite H; intro; clear H H1;
- rewrite <- (plus_IZR z 1) in H2; apply (tech_up r (z + 1));
- auto with zarith real.
+ intros.
+ apply tech_up with (1 := H0).
+ rewrite plus_IZR.
+ now apply Rplus_le_compat_r.
Qed.
(**********)
Lemma fp_R0 : frac_part 0 = 0.
Proof.
- unfold frac_part; unfold Int_part; elim (archimed 0); intros;
- unfold Rminus; elim (Rplus_ne (- IZR (up 0 - 1)));
- intros a b; rewrite b; clear a b; rewrite <- Z_R_minus;
- cut (up 0 = 1%Z).
- intro; rewrite H1;
- rewrite (Rminus_diag_eq (IZR 1) (IZR 1) (eq_refl (IZR 1)));
- apply Ropp_0.
- elim (archimed 0); intros; clear H2; unfold Rgt in H1;
- rewrite (Rminus_0_r (IZR (up 0))) in H0; generalize (lt_O_IZR (up 0) H1);
- intro; clear H1; generalize (le_IZR_R1 (up 0) H0);
- intro; clear H H0; omega.
+ unfold frac_part, Int_part.
+ replace (up 0) with 1%Z.
+ now rewrite <- minus_IZR.
+ destruct (archimed 0) as [H1 H2].
+ apply lt_IZR in H1.
+ rewrite <- minus_IZR in H2.
+ apply le_IZR in H2.
+ omega.
Qed.
(**********)
@@ -112,21 +107,12 @@ Lemma base_Int_part :
Proof.
intro; unfold Int_part; elim (archimed r); intros.
split; rewrite <- (Z_R_minus (up r) 1); simpl.
- generalize (Rle_minus (IZR (up r) - r) 1 H0); intro; unfold Rminus in H1;
- rewrite (Rplus_assoc (IZR (up r)) (- r) (-1)) in H1;
- rewrite (Rplus_comm (- r) (-1)) in H1;
- rewrite <- (Rplus_assoc (IZR (up r)) (-1) (- r)) in H1;
- fold (IZR (up r) - 1) in H1; fold (IZR (up r) - 1 - r) in H1;
- apply Rminus_le; auto with zarith real.
- generalize (Rplus_gt_compat_l (-1) (IZR (up r)) r H); intro;
- rewrite (Rplus_comm (-1) (IZR (up r))) in H1;
- generalize (Rplus_gt_compat_l (- r) (IZR (up r) + -1) (-1 + r) H1);
- intro; clear H H0 H1; rewrite (Rplus_comm (- r) (IZR (up r) + -1)) in H2;
- fold (IZR (up r) - 1) in H2; fold (IZR (up r) - 1 - r) in H2;
- rewrite (Rplus_comm (- r) (-1 + r)) in H2;
- rewrite (Rplus_assoc (-1) r (- r)) in H2; rewrite (Rplus_opp_r r) in H2;
- elim (Rplus_ne (-1)); intros a b; rewrite a in H2;
- clear a b; auto with zarith real.
+ apply Rminus_le.
+ replace (IZR (up r) - 1 - r) with (IZR (up r) - r - 1) by ring.
+ now apply Rle_minus.
+ apply Rminus_gt.
+ replace (IZR (up r) - 1 - r - -1) with (IZR (up r) - r) by ring.
+ now apply Rgt_minus.
Qed.
(**********)
@@ -238,9 +224,7 @@ Proof.
rewrite (Rplus_opp_r (IZR (Int_part r1) - IZR (Int_part r2))) in H;
elim (Rplus_ne (r1 - r2)); intros a b; rewrite b in H;
clear a b; rewrite (Z_R_minus (Int_part r1) (Int_part r2)) in H0;
- rewrite (Z_R_minus (Int_part r1) (Int_part r2)) in H;
- cut (1 = IZR 1); auto with zarith real.
- intro; rewrite H1 in H; clear H1;
+ rewrite (Z_R_minus (Int_part r1) (Int_part r2)) in H.
rewrite <- (plus_IZR (Int_part r1 - Int_part r2) 1) in H;
generalize (up_tech (r1 - r2) (Int_part r1 - Int_part r2) H0 H);
intros; clear H H0; unfold Int_part at 1;
@@ -324,12 +308,12 @@ Proof.
rewrite (Rplus_opp_r (IZR (Int_part r1) - IZR (Int_part r2))) in H0;
elim (Rplus_ne (r1 - r2)); intros a b; rewrite b in H0;
clear a b; rewrite <- (Rplus_opp_l 1) in H0;
- rewrite <- (Rplus_assoc (IZR (Int_part r1) - IZR (Int_part r2)) (-1) 1)
+ rewrite <- (Rplus_assoc (IZR (Int_part r1) - IZR (Int_part r2)) (-(1)) 1)
in H0; fold (IZR (Int_part r1) - IZR (Int_part r2) - 1) in H0;
rewrite (Z_R_minus (Int_part r1) (Int_part r2)) in H0;
rewrite (Z_R_minus (Int_part r1) (Int_part r2)) in H;
- cut (1 = IZR 1); auto with zarith real.
- intro; rewrite H1 in H; rewrite H1 in H0; clear H1;
+ auto with zarith real.
+ change (_ + -1) with (IZR (Int_part r1 - Int_part r2) - 1) in H;
rewrite (Z_R_minus (Int_part r1 - Int_part r2) 1) in H;
rewrite (Z_R_minus (Int_part r1 - Int_part r2) 1) in H0;
rewrite <- (plus_IZR (Int_part r1 - Int_part r2 - 1) 1) in H0;
@@ -442,9 +426,9 @@ Proof.
in H0; rewrite (Rplus_opp_r (IZR (Int_part r1) + IZR (Int_part r2))) in H0;
elim (Rplus_ne (r1 + r2)); intros a b; rewrite b in H0;
clear a b;
+ change 2 with (1 + 1) in H0;
rewrite <- (Rplus_assoc (IZR (Int_part r1) + IZR (Int_part r2)) 1 1) in H0;
- cut (1 = IZR 1); auto with zarith real.
- intro; rewrite H1 in H0; rewrite H1 in H; clear H1;
+ auto with zarith real.
rewrite <- (plus_IZR (Int_part r1) (Int_part r2)) in H;
rewrite <- (plus_IZR (Int_part r1) (Int_part r2)) in H0;
rewrite <- (plus_IZR (Int_part r1 + Int_part r2) 1) in H;
@@ -507,9 +491,7 @@ Proof.
in H0; rewrite (Rplus_opp_r (IZR (Int_part r1) + IZR (Int_part r2))) in H0;
elim (Rplus_ne (IZR (Int_part r1) + IZR (Int_part r2)));
intros a b; rewrite a in H0; clear a b; elim (Rplus_ne (r1 + r2));
- intros a b; rewrite b in H0; clear a b; cut (1 = IZR 1);
- auto with zarith real.
- intro; rewrite H in H1; clear H;
+ intros a b; rewrite b in H0; clear a b.
rewrite <- (plus_IZR (Int_part r1) (Int_part r2)) in H0;
rewrite <- (plus_IZR (Int_part r1) (Int_part r2)) in H1;
rewrite <- (plus_IZR (Int_part r1 + Int_part r2) 1) in H1;
@@ -536,7 +518,7 @@ Proof.
rewrite <- (Ropp_plus_distr (IZR (Int_part r1)) (IZR (Int_part r2)));
unfold Rminus;
rewrite
- (Rplus_assoc (r1 + r2) (- (IZR (Int_part r1) + IZR (Int_part r2))) (-1))
+ (Rplus_assoc (r1 + r2) (- (IZR (Int_part r1) + IZR (Int_part r2))) (-(1)))
; rewrite <- (Ropp_plus_distr (IZR (Int_part r1) + IZR (Int_part r2)) 1);
trivial with zarith real.
Qed.
diff --git a/theories/Reals/R_sqr.v b/theories/Reals/R_sqr.v
index 445ffcb21b..a8937e36fd 100644
--- a/theories/Reals/R_sqr.v
+++ b/theories/Reals/R_sqr.v
@@ -296,56 +296,9 @@ Lemma canonical_Rsqr :
a * Rsqr (x + b / (2 * a)) + (4 * a * c - Rsqr b) / (4 * a).
Proof.
intros.
- rewrite Rsqr_plus.
- repeat rewrite Rmult_plus_distr_l.
- repeat rewrite Rplus_assoc.
- apply Rplus_eq_compat_l.
- unfold Rdiv, Rminus.
- replace (2 * 1 + 2 * 1) with 4; [ idtac | ring ].
- rewrite (Rmult_plus_distr_r (4 * a * c) (- Rsqr b) (/ (4 * a))).
- rewrite Rsqr_mult.
- repeat rewrite Rinv_mult_distr.
- repeat rewrite (Rmult_comm a).
- repeat rewrite Rmult_assoc.
- rewrite <- Rinv_l_sym.
- rewrite Rmult_1_r.
- rewrite (Rmult_comm 2).
- repeat rewrite Rmult_assoc.
- rewrite <- Rinv_l_sym.
- rewrite Rmult_1_r.
- rewrite (Rmult_comm (/ 2)).
- rewrite (Rmult_comm 2).
- repeat rewrite Rmult_assoc; rewrite <- Rinv_l_sym.
- rewrite Rmult_1_r.
- rewrite (Rmult_comm a).
- repeat rewrite Rmult_assoc.
- rewrite <- Rinv_l_sym.
- rewrite Rmult_1_r.
- rewrite (Rmult_comm 2).
- repeat rewrite Rmult_assoc; rewrite <- Rinv_l_sym.
- rewrite Rmult_1_r.
- repeat rewrite Rplus_assoc.
- rewrite (Rplus_comm (Rsqr b * (Rsqr (/ a * / 2) * a))).
- repeat rewrite Rplus_assoc.
- rewrite (Rmult_comm x).
- apply Rplus_eq_compat_l.
- rewrite (Rmult_comm (/ a)).
- unfold Rsqr; repeat rewrite Rmult_assoc.
- rewrite <- Rinv_l_sym.
- rewrite Rmult_1_r.
- ring.
- apply (cond_nonzero a).
- discrR.
- apply (cond_nonzero a).
- discrR.
- discrR.
- apply (cond_nonzero a).
- discrR.
- discrR.
- discrR.
- apply (cond_nonzero a).
- discrR.
- apply (cond_nonzero a).
+ unfold Rsqr.
+ field.
+ apply a.
Qed.
Lemma Rsqr_eq : forall x y:R, Rsqr x = Rsqr y -> x = y \/ x = - y.
diff --git a/theories/Reals/R_sqrt.v b/theories/Reals/R_sqrt.v
index a6b1a26e03..0c1e0b7e86 100644
--- a/theories/Reals/R_sqrt.v
+++ b/theories/Reals/R_sqrt.v
@@ -359,107 +359,22 @@ Lemma Rsqr_sol_eq_0_1 :
x = sol_x1 a b c \/ x = sol_x2 a b c -> a * Rsqr x + b * x + c = 0.
Proof.
intros; elim H0; intro.
- unfold sol_x1 in H1; unfold Delta in H1; rewrite H1; unfold Rdiv;
- repeat rewrite Rsqr_mult; rewrite Rsqr_plus; rewrite <- Rsqr_neg;
- rewrite Rsqr_sqrt.
- rewrite Rsqr_inv.
- unfold Rsqr; repeat rewrite Rinv_mult_distr.
- repeat rewrite Rmult_assoc; rewrite (Rmult_comm a).
- repeat rewrite Rmult_assoc; rewrite <- Rinv_l_sym.
- rewrite Rmult_1_r; rewrite Rmult_plus_distr_r.
- repeat rewrite Rmult_assoc.
- pattern 2 at 2; rewrite (Rmult_comm 2).
- repeat rewrite Rmult_assoc; rewrite <- Rinv_l_sym.
- rewrite Rmult_1_r.
- rewrite
- (Rmult_plus_distr_r (- b) (sqrt (b * b - 2 * (2 * (a * c)))) (/ 2 * / a))
- .
- rewrite Rmult_plus_distr_l; repeat rewrite Rplus_assoc.
- replace
- (- b * (sqrt (b * b - 2 * (2 * (a * c))) * (/ 2 * / a)) +
- (b * (- b * (/ 2 * / a)) +
- (b * (sqrt (b * b - 2 * (2 * (a * c))) * (/ 2 * / a)) + c))) with
- (b * (- b * (/ 2 * / a)) + c).
- unfold Rminus; repeat rewrite <- Rplus_assoc.
- replace (b * b + b * b) with (2 * (b * b)).
- rewrite Rmult_plus_distr_r; repeat rewrite Rmult_assoc.
- rewrite (Rmult_comm 2); repeat rewrite Rmult_assoc.
- rewrite <- Rinv_l_sym.
- rewrite Rmult_1_r.
- rewrite Ropp_mult_distr_l_reverse; repeat rewrite Rmult_assoc;
- rewrite (Rmult_comm 2).
- repeat rewrite Rmult_assoc; rewrite <- Rinv_l_sym.
- rewrite Rmult_1_r; rewrite (Rmult_comm (/ 2)); repeat rewrite Rmult_assoc;
- rewrite (Rmult_comm 2).
- repeat rewrite Rmult_assoc; rewrite <- Rinv_l_sym.
- rewrite Rmult_1_r; repeat rewrite Rmult_assoc.
- rewrite (Rmult_comm a); rewrite Rmult_assoc.
- rewrite <- Rinv_l_sym.
- rewrite Rmult_1_r; rewrite <- Rmult_opp_opp.
- ring.
- apply (cond_nonzero a).
- discrR.
- discrR.
- discrR.
- ring.
- ring.
- discrR.
- apply (cond_nonzero a).
- discrR.
- apply (cond_nonzero a).
- apply prod_neq_R0; [ discrR | apply (cond_nonzero a) ].
- apply prod_neq_R0; [ discrR | apply (cond_nonzero a) ].
- apply prod_neq_R0; [ discrR | apply (cond_nonzero a) ].
- assumption.
- unfold sol_x2 in H1; unfold Delta in H1; rewrite H1; unfold Rdiv;
- repeat rewrite Rsqr_mult; rewrite Rsqr_minus; rewrite <- Rsqr_neg;
- rewrite Rsqr_sqrt.
- rewrite Rsqr_inv.
- unfold Rsqr; repeat rewrite Rinv_mult_distr;
- repeat rewrite Rmult_assoc.
- rewrite (Rmult_comm a); repeat rewrite Rmult_assoc.
- rewrite <- Rinv_l_sym.
- rewrite Rmult_1_r; unfold Rminus; rewrite Rmult_plus_distr_r.
- rewrite Ropp_mult_distr_l_reverse; repeat rewrite Rmult_assoc;
- pattern 2 at 2; rewrite (Rmult_comm 2).
- repeat rewrite Rmult_assoc; rewrite <- Rinv_l_sym.
- rewrite Rmult_1_r;
- rewrite
- (Rmult_plus_distr_r (- b) (- sqrt (b * b + - (2 * (2 * (a * c)))))
- (/ 2 * / a)).
- rewrite Rmult_plus_distr_l; repeat rewrite Rplus_assoc.
- rewrite Ropp_mult_distr_l_reverse; rewrite Ropp_involutive.
- replace
- (b * (sqrt (b * b + - (2 * (2 * (a * c)))) * (/ 2 * / a)) +
- (b * (- b * (/ 2 * / a)) +
- (b * (- sqrt (b * b + - (2 * (2 * (a * c)))) * (/ 2 * / a)) + c))) with
- (b * (- b * (/ 2 * / a)) + c).
- repeat rewrite <- Rplus_assoc; replace (b * b + b * b) with (2 * (b * b)).
- rewrite Rmult_plus_distr_r; repeat rewrite Rmult_assoc;
- rewrite (Rmult_comm 2); repeat rewrite Rmult_assoc;
- rewrite <- Rinv_l_sym.
- rewrite Ropp_mult_distr_l_reverse; repeat rewrite Rmult_assoc.
- rewrite (Rmult_comm 2); repeat rewrite Rmult_assoc; rewrite <- Rinv_l_sym.
- rewrite Rmult_1_r; rewrite (Rmult_comm (/ 2)); repeat rewrite Rmult_assoc.
- rewrite (Rmult_comm 2); repeat rewrite Rmult_assoc; rewrite <- Rinv_l_sym.
- rewrite Rmult_1_r; repeat rewrite Rmult_assoc; rewrite (Rmult_comm a);
- rewrite Rmult_assoc; rewrite <- Rinv_l_sym.
- rewrite Rmult_1_r; rewrite <- Rmult_opp_opp; ring.
- apply (cond_nonzero a).
- discrR.
- discrR.
- discrR.
- ring.
- ring.
- discrR.
- apply (cond_nonzero a).
- discrR.
- discrR.
- apply (cond_nonzero a).
- apply prod_neq_R0; discrR || apply (cond_nonzero a).
- apply prod_neq_R0; discrR || apply (cond_nonzero a).
- apply prod_neq_R0; discrR || apply (cond_nonzero a).
- assumption.
+ rewrite H1.
+ unfold sol_x1, Delta, Rsqr.
+ field_simplify.
+ rewrite <- (Rsqr_pow2 (sqrt _)), Rsqr_sqrt.
+ field.
+ apply a.
+ apply H.
+ apply a.
+ rewrite H1.
+ unfold sol_x2, Delta, Rsqr.
+ field_simplify.
+ rewrite <- (Rsqr_pow2 (sqrt _)), Rsqr_sqrt.
+ field.
+ apply a.
+ apply H.
+ apply a.
Qed.
Lemma Rsqr_sol_eq_0_0 :
@@ -505,10 +420,10 @@ Proof.
rewrite (Rmult_comm (/ a)).
rewrite Rmult_assoc.
rewrite <- Rinv_mult_distr.
- replace (2 * (2 * a) * a) with (Rsqr (2 * a)).
+ replace (4 * a * a) with (Rsqr (2 * a)).
reflexivity.
ring_Rsqr.
- rewrite <- Rmult_assoc; apply prod_neq_R0;
+ apply prod_neq_R0;
[ discrR | apply (cond_nonzero a) ].
apply (cond_nonzero a).
assumption.
diff --git a/theories/Reals/Ranalysis2.v b/theories/Reals/Ranalysis2.v
index 0254218c44..b749da0d2a 100644
--- a/theories/Reals/Ranalysis2.v
+++ b/theories/Reals/Ranalysis2.v
@@ -88,17 +88,11 @@ Proof.
right; unfold Rdiv.
repeat rewrite Rabs_mult.
rewrite Rabs_Rinv; discrR.
- replace (Rabs 8) with 8.
- replace 8 with 8; [ idtac | ring ].
- rewrite Rinv_mult_distr; [ idtac | discrR | discrR ].
- replace (2 * / Rabs (f2 x) * (Rabs eps * Rabs (f2 x) * (/ 2 * / 4))) with
- (Rabs eps * / 4 * (2 * / 2) * (Rabs (f2 x) * / Rabs (f2 x)));
- [ idtac | ring ].
- replace (Rabs eps) with eps.
- repeat rewrite <- Rinv_r_sym; try discrR || (apply Rabs_no_R0; assumption).
- ring.
- symmetry ; apply Rabs_right; left; assumption.
- symmetry ; apply Rabs_right; left; prove_sup.
+ rewrite (Rabs_pos_eq 8) by now apply IZR_le.
+ rewrite (Rabs_pos_eq eps).
+ field.
+ now apply Rabs_no_R0.
+ now apply Rlt_le.
Qed.
Lemma maj_term2 :
@@ -429,10 +423,7 @@ Proof.
intro; rewrite H11 in H10; assert (H12 := Rmult_lt_compat_l 2 _ _ Hyp H10);
rewrite Rmult_1_r in H12; rewrite <- Rinv_r_sym in H12;
[ idtac | discrR ].
- cut (IZR 1 < IZR 2).
- unfold IZR; unfold INR, Pos.to_nat; simpl; intro;
- elim (Rlt_irrefl 1 (Rlt_trans _ _ _ H13 H12)).
- apply IZR_lt; omega.
+ now apply lt_IZR in H12.
unfold Rabs; case (Rcase_abs (/ 2)) as [Hlt|Hge].
assert (Hyp : 0 < 2).
prove_sup0.
diff --git a/theories/Reals/Ranalysis3.v b/theories/Reals/Ranalysis3.v
index 4e88714d61..d4597aebaf 100644
--- a/theories/Reals/Ranalysis3.v
+++ b/theories/Reals/Ranalysis3.v
@@ -201,8 +201,8 @@ Proof.
apply Rabs_pos_lt.
unfold Rdiv, Rsqr; repeat rewrite Rmult_assoc.
repeat apply prod_neq_R0; try assumption.
- red; intro; rewrite H15 in H6; elim (Rlt_irrefl _ H6).
- apply Rinv_neq_0_compat; repeat apply prod_neq_R0; discrR || assumption.
+ now apply Rgt_not_eq.
+ apply Rinv_neq_0_compat; apply prod_neq_R0; [discrR | assumption].
apply H13.
split.
apply D_x_no_cond; assumption.
@@ -213,8 +213,7 @@ Proof.
red; intro; rewrite H11 in H6; elim (Rlt_irrefl _ H6).
assumption.
assumption.
- apply Rinv_neq_0_compat; repeat apply prod_neq_R0;
- [ discrR | discrR | discrR | assumption ].
+ apply Rinv_neq_0_compat; apply prod_neq_R0; [discrR | assumption].
(***********************************)
(* Third case *)
(* (f1 x)<>0 l1=0 l2=0 *)
@@ -224,11 +223,11 @@ Proof.
elim (H0 (Rabs (Rsqr (f2 x) * eps / (8 * f1 x))));
[ idtac
| apply Rabs_pos_lt; unfold Rdiv, Rsqr; repeat rewrite Rmult_assoc;
- repeat apply prod_neq_R0;
+ repeat apply prod_neq_R0 ;
[ assumption
| assumption
- | red; intro; rewrite H11 in H6; elim (Rlt_irrefl _ H6)
- | apply Rinv_neq_0_compat; repeat apply prod_neq_R0; discrR || assumption ] ].
+ | now apply Rgt_not_eq
+ | apply Rinv_neq_0_compat; apply prod_neq_R0; discrR || assumption ] ].
intros alp_f2d H12.
cut (0 < Rmin (Rmin eps_f2 alp_f2) (Rmin alp_f1d alp_f2d)).
intro.
@@ -295,8 +294,10 @@ Proof.
elim (H0 (Rabs (Rsqr (f2 x) * eps / (8 * f1 x))));
[ idtac
| apply Rabs_pos_lt; unfold Rsqr, Rdiv;
- repeat rewrite Rinv_mult_distr; repeat apply prod_neq_R0;
- try assumption || discrR ].
+ repeat apply prod_neq_R0 ;
+ [ assumption..
+ | now apply Rgt_not_eq
+ | apply Rinv_neq_0_compat; apply prod_neq_R0; discrR || assumption ] ].
intros alp_f2d H11.
assert (H12 := derivable_continuous_pt _ _ X).
unfold continuity_pt in H12.
@@ -380,15 +381,9 @@ Proof.
repeat apply prod_neq_R0; try assumption.
red; intro H18; rewrite H18 in H6; elim (Rlt_irrefl _ H6).
apply Rinv_neq_0_compat; discrR.
- apply Rinv_neq_0_compat; discrR.
- apply Rinv_neq_0_compat; discrR.
apply Rinv_neq_0_compat; assumption.
apply Rinv_neq_0_compat; assumption.
discrR.
- discrR.
- discrR.
- discrR.
- discrR.
apply prod_neq_R0; [ discrR | assumption ].
elim H13; intros.
apply H19.
@@ -408,16 +403,9 @@ Proof.
repeat apply prod_neq_R0; try assumption.
red; intro H13; rewrite H13 in H6; elim (Rlt_irrefl _ H6).
apply Rinv_neq_0_compat; discrR.
- apply Rinv_neq_0_compat; discrR.
- apply Rinv_neq_0_compat; discrR.
apply Rinv_neq_0_compat; assumption.
apply Rinv_neq_0_compat; assumption.
apply prod_neq_R0; [ discrR | assumption ].
- red; intro H11; rewrite H11 in H6; elim (Rlt_irrefl _ H6).
- apply Rinv_neq_0_compat; discrR.
- apply Rinv_neq_0_compat; discrR.
- apply Rinv_neq_0_compat; discrR.
- apply Rinv_neq_0_compat; assumption.
(***********************************)
(* Fifth case *)
(* (f1 x)<>0 l1<>0 l2=0 *)
diff --git a/theories/Reals/Ranalysis4.v b/theories/Reals/Ranalysis4.v
index 661bc8c76b..23daedb8ba 100644
--- a/theories/Reals/Ranalysis4.v
+++ b/theories/Reals/Ranalysis4.v
@@ -130,15 +130,8 @@ Proof.
intro; exists (mkposreal (- x) H1); intros.
rewrite (Rabs_left x).
rewrite (Rabs_left (x + h)).
- rewrite Rplus_comm.
- rewrite Ropp_plus_distr.
- unfold Rminus; rewrite Ropp_involutive; rewrite Rplus_assoc;
- rewrite Rplus_opp_l.
- rewrite Rplus_0_r; unfold Rdiv.
- rewrite Ropp_mult_distr_l_reverse.
- rewrite <- Rinv_r_sym.
- rewrite Ropp_involutive; rewrite Rplus_opp_l; rewrite Rabs_R0; apply H0.
- apply H2.
+ replace ((-(x + h) - - x) / h - -1) with 0 by now field.
+ rewrite Rabs_R0; apply H0.
destruct (Rcase_abs h) as [Hlt|Hgt].
apply Ropp_lt_cancel.
rewrite Ropp_0; rewrite Ropp_plus_distr; apply Rplus_lt_0_compat.
diff --git a/theories/Reals/Ranalysis5.v b/theories/Reals/Ranalysis5.v
index d172139f56..f9da88aad4 100644
--- a/theories/Reals/Ranalysis5.v
+++ b/theories/Reals/Ranalysis5.v
@@ -249,8 +249,10 @@ assert (Sublemma : forall x y lb ub, lb <= x <= ub /\ lb <= y <= ub -> lb <= (x+
split.
replace lb with ((lb + lb) * /2) by field.
unfold Rdiv ; apply Rmult_le_compat_r ; intuition.
+ now apply Rlt_le, Rinv_0_lt_compat, IZR_lt.
replace ub with ((ub + ub) * /2) by field.
unfold Rdiv ; apply Rmult_le_compat_r ; intuition.
+ now apply Rlt_le, Rinv_0_lt_compat, IZR_lt.
intros x y P N x_lt_y.
induction N.
simpl ; intuition.
@@ -1030,6 +1032,7 @@ intros x ub lb lb_lt_x x_lt_ub.
assert (T : 0 < ub - lb).
fourier.
unfold Rdiv ; apply Rlt_mult_inv_pos ; intuition.
+now apply IZR_lt.
Qed.
Definition mkposreal_lb_ub (x lb ub:R) (lb_lt_x:lb<x) (x_lt_ub:x<ub) : posreal.
@@ -1102,7 +1105,7 @@ assert (Main : Rabs ((f (x+h) - fn N (x+h)) - (f x - fn N x) + (fn N (x+h) - fn
rewrite <- Rmult_1_r ; replace 1 with (derive_pt id c (pr2 c P)) by reg.
replace (- (fn N (x + h) - fn N x)) with (fn N x - fn N (x + h)) by field.
assumption.
- solve[apply Rlt_not_eq ; intuition].
+ now apply Rlt_not_eq, IZR_lt.
rewrite <- Hc'; clear Hc Hc'.
replace (derive_pt (fn N) c (pr1 c P)) with (fn' N c).
replace (h * fn' N c - h * g x) with (h * (fn' N c - g x)) by field.
diff --git a/theories/Reals/Ratan.v b/theories/Reals/Ratan.v
index e13ef1f2ca..e438750df0 100644
--- a/theories/Reals/Ratan.v
+++ b/theories/Reals/Ratan.v
@@ -132,7 +132,7 @@ intros [ | N] Npos n decr to0 cv nN.
unfold Rminus; apply Rplus_le_compat_l, Ropp_le_contravar.
solve[apply Rge_le, (growing_prop _ _ _ (CV_ALT_step0 f decr) dist)].
unfold Rminus; rewrite tech5, Ropp_plus_distr, <- Rplus_assoc.
- unfold tg_alt at 2; rewrite pow_1_odd, Ropp_mult_distr_l_reverse; fourier.
+ unfold tg_alt at 2; rewrite pow_1_odd; fourier.
rewrite Nodd; destruct (alternated_series_ineq _ _ p decr to0 cv) as [B _].
destruct (alternated_series_ineq _ _ (S p) decr to0 cv) as [_ C].
assert (keep : (2 * S p = S (S ( 2 * p)))%nat) by ring.
@@ -161,7 +161,6 @@ clear WLOG; intros Hyp [ | n] decr to0 cv _.
generalize (alternated_series_ineq f l 0 decr to0 cv).
unfold R_dist, tg_alt; simpl; rewrite !Rmult_1_l, !Rmult_1_r.
assert (f 1%nat <= f 0%nat) by apply decr.
- rewrite Ropp_mult_distr_l_reverse.
intros [A B]; rewrite Rabs_pos_eq; fourier.
apply Rle_trans with (f 1%nat).
apply (Hyp 1%nat (le_n 1) (S n) decr to0 cv).
@@ -320,31 +319,12 @@ apply PI2_lower_bound;[split; fourier | ].
destruct (pre_cos_bound (3/2) 1) as [t _]; [fourier | fourier | ].
apply Rlt_le_trans with (2 := t); clear t.
unfold cos_approx; simpl; unfold cos_term.
-simpl mult; replace ((-1)^ 0) with 1 by ring; replace ((-1)^2) with 1 by ring;
- replace ((-1)^4) with 1 by ring; replace ((-1)^1) with (-1) by ring;
- replace ((-1)^3) with (-1) by ring; replace 3 with (IZR 3) by (simpl; ring);
- replace 2 with (IZR 2) by (simpl; ring); simpl Z.of_nat;
- rewrite !INR_IZR_INZ, Ropp_mult_distr_l_reverse, Rmult_1_l.
-match goal with |- _ < ?a =>
-replace a with ((- IZR 3 ^ 6 * IZR (Z.of_nat (fact 0)) * IZR (Z.of_nat (fact 2)) *
- IZR (Z.of_nat (fact 4)) +
- IZR 3 ^ 4 * IZR 2 ^ 2 * IZR (Z.of_nat (fact 0)) * IZR (Z.of_nat (fact 2)) *
- IZR (Z.of_nat (fact 6)) -
- IZR 3 ^ 2 * IZR 2 ^ 4 * IZR (Z.of_nat (fact 0)) * IZR (Z.of_nat (fact 4)) *
- IZR (Z.of_nat (fact 6)) +
- IZR 2 ^ 6 * IZR (Z.of_nat (fact 2)) * IZR (Z.of_nat (fact 4)) *
- IZR (Z.of_nat (fact 6))) /
- (IZR 2 ^ 6 * IZR (Z.of_nat (fact 0)) * IZR (Z.of_nat (fact 2)) *
- IZR (Z.of_nat (fact 4)) * IZR (Z.of_nat (fact 6))));[ | field;
- repeat apply conj;((rewrite <- INR_IZR_INZ; apply INR_fact_neq_0) ||
- (apply Rgt_not_eq; apply (IZR_lt 0); reflexivity)) ]
-end.
-rewrite !fact_simpl, !Nat2Z.inj_mul; simpl Z.of_nat.
-unfold Rdiv; apply Rmult_lt_0_compat.
-unfold Rminus; rewrite !pow_IZR, <- !opp_IZR, <- !mult_IZR, <- !opp_IZR,
- <- !plus_IZR; apply (IZR_lt 0); reflexivity.
-apply Rinv_0_lt_compat; rewrite !pow_IZR, <- !mult_IZR; apply (IZR_lt 0).
-reflexivity.
+rewrite !INR_IZR_INZ.
+simpl.
+field_simplify.
+unfold Rdiv.
+rewrite Rmult_0_l.
+apply Rdiv_lt_0_compat ; now apply IZR_lt.
Qed.
Lemma PI2_1 : 1 < PI/2.
@@ -502,11 +482,11 @@ split.
rewrite (Rmult_comm (-1)); simpl ((/(Rabs y + 1)) ^ 0).
unfold Rdiv; rewrite Rinv_1, !Rmult_assoc, <- !Rmult_plus_distr_l.
apply tmp;[assumption | ].
- rewrite Rplus_assoc, Rmult_1_l; pattern 1 at 3; rewrite <- Rplus_0_r.
+ rewrite Rplus_assoc, Rmult_1_l; pattern 1 at 2; rewrite <- Rplus_0_r.
apply Rplus_lt_compat_l.
rewrite <- Rmult_assoc.
match goal with |- (?a * (-1)) + _ < 0 =>
- rewrite <- (Rplus_opp_l a), Ropp_mult_distr_r_reverse, Rmult_1_r
+ rewrite <- (Rplus_opp_l a); change (-1) with (-(1)); rewrite Ropp_mult_distr_r_reverse, Rmult_1_r
end.
apply Rplus_lt_compat_l.
assert (0 < u ^ 2) by (apply pow_lt; assumption).
@@ -853,6 +833,8 @@ intros x Hx eps Heps.
apply Rlt_trans with (2 := H).
apply Rinv_0_lt_compat.
exact Heps.
+ unfold N.
+ rewrite INR_IZR_INZ, positive_nat_Z.
exact HN.
apply lt_INR.
omega.
@@ -1076,8 +1058,9 @@ apply Rlt_not_eq; apply Rle_lt_trans with 0;[ | apply Rlt_0_1].
assert (t := pow2_ge_0 x); fourier.
replace (1 + x ^ 2) with (1 - - (x ^ 2)) by ring; rewrite <- (tech3 _ n dif).
apply sum_eq; unfold tg_alt, Datan_seq; intros i _.
-rewrite pow_mult, <- Rpow_mult_distr, Ropp_mult_distr_l_reverse, Rmult_1_l.
-reflexivity.
+rewrite pow_mult, <- Rpow_mult_distr.
+f_equal.
+ring.
Qed.
Lemma Datan_seq_increasing : forall x y n, (n > 0)%nat -> 0 <= x < y -> Datan_seq x n < Datan_seq y n.
@@ -1165,6 +1148,7 @@ assert (tool : forall a b, a / b - /b = (-1 + a) /b).
reflexivity.
set (u := 1 + x ^ 2); rewrite tool; unfold Rminus; rewrite <- Rplus_assoc.
unfold Rdiv, u.
+change (-1) with (-(1)).
rewrite Rplus_opp_l, Rplus_0_l, Ropp_mult_distr_l_reverse, Rabs_Ropp.
rewrite Rabs_mult; clear tool u.
assert (tool : forall k, Rabs ((-x ^ 2) ^ k) = Rabs ((x ^ 2) ^ k)).
diff --git a/theories/Reals/Raxioms.v b/theories/Reals/Raxioms.v
index 9fbda92a2f..7f9db3b18f 100644
--- a/theories/Reals/Raxioms.v
+++ b/theories/Reals/Raxioms.v
@@ -115,19 +115,6 @@ Arguments INR n%nat.
(**********************************************************)
-(** * Injection from [Z] to [R] *)
-(**********************************************************)
-
-(**********)
-Definition IZR (z:Z) : R :=
- match z with
- | Z0 => 0
- | Zpos n => INR (Pos.to_nat n)
- | Zneg n => - INR (Pos.to_nat n)
- end.
-Arguments IZR z%Z.
-
-(**********************************************************)
(** * [R] Archimedean *)
(**********************************************************)
diff --git a/theories/Reals/Rbasic_fun.v b/theories/Reals/Rbasic_fun.v
index c889d73473..df16624976 100644
--- a/theories/Reals/Rbasic_fun.v
+++ b/theories/Reals/Rbasic_fun.v
@@ -451,20 +451,16 @@ Qed.
Lemma Rabs_Ropp : forall x:R, Rabs (- x) = Rabs x.
Proof.
- intro; cut (- x = -1 * x).
- intros; rewrite H.
+ intro; replace (-x) with (-1 * x) by ring.
rewrite Rabs_mult.
- cut (Rabs (-1) = 1).
- intros; rewrite H0.
- ring.
+ replace (Rabs (-1)) with 1.
+ apply Rmult_1_l.
unfold Rabs; case (Rcase_abs (-1)).
intro; ring.
- intro H0; generalize (Rge_le (-1) 0 H0); intros.
- generalize (Ropp_le_ge_contravar 0 (-1) H1).
- rewrite Ropp_involutive; rewrite Ropp_0.
- intro; generalize (Rgt_not_le 1 0 Rlt_0_1); intro; generalize (Rge_le 0 1 H2);
- intro; exfalso; auto.
- ring.
+ rewrite <- Ropp_0.
+ intro H0; apply Ropp_ge_cancel in H0.
+ elim (Rge_not_lt _ _ H0).
+ apply Rlt_0_1.
Qed.
(*********)
@@ -613,11 +609,12 @@ Qed.
Lemma Rabs_Zabs : forall z:Z, Rabs (IZR z) = IZR (Z.abs z).
Proof.
- intros z; case z; simpl; auto with real.
- apply Rabs_right; auto with real.
- intros p0; apply Rabs_right; auto with real zarith.
+ intros z; case z; unfold Zabs.
+ apply Rabs_R0.
+ now intros p0; apply Rabs_pos_eq, (IZR_le 0).
+ unfold IZR at 1.
intros p0; rewrite Rabs_Ropp.
- apply Rabs_right; auto with real zarith.
+ now apply Rabs_pos_eq, (IZR_le 0).
Qed.
Lemma abs_IZR : forall z, IZR (Z.abs z) = Rabs (IZR z).
diff --git a/theories/Reals/Rdefinitions.v b/theories/Reals/Rdefinitions.v
index f3f8f74098..cb5dea93ad 100644
--- a/theories/Reals/Rdefinitions.v
+++ b/theories/Reals/Rdefinitions.v
@@ -69,3 +69,32 @@ Notation "x <= y <= z" := (x <= y /\ y <= z) : R_scope.
Notation "x <= y < z" := (x <= y /\ y < z) : R_scope.
Notation "x < y < z" := (x < y /\ y < z) : R_scope.
Notation "x < y <= z" := (x < y /\ y <= z) : R_scope.
+
+(**********************************************************)
+(** * Injection from [Z] to [R] *)
+(**********************************************************)
+
+(* compact representation for 2*p *)
+Fixpoint IPR_2 (p:positive) : R :=
+ match p with
+ | xH => R1 + R1
+ | xO p => (R1 + R1) * IPR_2 p
+ | xI p => (R1 + R1) * (R1 + IPR_2 p)
+ end.
+
+Definition IPR (p:positive) : R :=
+ match p with
+ | xH => R1
+ | xO p => IPR_2 p
+ | xI p => R1 + IPR_2 p
+ end.
+Arguments IPR p%positive : simpl never.
+
+(**********)
+Definition IZR (z:Z) : R :=
+ match z with
+ | Z0 => R0
+ | Zpos n => IPR n
+ | Zneg n => - IPR n
+ end.
+Arguments IZR z%Z : simpl never.
diff --git a/theories/Reals/Rderiv.v b/theories/Reals/Rderiv.v
index bd330ac9b9..5fb6bd2b71 100644
--- a/theories/Reals/Rderiv.v
+++ b/theories/Reals/Rderiv.v
@@ -296,14 +296,10 @@ Proof.
intros; generalize (H0 eps H1); clear H0; intro; elim H0;
clear H0; intros; elim H0; clear H0; simpl;
intros; split with x; split; auto.
- intros; generalize (H2 x1 H3); clear H2; intro;
- rewrite Ropp_mult_distr_l_reverse in H2;
- rewrite Ropp_mult_distr_l_reverse in H2;
- rewrite Ropp_mult_distr_l_reverse in H2;
- rewrite (let (H1, H2) := Rmult_ne (f x1) in H2) in H2;
- rewrite (let (H1, H2) := Rmult_ne (f x0) in H2) in H2;
- rewrite (let (H1, H2) := Rmult_ne (df x0) in H2) in H2;
- assumption.
+ intros; generalize (H2 x1 H3); clear H2; intro.
+ replace (- f x1 - - f x0) with (-1 * f x1 - -1 * f x0) by ring.
+ replace (- df x0) with (-1 * df x0) by ring.
+ exact H2.
Qed.
(*********)
diff --git a/theories/Reals/Rfunctions.v b/theories/Reals/Rfunctions.v
index 0a49d49831..99acdd0a1c 100644
--- a/theories/Reals/Rfunctions.v
+++ b/theories/Reals/Rfunctions.v
@@ -416,8 +416,9 @@ Proof.
simpl; apply Rabs_R1.
replace (S n) with (n + 1)%nat; [ rewrite pow_add | ring ].
rewrite Rabs_mult.
- rewrite Hrecn; rewrite Rmult_1_l; simpl; rewrite Rmult_1_r;
- rewrite Rabs_Ropp; apply Rabs_R1.
+ rewrite Hrecn; rewrite Rmult_1_l; simpl; rewrite Rmult_1_r.
+ change (-1) with (-(1)).
+ rewrite Rabs_Ropp; apply Rabs_R1.
Qed.
Lemma pow_mult : forall (x:R) (n1 n2:nat), x ^ (n1 * n2) = (x ^ n1) ^ n2.
diff --git a/theories/Reals/RiemannInt_SF.v b/theories/Reals/RiemannInt_SF.v
index 7885d697f1..af7cbb940d 100644
--- a/theories/Reals/RiemannInt_SF.v
+++ b/theories/Reals/RiemannInt_SF.v
@@ -83,11 +83,10 @@ Proof.
cut (x = INR (pred x0)).
intro H19; rewrite H19; apply le_INR; apply lt_le_S; apply INR_lt; rewrite H18;
rewrite <- H19; assumption.
- rewrite H10; rewrite H8; rewrite <- INR_IZR_INZ; replace 1 with (INR 1);
- [ idtac | reflexivity ]; rewrite <- minus_INR.
- replace (x0 - 1)%nat with (pred x0);
- [ reflexivity
- | case x0; [ reflexivity | intro; simpl; apply minus_n_O ] ].
+ rewrite H10; rewrite H8; rewrite <- INR_IZR_INZ;
+ rewrite <- (minus_INR _ 1).
+ apply f_equal;
+ case x0; [ reflexivity | intro; apply sym_eq, minus_n_O ].
induction x0 as [|x0 Hrecx0].
rewrite H8 in H3. rewrite <- INR_IZR_INZ in H3; simpl in H3.
elim (Rlt_irrefl _ (Rle_lt_trans _ _ _ H6 H3)).
diff --git a/theories/Reals/Rlimit.v b/theories/Reals/Rlimit.v
index e424a732ac..843aa27521 100644
--- a/theories/Reals/Rlimit.v
+++ b/theories/Reals/Rlimit.v
@@ -29,59 +29,28 @@ Qed.
Lemma eps2 : forall eps:R, eps * / 2 + eps * / 2 = eps.
Proof.
intro esp.
- assert (H := double_var esp).
- unfold Rdiv in H.
- symmetry ; exact H.
+ apply eq_sym, double_var.
Qed.
(*********)
Lemma eps4 : forall eps:R, eps * / (2 + 2) + eps * / (2 + 2) = eps * / 2.
Proof.
intro eps.
- replace (2 + 2) with 4.
- pattern eps at 3; rewrite double_var.
- rewrite (Rmult_plus_distr_r (eps / 2) (eps / 2) (/ 2)).
- unfold Rdiv.
- repeat rewrite Rmult_assoc.
- rewrite <- Rinv_mult_distr.
- reflexivity.
- discrR.
- discrR.
- ring.
+ field.
Qed.
(*********)
Lemma Rlt_eps2_eps : forall eps:R, eps > 0 -> eps * / 2 < eps.
Proof.
intros.
- pattern eps at 2; rewrite <- Rmult_1_r.
- repeat rewrite (Rmult_comm eps).
- apply Rmult_lt_compat_r.
- exact H.
- apply Rmult_lt_reg_l with 2.
fourier.
- rewrite Rmult_1_r; rewrite <- Rinv_r_sym.
- fourier.
- discrR.
Qed.
(*********)
Lemma Rlt_eps4_eps : forall eps:R, eps > 0 -> eps * / (2 + 2) < eps.
Proof.
intros.
- replace (2 + 2) with 4.
- pattern eps at 2; rewrite <- Rmult_1_r.
- repeat rewrite (Rmult_comm eps).
- apply Rmult_lt_compat_r.
- exact H.
- apply Rmult_lt_reg_l with 4.
- replace 4 with 4.
- apply Rmult_lt_0_compat; fourier.
- ring.
- rewrite Rmult_1_r; rewrite <- Rinv_r_sym.
fourier.
- discrR.
- ring.
Qed.
(*********)
@@ -407,8 +376,7 @@ Proof.
generalize
(Rplus_lt_compat (R_dist (f x2) l) eps (R_dist (f x2) l') eps H H0);
unfold R_dist; intros; rewrite (Rabs_minus_sym (f x2) l) in H1;
- rewrite (Rmult_comm 2 eps); rewrite (Rmult_plus_distr_l eps 1 1);
- elim (Rmult_ne eps); intros a b; rewrite a; clear a b;
+ rewrite (Rmult_comm 2 eps); replace (eps *2) with (eps + eps) by ring;
generalize (R_dist_tri l l' (f x2)); unfold R_dist;
intros;
apply
diff --git a/theories/Reals/Rpow_def.v b/theories/Reals/Rpow_def.v
index 791718a450..f331bb2039 100644
--- a/theories/Reals/Rpow_def.v
+++ b/theories/Reals/Rpow_def.v
@@ -10,6 +10,6 @@ Require Import Rdefinitions.
Fixpoint pow (r:R) (n:nat) : R :=
match n with
- | O => R1
+ | O => 1
| S n => Rmult r (pow r n)
end.
diff --git a/theories/Reals/Rpower.v b/theories/Reals/Rpower.v
index b3ce6fa338..b8040bb4f5 100644
--- a/theories/Reals/Rpower.v
+++ b/theories/Reals/Rpower.v
@@ -55,25 +55,8 @@ Proof.
simpl in H0.
replace (/ 3) with
(1 * / 1 + -1 * 1 * / 1 + -1 * (-1 * 1) * / 2 +
- -1 * (-1 * (-1 * 1)) * / (2 + 1 + 1 + 1 + 1)).
+ -1 * (-1 * (-1 * 1)) * / (2 + 1 + 1 + 1 + 1)) by field.
apply H0.
- repeat rewrite Rinv_1; repeat rewrite Rmult_1_r;
- rewrite Ropp_mult_distr_l_reverse; rewrite Rmult_1_l;
- rewrite Ropp_involutive; rewrite Rplus_opp_r; rewrite Rmult_1_r;
- rewrite Rplus_0_l; rewrite Rmult_1_l; apply Rmult_eq_reg_l with 6.
- rewrite Rmult_plus_distr_l; replace (2 + 1 + 1 + 1 + 1) with 6.
- rewrite <- (Rmult_comm (/ 6)); rewrite <- Rmult_assoc; rewrite <- Rinv_r_sym.
- rewrite Rmult_1_l; replace 6 with 6.
- do 2 rewrite Rmult_assoc; rewrite <- Rinv_r_sym.
- rewrite Rmult_1_r; rewrite (Rmult_comm 3); rewrite <- Rmult_assoc;
- rewrite <- Rinv_r_sym.
- ring.
- discrR.
- discrR.
- ring.
- discrR.
- ring.
- discrR.
apply H.
unfold Un_decreasing; intros;
apply Rmult_le_reg_l with (INR (fact n)).
@@ -473,7 +456,7 @@ Proof.
unfold Rpower; auto.
rewrite Rpower_mult.
rewrite Rinv_l.
- replace 1 with (INR 1); auto.
+ change 1 with (INR 1).
repeat rewrite Rpower_pow; simpl.
pattern x at 1; rewrite <- (sqrt_sqrt x (Rlt_le _ _ H)).
ring.
@@ -505,12 +488,9 @@ Proof.
rewrite Rinv_r.
apply exp_lt_inv.
apply Rle_lt_trans with (1 := exp_le_3).
- change (3 < 2 ^R 2).
+ change (3 < 2 ^R (1 + 1)).
repeat rewrite Rpower_plus; repeat rewrite Rpower_1.
- repeat rewrite Rmult_plus_distr_r; repeat rewrite Rmult_plus_distr_l;
- repeat rewrite Rmult_1_l.
- pattern 3 at 1; rewrite <- Rplus_0_r; replace (2 + 2) with (3 + 1);
- [ apply Rplus_lt_compat_l; apply Rlt_0_1 | ring ].
+ now apply (IZR_lt 3 4).
prove_sup0.
discrR.
Qed.
@@ -732,7 +712,7 @@ Definition arcsinh x := ln (x + sqrt (x ^ 2 + 1)).
Lemma arcsinh_sinh : forall x, arcsinh (sinh x) = x.
intros x; unfold sinh, arcsinh.
assert (Rminus_eq_0 : forall r, r - r = 0) by (intros; ring).
-pattern 1 at 5; rewrite <- exp_0, <- (Rminus_eq_0 x); unfold Rminus.
+rewrite <- exp_0, <- (Rminus_eq_0 x); unfold Rminus.
rewrite exp_plus.
match goal with |- context[sqrt ?a] =>
replace a with (((exp x + exp(-x))/2)^2) by field
diff --git a/theories/Reals/Rseries.v b/theories/Reals/Rseries.v
index 744fd66416..c6b0c3f37a 100644
--- a/theories/Reals/Rseries.v
+++ b/theories/Reals/Rseries.v
@@ -207,7 +207,7 @@ Section sequence.
assert (Rabs (/2) < 1).
rewrite Rabs_pos_eq.
- rewrite <- Rinv_1 at 3.
+ rewrite <- Rinv_1.
apply Rinv_lt_contravar.
rewrite Rmult_1_l.
now apply (IZR_lt 0 2).
diff --git a/theories/Reals/Rsqrt_def.v b/theories/Reals/Rsqrt_def.v
index b3c9c7449a..6c2b0a1a77 100644
--- a/theories/Reals/Rsqrt_def.v
+++ b/theories/Reals/Rsqrt_def.v
@@ -648,7 +648,7 @@ Proof.
Qed.
(** We can now define the square root function as the reciprocal
- transformation of the square root function *)
+ transformation of the square function *)
Lemma Rsqrt_exists :
forall y:R, 0 <= y -> { z:R | 0 <= z /\ y = Rsqr z }.
Proof.
diff --git a/theories/Reals/Rtrigo1.v b/theories/Reals/Rtrigo1.v
index 4d24186396..5a999eebe6 100644
--- a/theories/Reals/Rtrigo1.v
+++ b/theories/Reals/Rtrigo1.v
@@ -182,13 +182,10 @@ destruct (pre_cos_bound _ 0 lo up) as [_ upper].
apply Rle_lt_trans with (1 := upper).
apply Rlt_le_trans with (2 := lower).
unfold cos_approx, sin_approx.
-simpl sum_f_R0; replace 7 with (IZR 7) by (simpl; field).
-replace 8 with (IZR 8) by (simpl; field).
+simpl sum_f_R0.
unfold cos_term, sin_term; simpl fact; rewrite !INR_IZR_INZ.
-simpl plus; simpl mult.
-field_simplify;
- try (repeat apply conj; apply not_eq_sym, Rlt_not_eq, (IZR_lt 0); reflexivity).
-unfold Rminus; rewrite !pow_IZR, <- !mult_IZR, <- !opp_IZR, <- ?plus_IZR.
+simpl plus; simpl mult; simpl Z_of_nat.
+field_simplify.
match goal with
|- IZR ?a / ?b < ?c / ?d =>
apply Rmult_lt_reg_r with d;[apply (IZR_lt 0); reflexivity |
@@ -198,7 +195,7 @@ match goal with
end.
unfold Rdiv; rewrite !Rmult_assoc, Rinv_l, Rmult_1_r;
[ | apply not_eq_sym, Rlt_not_eq, (IZR_lt 0); reflexivity].
-repeat (rewrite <- !plus_IZR || rewrite <- !mult_IZR).
+rewrite <- !mult_IZR.
apply IZR_lt; reflexivity.
Qed.
@@ -323,6 +320,7 @@ Lemma sin_PI : sin PI = 0.
Proof.
assert (H := sin2_cos2 PI).
rewrite cos_PI in H.
+ change (-1) with (-(1)) in H.
rewrite <- Rsqr_neg in H.
rewrite Rsqr_1 in H.
cut (Rsqr (sin PI) = 0).
@@ -533,9 +531,8 @@ Qed.
Lemma sin_PI_x : forall x:R, sin (PI - x) = sin x.
Proof.
- intro x; rewrite sin_minus; rewrite sin_PI; rewrite cos_PI; rewrite Rmult_0_l;
- unfold Rminus in |- *; rewrite Rplus_0_l; rewrite Ropp_mult_distr_l_reverse;
- rewrite Ropp_involutive; apply Rmult_1_l.
+ intro x; rewrite sin_minus; rewrite sin_PI; rewrite cos_PI.
+ ring.
Qed.
Lemma sin_period : forall (x:R) (k:nat), sin (x + 2 * INR k * PI) = sin x.
@@ -593,9 +590,9 @@ Proof.
generalize
(Rsqr_incrst_1 1 (sin x) H (Rlt_le 0 1 Rlt_0_1)
(Rlt_le 0 (sin x) (Rlt_trans 0 1 (sin x) Rlt_0_1 H)));
- rewrite Rsqr_1; intro; rewrite sin2 in H0; unfold Rminus in H0;
+ rewrite Rsqr_1; intro; rewrite sin2 in H0; unfold Rminus in H0.
generalize (Rplus_lt_compat_l (-1) 1 (1 + - Rsqr (cos x)) H0);
- repeat rewrite <- Rplus_assoc; repeat rewrite Rplus_opp_l;
+ repeat rewrite <- Rplus_assoc; change (-1) with (-(1)); rewrite Rplus_opp_l;
rewrite Rplus_0_l; intro; rewrite <- Ropp_0 in H1;
generalize (Ropp_lt_gt_contravar (-0) (- Rsqr (cos x)) H1);
repeat rewrite Ropp_involutive; intro; generalize (Rle_0_sqr (cos x));
@@ -603,6 +600,7 @@ Proof.
auto with real.
cut (sin x < -1).
intro; generalize (Ropp_lt_gt_contravar (sin x) (-1) H);
+ change (-1) with (-(1));
rewrite Ropp_involutive; clear H; intro;
generalize
(Rsqr_incrst_1 1 (- sin x) H (Rlt_le 0 1 Rlt_0_1)
@@ -610,7 +608,7 @@ Proof.
rewrite Rsqr_1; intro; rewrite <- Rsqr_neg in H0;
rewrite sin2 in H0; unfold Rminus in H0;
generalize (Rplus_lt_compat_l (-1) 1 (1 + - Rsqr (cos x)) H0);
- repeat rewrite <- Rplus_assoc; repeat rewrite Rplus_opp_l;
+ rewrite <- Rplus_assoc; change (-1) with (-(1)); rewrite Rplus_opp_l;
rewrite Rplus_0_l; intro; rewrite <- Ropp_0 in H1;
generalize (Ropp_lt_gt_contravar (-0) (- Rsqr (cos x)) H1);
repeat rewrite Ropp_involutive; intro; generalize (Rle_0_sqr (cos x));
@@ -696,41 +694,38 @@ Proof.
rewrite <- Rinv_l_sym.
do 2 rewrite Rmult_1_r; apply Rle_lt_trans with (INR (fact (2 * n + 1)) * 4).
apply Rmult_le_compat_l.
- replace 0 with (INR 0); [ idtac | reflexivity ]; apply le_INR; apply le_O_n.
- simpl in |- *; rewrite Rmult_1_r; replace 4 with (Rsqr 2);
- [ idtac | ring_Rsqr ]; replace (a * a) with (Rsqr a);
- [ idtac | reflexivity ]; apply Rsqr_incr_1.
+ apply pos_INR.
+ simpl in |- *; rewrite Rmult_1_r; change 4 with (Rsqr 2);
+ apply Rsqr_incr_1.
apply Rle_trans with (PI / 2);
[ assumption
| unfold Rdiv in |- *; apply Rmult_le_reg_l with 2;
[ prove_sup0
| rewrite <- Rmult_assoc; rewrite Rinv_r_simpl_m;
- [ replace 4 with 4; [ apply PI_4 | ring ] | discrR ] ] ].
+ [ apply PI_4 | discrR ] ] ].
left; assumption.
left; prove_sup0.
rewrite H1; replace (2 * n + 1 + 2)%nat with (S (S (2 * n + 1))).
do 2 rewrite fact_simpl; do 2 rewrite mult_INR.
repeat rewrite <- Rmult_assoc.
rewrite <- (Rmult_comm (INR (fact (2 * n + 1)))).
- rewrite Rmult_assoc.
apply Rmult_lt_compat_l.
apply lt_INR_0; apply neq_O_lt.
assert (H2 := fact_neq_0 (2 * n + 1)).
red in |- *; intro; elim H2; symmetry in |- *; assumption.
do 2 rewrite S_INR; rewrite plus_INR; rewrite mult_INR; set (x := INR n);
unfold INR in |- *.
- replace ((2 * x + 1 + 1 + 1) * (2 * x + 1 + 1)) with (4 * x * x + 10 * x + 6);
+ replace (((1 + 1) * x + 1 + 1 + 1) * ((1 + 1) * x + 1 + 1)) with (4 * x * x + 10 * x + 6);
[ idtac | ring ].
- apply Rplus_lt_reg_l with (-4); rewrite Rplus_opp_l;
- replace (-4 + (4 * x * x + 10 * x + 6)) with (4 * x * x + 10 * x + 2);
+ apply Rplus_lt_reg_l with (-(4)); rewrite Rplus_opp_l;
+ replace (-(4) + (4 * x * x + 10 * x + 6)) with (4 * x * x + 10 * x + 2);
[ idtac | ring ].
apply Rplus_le_lt_0_compat.
cut (0 <= x).
intro; apply Rplus_le_le_0_compat; repeat apply Rmult_le_pos;
assumption || left; prove_sup.
- unfold x in |- *; replace 0 with (INR 0);
- [ apply le_INR; apply le_O_n | reflexivity ].
- prove_sup0.
+ apply pos_INR.
+ now apply IZR_lt.
ring.
apply INR_fact_neq_0.
apply INR_fact_neq_0.
@@ -738,39 +733,33 @@ Proof.
Qed.
Lemma SIN : forall a:R, 0 <= a -> a <= PI -> sin_lb a <= sin a <= sin_ub a.
+Proof.
intros; unfold sin_lb, sin_ub in |- *; apply (sin_bound a 1 H H0).
Qed.
Lemma COS :
forall a:R, - PI / 2 <= a -> a <= PI / 2 -> cos_lb a <= cos a <= cos_ub a.
+Proof.
intros; unfold cos_lb, cos_ub in |- *; apply (cos_bound a 1 H H0).
Qed.
(**********)
Lemma _PI2_RLT_0 : - (PI / 2) < 0.
Proof.
- rewrite <- Ropp_0; apply Ropp_lt_contravar; apply PI2_RGT_0.
+ assert (H := PI_RGT_0).
+ fourier.
Qed.
Lemma PI4_RLT_PI2 : PI / 4 < PI / 2.
Proof.
- unfold Rdiv in |- *; apply Rmult_lt_compat_l.
- apply PI_RGT_0.
- apply Rinv_lt_contravar.
- apply Rmult_lt_0_compat; prove_sup0.
- pattern 2 at 1 in |- *; rewrite <- Rplus_0_r.
- replace 4 with (2 + 2); [ apply Rplus_lt_compat_l; prove_sup0 | ring ].
+ assert (H := PI_RGT_0).
+ fourier.
Qed.
Lemma PI2_Rlt_PI : PI / 2 < PI.
Proof.
- unfold Rdiv in |- *; pattern PI at 2 in |- *; rewrite <- Rmult_1_r.
- apply Rmult_lt_compat_l.
- apply PI_RGT_0.
- pattern 1 at 3 in |- *; rewrite <- Rinv_1; apply Rinv_lt_contravar.
- rewrite Rmult_1_l; prove_sup0.
- pattern 1 at 1 in |- *; rewrite <- Rplus_0_r; apply Rplus_lt_compat_l;
- apply Rlt_0_1.
+ assert (H := PI_RGT_0).
+ fourier.
Qed.
(***************************************************)
@@ -787,12 +776,10 @@ Proof.
rewrite H3; rewrite sin_PI2; apply Rlt_0_1.
rewrite <- sin_PI_x; generalize (Ropp_gt_lt_contravar x (PI / 2) H3);
intro H4; generalize (Rplus_lt_compat_l PI (- x) (- (PI / 2)) H4).
- replace (PI + - x) with (PI - x).
replace (PI + - (PI / 2)) with (PI / 2).
intro H5; generalize (Ropp_lt_gt_contravar x PI H0); intro H6;
change (- PI < - x) in H6; generalize (Rplus_lt_compat_l PI (- PI) (- x) H6).
rewrite Rplus_opp_r.
- replace (PI + - x) with (PI - x).
intro H7;
elim
(SIN (PI - x) (Rlt_le 0 (PI - x) H7)
@@ -800,9 +787,7 @@ Proof.
intros H8 _;
generalize (sin_lb_gt_0 (PI - x) H7 (Rlt_le (PI - x) (PI / 2) H5));
intro H9; apply (Rlt_le_trans 0 (sin_lb (PI - x)) (sin (PI - x)) H9 H8).
- reflexivity.
- pattern PI at 2 in |- *; rewrite double_var; ring.
- reflexivity.
+ field.
Qed.
Theorem cos_gt_0 : forall x:R, - (PI / 2) < x -> x < PI / 2 -> 0 < cos x.
@@ -855,16 +840,12 @@ Proof.
rewrite <- (Ropp_involutive (cos x)); apply Ropp_le_ge_contravar;
rewrite <- neg_cos; replace (x + PI) with (x - PI + 2 * INR 1 * PI).
rewrite cos_period; apply cos_ge_0.
- replace (- (PI / 2)) with (- PI + PI / 2).
+ replace (- (PI / 2)) with (- PI + PI / 2) by field.
unfold Rminus in |- *; rewrite (Rplus_comm x); apply Rplus_le_compat_l;
assumption.
- pattern PI at 1 in |- *; rewrite (double_var PI); rewrite Ropp_plus_distr;
- ring.
unfold Rminus in |- *; rewrite Rplus_comm;
- replace (PI / 2) with (- PI + 3 * (PI / 2)).
+ replace (PI / 2) with (- PI + 3 * (PI / 2)) by field.
apply Rplus_le_compat_l; assumption.
- pattern PI at 1 in |- *; rewrite (double_var PI); rewrite Ropp_plus_distr;
- ring.
unfold INR in |- *; ring.
Qed.
@@ -905,16 +886,12 @@ Proof.
apply Ropp_lt_gt_contravar; rewrite <- neg_cos;
replace (x + PI) with (x - PI + 2 * INR 1 * PI).
rewrite cos_period; apply cos_gt_0.
- replace (- (PI / 2)) with (- PI + PI / 2).
+ replace (- (PI / 2)) with (- PI + PI / 2) by field.
unfold Rminus in |- *; rewrite (Rplus_comm x); apply Rplus_lt_compat_l;
assumption.
- pattern PI at 1 in |- *; rewrite (double_var PI); rewrite Ropp_plus_distr;
- ring.
unfold Rminus in |- *; rewrite Rplus_comm;
- replace (PI / 2) with (- PI + 3 * (PI / 2)).
+ replace (PI / 2) with (- PI + 3 * (PI / 2)) by field.
apply Rplus_lt_compat_l; assumption.
- pattern PI at 1 in |- *; rewrite (double_var PI); rewrite Ropp_plus_distr;
- ring.
unfold INR in |- *; ring.
Qed.
@@ -951,7 +928,7 @@ Lemma cos_ge_0_3PI2 :
forall x:R, 3 * (PI / 2) <= x -> x <= 2 * PI -> 0 <= cos x.
Proof.
intros; rewrite <- cos_neg; rewrite <- (cos_period (- x) 1);
- unfold INR in |- *; replace (- x + 2 * 1 * PI) with (2 * PI - x).
+ unfold INR in |- *; replace (- x + 2 * 1 * PI) with (2 * PI - x) by ring.
generalize (Ropp_le_ge_contravar x (2 * PI) H0); intro H1;
generalize (Rge_le (- x) (- (2 * PI)) H1); clear H1;
intro H1; generalize (Rplus_le_compat_l (2 * PI) (- (2 * PI)) (- x) H1).
@@ -960,36 +937,30 @@ Proof.
generalize (Rge_le (- (3 * (PI / 2))) (- x) H3); clear H3;
intro H3;
generalize (Rplus_le_compat_l (2 * PI) (- x) (- (3 * (PI / 2))) H3).
- replace (2 * PI + - (3 * (PI / 2))) with (PI / 2).
+ replace (2 * PI + - (3 * (PI / 2))) with (PI / 2) by field.
intro H4;
apply
(cos_ge_0 (2 * PI - x)
(Rlt_le (- (PI / 2)) (2 * PI - x)
(Rlt_le_trans (- (PI / 2)) 0 (2 * PI - x) _PI2_RLT_0 H2)) H4).
- rewrite double; pattern PI at 2 3 in |- *; rewrite double_var; ring.
- ring.
Qed.
Lemma form1 :
forall p q:R, cos p + cos q = 2 * cos ((p - q) / 2) * cos ((p + q) / 2).
Proof.
intros p q; pattern p at 1 in |- *;
- replace p with ((p - q) / 2 + (p + q) / 2).
- rewrite <- (cos_neg q); replace (- q) with ((p - q) / 2 - (p + q) / 2).
+ replace p with ((p - q) / 2 + (p + q) / 2) by field.
+ rewrite <- (cos_neg q); replace (- q) with ((p - q) / 2 - (p + q) / 2) by field.
rewrite cos_plus; rewrite cos_minus; ring.
- pattern q at 3 in |- *; rewrite double_var; unfold Rdiv in |- *; ring.
- pattern p at 3 in |- *; rewrite double_var; unfold Rdiv in |- *; ring.
Qed.
Lemma form2 :
forall p q:R, cos p - cos q = -2 * sin ((p - q) / 2) * sin ((p + q) / 2).
Proof.
intros p q; pattern p at 1 in |- *;
- replace p with ((p - q) / 2 + (p + q) / 2).
- rewrite <- (cos_neg q); replace (- q) with ((p - q) / 2 - (p + q) / 2).
+ replace p with ((p - q) / 2 + (p + q) / 2) by field.
+ rewrite <- (cos_neg q); replace (- q) with ((p - q) / 2 - (p + q) / 2) by field.
rewrite cos_plus; rewrite cos_minus; ring.
- pattern q at 3 in |- *; rewrite double_var; unfold Rdiv in |- *; ring.
- pattern p at 3 in |- *; rewrite double_var; unfold Rdiv in |- *; ring.
Qed.
Lemma form3 :
@@ -1007,11 +978,9 @@ Lemma form4 :
forall p q:R, sin p - sin q = 2 * cos ((p + q) / 2) * sin ((p - q) / 2).
Proof.
intros p q; pattern p at 1 in |- *;
- replace p with ((p - q) / 2 + (p + q) / 2).
- pattern q at 3 in |- *; replace q with ((p + q) / 2 - (p - q) / 2).
+ replace p with ((p - q) / 2 + (p + q) / 2) by field.
+ pattern q at 3 in |- *; replace q with ((p + q) / 2 - (p - q) / 2) by field.
rewrite sin_plus; rewrite sin_minus; ring.
- pattern q at 3 in |- *; rewrite double_var; unfold Rdiv in |- *; ring.
- pattern p at 3 in |- *; rewrite double_var; unfold Rdiv in |- *; ring.
Qed.
@@ -1067,13 +1036,13 @@ Proof.
repeat rewrite (Rmult_comm (/ 2)).
clear H4; intro H4;
generalize (Rplus_le_compat (- (PI / 2)) x (- (PI / 2)) y H H1);
- replace (- (PI / 2) + - (PI / 2)) with (- PI).
+ replace (- (PI / 2) + - (PI / 2)) with (- PI) by field.
intro H5;
generalize
(Rmult_le_compat_l (/ 2) (- PI) (x + y)
(Rlt_le 0 (/ 2) (Rinv_0_lt_compat 2 Hyp)) H5).
- replace (/ 2 * (x + y)) with ((x + y) / 2).
- replace (/ 2 * - PI) with (- (PI / 2)).
+ replace (/ 2 * (x + y)) with ((x + y) / 2) by apply Rmult_comm.
+ replace (/ 2 * - PI) with (- (PI / 2)) by field.
clear H5; intro H5; elim H4; intro H40.
elim H5; intro H50.
generalize (cos_gt_0 ((x + y) / 2) H50 H40); intro H6;
@@ -1095,13 +1064,6 @@ Proof.
rewrite H40 in H3; assert (H50 := cos_PI2); unfold Rdiv in H50;
rewrite H50 in H3; rewrite Rmult_0_r in H3; rewrite Rmult_0_l in H3;
elim (Rlt_irrefl 0 H3).
- unfold Rdiv in |- *.
- rewrite <- Ropp_mult_distr_l_reverse.
- apply Rmult_comm.
- unfold Rdiv in |- *; apply Rmult_comm.
- pattern PI at 1 in |- *; rewrite double_var.
- rewrite Ropp_plus_distr.
- reflexivity.
Qed.
Lemma sin_increasing_1 :
@@ -1111,43 +1073,42 @@ Lemma sin_increasing_1 :
Proof.
intros; generalize (Rplus_lt_compat_l x x y H3); intro H4;
generalize (Rplus_le_compat (- (PI / 2)) x (- (PI / 2)) x H H);
- replace (- (PI / 2) + - (PI / 2)) with (- PI).
+ replace (- (PI / 2) + - (PI / 2)) with (- PI) by field.
assert (Hyp : 0 < 2).
prove_sup0.
intro H5; generalize (Rle_lt_trans (- PI) (x + x) (x + y) H5 H4); intro H6;
generalize
(Rmult_lt_compat_l (/ 2) (- PI) (x + y) (Rinv_0_lt_compat 2 Hyp) H6);
- replace (/ 2 * - PI) with (- (PI / 2)).
- replace (/ 2 * (x + y)) with ((x + y) / 2).
+ replace (/ 2 * - PI) with (- (PI / 2)) by field.
+ replace (/ 2 * (x + y)) with ((x + y) / 2) by apply Rmult_comm.
clear H4 H5 H6; intro H4; generalize (Rplus_lt_compat_l y x y H3); intro H5;
rewrite Rplus_comm in H5;
generalize (Rplus_le_compat y (PI / 2) y (PI / 2) H2 H2).
rewrite <- double_var.
intro H6; generalize (Rlt_le_trans (x + y) (y + y) PI H5 H6); intro H7;
generalize (Rmult_lt_compat_l (/ 2) (x + y) PI (Rinv_0_lt_compat 2 Hyp) H7);
- replace (/ 2 * PI) with (PI / 2).
- replace (/ 2 * (x + y)) with ((x + y) / 2).
+ replace (/ 2 * PI) with (PI / 2) by apply Rmult_comm.
+ replace (/ 2 * (x + y)) with ((x + y) / 2) by apply Rmult_comm.
clear H5 H6 H7; intro H5; generalize (Ropp_le_ge_contravar (- (PI / 2)) y H1);
rewrite Ropp_involutive; clear H1; intro H1;
generalize (Rge_le (PI / 2) (- y) H1); clear H1; intro H1;
generalize (Ropp_le_ge_contravar y (PI / 2) H2); clear H2;
intro H2; generalize (Rge_le (- y) (- (PI / 2)) H2);
clear H2; intro H2; generalize (Rplus_lt_compat_l (- y) x y H3);
- replace (- y + x) with (x - y).
+ replace (- y + x) with (x - y) by apply Rplus_comm.
rewrite Rplus_opp_l.
intro H6;
generalize (Rmult_lt_compat_l (/ 2) (x - y) 0 (Rinv_0_lt_compat 2 Hyp) H6);
- rewrite Rmult_0_r; replace (/ 2 * (x - y)) with ((x - y) / 2).
+ rewrite Rmult_0_r; replace (/ 2 * (x - y)) with ((x - y) / 2) by apply Rmult_comm.
clear H6; intro H6;
generalize (Rplus_le_compat (- (PI / 2)) x (- (PI / 2)) (- y) H H2);
- replace (- (PI / 2) + - (PI / 2)) with (- PI).
- replace (x + - y) with (x - y).
+ replace (- (PI / 2) + - (PI / 2)) with (- PI) by field.
intro H7;
generalize
(Rmult_le_compat_l (/ 2) (- PI) (x - y)
(Rlt_le 0 (/ 2) (Rinv_0_lt_compat 2 Hyp)) H7);
- replace (/ 2 * - PI) with (- (PI / 2)).
- replace (/ 2 * (x - y)) with ((x - y) / 2).
+ replace (/ 2 * - PI) with (- (PI / 2)) by field.
+ replace (/ 2 * (x - y)) with ((x - y) / 2) by apply Rmult_comm.
clear H7; intro H7; clear H H0 H1 H2; apply Rminus_lt; rewrite form4;
generalize (cos_gt_0 ((x + y) / 2) H4 H5); intro H8;
generalize (Rmult_lt_0_compat 2 (cos ((x + y) / 2)) Hyp H8);
@@ -1162,23 +1123,6 @@ Proof.
2 * cos ((x + y) / 2)) H10 H8); intro H11; rewrite Rmult_0_r in H11;
rewrite Rmult_comm; assumption.
apply Ropp_lt_gt_contravar; apply PI2_Rlt_PI.
- unfold Rdiv in |- *; apply Rmult_comm.
- unfold Rdiv in |- *; rewrite <- Ropp_mult_distr_l_reverse; apply Rmult_comm.
- reflexivity.
- pattern PI at 1 in |- *; rewrite double_var.
- rewrite Ropp_plus_distr.
- reflexivity.
- unfold Rdiv in |- *; apply Rmult_comm.
- unfold Rminus in |- *; apply Rplus_comm.
- unfold Rdiv in |- *; apply Rmult_comm.
- unfold Rdiv in |- *; apply Rmult_comm.
- unfold Rdiv in |- *; apply Rmult_comm.
- unfold Rdiv in |- *.
- rewrite <- Ropp_mult_distr_l_reverse.
- apply Rmult_comm.
- pattern PI at 1 in |- *; rewrite double_var.
- rewrite Ropp_plus_distr.
- reflexivity.
Qed.
Lemma sin_decreasing_0 :
@@ -1193,33 +1137,16 @@ Proof.
generalize (Rplus_le_compat_l (- PI) (PI / 2) x H0);
generalize (Rplus_le_compat_l (- PI) y (3 * (PI / 2)) H1);
generalize (Rplus_le_compat_l (- PI) (PI / 2) y H2);
- replace (- PI + x) with (x - PI).
- replace (- PI + PI / 2) with (- (PI / 2)).
- replace (- PI + y) with (y - PI).
- replace (- PI + 3 * (PI / 2)) with (PI / 2).
- replace (- (PI - x)) with (x - PI).
- replace (- (PI - y)) with (y - PI).
+ replace (- PI + x) with (x - PI) by apply Rplus_comm.
+ replace (- PI + PI / 2) with (- (PI / 2)) by field.
+ replace (- PI + y) with (y - PI) by apply Rplus_comm.
+ replace (- PI + 3 * (PI / 2)) with (PI / 2) by field.
+ replace (- (PI - x)) with (x - PI) by ring.
+ replace (- (PI - y)) with (y - PI) by ring.
intros; change (sin (y - PI) < sin (x - PI)) in H8;
- apply Rplus_lt_reg_l with (- PI); rewrite Rplus_comm;
- replace (y + - PI) with (y - PI).
- rewrite Rplus_comm; replace (x + - PI) with (x - PI).
+ apply Rplus_lt_reg_l with (- PI); rewrite Rplus_comm.
+ rewrite (Rplus_comm _ x).
apply (sin_increasing_0 (y - PI) (x - PI) H4 H5 H6 H7 H8).
- reflexivity.
- reflexivity.
- unfold Rminus in |- *; rewrite Ropp_plus_distr.
- rewrite Ropp_involutive.
- apply Rplus_comm.
- unfold Rminus in |- *; rewrite Ropp_plus_distr.
- rewrite Ropp_involutive.
- apply Rplus_comm.
- pattern PI at 2 in |- *; rewrite double_var.
- rewrite Ropp_plus_distr.
- ring.
- unfold Rminus in |- *; apply Rplus_comm.
- pattern PI at 2 in |- *; rewrite double_var.
- rewrite Ropp_plus_distr.
- ring.
- unfold Rminus in |- *; apply Rplus_comm.
Qed.
Lemma sin_decreasing_1 :
@@ -1233,24 +1160,14 @@ Proof.
generalize (Rplus_le_compat_l (- PI) y (3 * (PI / 2)) H1);
generalize (Rplus_le_compat_l (- PI) (PI / 2) y H2);
generalize (Rplus_lt_compat_l (- PI) x y H3);
- replace (- PI + PI / 2) with (- (PI / 2)).
- replace (- PI + y) with (y - PI).
- replace (- PI + 3 * (PI / 2)) with (PI / 2).
- replace (- PI + x) with (x - PI).
+ replace (- PI + PI / 2) with (- (PI / 2)) by field.
+ replace (- PI + y) with (y - PI) by apply Rplus_comm.
+ replace (- PI + 3 * (PI / 2)) with (PI / 2) by field.
+ replace (- PI + x) with (x - PI) by apply Rplus_comm.
intros; apply Ropp_lt_cancel; repeat rewrite <- sin_neg;
- replace (- (PI - x)) with (x - PI).
- replace (- (PI - y)) with (y - PI).
+ replace (- (PI - x)) with (x - PI) by ring.
+ replace (- (PI - y)) with (y - PI) by ring.
apply (sin_increasing_1 (x - PI) (y - PI) H7 H8 H5 H6 H4).
- unfold Rminus in |- *; rewrite Ropp_plus_distr.
- rewrite Ropp_involutive.
- apply Rplus_comm.
- unfold Rminus in |- *; rewrite Ropp_plus_distr.
- rewrite Ropp_involutive.
- apply Rplus_comm.
- unfold Rminus in |- *; apply Rplus_comm.
- pattern PI at 2 in |- *; rewrite double_var; ring.
- unfold Rminus in |- *; apply Rplus_comm.
- pattern PI at 2 in |- *; rewrite double_var; ring.
Qed.
Lemma cos_increasing_0 :
@@ -1260,44 +1177,22 @@ Proof.
intros x y H1 H2 H3 H4; rewrite <- (cos_neg x); rewrite <- (cos_neg y);
rewrite <- (cos_period (- x) 1); rewrite <- (cos_period (- y) 1);
unfold INR in |- *;
- replace (- x + 2 * 1 * PI) with (PI / 2 - (x - 3 * (PI / 2))).
- replace (- y + 2 * 1 * PI) with (PI / 2 - (y - 3 * (PI / 2))).
+ replace (- x + 2 * 1 * PI) with (PI / 2 - (x - 3 * (PI / 2))) by field.
+ replace (- y + 2 * 1 * PI) with (PI / 2 - (y - 3 * (PI / 2))) by field.
repeat rewrite cos_shift; intro H5;
generalize (Rplus_le_compat_l (-3 * (PI / 2)) PI x H1);
generalize (Rplus_le_compat_l (-3 * (PI / 2)) x (2 * PI) H2);
generalize (Rplus_le_compat_l (-3 * (PI / 2)) PI y H3);
generalize (Rplus_le_compat_l (-3 * (PI / 2)) y (2 * PI) H4).
- replace (-3 * (PI / 2) + y) with (y - 3 * (PI / 2)).
- replace (-3 * (PI / 2) + x) with (x - 3 * (PI / 2)).
- replace (-3 * (PI / 2) + 2 * PI) with (PI / 2).
- replace (-3 * (PI / 2) + PI) with (- (PI / 2)).
+ replace (-3 * (PI / 2) + y) with (y - 3 * (PI / 2)) by ring.
+ replace (-3 * (PI / 2) + x) with (x - 3 * (PI / 2)) by ring.
+ replace (-3 * (PI / 2) + 2 * PI) with (PI / 2) by field.
+ replace (-3 * (PI / 2) + PI) with (- (PI / 2)) by field.
clear H1 H2 H3 H4; intros H1 H2 H3 H4;
apply Rplus_lt_reg_l with (-3 * (PI / 2));
- replace (-3 * (PI / 2) + x) with (x - 3 * (PI / 2)).
- replace (-3 * (PI / 2) + y) with (y - 3 * (PI / 2)).
+ replace (-3 * (PI / 2) + x) with (x - 3 * (PI / 2)) by ring.
+ replace (-3 * (PI / 2) + y) with (y - 3 * (PI / 2)) by ring.
apply (sin_increasing_0 (x - 3 * (PI / 2)) (y - 3 * (PI / 2)) H4 H3 H2 H1 H5).
- unfold Rminus in |- *.
- rewrite Ropp_mult_distr_l_reverse.
- apply Rplus_comm.
- unfold Rminus in |- *.
- rewrite Ropp_mult_distr_l_reverse.
- apply Rplus_comm.
- pattern PI at 3 in |- *; rewrite double_var.
- ring.
- rewrite double; pattern PI at 3 4 in |- *; rewrite double_var.
- ring.
- unfold Rminus in |- *.
- rewrite Ropp_mult_distr_l_reverse.
- apply Rplus_comm.
- unfold Rminus in |- *.
- rewrite Ropp_mult_distr_l_reverse.
- apply Rplus_comm.
- rewrite Rmult_1_r.
- rewrite (double PI); pattern PI at 3 4 in |- *; rewrite double_var.
- ring.
- rewrite Rmult_1_r.
- rewrite (double PI); pattern PI at 3 4 in |- *; rewrite double_var.
- ring.
Qed.
Lemma cos_increasing_1 :
@@ -1312,31 +1207,16 @@ Proof.
generalize (Rplus_lt_compat_l (-3 * (PI / 2)) x y H5);
rewrite <- (cos_neg x); rewrite <- (cos_neg y);
rewrite <- (cos_period (- x) 1); rewrite <- (cos_period (- y) 1);
- unfold INR in |- *; replace (-3 * (PI / 2) + x) with (x - 3 * (PI / 2)).
- replace (-3 * (PI / 2) + y) with (y - 3 * (PI / 2)).
- replace (-3 * (PI / 2) + PI) with (- (PI / 2)).
- replace (-3 * (PI / 2) + 2 * PI) with (PI / 2).
+ unfold INR in |- *; replace (-3 * (PI / 2) + x) with (x - 3 * (PI / 2)) by ring.
+ replace (-3 * (PI / 2) + y) with (y - 3 * (PI / 2)) by ring.
+ replace (-3 * (PI / 2) + PI) with (- (PI / 2)) by field.
+ replace (-3 * (PI / 2) + 2 * PI) with (PI / 2) by field.
clear H1 H2 H3 H4 H5; intros H1 H2 H3 H4 H5;
- replace (- x + 2 * 1 * PI) with (PI / 2 - (x - 3 * (PI / 2))).
- replace (- y + 2 * 1 * PI) with (PI / 2 - (y - 3 * (PI / 2))).
+ replace (- x + 2 * 1 * PI) with (PI / 2 - (x - 3 * (PI / 2))) by field.
+ replace (- y + 2 * 1 * PI) with (PI / 2 - (y - 3 * (PI / 2))) by field.
repeat rewrite cos_shift;
apply
(sin_increasing_1 (x - 3 * (PI / 2)) (y - 3 * (PI / 2)) H5 H4 H3 H2 H1).
- rewrite Rmult_1_r.
- rewrite (double PI); pattern PI at 3 4 in |- *; rewrite double_var.
- ring.
- rewrite Rmult_1_r.
- rewrite (double PI); pattern PI at 3 4 in |- *; rewrite double_var.
- ring.
- rewrite (double PI); pattern PI at 3 4 in |- *; rewrite double_var.
- ring.
- pattern PI at 3 in |- *; rewrite double_var; ring.
- unfold Rminus in |- *.
- rewrite <- Ropp_mult_distr_l_reverse.
- apply Rplus_comm.
- unfold Rminus in |- *.
- rewrite <- Ropp_mult_distr_l_reverse.
- apply Rplus_comm.
Qed.
Lemma cos_decreasing_0 :
@@ -1375,31 +1255,8 @@ Lemma tan_diff :
cos x <> 0 -> cos y <> 0 -> tan x - tan y = sin (x - y) / (cos x * cos y).
Proof.
intros; unfold tan in |- *; rewrite sin_minus.
- unfold Rdiv in |- *.
- unfold Rminus in |- *.
- rewrite Rmult_plus_distr_r.
- rewrite Rinv_mult_distr.
- repeat rewrite (Rmult_comm (sin x)).
- repeat rewrite Rmult_assoc.
- rewrite (Rmult_comm (cos y)).
- repeat rewrite Rmult_assoc.
- rewrite <- Rinv_l_sym.
- rewrite Rmult_1_r.
- rewrite (Rmult_comm (sin x)).
- apply Rplus_eq_compat_l.
- rewrite <- Ropp_mult_distr_l_reverse.
- rewrite <- Ropp_mult_distr_r_reverse.
- rewrite (Rmult_comm (/ cos x)).
- repeat rewrite Rmult_assoc.
- rewrite (Rmult_comm (cos x)).
- repeat rewrite Rmult_assoc.
- rewrite <- Rinv_l_sym.
- rewrite Rmult_1_r.
- reflexivity.
- assumption.
- assumption.
- assumption.
- assumption.
+ field.
+ now split.
Qed.
Lemma tan_increasing_0 :
@@ -1436,10 +1293,9 @@ Proof.
intro H11; generalize (Rge_le (- y) (- (PI / 4)) H11);
clear H11; intro H11;
generalize (Rplus_le_compat (- (PI / 4)) x (- (PI / 4)) (- y) H H11);
- generalize (Rplus_le_compat x (PI / 4) (- y) (PI / 4) H0 H10);
- replace (x + - y) with (x - y).
- replace (PI / 4 + PI / 4) with (PI / 2).
- replace (- (PI / 4) + - (PI / 4)) with (- (PI / 2)).
+ generalize (Rplus_le_compat x (PI / 4) (- y) (PI / 4) H0 H10).
+ replace (PI / 4 + PI / 4) with (PI / 2) by field.
+ replace (- (PI / 4) + - (PI / 4)) with (- (PI / 2)) by field.
intros; case (Rtotal_order 0 (x - y)); intro H14.
generalize
(sin_gt_0 (x - y) H14 (Rle_lt_trans (x - y) (PI / 2) PI H12 PI2_Rlt_PI));
@@ -1447,28 +1303,6 @@ Proof.
elim H14; intro H15.
rewrite <- H15 in H9; rewrite sin_0 in H9; elim (Rlt_irrefl 0 H9).
apply Rminus_lt; assumption.
- pattern PI at 1 in |- *; rewrite double_var.
- unfold Rdiv in |- *.
- rewrite Rmult_plus_distr_r.
- repeat rewrite Rmult_assoc.
- rewrite <- Rinv_mult_distr.
- rewrite Ropp_plus_distr.
- replace 4 with 4.
- reflexivity.
- ring.
- discrR.
- discrR.
- pattern PI at 1 in |- *; rewrite double_var.
- unfold Rdiv in |- *.
- rewrite Rmult_plus_distr_r.
- repeat rewrite Rmult_assoc.
- rewrite <- Rinv_mult_distr.
- replace 4 with 4.
- reflexivity.
- ring.
- discrR.
- discrR.
- reflexivity.
case (Rcase_abs (sin (x - y))); intro H9.
assumption.
generalize (Rge_le (sin (x - y)) 0 H9); clear H9; intro H9;
@@ -1482,8 +1316,7 @@ Proof.
(Rlt_le 0 (/ (cos x * cos y)) H12)); intro H13;
elim
(Rlt_irrefl 0 (Rle_lt_trans 0 (sin (x - y) * / (cos x * cos y)) 0 H13 H3)).
- rewrite Rinv_mult_distr.
- reflexivity.
+ apply Rinv_mult_distr.
assumption.
assumption.
Qed.
@@ -1521,9 +1354,8 @@ Proof.
clear H10 H11; intro H8; generalize (Ropp_le_ge_contravar y (PI / 4) H2);
intro H11; generalize (Rge_le (- y) (- (PI / 4)) H11);
clear H11; intro H11;
- generalize (Rplus_le_compat (- (PI / 4)) x (- (PI / 4)) (- y) H H11);
- replace (x + - y) with (x - y).
- replace (- (PI / 4) + - (PI / 4)) with (- (PI / 2)).
+ generalize (Rplus_le_compat (- (PI / 4)) x (- (PI / 4)) (- y) H H11).
+ replace (- (PI / 4) + - (PI / 4)) with (- (PI / 2)) by field.
clear H11; intro H9; generalize (Rlt_minus x y H3); clear H3; intro H3;
clear H H0 H1 H2 H4 H5 HP1 HP2; generalize PI2_Rlt_PI;
intro H1; generalize (Ropp_lt_gt_contravar (PI / 2) PI H1);
@@ -1534,18 +1366,6 @@ Proof.
generalize
(Rmult_lt_gt_compat_neg_l (sin (x - y)) 0 (/ (cos x * cos y)) H2 H8);
rewrite Rmult_0_r; intro H4; assumption.
- pattern PI at 1 in |- *; rewrite double_var.
- unfold Rdiv in |- *.
- rewrite Rmult_plus_distr_r.
- repeat rewrite Rmult_assoc.
- rewrite <- Rinv_mult_distr.
- replace 4 with 4.
- rewrite Ropp_plus_distr.
- reflexivity.
- ring.
- discrR.
- discrR.
- reflexivity.
apply Rinv_mult_distr; assumption.
Qed.
@@ -1737,7 +1557,7 @@ Proof.
rewrite H5.
rewrite mult_INR.
simpl in |- *.
- rewrite <- (Rplus_0_l (2 * INR x2 * PI)).
+ rewrite <- (Rplus_0_l ((1 + 1) * INR x2 * PI)).
rewrite sin_period.
apply sin_0.
rewrite H5.
@@ -1747,7 +1567,7 @@ Proof.
rewrite Rmult_1_l; rewrite sin_plus.
rewrite sin_PI.
rewrite Rmult_0_r.
- rewrite <- (Rplus_0_l (2 * INR x2 * PI)).
+ rewrite <- (Rplus_0_l ((1 + 1) * INR x2 * PI)).
rewrite sin_period.
rewrite sin_0; ring.
apply le_IZR.
@@ -1769,7 +1589,7 @@ Proof.
rewrite H5.
rewrite mult_INR.
simpl in |- *.
- rewrite <- (Rplus_0_l (2 * INR x2 * PI)).
+ rewrite <- (Rplus_0_l ((1 + 1) * INR x2 * PI)).
rewrite sin_period.
rewrite sin_0; ring.
rewrite H5.
@@ -1779,7 +1599,7 @@ Proof.
rewrite Rmult_1_l; rewrite sin_plus.
rewrite sin_PI.
rewrite Rmult_0_r.
- rewrite <- (Rplus_0_l (2 * INR x2 * PI)).
+ rewrite <- (Rplus_0_l ((1 + 1) * INR x2 * PI)).
rewrite sin_period.
rewrite sin_0; ring.
apply le_IZR.
@@ -1787,8 +1607,7 @@ Proof.
rewrite Rplus_0_r.
rewrite Ropp_Ropp_IZR.
rewrite Rplus_opp_r.
- left; replace 0 with (IZR 0); [ apply IZR_lt | reflexivity ].
- assumption.
+ now apply Rlt_le, IZR_lt.
rewrite <- sin_neg.
rewrite Ropp_mult_distr_l_reverse.
rewrite Ropp_involutive.
@@ -1858,7 +1677,7 @@ Proof.
- right; left; auto.
- left.
clear Hi. subst.
- replace 0 with (IZR 0 * PI) by (simpl; ring). f_equal. f_equal.
+ replace 0 with (IZR 0 * PI) by apply Rmult_0_l. f_equal. f_equal.
apply one_IZR_lt1.
split.
+ apply Rlt_le_trans with 0;
diff --git a/theories/Reals/Rtrigo_alt.v b/theories/Reals/Rtrigo_alt.v
index a5092d22dc..55cb74e35d 100644
--- a/theories/Reals/Rtrigo_alt.v
+++ b/theories/Reals/Rtrigo_alt.v
@@ -99,24 +99,22 @@ Proof.
apply Rle_trans with 20.
apply Rle_trans with 16.
replace 16 with (Rsqr 4); [ idtac | ring_Rsqr ].
- replace (a * a) with (Rsqr a); [ idtac | reflexivity ].
apply Rsqr_incr_1.
assumption.
assumption.
- left; prove_sup0.
- rewrite <- (Rplus_0_r 16); replace 20 with (16 + 4);
- [ apply Rplus_le_compat_l; left; prove_sup0 | ring ].
- rewrite <- (Rplus_comm 20); pattern 20 at 1; rewrite <- Rplus_0_r;
- apply Rplus_le_compat_l.
+ now apply IZR_le.
+ now apply IZR_le.
+ rewrite <- (Rplus_0_l 20) at 1;
+ apply Rplus_le_compat_r.
apply Rplus_le_le_0_compat.
- repeat apply Rmult_le_pos.
- left; prove_sup0.
- left; prove_sup0.
- replace 0 with (INR 0); [ apply le_INR; apply le_O_n | reflexivity ].
- replace 0 with (INR 0); [ apply le_INR; apply le_O_n | reflexivity ].
apply Rmult_le_pos.
- left; prove_sup0.
- replace 0 with (INR 0); [ apply le_INR; apply le_O_n | reflexivity ].
+ apply Rmult_le_pos.
+ now apply IZR_le.
+ apply pos_INR.
+ apply pos_INR.
+ apply Rmult_le_pos.
+ now apply IZR_le.
+ apply pos_INR.
apply INR_fact_neq_0.
apply INR_fact_neq_0.
simpl; ring.
@@ -182,16 +180,14 @@ Proof.
replace (- sum_f_R0 (tg_alt Un) (S (2 * n))) with
(-1 * sum_f_R0 (tg_alt Un) (S (2 * n))); [ rewrite scal_sum | ring ].
apply sum_eq; intros; unfold sin_term, Un, tg_alt;
- replace ((-1) ^ S i) with (-1 * (-1) ^ i).
+ change ((-1) ^ S i) with (-1 * (-1) ^ i).
unfold Rdiv; ring.
- reflexivity.
replace (- sum_f_R0 (tg_alt Un) (2 * n)) with
(-1 * sum_f_R0 (tg_alt Un) (2 * n)); [ rewrite scal_sum | ring ].
apply sum_eq; intros.
unfold sin_term, Un, tg_alt;
- replace ((-1) ^ S i) with (-1 * (-1) ^ i).
+ change ((-1) ^ S i) with (-1 * (-1) ^ i).
unfold Rdiv; ring.
- reflexivity.
replace (2 * (n + 1))%nat with (S (S (2 * n))).
reflexivity.
ring.
@@ -279,26 +275,23 @@ Proof.
with (4 * INR n1 * INR n1 + 14 * INR n1 + 12); [ idtac | ring ].
apply Rle_trans with 12.
apply Rle_trans with 4.
- replace 4 with (Rsqr 2); [ idtac | ring_Rsqr ].
- replace (a0 * a0) with (Rsqr a0); [ idtac | reflexivity ].
+ change 4 with (Rsqr 2).
apply Rsqr_incr_1.
assumption.
- discrR.
assumption.
- left; prove_sup0.
- pattern 4 at 1; rewrite <- Rplus_0_r; replace 12 with (4 + 8);
- [ apply Rplus_le_compat_l; left; prove_sup0 | ring ].
- rewrite <- (Rplus_comm 12); pattern 12 at 1; rewrite <- Rplus_0_r;
- apply Rplus_le_compat_l.
+ now apply IZR_le.
+ now apply IZR_le.
+ rewrite <- (Rplus_0_l 12) at 1;
+ apply Rplus_le_compat_r.
apply Rplus_le_le_0_compat.
- repeat apply Rmult_le_pos.
- left; prove_sup0.
- left; prove_sup0.
- replace 0 with (INR 0); [ apply le_INR; apply le_O_n | reflexivity ].
- replace 0 with (INR 0); [ apply le_INR; apply le_O_n | reflexivity ].
apply Rmult_le_pos.
- left; prove_sup0.
- replace 0 with (INR 0); [ apply le_INR; apply le_O_n | reflexivity ].
+ apply Rmult_le_pos.
+ now apply IZR_le.
+ apply pos_INR.
+ apply pos_INR.
+ apply Rmult_le_pos.
+ now apply IZR_le.
+ apply pos_INR.
apply INR_fact_neq_0.
apply INR_fact_neq_0.
simpl; ring.
@@ -320,7 +313,7 @@ Proof.
(1 - sum_f_R0 (fun i:nat => cos_n i * Rsqr a0 ^ i) (S n1)).
unfold Rminus; rewrite Ropp_plus_distr; rewrite Ropp_involutive;
repeat rewrite Rplus_assoc; rewrite (Rplus_comm 1);
- rewrite (Rplus_comm (-1)); repeat rewrite Rplus_assoc;
+ rewrite (Rplus_comm (-(1))); repeat rewrite Rplus_assoc;
rewrite Rplus_opp_l; rewrite Rplus_0_r; rewrite <- Rabs_Ropp;
rewrite Ropp_plus_distr; rewrite Ropp_involutive;
unfold Rminus in H6; apply H6.
@@ -351,15 +344,13 @@ Proof.
replace (- sum_f_R0 (tg_alt Un) (S (2 * n0))) with
(-1 * sum_f_R0 (tg_alt Un) (S (2 * n0))); [ rewrite scal_sum | ring ].
apply sum_eq; intros; unfold cos_term, Un, tg_alt;
- replace ((-1) ^ S i) with (-1 * (-1) ^ i).
+ change ((-1) ^ S i) with (-1 * (-1) ^ i).
unfold Rdiv; ring.
- reflexivity.
replace (- sum_f_R0 (tg_alt Un) (2 * n0)) with
(-1 * sum_f_R0 (tg_alt Un) (2 * n0)); [ rewrite scal_sum | ring ];
apply sum_eq; intros; unfold cos_term, Un, tg_alt;
- replace ((-1) ^ S i) with (-1 * (-1) ^ i).
+ change ((-1) ^ S i) with (-1 * (-1) ^ i).
unfold Rdiv; ring.
- reflexivity.
replace (2 * (n0 + 1))%nat with (S (S (2 * n0))).
reflexivity.
ring.
@@ -367,10 +358,10 @@ Proof.
reflexivity.
ring.
intro; elim H2; intros; split.
- apply Rplus_le_reg_l with (-1).
+ apply Rplus_le_reg_l with (-(1)).
rewrite <- Rplus_assoc; rewrite Rplus_opp_l; rewrite Rplus_0_l;
rewrite (Rplus_comm (-1)); apply H3.
- apply Rplus_le_reg_l with (-1).
+ apply Rplus_le_reg_l with (-(1)).
rewrite <- Rplus_assoc; rewrite Rplus_opp_l; rewrite Rplus_0_l;
rewrite (Rplus_comm (-1)); apply H4.
unfold cos_term; simpl; unfold Rdiv; rewrite Rinv_1;
diff --git a/theories/Reals/Rtrigo_calc.v b/theories/Reals/Rtrigo_calc.v
index 9ba14ee734..53056cabdf 100644
--- a/theories/Reals/Rtrigo_calc.v
+++ b/theories/Reals/Rtrigo_calc.v
@@ -32,48 +32,22 @@ Proof.
Qed.
Lemma sin_cos_PI4 : sin (PI / 4) = cos (PI / 4).
-Proof with trivial.
- rewrite cos_sin...
- replace (PI / 2 + PI / 4) with (- (PI / 4) + PI)...
- rewrite neg_sin; rewrite sin_neg; ring...
- cut (PI = PI / 2 + PI / 2); [ intro | apply double_var ]...
- pattern PI at 2 3; rewrite H; pattern PI at 2 3; rewrite H...
- assert (H0 : 2 <> 0);
- [ discrR | unfold Rdiv; rewrite Rinv_mult_distr; try ring ]...
+Proof.
+ rewrite cos_sin.
+ replace (PI / 2 + PI / 4) with (- (PI / 4) + PI) by field.
+ rewrite neg_sin, sin_neg; ring.
Qed.
Lemma sin_PI3_cos_PI6 : sin (PI / 3) = cos (PI / 6).
-Proof with trivial.
- replace (PI / 6) with (PI / 2 - PI / 3)...
- rewrite cos_shift...
- assert (H0 : 6 <> 0); [ discrR | idtac ]...
- assert (H1 : 3 <> 0); [ discrR | idtac ]...
- assert (H2 : 2 <> 0); [ discrR | idtac ]...
- apply Rmult_eq_reg_l with 6...
- rewrite Rmult_minus_distr_l; repeat rewrite (Rmult_comm 6)...
- unfold Rdiv; repeat rewrite Rmult_assoc...
- rewrite <- Rinv_l_sym...
- rewrite (Rmult_comm (/ 3)); repeat rewrite Rmult_assoc; rewrite <- Rinv_r_sym...
- rewrite (Rmult_comm PI); repeat rewrite Rmult_1_r;
- repeat rewrite <- Rmult_assoc; rewrite <- Rinv_l_sym...
- ring...
+Proof.
+ replace (PI / 6) with (PI / 2 - PI / 3) by field.
+ now rewrite cos_shift.
Qed.
Lemma sin_PI6_cos_PI3 : cos (PI / 3) = sin (PI / 6).
-Proof with trivial.
- replace (PI / 6) with (PI / 2 - PI / 3)...
- rewrite sin_shift...
- assert (H0 : 6 <> 0); [ discrR | idtac ]...
- assert (H1 : 3 <> 0); [ discrR | idtac ]...
- assert (H2 : 2 <> 0); [ discrR | idtac ]...
- apply Rmult_eq_reg_l with 6...
- rewrite Rmult_minus_distr_l; repeat rewrite (Rmult_comm 6)...
- unfold Rdiv; repeat rewrite Rmult_assoc...
- rewrite <- Rinv_l_sym...
- rewrite (Rmult_comm (/ 3)); repeat rewrite Rmult_assoc; rewrite <- Rinv_r_sym...
- rewrite (Rmult_comm PI); repeat rewrite Rmult_1_r;
- repeat rewrite <- Rmult_assoc; rewrite <- Rinv_l_sym...
- ring...
+Proof.
+ replace (PI / 6) with (PI / 2 - PI / 3) by field.
+ now rewrite sin_shift.
Qed.
Lemma PI6_RGT_0 : 0 < PI / 6.
@@ -90,29 +64,20 @@ Proof.
Qed.
Lemma sin_PI6 : sin (PI / 6) = 1 / 2.
-Proof with trivial.
- assert (H : 2 <> 0); [ discrR | idtac ]...
- apply Rmult_eq_reg_l with (2 * cos (PI / 6))...
+Proof.
+ apply Rmult_eq_reg_l with (2 * cos (PI / 6)).
replace (2 * cos (PI / 6) * sin (PI / 6)) with
- (2 * sin (PI / 6) * cos (PI / 6))...
- rewrite <- sin_2a; replace (2 * (PI / 6)) with (PI / 3)...
- rewrite sin_PI3_cos_PI6...
- unfold Rdiv; rewrite Rmult_1_l; rewrite Rmult_assoc;
- pattern 2 at 2; rewrite (Rmult_comm 2); rewrite Rmult_assoc;
- rewrite <- Rinv_l_sym...
- rewrite Rmult_1_r...
- unfold Rdiv; rewrite Rinv_mult_distr...
- rewrite (Rmult_comm (/ 2)); rewrite (Rmult_comm 2);
- repeat rewrite Rmult_assoc; rewrite <- Rinv_l_sym...
- rewrite Rmult_1_r...
- discrR...
- ring...
- apply prod_neq_R0...
+ (2 * sin (PI / 6) * cos (PI / 6)) by ring.
+ rewrite <- sin_2a; replace (2 * (PI / 6)) with (PI / 3) by field.
+ rewrite sin_PI3_cos_PI6.
+ field.
+ apply prod_neq_R0.
+ discrR.
cut (0 < cos (PI / 6));
[ intro H1; auto with real
| apply cos_gt_0;
[ apply (Rlt_trans (- (PI / 2)) 0 (PI / 6) _PI2_RLT_0 PI6_RGT_0)
- | apply PI6_RLT_PI2 ] ]...
+ | apply PI6_RLT_PI2 ] ].
Qed.
Lemma sqrt2_neq_0 : sqrt 2 <> 0.
@@ -188,20 +153,13 @@ Proof with trivial.
apply Rinv_0_lt_compat; apply Rlt_sqrt2_0...
rewrite Rsqr_div...
rewrite Rsqr_1; rewrite Rsqr_sqrt...
- assert (H : 2 <> 0); [ discrR | idtac ]...
unfold Rsqr; pattern (cos (PI / 4)) at 1;
rewrite <- sin_cos_PI4;
replace (sin (PI / 4) * cos (PI / 4)) with
- (1 / 2 * (2 * sin (PI / 4) * cos (PI / 4)))...
- rewrite <- sin_2a; replace (2 * (PI / 4)) with (PI / 2)...
+ (1 / 2 * (2 * sin (PI / 4) * cos (PI / 4))) by field.
+ rewrite <- sin_2a; replace (2 * (PI / 4)) with (PI / 2) by field.
rewrite sin_PI2...
- apply Rmult_1_r...
- unfold Rdiv; rewrite (Rmult_comm 2); rewrite Rinv_mult_distr...
- repeat rewrite Rmult_assoc; rewrite <- Rinv_l_sym...
- rewrite Rmult_1_r...
- unfold Rdiv; rewrite Rmult_1_l; repeat rewrite <- Rmult_assoc...
- rewrite <- Rinv_l_sym...
- rewrite Rmult_1_l...
+ field.
left; prove_sup...
apply sqrt2_neq_0...
Qed.
@@ -219,24 +177,17 @@ Proof.
Qed.
Lemma cos3PI4 : cos (3 * (PI / 4)) = -1 / sqrt 2.
-Proof with trivial.
- replace (3 * (PI / 4)) with (PI / 2 - - (PI / 4))...
- rewrite cos_shift; rewrite sin_neg; rewrite sin_PI4...
- unfold Rdiv; rewrite Ropp_mult_distr_l_reverse...
- unfold Rminus; rewrite Ropp_involutive; pattern PI at 1;
- rewrite double_var; unfold Rdiv; rewrite Rmult_plus_distr_r;
- repeat rewrite Rmult_assoc; rewrite <- Rinv_mult_distr;
- [ ring | discrR | discrR ]...
+Proof.
+ replace (3 * (PI / 4)) with (PI / 2 - - (PI / 4)) by field.
+ rewrite cos_shift; rewrite sin_neg; rewrite sin_PI4.
+ unfold Rdiv.
+ ring.
Qed.
Lemma sin3PI4 : sin (3 * (PI / 4)) = 1 / sqrt 2.
-Proof with trivial.
- replace (3 * (PI / 4)) with (PI / 2 - - (PI / 4))...
- rewrite sin_shift; rewrite cos_neg; rewrite cos_PI4...
- unfold Rminus; rewrite Ropp_involutive; pattern PI at 1;
- rewrite double_var; unfold Rdiv; rewrite Rmult_plus_distr_r;
- repeat rewrite Rmult_assoc; rewrite <- Rinv_mult_distr;
- [ ring | discrR | discrR ]...
+Proof.
+ replace (3 * (PI / 4)) with (PI / 2 - - (PI / 4)) by field.
+ now rewrite sin_shift, cos_neg, cos_PI4.
Qed.
Lemma cos_PI6 : cos (PI / 6) = sqrt 3 / 2.
@@ -248,19 +199,11 @@ Proof with trivial.
left; apply (Rmult_lt_0_compat (sqrt 3) (/ 2))...
apply Rlt_sqrt3_0...
apply Rinv_0_lt_compat; prove_sup0...
- assert (H : 2 <> 0); [ discrR | idtac ]...
- assert (H1 : 4 <> 0); [ apply prod_neq_R0 | idtac ]...
rewrite Rsqr_div...
rewrite cos2; unfold Rsqr; rewrite sin_PI6; rewrite sqrt_def...
- unfold Rdiv; rewrite Rmult_1_l; apply Rmult_eq_reg_l with 4...
- rewrite Rmult_minus_distr_l; rewrite (Rmult_comm 3);
- repeat rewrite <- Rmult_assoc; rewrite <- Rinv_r_sym...
- rewrite Rmult_1_l; rewrite Rmult_1_r...
- rewrite <- (Rmult_comm (/ 2)); repeat rewrite <- Rmult_assoc...
- rewrite <- Rinv_l_sym...
- rewrite Rmult_1_l; rewrite <- Rinv_r_sym...
- ring...
- left; prove_sup0...
+ field.
+ left ; prove_sup0.
+ discrR.
Qed.
Lemma tan_PI6 : tan (PI / 6) = 1 / sqrt 3.
@@ -306,56 +249,32 @@ Proof.
Qed.
Lemma cos_2PI3 : cos (2 * (PI / 3)) = -1 / 2.
-Proof with trivial.
- assert (H : 2 <> 0); [ discrR | idtac ]...
- assert (H0 : 4 <> 0); [ apply prod_neq_R0 | idtac ]...
- rewrite double; rewrite cos_plus; rewrite sin_PI3; rewrite cos_PI3;
- unfold Rdiv; rewrite Rmult_1_l; apply Rmult_eq_reg_l with 4...
- rewrite Rmult_minus_distr_l; repeat rewrite Rmult_assoc;
- rewrite (Rmult_comm 2)...
- repeat rewrite Rmult_assoc; rewrite <- Rinv_l_sym...
- rewrite Rmult_1_r; rewrite <- Rinv_r_sym...
- pattern 2 at 4; rewrite (Rmult_comm 2); repeat rewrite Rmult_assoc;
- rewrite <- Rinv_l_sym...
- rewrite Rmult_1_r; rewrite Ropp_mult_distr_r_reverse; rewrite Rmult_1_r...
- rewrite (Rmult_comm 2); repeat rewrite Rmult_assoc; rewrite <- Rinv_l_sym...
- rewrite Rmult_1_r; rewrite (Rmult_comm 2); rewrite (Rmult_comm (/ 2))...
- repeat rewrite Rmult_assoc; rewrite <- Rinv_l_sym...
- rewrite Rmult_1_r; rewrite sqrt_def...
- ring...
- left; prove_sup...
+Proof.
+ rewrite cos_2a, sin_PI3, cos_PI3.
+ replace (sqrt 3 / 2 * (sqrt 3 / 2)) with ((sqrt 3 * sqrt 3) / 4) by field.
+ rewrite sqrt_sqrt.
+ field.
+ left ; prove_sup0.
Qed.
Lemma tan_2PI3 : tan (2 * (PI / 3)) = - sqrt 3.
-Proof with trivial.
- assert (H : 2 <> 0); [ discrR | idtac ]...
- unfold tan; rewrite sin_2PI3; rewrite cos_2PI3; unfold Rdiv;
- rewrite Ropp_mult_distr_l_reverse; rewrite Rmult_1_l;
- rewrite <- Ropp_inv_permute...
- rewrite Rinv_involutive...
- rewrite Rmult_assoc; rewrite Ropp_mult_distr_r_reverse; rewrite <- Rinv_l_sym...
- ring...
- apply Rinv_neq_0_compat...
+Proof.
+ unfold tan; rewrite sin_2PI3, cos_2PI3.
+ field.
Qed.
Lemma cos_5PI4 : cos (5 * (PI / 4)) = -1 / sqrt 2.
-Proof with trivial.
- replace (5 * (PI / 4)) with (PI / 4 + PI)...
- rewrite neg_cos; rewrite cos_PI4; unfold Rdiv;
- rewrite Ropp_mult_distr_l_reverse...
- pattern PI at 2; rewrite double_var; pattern PI at 2 3;
- rewrite double_var; assert (H : 2 <> 0);
- [ discrR | unfold Rdiv; repeat rewrite Rinv_mult_distr; try ring ]...
+Proof.
+ replace (5 * (PI / 4)) with (PI / 4 + PI) by field.
+ rewrite neg_cos; rewrite cos_PI4; unfold Rdiv.
+ ring.
Qed.
Lemma sin_5PI4 : sin (5 * (PI / 4)) = -1 / sqrt 2.
-Proof with trivial.
- replace (5 * (PI / 4)) with (PI / 4 + PI)...
- rewrite neg_sin; rewrite sin_PI4; unfold Rdiv;
- rewrite Ropp_mult_distr_l_reverse...
- pattern PI at 2; rewrite double_var; pattern PI at 2 3;
- rewrite double_var; assert (H : 2 <> 0);
- [ discrR | unfold Rdiv; repeat rewrite Rinv_mult_distr; try ring ]...
+Proof.
+ replace (5 * (PI / 4)) with (PI / 4 + PI) by field.
+ rewrite neg_sin; rewrite sin_PI4; unfold Rdiv.
+ ring.
Qed.
Lemma sin_cos5PI4 : cos (5 * (PI / 4)) = sin (5 * (PI / 4)).
diff --git a/theories/Reals/Rtrigo_def.v b/theories/Reals/Rtrigo_def.v
index 0d2a9a8bac..b46df202e2 100644
--- a/theories/Reals/Rtrigo_def.v
+++ b/theories/Reals/Rtrigo_def.v
@@ -157,7 +157,7 @@ Proof.
apply Rinv_0_lt_compat; assumption.
rewrite H3 in H0; assumption.
apply lt_le_trans with 1%nat; [ apply lt_O_Sn | apply le_max_r ].
- apply le_IZR; replace (IZR 0) with 0; [ idtac | reflexivity ]; left;
+ apply le_IZR; left;
apply Rlt_trans with (/ eps);
[ apply Rinv_0_lt_compat; assumption | assumption ].
assert (H0 := archimed (/ eps)).
@@ -194,30 +194,27 @@ Proof.
elim H1; intros; assumption.
apply lt_le_trans with (S n).
unfold ge in H2; apply le_lt_n_Sm; assumption.
- replace (2 * n + 1)%nat with (S (2 * n)); [ idtac | ring ].
+ replace (2 * n + 1)%nat with (S (2 * n)) by ring.
apply le_n_S; apply le_n_2n.
apply Rmult_lt_reg_l with (INR (2 * S n)).
apply lt_INR_0; replace (2 * S n)%nat with (S (S (2 * n))).
apply lt_O_Sn.
- replace (S n) with (n + 1)%nat; [ idtac | ring ].
+ replace (S n) with (n + 1)%nat by ring.
ring.
rewrite <- Rinv_r_sym.
- rewrite Rmult_1_r; replace 1 with (INR 1); [ apply lt_INR | reflexivity ].
+ rewrite Rmult_1_r.
+ apply (lt_INR 1).
replace (2 * S n)%nat with (S (S (2 * n))).
apply lt_n_S; apply lt_O_Sn.
- replace (S n) with (n + 1)%nat; [ ring | ring ].
+ ring.
apply not_O_INR; discriminate.
apply not_O_INR; discriminate.
replace (2 * n + 1)%nat with (S (2 * n));
[ apply not_O_INR; discriminate | ring ].
apply Rle_ge; left; apply Rinv_0_lt_compat.
apply lt_INR_0.
- replace (2 * S n * (2 * n + 1))%nat with (S (S (4 * (n * n) + 6 * n))).
+ replace (2 * S n * (2 * n + 1))%nat with (2 + (4 * (n * n) + 6 * n))%nat by ring.
apply lt_O_Sn.
- apply INR_eq.
- repeat rewrite S_INR; rewrite plus_INR; repeat rewrite mult_INR;
- rewrite plus_INR; rewrite mult_INR; repeat rewrite S_INR;
- replace (INR 0) with 0; [ ring | reflexivity ].
Qed.
Lemma cosn_no_R0 : forall n:nat, cos_n n <> 0.
@@ -318,28 +315,25 @@ Proof.
elim H1; intros; assumption.
apply lt_le_trans with (S n).
unfold ge in H2; apply le_lt_n_Sm; assumption.
- replace (2 * S n + 1)%nat with (S (2 * S n)); [ idtac | ring ].
+ replace (2 * S n + 1)%nat with (S (2 * S n)) by ring.
apply le_S; apply le_n_2n.
apply Rmult_lt_reg_l with (INR (2 * S n)).
apply lt_INR_0; replace (2 * S n)%nat with (S (S (2 * n)));
- [ apply lt_O_Sn | replace (S n) with (n + 1)%nat; [ idtac | ring ]; ring ].
+ [ apply lt_O_Sn | ring ].
rewrite <- Rinv_r_sym.
- rewrite Rmult_1_r; replace 1 with (INR 1); [ apply lt_INR | reflexivity ].
+ rewrite Rmult_1_r.
+ apply (lt_INR 1).
replace (2 * S n)%nat with (S (S (2 * n))).
apply lt_n_S; apply lt_O_Sn.
- replace (S n) with (n + 1)%nat; [ ring | ring ].
+ ring.
apply not_O_INR; discriminate.
apply not_O_INR; discriminate.
apply not_O_INR; discriminate.
- left; change (0 < / INR ((2 * S n + 1) * (2 * S n)));
- apply Rinv_0_lt_compat.
+ left; apply Rinv_0_lt_compat.
apply lt_INR_0.
replace ((2 * S n + 1) * (2 * S n))%nat with
- (S (S (S (S (S (S (4 * (n * n) + 10 * n))))))).
+ (6 + (4 * (n * n) + 10 * n))%nat by ring.
apply lt_O_Sn.
- apply INR_eq; repeat rewrite S_INR; rewrite plus_INR; repeat rewrite mult_INR;
- rewrite plus_INR; rewrite mult_INR; repeat rewrite S_INR;
- replace (INR 0) with 0; [ ring | reflexivity ].
Qed.
Lemma sin_no_R0 : forall n:nat, sin_n n <> 0.
diff --git a/theories/Reals/Rtrigo_reg.v b/theories/Reals/Rtrigo_reg.v
index eed612d94b..d9c18d3587 100644
--- a/theories/Reals/Rtrigo_reg.v
+++ b/theories/Reals/Rtrigo_reg.v
@@ -251,6 +251,7 @@ Proof.
exists delta; intros.
rewrite Rplus_0_l; replace (cos h - cos 0) with (-2 * Rsqr (sin (h / 2))).
unfold Rminus; rewrite Ropp_0; rewrite Rplus_0_r.
+ change (-2) with (-(2)).
unfold Rdiv; do 2 rewrite Ropp_mult_distr_l_reverse.
rewrite Rabs_Ropp.
replace (2 * Rsqr (sin (h * / 2)) * / h) with
@@ -266,7 +267,7 @@ Proof.
apply Rabs_pos.
assert (H9 := SIN_bound (h / 2)).
unfold Rabs; case (Rcase_abs (sin (h / 2))); intro.
- pattern 1 at 3; rewrite <- (Ropp_involutive 1).
+ rewrite <- (Ropp_involutive 1).
apply Ropp_le_contravar.
elim H9; intros; assumption.
elim H9; intros; assumption.
@@ -395,15 +396,8 @@ Proof.
apply Rlt_le_trans with alp.
apply H7.
unfold alp; apply Rmin_l.
- rewrite sin_plus; unfold Rminus, Rdiv;
- repeat rewrite Rmult_plus_distr_r; repeat rewrite Rmult_plus_distr_l;
- repeat rewrite Rmult_assoc; repeat rewrite Rplus_assoc;
- apply Rplus_eq_compat_l.
- rewrite (Rplus_comm (sin x * (-1 * / h))); repeat rewrite Rplus_assoc;
- apply Rplus_eq_compat_l.
- rewrite Ropp_mult_distr_r_reverse; rewrite Ropp_mult_distr_l_reverse;
- rewrite Rmult_1_r; rewrite Rmult_1_l; rewrite Ropp_mult_distr_r_reverse;
- rewrite <- Ropp_mult_distr_l_reverse; apply Rplus_comm.
+ rewrite sin_plus.
+ now field.
unfold alp; unfold Rmin; case (Rle_dec alp1 alp2); intro.
apply (cond_pos alp1).
apply (cond_pos alp2).
diff --git a/theories/Reals/SeqProp.v b/theories/Reals/SeqProp.v
index 5a2a07c42d..3697999f70 100644
--- a/theories/Reals/SeqProp.v
+++ b/theories/Reals/SeqProp.v
@@ -1167,7 +1167,7 @@ Proof.
assert (H6 := archimed (Rabs x)); fold M in H6; elim H6; intros.
rewrite H4 in H7; rewrite <- INR_IZR_INZ in H7.
simpl in H7; elim (Rlt_irrefl _ (Rlt_trans _ _ _ H2 H7)).
- replace 1 with (INR 1); [ apply le_INR | reflexivity ]; apply le_n_S;
+ apply (le_INR 1); apply le_n_S;
apply le_O_n.
apply le_IZR; simpl; left; apply Rlt_trans with (Rabs x).
assumption.
diff --git a/theories/Reals/Sqrt_reg.v b/theories/Reals/Sqrt_reg.v
index d43baee8cd..12d5cbbf0f 100644
--- a/theories/Reals/Sqrt_reg.v
+++ b/theories/Reals/Sqrt_reg.v
@@ -21,6 +21,7 @@ Proof.
destruct (total_order_T h 0) as [[Hlt|Heq]|Hgt].
repeat rewrite Rabs_left.
unfold Rminus; do 2 rewrite <- (Rplus_comm (-1)).
+ change (-1) with (-(1)).
do 2 rewrite Ropp_plus_distr; rewrite Ropp_involutive;
apply Rplus_le_compat_l.
apply Ropp_le_contravar; apply sqrt_le_1.
diff --git a/theories/Vectors/VectorDef.v b/theories/Vectors/VectorDef.v
index 1f8b76cb62..c494517766 100644
--- a/theories/Vectors/VectorDef.v
+++ b/theories/Vectors/VectorDef.v
@@ -147,6 +147,16 @@ Definition shiftrepeat {A} := @rectS _ (fun n _ => t A (S (S n)))
(fun h => h :: h :: []) (fun h _ _ H => h :: H).
Global Arguments shiftrepeat {A} {n} v.
+(** Take first [p] elements of a vector *)
+Fixpoint take {A} {n} (p:nat) (le:p <= n) (v:t A n) : t A p :=
+ match p as p return p <= n -> t A p with
+ | 0 => fun _ => []
+ | S p' => match v in t _ n return S p' <= n -> t A (S p') with
+ | []=> fun le => False_rect _ (Nat.nle_succ_0 p' le)
+ | x::xs => fun le => x::take p' (le_S_n p' _ le) xs
+ end
+ end le.
+
(** Remove [p] last elements of a vector *)
Lemma trunc : forall {A} {n} (p:nat), n > p -> t A n
-> t A (n - p).
diff --git a/theories/Vectors/VectorSpec.v b/theories/Vectors/VectorSpec.v
index c5278b918f..869d0fb5af 100644
--- a/theories/Vectors/VectorSpec.v
+++ b/theories/Vectors/VectorSpec.v
@@ -122,3 +122,32 @@ induction l.
- reflexivity.
- unfold to_list; simpl. now f_equal.
Qed.
+
+Lemma take_O : forall {A} {n} le (v:t A n), take 0 le v = [].
+Proof.
+ reflexivity.
+Qed.
+
+Lemma take_idem : forall {A} p n (v:t A n) le le',
+ take p le' (take p le v) = take p le v.
+Proof.
+ induction p; intros n v le le'.
+ - auto.
+ - destruct v. inversion le. simpl. apply f_equal. apply IHp.
+Qed.
+
+Lemma take_app : forall {A} {n} (v:t A n) {m} (w:t A m) le, take n le (append v w) = v.
+Proof.
+ induction v; intros m w le.
+ - reflexivity.
+ - simpl. apply f_equal. apply IHv.
+Qed.
+
+(* Proof is irrelevant for [take] *)
+Lemma take_prf_irr : forall {A} p {n} (v:t A n) le le', take p le v = take p le' v.
+Proof.
+ induction p; intros n v le le'.
+ - reflexivity.
+ - destruct v. inversion le. simpl. apply f_equal. apply IHp.
+Qed.
+
diff --git a/tools/coq_makefile.ml b/tools/coq_makefile.ml
index 4842a89151..22b1408c0b 100644
--- a/tools/coq_makefile.ml
+++ b/tools/coq_makefile.ml
@@ -125,12 +125,9 @@ 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
+ else ldir
in
- for i = 0 to le - 1 do
- if pdir.[i] = '.' then pdir.[i] <- '/';
- done;
- pdir
+ String.map (fun c -> if c = '.' then '/' else c) pdir
let standard opt =
print "byte:\n";
@@ -524,10 +521,10 @@ let variables is_install opt (args,defs) =
List.iter (fun c -> print " \\
-I \"$(COQLIB)/"; print c; print "\"") Coq_config.plugins_dirs; print "\n";
print "ZFLAGS=$(OCAMLLIBS) $(COQSRCLIBS) -I $(CAMLP4LIB)\n\n";
- print "CAMLC?=$(OCAMLFIND) ocamlc -c -rectypes -thread\n";
- print "CAMLOPTC?=$(OCAMLFIND) opt -c -rectypes -thread\n";
- print "CAMLLINK?=$(OCAMLFIND) ocamlc -rectypes -thread\n";
- print "CAMLOPTLINK?=$(OCAMLFIND) opt -rectypes -thread\n";
+ print "CAMLC?=$(OCAMLFIND) ocamlc -c -rectypes -thread -safe-string\n";
+ print "CAMLOPTC?=$(OCAMLFIND) opt -c -rectypes -thread -safe-string\n";
+ print "CAMLLINK?=$(OCAMLFIND) ocamlc -rectypes -thread -safe-string\n";
+ print "CAMLOPTLINK?=$(OCAMLFIND) opt -rectypes -thread -safe-string\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";
@@ -676,6 +673,7 @@ let main_targets vfiles (mlifiles,ml4files,mlfiles,mllibfiles,mlpackfiles) other
print "VO=vo\n";
print "VOFILES:=$(VFILES:.v=.$(VO))\n";
classify_files_by_root "VOFILES" l inc;
+ classify_files_by_root "VFILES" l inc;
print "GLOBFILES:=$(VFILES:.v=.glob)\n";
print "GFILES:=$(VFILES:.v=.g)\n";
print "HTMLFILES:=$(VFILES:.v=.html)\n";
@@ -767,9 +765,9 @@ let main_targets vfiles (mlifiles,ml4files,mlfiles,mllibfiles,mlpackfiles) other
begin
print "mlihtml: $(MLIFILES:.mli=.cmi)\n";
print "\t mkdir $@ || rm -rf $@/*\n";
- print "\t$(OCAMLFIND) ocamldoc -html -rectypes -d $@ -m A $(ZDEBUG) $(ZFLAGS) $(^:.cmi=.mli)\n\n";
+ print "\t$(OCAMLFIND) ocamldoc -html -safe-string -rectypes -d $@ -m A $(ZDEBUG) $(ZFLAGS) $(^:.cmi=.mli)\n\n";
print "all-mli.tex: $(MLIFILES:.mli=.cmi)\n";
- print "\t$(OCAMLFIND) ocamldoc -latex -rectypes -o $@ -m A $(ZDEBUG) $(ZFLAGS) $(^:.cmi=.mli)\n\n";
+ print "\t$(OCAMLFIND) ocamldoc -latex -safe-string -rectypes -o $@ -m A $(ZDEBUG) $(ZFLAGS) $(^:.cmi=.mli)\n\n";
end;
if !some_vfile then
begin
@@ -885,7 +883,7 @@ let check_overlapping_include (_,inc_i,inc_r) =
*)
let merlin targets (ml_inc,_,_) =
print ".merlin:\n";
- print "\t@echo 'FLG -rectypes' > .merlin\n" ;
+ print "\t@echo 'FLG -rectypes -safe-string' > .merlin\n" ;
List.iter (fun c ->
printf "\t@echo \"B $(COQLIB)%s\" >> .merlin\n" c)
lib_dirs ;
diff --git a/tools/coqdoc/alpha.ml b/tools/coqdoc/alpha.ml
index f817ed5a2a..3d92c9356b 100644
--- a/tools/coqdoc/alpha.ml
+++ b/tools/coqdoc/alpha.ml
@@ -26,12 +26,7 @@ let norm_char c =
if !latin1 then norm_char_latin1 c else
Char.uppercase c
-let norm_string s =
- let u = String.copy s in
- for i = 0 to String.length s - 1 do
- u.[i] <- norm_char s.[i]
- done;
- u
+let norm_string = String.map (fun s -> norm_char s)
let compare_char c1 c2 = match norm_char c1, norm_char c2 with
| ('A'..'Z' as c1), ('A'..'Z' as c2) -> compare c1 c2
diff --git a/tools/coqdoc/index.ml b/tools/coqdoc/index.ml
index 9be791a8de..34108eff42 100644
--- a/tools/coqdoc/index.ml
+++ b/tools/coqdoc/index.ml
@@ -197,7 +197,7 @@ let prepare_entry s = function
let h = try String.index_from s 0 ':' with _ -> err () in
let i = try String.index_from s (h+1) ':' with _ -> err () in
let sc = String.sub s (h+1) (i-h-1) in
- let ntn = String.make (String.length s - i) ' ' in
+ let ntn = Bytes.make (String.length s - i) ' ' in
let k = ref 0 in
let j = ref (i+1) in
let quoted = ref false in
@@ -205,22 +205,22 @@ let prepare_entry s = function
while !j <= l do
if not !quoted then begin
(match s.[!j] with
- | '_' -> ntn.[!k] <- ' '; incr k
- | 'x' -> ntn.[!k] <- '_'; incr k
+ | '_' -> Bytes.set ntn !k ' '; incr k
+ | 'x' -> Bytes.set ntn !k '_'; incr k
| '\'' -> quoted := true
| _ -> assert false)
end
else
if s.[!j] = '\'' then
if (!j = l || s.[!j+1] = '_') then quoted := false
- else (incr j; ntn.[!k] <- s.[!j]; incr k)
+ else (incr j; Bytes.set ntn !k s.[!j]; incr k)
else begin
- ntn.[!k] <- s.[!j];
+ Bytes.set ntn !k s.[!j];
incr k
end;
incr j
done;
- let ntn = String.sub ntn 0 !k in
+ let ntn = Bytes.sub_string ntn 0 !k in
if sc = "" then ntn else ntn ^ " (" ^ sc ^ ")"
| _ ->
s
diff --git a/tools/coqworkmgr.ml b/tools/coqworkmgr.ml
index d7bdf907a2..b8e69d6c6d 100644
--- a/tools/coqworkmgr.ml
+++ b/tools/coqworkmgr.ml
@@ -72,10 +72,13 @@ let really_read_fd fd s off len =
let raw_input_line fd =
try
let b = Buffer.create 80 in
- let s = String.make 1 '\000' in
- while s <> "\n" do
+ let s = Bytes.make 1 '\000' in
+ let endl = Bytes.of_string "\n" in
+ let endr = Bytes.of_string "\r" in
+ while Bytes.compare s endl <> 0 do
really_read_fd fd s 0 1;
- if s <> "\n" && s <> "\r" then Buffer.add_string b s;
+ if Bytes.compare s endl <> 0 && Bytes.compare s endr <> 0
+ then Buffer.add_bytes b s;
done;
Buffer.contents b
with Unix.Unix_error _ -> raise End_of_file
diff --git a/tools/fake_ide.ml b/tools/fake_ide.ml
index 8fcca535d1..932097607b 100644
--- a/tools/fake_ide.ml
+++ b/tools/fake_ide.ml
@@ -12,24 +12,15 @@ let error s =
prerr_endline ("fake_id: error: "^s);
exit 1
+let pperr_endline pp = Format.eprintf "@[%a@]\n%!" Pp.pp_with pp
+
type coqtop = {
xml_printer : Xml_printer.t;
xml_parser : Xml_parser.t;
}
-let print_xml chan xml =
- let rec print = function
- | Xml_datatype.PCData s -> output_string chan s
- | Xml_datatype.Element (_, _, children) -> List.iter print children
- in
- print xml
-
-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 (Richpp.repr content)
+let print_error msg =
+ Format.eprintf "fake_id: error: @[%a@]\n%!" Pp.pp_with msg
let base_eval_call ?(print=true) ?(fail=true) call coqtop =
if print then prerr_endline (Xmlprotocol.pr_call call);
@@ -37,20 +28,15 @@ 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
- match Xmlprotocol.is_message xml with
- | Some (level, _loc, content) ->
- logger level content;
+ if Xmlprotocol.is_feedback xml then
loop ()
- | None ->
- if Xmlprotocol.is_feedback xml then
- loop ()
- else Xmlprotocol.to_answer call xml
+ else Xmlprotocol.to_answer call xml
in
let res = loop () in
if print then prerr_endline (Xmlprotocol.pr_full_value call res);
match res with
- | Interface.Fail (_,_,s) when fail -> error_xml (Richpp.repr s)
- | Interface.Fail (_,_,s) as x -> Printf.eprintf "%a\n%!" print_xml (Richpp.repr s); x
+ | Interface.Fail (_,_,s) when fail -> print_error s; exit 1
+ | Interface.Fail (_,_,s) as x -> print_error s; x
| x -> x
let eval_call c q = ignore(base_eval_call c q)
@@ -186,7 +172,7 @@ let print_document () =
Str.global_replace (Str.regexp "^[\n ]*") ""
(if String.length s > 20 then String.sub s 0 17 ^ "..."
else s) in
- prerr_endline (Pp.string_of_ppcmds
+ pperr_endline (
(Document.print doc
(fun b state_id { name; text } ->
Pp.str (Printf.sprintf "%s[%10s, %3s] %s"
@@ -199,7 +185,7 @@ let print_document () =
module GUILogic = struct
let after_add = function
- | Interface.Fail (_,_,s) -> error_xml (Richpp.repr s)
+ | Interface.Fail (_,_,s) -> print_error s; exit 1
| Interface.Good (id, (Util.Inl (), _)) ->
Document.assign_tip_id doc id
| Interface.Good (id, (Util.Inr tip, _)) ->
@@ -211,7 +197,7 @@ module GUILogic = struct
let at id id' _ = Stateid.equal id' id
let after_edit_at (id,need_unfocus) = function
- | Interface.Fail (_,_,s) -> error_xml (Richpp.repr s)
+ | Interface.Fail (_,_,s) -> print_error s; exit 1
| Interface.Good (Util.Inl ()) ->
if need_unfocus then Document.unfocus doc;
ignore(Document.cut_at doc id);
@@ -310,11 +296,12 @@ let main =
Sys.set_signal Sys.sigpipe
(Sys.Signal_handle
(fun _ -> prerr_endline "Broken Pipe (coqtop died ?)"; exit 1));
+ let def_args = ["--xml_format=Ppcmds"; "-ideslave"] in
let coqtop_name, coqtop_args, input_file = match Sys.argv with
- | [| _; f |] -> "coqtop",[|"-ideslave"|], f
+ | [| _; f |] -> "coqtop", Array.of_list def_args, f
| [| _; f; ct |] ->
let ct = Str.split (Str.regexp " ") ct in
- List.hd ct, Array.of_list ("-ideslave" :: List.tl ct), f
+ List.hd ct, Array.of_list (def_args @ List.tl ct), f
| _ -> usage () in
let inc = if input_file = "-" then stdin else open_in input_file in
let coq =
@@ -334,7 +321,7 @@ let main =
let finish () =
match base_eval_call (Xmlprotocol.status true) coq with
| Interface.Good _ -> exit 0
- | Interface.Fail (_,_,s) -> error_xml (Richpp.repr s) in
+ | Interface.Fail (_,_,s) -> print_error s; exit 1 in
(* The main loop *)
init ();
while true do
diff --git a/toplevel/coqloop.ml b/toplevel/coqloop.ml
index e9771cfa40..8e6f9ffb59 100644
--- a/toplevel/coqloop.ml
+++ b/toplevel/coqloop.ml
@@ -13,14 +13,15 @@ open Flags
open Vernac
open Pcoq
-let top_stderr x = msg_with ~pp_tag:Ppstyle.pp_tag !Pp_control.err_ft x
+let top_stderr x =
+ Format.fprintf !Topfmt.err_ft "@[%a@]%!" pp_with x
(* A buffer for the character read from a channel. We store the command
* entered to be able to report errors without pretty-printing. *)
type input_buffer = {
mutable prompt : unit -> string;
- mutable str : string; (* buffer of already read characters *)
+ mutable str : Bytes.t; (* buffer of already read characters *)
mutable len : int; (* number of chars in the buffer *)
mutable bols : int list; (* offsets in str of beginning of lines *)
mutable tokens : Gram.coq_parsable; (* stream of tokens *)
@@ -28,9 +29,9 @@ type input_buffer = {
(* Double the size of the buffer. *)
-let resize_buffer ibuf =
- let nstr = String.create (2 * String.length ibuf.str + 1) in
- String.blit ibuf.str 0 nstr 0 (String.length ibuf.str);
+let resize_buffer ibuf = let open Bytes in
+ let nstr = create (2 * length ibuf.str + 1) in
+ blit ibuf.str 0 nstr 0 (length ibuf.str);
ibuf.str <- nstr
(* Delete all irrelevant lines of the input buffer. Keep the last line
@@ -40,7 +41,7 @@ let resynch_buffer ibuf =
match ibuf.bols with
| ll::_ ->
let new_len = ibuf.len - ll in
- String.blit ibuf.str ll ibuf.str 0 new_len;
+ Bytes.blit ibuf.str ll ibuf.str 0 new_len;
ibuf.len <- new_len;
ibuf.bols <- [];
ibuf.start <- ibuf.start + ll
@@ -51,7 +52,6 @@ let resynch_buffer ibuf =
to avoid interfering with utf8. Compatibility code removed. *)
let emacs_prompt_startstring() = Printer.emacs_str "<prompt>"
-
let emacs_prompt_endstring() = Printer.emacs_str "</prompt>"
(* Read a char in an input channel, displaying a prompt at every
@@ -65,8 +65,8 @@ let prompt_char ic ibuf count =
try
let c = input_char ic in
if c == '\n' then ibuf.bols <- (ibuf.len+1) :: ibuf.bols;
- if ibuf.len == String.length ibuf.str then resize_buffer ibuf;
- ibuf.str.[ibuf.len] <- c;
+ if ibuf.len == Bytes.length ibuf.str then resize_buffer ibuf;
+ Bytes.set ibuf.str ibuf.len c;
ibuf.len <- ibuf.len + 1;
Some c
with End_of_file ->
@@ -75,13 +75,14 @@ let prompt_char ic ibuf count =
(* Reinitialize the char stream (after a Drop) *)
let reset_input_buffer ic ibuf =
- ibuf.str <- "";
+ ibuf.str <- Bytes.empty;
ibuf.len <- 0;
ibuf.bols <- [];
ibuf.tokens <- Gram.parsable (Stream.from (prompt_char ic ibuf));
ibuf.start <- 0
(* Functions to print underlined locations from an input buffer. *)
+module TopErr = struct
(* Given a location, returns the list of locations of each line. The last
line is returned separately. It also checks the location bounds. *)
@@ -109,65 +110,96 @@ let dotted_location (b,e) =
else
(String.make (e-b-1) '.', " ")
-let blanch_utf8_string s bp ep =
- let s' = String.make (ep-bp) ' ' in
+let blanch_utf8_string s bp ep = let open Bytes in
+ let s' = make (ep-bp) ' ' in
let j = ref 0 in
for i = bp to ep - 1 do
- let n = Char.code s.[i] in
+ let n = Char.code (get s i) in
(* Heuristic: assume utf-8 chars are printed using a single
fixed-size char and therefore contract all utf-8 code into one
space; in any case, preserve tabulation so
that its effective interpretation in terms of spacing is preserved *)
- if s.[i] == '\t' then s'.[!j] <- '\t';
+ if get s i == '\t' then set s' !j '\t';
if n < 0x80 || 0xC0 <= n then incr j
done;
- String.sub s' 0 !j
+ Bytes.sub_string s' 0 !j
+
+let adjust_loc_buf ib loc = let open Loc in
+ { loc with ep = loc.ep - ib.start; bp = loc.bp - ib.start }
let print_highlight_location ib loc =
let (bp,ep) = Loc.unloc loc in
- let bp = bp - ib.start
- and ep = ep - ib.start in
let highlight_lines =
match get_bols_of_loc ib (bp,ep) with
| ([],(bl,el)) ->
let shift = blanch_utf8_string ib.str bl bp in
let span = String.length (blanch_utf8_string ib.str bp ep) in
- (str"> " ++ str(String.sub ib.str bl (el-bl-1)) ++ fnl () ++
+ (str"> " ++ str(Bytes.sub_string ib.str bl (el-bl-1)) ++ fnl () ++
str"> " ++ str(shift) ++ str(String.make span '^'))
| ((b1,e1)::ml,(bn,en)) ->
let (d1,s1) = dotted_location (b1,bp) in
let (dn,sn) = dotted_location (ep,en) in
let l1 = (str"> " ++ str d1 ++ str s1 ++
- str(String.sub ib.str bp (e1-bp))) in
+ str(Bytes.sub_string ib.str bp (e1-bp))) in
let li =
prlist (fun (bi,ei) ->
- (str"> " ++ str(String.sub ib.str bi (ei-bi)))) ml in
- let ln = (str"> " ++ str(String.sub ib.str bn (ep-bn)) ++
+ (str"> " ++ str(Bytes.sub_string ib.str bi (ei-bi)))) ml in
+ let ln = (str"> " ++ str(Bytes.sub_string ib.str bn (ep-bn)) ++
str sn ++ str dn) in
(l1 ++ li ++ ln)
in
- let loc = Loc.make_loc (bp,ep) in
- (Pp.pr_loc loc ++ highlight_lines ++ fnl ())
-
-(* Functions to report located errors in a file. *)
-
-let print_location_in_file loc =
- let fname = loc.Loc.fname in
- let errstrm = str"Error while reading " ++ str fname in
- if Loc.is_ghost loc then
- hov 1 (errstrm ++ spc() ++ str" (unknown location):") ++ fnl ()
- else
- let errstrm = mt ()
- (* if String.equal outer_fname fname then mt() else errstrm ++ str":" ++ fnl() *)
- in
- let open Loc in
- hov 0 (* No line break so as to follow emacs error message format *)
- (errstrm ++ Pp.pr_loc loc)
+ highlight_lines
let valid_buffer_loc ib loc =
not (Loc.is_ghost loc) &&
let (b,e) = Loc.unloc loc in b-ib.start >= 0 && e-ib.start < ib.len && b<=e
+(* This is specific to the toplevel *)
+let pr_loc loc =
+ if Loc.is_ghost loc then str"<unknown>"
+ else
+ let fname = loc.Loc.fname in
+ if CString.equal fname "" then
+ Loc.(str"Toplevel input, characters " ++ int loc.bp ++
+ str"-" ++ int loc.ep ++ str":")
+ else
+ Loc.(str"File " ++ str "\"" ++ str fname ++ str "\"" ++
+ str", line " ++ int loc.line_nb ++ str", characters " ++
+ int (loc.bp-loc.bol_pos) ++ str"-" ++ int (loc.ep-loc.bol_pos) ++
+ str":")
+
+(* Toplevel error explanation. *)
+let error_info_for_buffer ?loc buf =
+ Option.map (fun loc ->
+ let fname = loc.Loc.fname in
+ let hl, loc =
+ (* We are in the toplevel *)
+ if String.equal fname "" then
+ let nloc = adjust_loc_buf buf loc in
+ if valid_buffer_loc buf loc then
+ (fnl () ++ print_highlight_location buf nloc, nloc)
+ (* in the toplevel, but not a valid buffer *)
+ else (mt (), nloc)
+ (* we are in batch mode, don't adjust location *)
+ else (mt (), loc)
+ in pr_loc loc ++ hl
+ ) loc
+
+(* Actual printing routine *)
+let print_error_for_buffer ?loc lvl msg buf =
+ let pre_hdr = error_info_for_buffer ?loc buf in
+ if !Flags.print_emacs
+ then Topfmt.emacs_logger ?pre_hdr lvl msg
+ else Topfmt.std_logger ?pre_hdr lvl msg
+
+let print_toplevel_parse_error (e, info) buf =
+ let loc = Loc.get_loc info in
+ let lvl = Feedback.Error in
+ let msg = CErrors.iprint (e, info) in
+ print_error_for_buffer ?loc lvl msg buf
+
+end
+
(*s The Coq prompt is the name of the focused proof, if any, and "Coq"
otherwise. We trap all exceptions to prevent the error message printing
from cycling. *)
@@ -177,18 +209,6 @@ let make_prompt () =
with Proof_global.NoCurrentProof ->
"Coq < "
-(*let build_pending_list l =
- let pl = ref ">" in
- let l' = ref l in
- let res =
- while List.length !l' > 1 do
- pl := !pl ^ "|" Names.Id.to_string x;
- l':=List.tl !l'
- done in
- let last = try List.hd !l' with _ -> in
- "<"^l'
-*)
-
(* the coq prompt added to the default one when in emacs mode
The prompt contains the current state label [n] (for global
backtracking) and the current proof state [p] (for proof
@@ -220,7 +240,7 @@ let top_buffer =
^ emacs_prompt_endstring()
in
{ prompt = pr;
- str = "";
+ str = Bytes.empty;
len = 0;
bols = [];
tokens = Gram.parsable (Stream.of_list []);
@@ -233,26 +253,6 @@ let set_prompt prompt =
^ prompt ()
^ emacs_prompt_endstring())
-(* The following exceptions need not be located. *)
-
-let locate_exn = function
- | Out_of_memory | Stack_overflow | Sys.Break -> false
- | _ -> true
-
-(* Toplevel error explanation. *)
-
-let print_toplevel_error (e, info) =
- let loc = Option.default Loc.ghost (Loc.get_loc info) in
- let fname = loc.Loc.fname in
- let locmsg =
- if Loc.is_ghost loc || String.equal fname "" then
- if locate_exn e && valid_buffer_loc top_buffer loc then
- print_highlight_location top_buffer loc
- else mt ()
- else print_location_in_file loc
- in
- locmsg ++ CErrors.iprint (e, info)
-
(* Read the input stream until a dot is encountered *)
let parse_to_dot =
let rec dot st = match Compat.get_tok (Stream.next st) with
@@ -281,8 +281,27 @@ let read_sentence input =
with reraise ->
let reraise = CErrors.push reraise in
discard_to_dot ();
+ TopErr.print_toplevel_parse_error reraise top_buffer;
iraise reraise
+(** Coqloop Console feedback handler *)
+let coqloop_feed (fb : Feedback.feedback) = let open Feedback in
+ match fb.contents with
+ | Processed -> ()
+ | Incomplete -> ()
+ | Complete -> ()
+ | ProcessingIn _ -> ()
+ | InProgress _ -> ()
+ | WorkerStatus (_,_) -> ()
+ | AddedAxiom -> ()
+ | GlobRef (_,_,_,_,_) -> ()
+ | GlobDef (_,_,_,_) -> ()
+ | FileDependency (_,_) -> ()
+ | FileLoaded (_,_) -> ()
+ | Custom (_,_,_) -> ()
+ | Message (lvl,loc,msg) ->
+ TopErr.print_error_for_buffer ?loc lvl msg top_buffer
+
(** [do_vernac] reads and executes a toplevel phrase, and print error
messages when an exception is raised, except for the following:
- Drop: kill the Coq toplevel, going down to the Caml toplevel if it exists.
@@ -305,12 +324,13 @@ let do_vernac () =
top_stderr (fnl ()); raise CErrors.Quit
| CErrors.Drop -> (* Last chance *)
if Mltop.is_ocaml_top() then raise CErrors.Drop
- else Feedback.msg_error (str"There is no ML toplevel.")
- | any ->
- let any = CErrors.push any in
- let msg = print_toplevel_error any ++ fnl () in
- pp_with ~pp_tag:Ppstyle.pp_tag !Pp_control.std_ft msg;
- Format.pp_print_flush !Pp_control.std_ft ()
+ else Feedback.msg_error (str "There is no ML toplevel.")
+ (* Exception printing is done now by the feedback listener. *)
+ (* XXX: We need this hack due to the side effects of the exception
+ printer and the reliance of Stm.define on attaching crutial
+ state to exceptions *)
+ | any -> ignore (CErrors.(iprint (push any)))
+
(** Main coq loop : read vernacular expressions until Drop is entered.
Ctrl-C is handled internally as Sys.Break instead of aborting Coq.
@@ -318,22 +338,13 @@ let do_vernac () =
exit the loop are Drop and Quit. Any other exception there indicates
an issue with [print_toplevel_error] above. *)
-(*
-let feed_emacs = function
- | { Interface.id = Interface.State id;
- Interface.content = Interface.GlobRef (_,a,_,c,_) } ->
- prerr_endline ("<info>" ^"<id>"^Stateid.to_string id ^"</id>"
- ^a^" "^c^ "</info>")
- | _ -> ()
-*)
-
(* Flush in a compatible order with 8.5 *)
(* This mimics the semantics of the old Pp.flush_all *)
let loop_flush_all () =
Pervasives.flush stderr;
Pervasives.flush stdout;
- Format.pp_print_flush !Pp_control.std_ft ();
- Format.pp_print_flush !Pp_control.err_ft ()
+ Format.pp_print_flush !Topfmt.std_ft ();
+ Format.pp_print_flush !Topfmt.err_ft ()
let rec loop () =
Sys.catch_break true;
@@ -346,9 +357,9 @@ let rec loop () =
| CErrors.Drop -> ()
| CErrors.Quit -> exit 0
| any ->
- Feedback.msg_error (str"Anomaly: main loop exited with exception: " ++
- str (Printexc.to_string any) ++
- fnl() ++
- str"Please report" ++
- strbrk" at " ++ str Coq_config.wwwbugtracker ++ str ".");
+ Feedback.msg_error (str "Anomaly: main loop exited with exception: " ++
+ str (Printexc.to_string any) ++
+ fnl() ++
+ str"Please report" ++
+ strbrk" at " ++ str Coq_config.wwwbugtracker ++ str ".");
loop ()
diff --git a/toplevel/coqloop.mli b/toplevel/coqloop.mli
index e40353e0f9..8a34ded6d9 100644
--- a/toplevel/coqloop.mli
+++ b/toplevel/coqloop.mli
@@ -15,7 +15,7 @@ open Pp
type input_buffer = {
mutable prompt : unit -> string;
- mutable str : string; (** buffer of already read characters *)
+ mutable str : Bytes.t; (** buffer of already read characters *)
mutable len : int; (** number of chars in the buffer *)
mutable bols : int list; (** offsets in str of begining of lines *)
mutable tokens : Pcoq.Gram.coq_parsable; (** stream of tokens *)
@@ -26,11 +26,8 @@ type input_buffer = {
val top_buffer : input_buffer
val set_prompt : (unit -> string) -> unit
-(** Toplevel error explanation, dealing with locations, Drop, Ctrl-D
- May raise only the following exceptions: [Drop] and [End_of_input],
- meaning we get out of the Coq loop. *)
-
-val print_toplevel_error : Exninfo.iexn -> std_ppcmds
+(** Toplevel feedback printer. *)
+val coqloop_feed : Feedback.feedback -> unit
(** Parse and execute one vernac command. *)
diff --git a/toplevel/coqtop.ml b/toplevel/coqtop.ml
index cc1c44fe31..4968804fde 100644
--- a/toplevel/coqtop.ml
+++ b/toplevel/coqtop.ml
@@ -61,15 +61,15 @@ let init_color () =
match colors with
| None ->
(** Default colors *)
- Feedback.init_color_output ()
+ Topfmt.init_color_output ()
| Some "" ->
(** No color output *)
()
| Some s ->
(** Overwrite all colors *)
- Ppstyle.clear_styles ();
- Ppstyle.parse_config s;
- Feedback.init_color_output ()
+ Topfmt.clear_styles ();
+ Topfmt.parse_color_config s;
+ Topfmt.init_color_output ()
end
let toploop_init = ref begin fun x ->
@@ -78,15 +78,27 @@ let toploop_init = ref begin fun x ->
x
end
-let toploop_run = ref (fun () ->
+(* Feedback received in the init stage, this is different as the STM
+ will not be generally be initialized, thus stateid, etc... may be
+ bogus. For now we just print to the console too *)
+let coqtop_init_feed = Coqloop.coqloop_feed
+
+(* Default toplevel loop *)
+let console_toploop_run () =
+ (* We initialize the console only if we run the toploop_run *)
+ let tl_feed = Feedback.add_feeder Coqloop.coqloop_feed in
if Dumpglob.dump () then begin
if_verbose warning "Dumpglob cannot be used in interactive mode.";
Dumpglob.noglob ()
end;
Coqloop.loop();
+ (* We remove the feeder but it could be ok not to do so *)
+ Feedback.del_feeder tl_feed;
(* Initialise and launch the Ocaml toplevel *)
Coqinit.init_ocaml_path();
- Mltop.ocaml_toploop())
+ Mltop.ocaml_toploop()
+
+let toploop_run = ref console_toploop_run
let output_context = ref false
@@ -122,11 +134,10 @@ let engage () =
let set_batch_mode () = batch_mode := true
let toplevel_default_name = DirPath.make [Id.of_string "Top"]
-let toplevel_name = ref (Some toplevel_default_name)
+let toplevel_name = ref toplevel_default_name
let set_toplevel_name dir =
if DirPath.is_empty dir then error "Need a non empty toplevel module name";
- toplevel_name := Some dir
-let unset_toplevel_name () = toplevel_name := None
+ toplevel_name := dir
let remove_top_ml () = Mltop.remove ()
@@ -228,7 +239,6 @@ let compile_files () =
if !compile_list == [] then ()
else
let init_state = States.freeze ~marshallable:`No in
- Feedback.(add_feeder debug_feeder);
List.iter (fun vf ->
States.unfreeze init_state;
compile_file vf)
@@ -240,7 +250,6 @@ let set_emacs () =
if not (Option.is_empty !toploop) then
error "Flag -emacs is incompatible with a custom toplevel loop";
Flags.print_emacs := true;
- Feedback.(set_logger emacs_logger);
Vernacentries.qed_display_script := false;
color := `OFF
@@ -298,24 +307,16 @@ let usage () =
let print_style_tags () =
let () = init_color () in
- let tags = Ppstyle.dump () in
+ let tags = Topfmt.dump_tags () in
let iter (t, st) =
- let st = match st with Some st -> st | None -> Terminal.make () in
- let opt =
- Terminal.eval st ^
- String.concat "." (Ppstyle.repr t) ^
- Terminal.reset ^ "\n"
- in
+ let opt = Terminal.eval st ^ t ^ Terminal.reset ^ "\n" in
print_string opt
in
- let make (t, st) = match st with
- | None -> None
- | Some st ->
+ let make (t, st) =
let tags = List.map string_of_int (Terminal.repr st) in
- let t = String.concat "." (Ppstyle.repr t) in
- Some (t ^ "=" ^ String.concat ";" tags)
+ (t ^ "=" ^ String.concat ";" tags)
in
- let repr = List.map_filter make tags in
+ let repr = List.map make tags in
let () = Printf.printf "COQ_COLORS=\"%s\"\n" (String.concat ":" repr) in
let () = List.iter iter tags in
flush_all ()
@@ -431,6 +432,13 @@ let get_native_name s =
Nativelib.output_dir; Library.native_name_from_filename s]
with _ -> ""
+(** Prints info which is either an error or an anomaly and then exits
+ with the appropriate error code *)
+let fatal_error info anomaly =
+ let msg = info ++ fnl () in
+ Format.fprintf !Topfmt.err_ft "@[%a@]%!" pp_with msg;
+ exit (if anomaly then 129 else 1)
+
let parse_args arglist =
let args = ref arglist in
let extras = ref [] in
@@ -556,7 +564,6 @@ let parse_args arglist =
if Coq_config.no_native_compiler then
warning "Native compilation was disabled at configure time."
else native_compiler := true
- |"-notop" -> unset_toplevel_name ()
|"-output-context" -> output_context := true
|"-profile-ltac" -> Flags.profile_ltac := true
|"-q" -> no_load_rc ()
@@ -595,13 +602,14 @@ let parse_args arglist =
parse ()
with
| UserError(_, s) as e ->
- if is_empty s then exit 1
+ if ismt s then exit 1
else fatal_error (CErrors.print e) false
| any -> fatal_error (CErrors.print any) (CErrors.is_anomaly any)
let init_toplevel arglist =
init_gc ();
Sys.catch_break false; (* Ctrl-C is fatal during the initialisation *)
+ let init_feeder = Feedback.add_feeder coqtop_init_feed in
Lib.init();
begin
try
@@ -628,7 +636,7 @@ let init_toplevel arglist =
engage ();
if (not !batch_mode || List.is_empty !compile_list)
&& Global.env_is_initial ()
- then Option.iter Declaremods.start_library !toplevel_name;
+ then Declaremods.start_library !toplevel_name;
init_library_roots ();
load_vernac_obj ();
require ();
@@ -645,10 +653,10 @@ let init_toplevel arglist =
flush_all();
let msg =
if !batch_mode then mt ()
- else str "Error during initialization:" ++ fnl ()
+ else str "Error during initialization: " ++ CErrors.iprint any ++ fnl ()
in
let is_anomaly e = CErrors.is_anomaly e || not (CErrors.handled e) in
- fatal_error (msg ++ Coqloop.print_toplevel_error any) (is_anomaly (fst any))
+ fatal_error msg (is_anomaly (fst any))
end;
if !batch_mode then begin
flush_all();
@@ -656,7 +664,8 @@ let init_toplevel arglist =
Feedback.msg_notice (with_option raw_print Prettyp.print_full_pure_context () ++ fnl ());
Profile.print_profile ();
exit 0
- end
+ end;
+ Feedback.del_feeder init_feeder
let start () =
let () = init_toplevel (List.tl (Array.to_list Sys.argv)) in
diff --git a/toplevel/usage.ml b/toplevel/usage.ml
index 38ceacf5ec..66f782ffbe 100644
--- a/toplevel/usage.ml
+++ b/toplevel/usage.ml
@@ -30,7 +30,6 @@ let print_usage_channel co command =
\n -R dir coqdir recursively map physical dir to logical coqdir\
\n -Q dir coqdir map physical dir to logical coqdir\
\n -top coqdir set the toplevel name to be coqdir instead of Top\
-\n -notop set the toplevel name to be the empty logical path\
\n -exclude-dir f exclude subdirectories named f for option -R\
\n\
\n -noinit start without loading the Init library\
diff --git a/toplevel/vernac.ml b/toplevel/vernac.ml
index f914f83b9b..9917a49b42 100644
--- a/toplevel/vernac.ml
+++ b/toplevel/vernac.ml
@@ -108,7 +108,7 @@ let verbose_phrase verbch loc =
let s = Bytes.create len in
seek_in ch (fst loc);
really_input ch s 0 len;
- Feedback.msg_notice (str s)
+ Feedback.msg_notice (str (Bytes.to_string s))
| None -> ()
exception End_of_input
@@ -126,7 +126,7 @@ let chan_beautify = ref stdout
let beautify_suffix = ".beautified"
let set_formatter_translator ch =
- let out s b e = output ch s b e in
+ let out s b e = output_substring ch s b e in
Format.set_formatter_output_functions out (fun () -> flush ch);
Format.set_max_boxes max_int
@@ -143,7 +143,8 @@ let pr_new_syntax_in_context loc chan_beautify ocom =
| None -> mt() in
let after = comment (CLexer.extract_comments (snd loc)) in
if !beautify_file then
- Pp.msg_with !Pp_control.std_ft (hov 0 (before ++ com ++ after))
+ (Pp.pp_with !Topfmt.std_ft (hov 0 (before ++ com ++ after));
+ Format.pp_print_flush !Topfmt.std_ft ())
else
Feedback.msg_info (hov 4 (str"New Syntax:" ++ fnl() ++ (hov 0 com)));
States.unfreeze fs;
@@ -161,13 +162,11 @@ let pr_new_syntax po loc chan_beautify ocom =
let pp_cmd_header loc com =
let shorten s = try (String.sub s 0 30)^"..." with _ -> s in
- let noblank s =
- for i = 0 to Bytes.length s - 1 do
- match s.[i] with
- | ' ' | '\n' | '\t' | '\r' -> s.[i] <- '~'
- | _ -> ()
- done;
- s
+ let noblank s = String.map (fun c ->
+ match c with
+ | ' ' | '\n' | '\t' | '\r' -> '~'
+ | x -> x
+ ) s
in
let (start,stop) = Loc.unloc loc in
let safe_pr_vernac x =
@@ -180,9 +179,10 @@ let pp_cmd_header loc com =
(* This is a special case where we assume we are in console batch mode
and take control of the console.
*)
+(* FIXME *)
let print_cmd_header loc com =
- Pp.pp_with ~pp_tag:Ppstyle.pp_tag !Pp_control.std_ft (pp_cmd_header loc com);
- Format.pp_print_flush !Pp_control.std_ft ()
+ Pp.pp_with !Topfmt.std_ft (pp_cmd_header loc com);
+ Format.pp_print_flush !Topfmt.std_ft ()
let rec interp_vernac po chan_beautify checknav (loc,com) =
let interp = function
@@ -266,9 +266,9 @@ let ensure_bname src tgt =
let src, tgt = Filename.basename src, Filename.basename tgt in
let src, tgt = chop_extension src, 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);
+ Feedback.msg_error (str "Source and target file names must coincide, directories can differ" ++ fnl () ++
+ str "Source: " ++ str src ++ fnl () ++
+ str "Target: " ++ str tgt);
flush_all ();
exit 1
end
diff --git a/vernac/auto_ind_decl.ml b/vernac/auto_ind_decl.ml
index 594f2e9449..6d71601cc5 100644
--- a/vernac/auto_ind_decl.ml
+++ b/vernac/auto_ind_decl.ml
@@ -444,14 +444,14 @@ let do_replace_bl mode bl_scheme_key (ind,u as indu) aavoid narg lft rgt =
with Not_found ->
(* spiwack: the format of this error message should probably
be improved. *)
- let err_msg = string_of_ppcmds
+ let err_msg =
(str "boolean->Leibniz:" ++
str "You have to declare the" ++
str "decidability over " ++
Printer.pr_constr tt1 ++
str " first.")
in
- error err_msg
+ user_err err_msg
in let bl_args =
Array.append (Array.append
(Array.map (fun x -> x) v)
diff --git a/vernac/classes.ml b/vernac/classes.ml
index 6512f3defa..c577fe6e38 100644
--- a/vernac/classes.ml
+++ b/vernac/classes.ml
@@ -334,7 +334,7 @@ let new_instance ?(abstract=false) ?(global=false) ?(refine= !refine_instance) p
the refinement manually.*)
let gls = List.rev (Evd.future_goals evm) in
let evm = Evd.reset_future_goals evm in
- Lemmas.start_proof id kind evm termtype
+ Lemmas.start_proof id ?pl kind evm termtype
(Lemmas.mk_hook
(fun _ -> instance_hook k pri global imps ?hook));
(* spiwack: I don't know what to do with the status here. *)
diff --git a/vernac/classes.mli b/vernac/classes.mli
index d2cb788eae..69ea841582 100644
--- a/vernac/classes.mli
+++ b/vernac/classes.mli
@@ -42,7 +42,7 @@ val new_instance :
?global:bool -> (** Not global by default. *)
?refine:bool -> (** Allow refinement *)
Decl_kinds.polymorphic ->
- local_binder list ->
+ local_binder_expr list ->
typeclass_constraint ->
(bool * constr_expr) option ->
?generalize:bool ->
@@ -63,4 +63,4 @@ val id_of_class : typeclass -> Id.t
(** returns [false] if, for lack of section, it declares an assumption
(unless in a module type). *)
-val context : Decl_kinds.polymorphic -> local_binder list -> bool
+val context : Decl_kinds.polymorphic -> local_binder_expr list -> bool
diff --git a/vernac/command.ml b/vernac/command.ml
index 049f58aa26..6eb7037f84 100644
--- a/vernac/command.ml
+++ b/vernac/command.ml
@@ -55,7 +55,7 @@ let rec under_binders env sigma f n c =
let rec complete_conclusion a cs = function
| CProdN (loc,bl,c) -> CProdN (loc,bl,complete_conclusion a cs c)
- | CLetIn (loc,b,t,c) -> CLetIn (loc,b,t,complete_conclusion a cs c)
+ | CLetIn (loc,na,b,t,c) -> CLetIn (loc,na,b,t,complete_conclusion a cs c)
| CHole (loc, k, _, _) ->
let (has_no_args,name,params) = a in
if not has_no_args then
@@ -81,7 +81,7 @@ let red_constant_entry n ce sigma = function
let Sigma (c, _, _) = redfun.e_redfun env sigma c in
c
in
- { ce with const_entry_body = Future.chain ~greedy:true ~pure:true proof_out
+ { ce with const_entry_body = Future.chain ~pure:true proof_out
(fun ((body,ctx),eff) -> (under_binders env sigma redfun n body,ctx),eff) }
let warn_implicits_in_term =
@@ -139,7 +139,7 @@ let interp_definition pl bl p red_option c ctypopt =
red_constant_entry (Context.Rel.length ctx) ce !evdref red_option, !evdref, pl, imps
let check_definition (ce, evd, _, imps) =
- check_evars_are_solved (Global.env ()) evd (Evd.empty,evd);
+ check_evars_are_solved (Global.env ()) evd Evd.empty;
ce
let warn_local_declaration =
@@ -299,7 +299,7 @@ let do_assumptions_unbound_univs (_, poly, _ as kind) nl l =
((env,ienv),((is_coe,idl),t,imps)))
(env,empty_internalization_env) l
in
- let evd = solve_remaining_evars all_and_fail_flags env !evdref (Evd.empty,!evdref) in
+ let evd = solve_remaining_evars all_and_fail_flags env !evdref Evd.empty in
(* The universe constraints come from the whole telescope. *)
let evd = Evd.nf_constraints evd in
let ctx = Evd.universe_context_set evd in
@@ -370,7 +370,7 @@ type structured_one_inductive_expr = {
}
type structured_inductive_expr =
- local_binder list * structured_one_inductive_expr list
+ local_binder_expr list * structured_one_inductive_expr list
let minductive_message warn = function
| [] -> error "No inductive definition."
@@ -416,7 +416,7 @@ let rec check_anonymous_type ind =
match ind with
| GSort (_, GType []) -> true
| GProd (_, _, _, _, e)
- | GLetIn (_, _, _, e)
+ | GLetIn (_, _, _, _, e)
| GLambda (_, _, _, _, e)
| GApp (_, e, _)
| GCast (_, e, _) -> check_anonymous_type e
@@ -560,10 +560,10 @@ let check_named (loc, na) = match na with
let check_param = function
-| LocalRawDef (na, _) -> check_named na
-| LocalRawAssum (nas, Default _, _) -> List.iter check_named nas
-| LocalRawAssum (nas, Generalized _, _) -> ()
-| LocalPattern _ -> assert false
+| CLocalDef (na, _, _) -> check_named na
+| CLocalAssum (nas, Default _, _) -> List.iter check_named nas
+| CLocalAssum (nas, Generalized _, _) -> ()
+| CLocalPattern _ -> assert false
let interp_mutual_inductive (paramsl,indl) notations poly prv finite =
check_all_names_different indl;
@@ -604,7 +604,7 @@ let interp_mutual_inductive (paramsl,indl) notations poly prv finite =
() in
(* Try further to solve evars, and instantiate them *)
- let sigma = solve_remaining_evars all_and_fail_flags env_params !evdref (Evd.empty,!evdref) in
+ let sigma = solve_remaining_evars all_and_fail_flags env_params !evdref Evd.empty in
evdref := sigma;
(* Compute renewed arities *)
let nf,_ = e_nf_evars_and_universes evdref in
@@ -830,7 +830,7 @@ type structured_fixpoint_expr = {
fix_name : Id.t;
fix_univs : lident list option;
fix_annot : Id.t Loc.located option;
- fix_binders : local_binder list;
+ fix_binders : local_binder_expr list;
fix_body : constr_expr option;
fix_type : constr_expr
}
@@ -1142,7 +1142,7 @@ let interp_recursive isfix fixl notations =
(env,rec_sign,all_universes,evd), (fixnames,fixdefs,fixtypes), List.combine3 fixctxnames fiximps fixannots
let check_recursive isfix env evd (fixnames,fixdefs,_) =
- check_evars_are_solved env evd (Evd.empty,evd);
+ check_evars_are_solved env evd Evd.empty;
if List.for_all Option.has_some fixdefs then begin
let fixdefs = List.map Option.get fixdefs in
check_mutuality env isfix (List.combine fixnames fixdefs)
diff --git a/vernac/command.mli b/vernac/command.mli
index 616afb91f0..bccc22ae92 100644
--- a/vernac/command.mli
+++ b/vernac/command.mli
@@ -32,7 +32,7 @@ val get_declare_definition_hook : unit -> (Safe_typing.private_constants definit
(** {6 Definitions/Let} *)
val interp_definition :
- lident list option -> local_binder list -> polymorphic -> red_expr option -> constr_expr ->
+ lident list option -> local_binder_expr list -> polymorphic -> red_expr option -> constr_expr ->
constr_expr option -> Safe_typing.private_constants definition_entry * Evd.evar_map *
Universes.universe_binders * Impargs.manual_implicits
@@ -41,13 +41,13 @@ val declare_definition : Id.t -> definition_kind ->
Globnames.global_reference Lemmas.declaration_hook -> Globnames.global_reference
val do_definition : Id.t -> definition_kind -> lident list option ->
- local_binder list -> red_expr option -> constr_expr ->
+ local_binder_expr list -> red_expr option -> constr_expr ->
constr_expr option -> unit Lemmas.declaration_hook -> unit
(** {6 Parameters/Assumptions} *)
(* val interp_assumption : env -> evar_map ref -> *)
-(* local_binder list -> constr_expr -> *)
+(* local_binder_expr list -> constr_expr -> *)
(* types Univ.in_universe_context_set * Impargs.manual_implicits *)
(** returns [false] if the assumption is neither local to a section,
@@ -78,7 +78,7 @@ type structured_one_inductive_expr = {
}
type structured_inductive_expr =
- local_binder list * structured_one_inductive_expr list
+ local_binder_expr list * structured_one_inductive_expr list
val extract_mutual_inductive_declaration_components :
(one_inductive_expr * decl_notation list) list ->
@@ -114,7 +114,7 @@ type structured_fixpoint_expr = {
fix_name : Id.t;
fix_univs : lident list option;
fix_annot : Id.t Loc.located option;
- fix_binders : local_binder list;
+ fix_binders : local_binder_expr list;
fix_body : constr_expr option;
fix_type : constr_expr
}
diff --git a/vernac/explainErr.ml b/vernac/explainErr.ml
index 17897460c0..f1e0c48f03 100644
--- a/vernac/explainErr.ml
+++ b/vernac/explainErr.ml
@@ -45,15 +45,9 @@ let _ = CErrors.register_handler explain_exn_default
(** Pre-explain a vernac interpretation error *)
-let wrap_vernac_error with_header (exn, info) strm =
- if with_header then
- let header = Pp.tag (Pp.Tag.inj Ppstyle.error_tag Ppstyle.tag) (str "Error:") in
- let e = EvaluatedError (hov 0 (header ++ spc () ++ strm), None) in
- (e, info)
- else
- (EvaluatedError (strm, None), info)
+let wrap_vernac_error (exn, info) strm = (EvaluatedError (strm, None), info)
-let process_vernac_interp_error with_header exn = match fst exn with
+let process_vernac_interp_error exn = match fst exn with
| Univ.UniverseInconsistency i ->
let msg =
if !Constrextern.print_universes then
@@ -61,40 +55,40 @@ let process_vernac_interp_error with_header exn = match fst exn with
Univ.explain_universe_inconsistency Universes.pr_with_global_universes i
else
mt() in
- wrap_vernac_error with_header exn (str "Universe inconsistency" ++ msg ++ str ".")
+ wrap_vernac_error exn (str "Universe inconsistency" ++ msg ++ str ".")
| TypeError(ctx,te) ->
- wrap_vernac_error with_header exn (Himsg.explain_type_error ctx Evd.empty te)
+ wrap_vernac_error exn (Himsg.explain_type_error ctx Evd.empty te)
| PretypeError(ctx,sigma,te) ->
- wrap_vernac_error with_header exn (Himsg.explain_pretype_error ctx sigma te)
+ wrap_vernac_error exn (Himsg.explain_pretype_error ctx sigma te)
| Typeclasses_errors.TypeClassError(env, te) ->
- wrap_vernac_error with_header exn (Himsg.explain_typeclass_error env te)
+ wrap_vernac_error exn (Himsg.explain_typeclass_error env te)
| InductiveError e ->
- wrap_vernac_error with_header exn (Himsg.explain_inductive_error e)
+ wrap_vernac_error exn (Himsg.explain_inductive_error e)
| Modops.ModuleTypingError e ->
- wrap_vernac_error with_header exn (Himsg.explain_module_error e)
+ wrap_vernac_error exn (Himsg.explain_module_error e)
| Modintern.ModuleInternalizationError e ->
- wrap_vernac_error with_header exn (Himsg.explain_module_internalization_error e)
+ wrap_vernac_error exn (Himsg.explain_module_internalization_error e)
| RecursionSchemeError e ->
- wrap_vernac_error with_header exn (Himsg.explain_recursion_scheme_error e)
+ wrap_vernac_error exn (Himsg.explain_recursion_scheme_error e)
| Cases.PatternMatchingError (env,sigma,e) ->
- wrap_vernac_error with_header exn (Himsg.explain_pattern_matching_error env sigma e)
+ wrap_vernac_error exn (Himsg.explain_pattern_matching_error env sigma e)
| Tacred.ReductionTacticError e ->
- wrap_vernac_error with_header exn (Himsg.explain_reduction_tactic_error e)
+ wrap_vernac_error exn (Himsg.explain_reduction_tactic_error e)
| Logic.RefinerError e ->
- wrap_vernac_error with_header exn (Himsg.explain_refiner_error e)
+ wrap_vernac_error exn (Himsg.explain_refiner_error e)
| Nametab.GlobalizationError q ->
- wrap_vernac_error with_header exn
+ wrap_vernac_error exn
(str "The reference" ++ spc () ++ Libnames.pr_qualid q ++
spc () ++ str "was not found" ++
spc () ++ str "in the current" ++ spc () ++ str "environment.")
| Refiner.FailError (i,s) ->
let s = Lazy.force s in
- wrap_vernac_error with_header exn
+ wrap_vernac_error exn
(str "Tactic failure" ++
- (if Pp.is_empty s then s else str ": " ++ s) ++
+ (if Pp.ismt s then s else str ": " ++ s) ++
if Int.equal i 0 then str "." else str " (level " ++ int i ++ str").")
| AlreadyDeclared msg ->
- wrap_vernac_error with_header exn (msg ++ str ".")
+ wrap_vernac_error exn (msg ++ str ".")
| _ ->
exn
@@ -108,9 +102,9 @@ 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 process_vernac_interp_error ?(allow_uncaught=true) (exc, info) =
let exc = strip_wrapping_exceptions exc in
- let e = process_vernac_interp_error with_header (exc, info) in
+ let e = process_vernac_interp_error (exc, info) in
let () =
if not allow_uncaught && not (CErrors.handled (fst e)) then
let (e, info) = e in
diff --git a/vernac/explainErr.mli b/vernac/explainErr.mli
index a67c887af3..370ad7e3b5 100644
--- a/vernac/explainErr.mli
+++ b/vernac/explainErr.mli
@@ -11,7 +11,7 @@ exception EvaluatedError of Pp.std_ppcmds * exn option
(** Pre-explain a vernac interpretation error *)
-val process_vernac_interp_error : ?allow_uncaught:bool -> ?with_header:bool -> Util.iexn -> Util.iexn
+val process_vernac_interp_error : ?allow_uncaught:bool -> Util.iexn -> Util.iexn
(** General explain function. Should not be used directly now,
see instead function [Errors.print] and variants *)
diff --git a/vernac/lemmas.ml b/vernac/lemmas.ml
index 55f33be399..409676276a 100644
--- a/vernac/lemmas.ml
+++ b/vernac/lemmas.ml
@@ -60,7 +60,7 @@ let adjust_guardness_conditions const = function
(* Try all combinations... not optimal *)
let env = Global.env() in
{ const with const_entry_body =
- Future.chain ~greedy:true ~pure:true const.const_entry_body
+ Future.chain ~pure:true const.const_entry_body
(fun ((body, ctx), eff) ->
match kind_of_term body with
| Fix ((nv,0),(_,_,fixdefs as fixdecls)) ->
@@ -463,7 +463,7 @@ let start_proof_com ?inference_hook kind thms hook =
let t', imps' = interp_type_evars_impls ~impls env evdref t in
let flags = all_and_fail_flags in
let flags = { flags with use_hook = inference_hook } in
- evdref := solve_remaining_evars flags env !evdref (Evd.empty,!evdref);
+ evdref := solve_remaining_evars flags env !evdref Evd.empty;
let ids = List.map RelDecl.get_name ctx in
(compute_proof_name (pi1 kind) sopt,
(nf_evar !evdref (it_mkProd_or_LetIn t' ctx),
diff --git a/vernac/metasyntax.ml b/vernac/metasyntax.ml
index 0aaf6afd7e..7e98d114a3 100644
--- a/vernac/metasyntax.ml
+++ b/vernac/metasyntax.ml
@@ -932,8 +932,8 @@ let find_precedence lev etyps symbols =
let first_symbol =
let rec aux = function
| Break _ :: t -> aux t
- | h :: t -> h
- | [] -> assert false (* rule is known to be productive *) in
+ | h :: t -> Some h
+ | [] -> None in
aux symbols in
let last_is_terminal () =
let rec aux b = function
@@ -943,7 +943,8 @@ let find_precedence lev etyps symbols =
| [] -> b in
aux false symbols in
match first_symbol with
- | NonTerminal x ->
+ | None -> [],0
+ | Some (NonTerminal x) ->
(try match List.assoc x etyps with
| ETConstr _ ->
error "The level of the leftmost non-terminal cannot be changed."
@@ -966,11 +967,11 @@ 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 _ when last_is_terminal () ->
+ | Some (Terminal _) when last_is_terminal () ->
if Option.is_empty lev then
([Feedback.msg_info ?loc:None ,strbrk "Setting notation at level 0."], 0)
else [],Option.get lev
- | _ ->
+ | Some _ ->
if Option.is_empty lev then error "Cannot determine the level.";
[],Option.get lev
@@ -1049,6 +1050,9 @@ let compute_syntax_data df modifiers =
let open SynData in
let open NotationMods in
let mods = interp_modifiers modifiers in
+ let onlyprint = mods.only_printing in
+ let onlyparse = mods.only_parsing in
+ if onlyprint && onlyparse then error "A notation cannot be both 'only printing' and 'only parsing'.";
let assoc = Option.append mods.assoc (Some NonA) in
let toks = split_notation_string df in
let recvars,mainvars,symbols = analyze_notation_tokens toks in
@@ -1058,7 +1062,7 @@ let compute_syntax_data df modifiers =
let ntn_for_interp = make_notation_key symbols in
let symbols' = remove_curly_brackets symbols in
let ntn_for_grammar = make_notation_key symbols' in
- check_rule_productivity symbols';
+ if not onlyprint then check_rule_productivity symbols';
(* Misc *)
let need_squash = not (List.equal Notation.symbol_eq symbols symbols') in
diff --git a/vernac/record.ml b/vernac/record.ml
index b494430c28..288d3391bb 100644
--- a/vernac/record.ml
+++ b/vernac/record.ml
@@ -108,9 +108,9 @@ let typecheck_params_and_fields def id pl t ps nots fs =
| _ -> ()
in
List.iter
- (function LocalRawDef (b, _) -> error default_binder_kind b
- | LocalRawAssum (ls, bk, ce) -> List.iter (error bk) ls
- | LocalPattern (loc,_,_) ->
+ (function CLocalDef (b, _, _) -> error default_binder_kind b
+ | CLocalAssum (ls, bk, ce) -> List.iter (error bk) ls
+ | CLocalPattern (loc,_,_) ->
Loc.raise ~loc (Stream.Error "pattern with quote not allowed in record parameters.")) ps
in
let impls_env, ((env1,newps), imps) = interp_context_evars env0 evars ps in
@@ -141,7 +141,7 @@ let typecheck_params_and_fields def id pl t ps nots fs =
interp_fields_evars env_ar evars impls_env nots (binders_of_decls fs)
in
let sigma =
- Pretyping.solve_remaining_evars Pretyping.all_and_fail_flags env_ar !evars (Evd.empty,!evars) in
+ Pretyping.solve_remaining_evars Pretyping.all_and_fail_flags env_ar !evars Evd.empty in
let evars, nf = Evarutil.nf_evars_and_universes sigma in
let arity = nf t' in
let arity, evars =
diff --git a/vernac/record.mli b/vernac/record.mli
index c50e577860..3fd651db90 100644
--- a/vernac/record.mli
+++ b/vernac/record.mli
@@ -39,7 +39,7 @@ val declare_structure :
val definition_structure :
inductive_kind * Decl_kinds.polymorphic * Decl_kinds.recursivity_kind *
- plident with_coercion * local_binder list *
+ plident with_coercion * local_binder_expr list *
(local_decl_expr with_instance with_priority with_notation) list *
Id.t * constr_expr option -> global_reference
diff --git a/vernac/search.ml b/vernac/search.ml
index e1b56b1319..540573843e 100644
--- a/vernac/search.ml
+++ b/vernac/search.ml
@@ -367,7 +367,7 @@ let interface_search =
let answer = {
coq_object_prefix = prefix;
coq_object_qualid = qualid;
- coq_object_object = string_of_ppcmds (pr_lconstr_env env Evd.empty constr);
+ coq_object_object = constr;
} in
ans := answer :: !ans;
in
diff --git a/vernac/search.mli b/vernac/search.mli
index c9167c485d..82b79f75de 100644
--- a/vernac/search.mli
+++ b/vernac/search.mli
@@ -67,7 +67,7 @@ type 'a coq_object = {
}
val interface_search : ?glnum:int -> (search_constraint * bool) list ->
- string coq_object list
+ constr coq_object list
(** {6 Generic search function} *)
diff --git a/vernac/topfmt.ml b/vernac/topfmt.ml
new file mode 100644
index 0000000000..ee55366927
--- /dev/null
+++ b/vernac/topfmt.ml
@@ -0,0 +1,288 @@
+(************************************************************************)
+(* 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 Feedback
+open Pp
+
+(** Pp control also belongs here as the terminal is private to the toplevel *)
+
+type pp_global_params = {
+ margin : int;
+ max_indent : int;
+ max_depth : int;
+ ellipsis : string }
+
+(* Default parameters of pretty-printing *)
+
+let dflt_gp = {
+ margin = 78;
+ max_indent = 50;
+ max_depth = 50;
+ ellipsis = "..." }
+
+(* A deeper pretty-printer to print proof scripts *)
+
+let deep_gp = {
+ margin = 78;
+ max_indent = 50;
+ max_depth = 10000;
+ ellipsis = "..." }
+
+(* set_gp : Format.formatter -> pp_global_params -> unit
+ * set the parameters of a formatter *)
+
+let set_gp ft gp =
+ Format.pp_set_margin ft gp.margin ;
+ Format.pp_set_max_indent ft gp.max_indent ;
+ Format.pp_set_max_boxes ft gp.max_depth ;
+ Format.pp_set_ellipsis_text ft gp.ellipsis
+
+let set_dflt_gp ft = set_gp ft dflt_gp
+
+let get_gp ft =
+ { margin = Format.pp_get_margin ft ();
+ max_indent = Format.pp_get_max_indent ft ();
+ max_depth = Format.pp_get_max_boxes ft ();
+ ellipsis = Format.pp_get_ellipsis_text ft () }
+
+(* with_fp : 'a pp_formatter_params -> Format.formatter
+ * returns of formatter for given formatter functions *)
+
+let with_fp chan out_function flush_function =
+ let ft = Format.make_formatter out_function flush_function in
+ Format.pp_set_formatter_out_channel ft chan;
+ ft
+
+(* Output on a channel ch *)
+
+let with_output_to ch =
+ let ft = with_fp ch (output_substring ch) (fun () -> flush ch) in
+ set_gp ft deep_gp;
+ ft
+
+let std_ft = ref Format.std_formatter
+let _ = set_dflt_gp !std_ft
+
+let err_ft = ref Format.err_formatter
+let _ = set_gp !err_ft deep_gp
+
+let deep_ft = ref (with_output_to stdout)
+let _ = set_gp !deep_ft deep_gp
+
+(* For parametrization through vernacular *)
+let default = Format.pp_get_max_boxes !std_ft ()
+let default_margin = Format.pp_get_margin !std_ft ()
+
+let get_depth_boxes () = Some (Format.pp_get_max_boxes !std_ft ())
+let set_depth_boxes v =
+ Format.pp_set_max_boxes !std_ft (match v with None -> default | Some v -> v)
+
+let get_margin () = Some (Format.pp_get_margin !std_ft ())
+let set_margin v =
+ let v = match v with None -> default_margin | Some v -> v in
+ Format.pp_set_margin Format.str_formatter v;
+ Format.pp_set_margin !std_ft v;
+ Format.pp_set_margin !deep_ft v;
+ (* Heuristic, based on usage: the column on the right of max_indent
+ column is 20% of width, capped to 30 characters *)
+ let m = max (64 * v / 100) (v-30) in
+ Format.pp_set_max_indent Format.str_formatter m;
+ Format.pp_set_max_indent !std_ft m;
+ Format.pp_set_max_indent !deep_ft m
+
+(** Console display of feedback *)
+
+(** Default tags *)
+module Tag = struct
+
+ let error = "message.error"
+ let warning = "message.warning"
+ let debug = "message.debug"
+
+end
+
+type logger = ?loc:Loc.t -> level -> std_ppcmds -> unit
+
+let msgnl_with ?pre_hdr fmt strm =
+ pp_with fmt (strm ++ fnl ());
+ Format.pp_print_flush fmt ()
+
+(* 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_hdr = tag Tag.debug (str "Debug:") ++ spc ()
+let info_hdr = mt ()
+let warn_hdr = tag Tag.warning (str "Warning:") ++ spc ()
+let err_hdr = tag Tag.error (str "Error:") ++ spc ()
+let ann_hdr = tag Tag.error (str "Anomaly:") ++ spc ()
+
+let make_body quoter info ?pre_hdr s =
+ pr_opt_no_spc (fun x -> x ++ fnl ()) pre_hdr ++ quoter (hov 0 (info ++ s))
+
+(* Generic logger *)
+let gen_logger dbg err ?pre_hdr level msg = match level with
+ | Debug -> msgnl_with !std_ft (make_body dbg dbg_hdr ?pre_hdr msg)
+ | Info -> msgnl_with !std_ft (make_body dbg info_hdr ?pre_hdr msg)
+ | Notice -> msgnl_with !std_ft (make_body dbg info_hdr ?pre_hdr msg)
+ | Warning -> Flags.if_warn (fun () ->
+ msgnl_with !err_ft (make_body err warn_hdr ?pre_hdr msg)) ()
+ | Error -> msgnl_with !err_ft (make_body err err_hdr ?pre_hdr msg)
+
+(** Standard loggers *)
+
+(* We provide a generic clear_log_backend callback for backends
+ wanting to do clenaup after the print.
+*)
+let std_logger_cleanup = ref (fun () -> ())
+
+let std_logger ?pre_hdr level msg =
+ gen_logger (fun x -> x) (fun x -> x) ?pre_hdr level msg;
+ !std_logger_cleanup ()
+
+(** Color logging. Moved from Ppstyle, it may need some more refactoring *)
+
+(* Tag map for terminal style *)
+let default_tag_map () = let open Terminal in [
+ (* Local to console toplevel *)
+ "message.error" , make ~bold:true ~fg_color:`WHITE ~bg_color:`RED ()
+ ; "message.warning" , make ~bold:true ~fg_color:`WHITE ~bg_color:`YELLOW ()
+ ; "message.debug" , make ~bold:true ~fg_color:`WHITE ~bg_color:`MAGENTA ()
+ (* Coming from the printer *)
+ ; "constr.evar" , make ~fg_color:`LIGHT_BLUE ()
+ ; "constr.keyword" , make ~bold:true ()
+ ; "constr.type" , make ~bold:true ~fg_color:`YELLOW ()
+ ; "constr.notation" , make ~fg_color:`WHITE ()
+ (* ["constr"; "variable"] is not assigned *)
+ ; "constr.reference" , make ~fg_color:`LIGHT_GREEN ()
+ ; "constr.path" , make ~fg_color:`LIGHT_MAGENTA ()
+ ; "module.definition", make ~bold:true ~fg_color:`LIGHT_RED ()
+ ; "module.keyword" , make ~bold:true ()
+ ; "tactic.keyword" , make ~bold:true ()
+ ; "tactic.primitive" , make ~fg_color:`LIGHT_GREEN ()
+ ; "tactic.string" , make ~fg_color:`LIGHT_RED ()
+ ]
+
+let tag_map = ref CString.Map.empty
+
+let init_tag_map styles =
+ let set accu (name, st) = CString.Map.add name st accu in
+ tag_map := List.fold_left set !tag_map styles
+
+let clear_styles () =
+ tag_map := CString.Map.empty
+
+let parse_color_config file =
+ let styles = Terminal.parse file in
+ init_tag_map styles
+
+let dump_tags () = CString.Map.bindings !tag_map
+
+(** Not thread-safe. We should put a lock somewhere if we print from
+ different threads. Do we? *)
+let make_style_stack () =
+ (** Default tag is to reset everything *)
+ let empty = Terminal.make () in
+ let default_tag = Terminal.({
+ fg_color = Some `DEFAULT;
+ bg_color = Some `DEFAULT;
+ bold = Some false;
+ italic = Some false;
+ underline = Some false;
+ negative = Some false;
+ })
+ in
+ let style_stack = ref [] in
+ let peek () = match !style_stack with
+ | [] -> default_tag (** Anomalous case, but for robustness *)
+ | st :: _ -> st
+ in
+ let push tag =
+ let style =
+ try CString.Map.find tag !tag_map
+ with | Not_found -> empty
+ in
+ (** Use the merging of the latest tag and the one being currently pushed.
+ This may be useful if for instance the latest tag changes the background and
+ the current one the foreground, so that the two effects are additioned. *)
+ let style = Terminal.merge (peek ()) style in
+ style_stack := style :: !style_stack;
+ Terminal.eval style
+ in
+ let pop _ = match !style_stack with
+ | [] -> (** Something went wrong, we fallback *)
+ Terminal.eval default_tag
+ | _ :: rem -> style_stack := rem;
+ Terminal.eval (peek ())
+ in
+ let clear () = style_stack := [] in
+ push, pop, clear
+
+let init_color_output () =
+ init_tag_map (default_tag_map ());
+ let push_tag, pop_tag, clear_tag = make_style_stack () in
+ std_logger_cleanup := clear_tag;
+ let tag_handler = {
+ Format.mark_open_tag = push_tag;
+ Format.mark_close_tag = pop_tag;
+ Format.print_open_tag = ignore;
+ Format.print_close_tag = ignore;
+ } 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
+
+(* 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
+
+(* Output to file, used only in extraction so a candidate for removal *)
+let ft_logger old_logger ft ?loc level mesg =
+ let id x = x in
+ match level with
+ | Debug -> msgnl_with ft (make_body id dbg_hdr mesg)
+ | Info -> msgnl_with ft (make_body id info_hdr mesg)
+ | Notice -> msgnl_with ft mesg
+ | Warning -> old_logger ?loc level mesg
+ | Error -> old_logger ?loc level mesg
+
+let with_output_to_file fname func input =
+ (* XXX FIXME: redirect std_ft *)
+ (* 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/pp_control.mli b/vernac/topfmt.mli
index d26f89eb30..909dd70775 100644
--- a/lib/pp_control.mli
+++ b/vernac/topfmt.mli
@@ -6,7 +6,7 @@
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
-(** Parameters of pretty-printing. *)
+(** Console printing options *)
type pp_global_params = {
margin : int;
@@ -20,13 +20,12 @@ val set_gp : Format.formatter -> pp_global_params -> unit
val set_dflt_gp : Format.formatter -> unit
val get_gp : Format.formatter -> pp_global_params
-
(** {6 Output functions of pretty-printing. } *)
val with_output_to : out_channel -> Format.formatter
-val std_ft : Format.formatter ref
-val err_ft : Format.formatter ref
+val std_ft : Format.formatter ref
+val err_ft : Format.formatter ref
val deep_ft : Format.formatter ref
(** {6 For parametrization through vernacular. } *)
@@ -36,3 +35,21 @@ val get_depth_boxes : unit -> int option
val set_margin : int option -> unit
val get_margin : unit -> int option
+
+(** Headers for tagging *)
+val err_hdr : Pp.std_ppcmds
+val ann_hdr : Pp.std_ppcmds
+
+(** Console display of feedback, we may add some location information *)
+val std_logger : ?pre_hdr:Pp.std_ppcmds -> Feedback.level -> Pp.std_ppcmds -> unit
+val emacs_logger : ?pre_hdr:Pp.std_ppcmds -> Feedback.level -> Pp.std_ppcmds -> unit
+
+val init_color_output : unit -> unit
+val clear_styles : unit -> unit
+val parse_color_config : string -> unit
+val dump_tags : unit -> (string * Terminal.style) list
+
+(** [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
+
diff --git a/vernac/vernac.mllib b/vernac/vernac.mllib
index 94ef54f70f..283c095eb6 100644
--- a/vernac/vernac.mllib
+++ b/vernac/vernac.mllib
@@ -14,4 +14,5 @@ Record
Assumptions
Vernacinterp
Mltop
+Topfmt
Vernacentries
diff --git a/vernac/vernacentries.ml b/vernac/vernacentries.ml
index 3afe04b37b..ca03ba3f3a 100644
--- a/vernac/vernacentries.ml
+++ b/vernac/vernacentries.ml
@@ -39,8 +39,9 @@ module NamedDecl = Context.Named.Declaration
let (f_interp_redexp, interp_redexp_hook) = Hook.make ()
let debug = false
-let prerr_endline x =
- if debug then prerr_endline (x ()) else ()
+(* XXX Should move to a common library *)
+let vernac_pperr_endline pp =
+ if debug then Format.eprintf "@[%a@]@\n%!" Pp.pp_with (pp ()) else ()
(* Misc *)
@@ -66,8 +67,7 @@ let show_node () =
could, possibly, be cleaned away. (Feb. 2010) *)
()
-let show_thesis () =
- Feedback.msg_error (anomaly (Pp.str "TODO") )
+let show_thesis () = CErrors.anomaly (Pp.str "Show Thesis: TODO")
let show_top_evars () =
(* spiwack: new as of Feb. 2010: shows goal evars in addition to non-goal evars. *)
@@ -1448,8 +1448,8 @@ let _ =
optdepr = false;
optname = "the printing depth";
optkey = ["Printing";"Depth"];
- optread = Pp_control.get_depth_boxes;
- optwrite = Pp_control.set_depth_boxes }
+ optread = Topfmt.get_depth_boxes;
+ optwrite = Topfmt.set_depth_boxes }
let _ =
declare_int_option
@@ -1457,8 +1457,8 @@ let _ =
optdepr = false;
optname = "the printing width";
optkey = ["Printing";"Width"];
- optread = Pp_control.get_margin;
- optwrite = Pp_control.set_margin }
+ optread = Topfmt.get_margin;
+ optwrite = Topfmt.set_margin }
let _ =
declare_bool_option
@@ -1933,7 +1933,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 (fun () -> "interpreting: " ^ Pp.string_of_ppcmds (Ppvernac.pr_vernac c));
+ vernac_pperr_endline (fun () -> str "interpreting: " ++ Ppvernac.pr_vernac c);
match c with
(* The below vernac are candidates for removal from the main type
and to be put into a new doc_command datatype: *)
@@ -2193,7 +2193,7 @@ let with_fail b f =
| e ->
let e = CErrors.push e in
raise (HasFailed (CErrors.iprint
- (ExplainErr.process_vernac_interp_error ~allow_uncaught:false ~with_header:false e))))
+ (ExplainErr.process_vernac_interp_error ~allow_uncaught:false e))))
()
with e when CErrors.noncritical e ->
let (e, _) = CErrors.push e in
@@ -2209,6 +2209,11 @@ let with_fail b f =
let interp ?(verbosely=true) ?proof (loc,c) =
let orig_program_mode = Flags.is_program_mode () in
let rec aux ?locality ?polymorphism isprogcmd = function
+
+ (* This assert case will be removed when fake_ide can understand
+ completion feedback *)
+ | VernacStm _ -> assert false (* Done by Stm *)
+
| VernacProgram c when not isprogcmd -> aux ?locality ?polymorphism true c
| VernacProgram _ -> CErrors.error "Program mode specified twice"
| VernacLocal (b, c) when Option.is_empty locality ->
@@ -2217,16 +2222,13 @@ let interp ?(verbosely=true) ?proof (loc,c) =
aux ?locality ~polymorphism:b isprogcmd c
| VernacPolymorphic (b, c) -> CErrors.error "Polymorphism specified twice"
| VernacLocal _ -> CErrors.error "Locality specified twice"
- | VernacStm (Command c) -> aux ?locality ?polymorphism isprogcmd c
- | VernacStm (PGLast c) -> aux ?locality ?polymorphism isprogcmd c
- | VernacStm _ -> assert false (* Done by Stm *)
| VernacFail v ->
with_fail true (fun () -> aux ?locality ?polymorphism isprogcmd v)
| VernacTimeout (n,v) ->
current_timeout := Some n;
aux ?locality ?polymorphism isprogcmd v
| VernacRedirect (s, (_,v)) ->
- Feedback.with_output_to_file s (aux false) v
+ Topfmt.with_output_to_file s (aux false) v
| VernacTime (_,v) ->
System.with_time !Flags.time
(aux ?locality ?polymorphism isprogcmd) v;