aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitlab-ci.yml2
-rw-r--r--Makefile.build6
-rw-r--r--Makefile.make2
-rwxr-xr-xdev/bench/gitlab.sh3
-rwxr-xr-xdev/build/windows/makecoq_mingw.sh2
-rwxr-xr-xdev/ci/ci-iris.sh4
-rw-r--r--dev/ci/docker/bionic_coq/Dockerfile4
-rw-r--r--dev/ci/user-overlays/12449-SkySkimmer-minim-prop-toset.sh6
-rw-r--r--dev/ci/user-overlays/13088-gares-par-to-tactic.sh6
-rw-r--r--dev/ci/user-overlays/13128-SkySkimmer-noinstance.sh6
-rw-r--r--dev/ci/user-overlays/13143-herbelin-master+drop-misleading-arg-hbox.sh9
-rw-r--r--dev/ci/user-overlays/13166-herbelin-master+fixes13165-missing-impargs-defined-fields.sh6
-rw-r--r--dev/doc/changes.md28
-rw-r--r--doc/changelog/02-specification-language/10331-minim-prop-toset.rst5
-rw-r--r--doc/changelog/02-specification-language/13166-master+fixes13165-missing-impargs-defined-fields.rst5
-rw-r--r--doc/changelog/03-notations/12950-master+reorganization-notations-only-parsing-only-printing.rst10
-rw-r--r--doc/changelog/04-tactics/12648-zify-int63.rst3
-rw-r--r--doc/changelog/09-coqide/12874-show_proof_diffs.rst5
-rw-r--r--doc/sphinx/_static/diffs-show-proof.pngbin0 -> 13641 bytes
-rw-r--r--doc/sphinx/addendum/micromega.rst11
-rw-r--r--doc/sphinx/language/core/inductive.rst2
-rw-r--r--doc/sphinx/language/core/records.rst4
-rw-r--r--doc/sphinx/proof-engine/proof-handling.rst43
-rw-r--r--doc/sphinx/user-extensions/syntax-extensions.rst43
-rw-r--r--doc/stdlib/hidden-files1
-rw-r--r--doc/tools/docgram/common.edit_mlg6
-rw-r--r--doc/tools/docgram/doc_grammar.ml19
-rw-r--r--doc/tools/docgram/fullGrammar2
-rw-r--r--doc/tools/docgram/orderedGrammar6
-rw-r--r--engine/termops.ml12
-rw-r--r--engine/uState.ml6
-rw-r--r--engine/univMinim.ml11
-rw-r--r--gramlib/.merlin.in3
-rw-r--r--ide/.merlin.in10
-rw-r--r--ide/coqide/coq.ml4
-rw-r--r--ide/coqide/coq.mli5
-rw-r--r--ide/coqide/coqOps.ml22
-rw-r--r--ide/coqide/coqOps.mli2
-rw-r--r--ide/coqide/coqide.ml33
-rw-r--r--ide/coqide/coqide_ui.ml1
-rw-r--r--ide/coqide/fake_ide.ml30
-rw-r--r--ide/coqide/idetop.ml19
-rw-r--r--ide/coqide/protocol/interface.ml5
-rw-r--r--ide/coqide/protocol/serialize.ml5
-rw-r--r--ide/coqide/protocol/serialize.mli1
-rw-r--r--ide/coqide/protocol/xmlprotocol.ml49
-rw-r--r--ide/coqide/protocol/xmlprotocol.mli1
-rw-r--r--interp/constrexpr.ml2
-rw-r--r--interp/constrexpr_ops.ml4
-rw-r--r--interp/constrextern.ml12
-rw-r--r--interp/constrintern.ml2
-rw-r--r--interp/notation.ml373
-rw-r--r--interp/notation.mli24
-rw-r--r--interp/notation_ops.ml4
-rw-r--r--interp/stdarg.ml6
-rw-r--r--interp/stdarg.mli3
-rw-r--r--kernel/dune7
-rw-r--r--kernel/environ.ml15
-rw-r--r--kernel/environ.mli2
-rw-r--r--kernel/float64_31.ml35
-rw-r--r--kernel/float64_63.ml35
-rw-r--r--kernel/float64_common.ml (renamed from kernel/float64.ml)24
-rw-r--r--kernel/float64_common.mli95
-rw-r--r--kernel/indTyping.ml2
-rw-r--r--kernel/kernel.mllib1
-rw-r--r--kernel/mod_typing.ml10
-rw-r--r--kernel/nativeconv.ml4
-rw-r--r--kernel/reduction.ml42
-rw-r--r--kernel/reduction.mli6
-rw-r--r--kernel/safe_typing.ml10
-rw-r--r--kernel/subtyping.ml2
-rw-r--r--kernel/typeops.mli2
-rw-r--r--kernel/uGraph.ml32
-rw-r--r--kernel/uGraph.mli12
-rw-r--r--kernel/univ.ml42
-rw-r--r--kernel/vconv.ml4
-rw-r--r--kernel/vmbytecodes.ml6
-rw-r--r--lib/explore.ml2
-rw-r--r--lib/flags.ml1
-rw-r--r--lib/flags.mli1
-rw-r--r--lib/pp.ml20
-rw-r--r--lib/pp.mli4
-rw-r--r--lib/pp_diff.ml14
-rw-r--r--parsing/g_constr.mlg10
-rw-r--r--parsing/g_prim.mlg15
-rw-r--r--parsing/pcoq.ml7
-rw-r--r--parsing/pcoq.mli7
-rw-r--r--parsing/ppextend.ml4
-rw-r--r--parsing/ppextend.mli2
-rw-r--r--plugins/extraction/scheme.ml2
-rw-r--r--plugins/funind/gen_principle.ml6
-rw-r--r--plugins/ltac/coretactics.mlg2
-rw-r--r--plugins/ltac/extraargs.mlg4
-rw-r--r--plugins/ltac/extratactics.mlg4
-rw-r--r--plugins/ltac/g_auto.mlg2
-rw-r--r--plugins/ltac/g_class.mlg12
-rw-r--r--plugins/ltac/g_ltac.mlg50
-rw-r--r--plugins/ltac/g_obligations.mlg2
-rw-r--r--plugins/ltac/g_rewrite.mlg2
-rw-r--r--plugins/ltac/g_tactic.mlg2
-rw-r--r--plugins/ltac/pptactic.ml4
-rw-r--r--plugins/ltac/profile_ltac.ml4
-rw-r--r--plugins/ltac/taccoerce.ml28
-rw-r--r--plugins/ltac/tacentries.ml4
-rw-r--r--plugins/ltac/tacintern.ml2
-rw-r--r--plugins/ltac/tacinterp.ml30
-rw-r--r--plugins/ltac/tacinterp.mli6
-rw-r--r--plugins/ltac/tacsubst.ml2
-rw-r--r--plugins/micromega/coq_micromega.ml2228
-rw-r--r--plugins/micromega/zify.ml85
-rw-r--r--plugins/ssr/ssrcommon.ml2
-rw-r--r--plugins/ssr/ssrparser.mlg2
-rw-r--r--plugins/ssrmatching/ssrmatching.ml3
-rw-r--r--pretyping/detyping.ml17
-rw-r--r--pretyping/evardefine.ml24
-rw-r--r--pretyping/evardefine.mli8
-rw-r--r--pretyping/glob_ops.ml4
-rw-r--r--pretyping/glob_term.ml2
-rw-r--r--pretyping/pretype_errors.ml2
-rw-r--r--pretyping/pretype_errors.mli4
-rw-r--r--pretyping/pretyping.ml53
-rw-r--r--pretyping/pretyping.mli2
-rw-r--r--pretyping/reductionops.ml14
-rw-r--r--pretyping/typing.ml25
-rw-r--r--pretyping/unification.ml4
-rw-r--r--pretyping/vnorm.ml3
-rw-r--r--printing/ppconstr.ml59
-rw-r--r--printing/ppconstr.mli3
-rw-r--r--printing/printer.ml6
-rw-r--r--printing/proof_diffs.ml28
-rw-r--r--printing/proof_diffs.mli6
-rw-r--r--proofs/clenv.ml2
-rw-r--r--stm/asyncTaskQueue.ml5
-rw-r--r--stm/asyncTaskQueue.mli3
-rw-r--r--stm/partac.ml178
-rw-r--r--stm/partac.mli13
-rw-r--r--stm/stm.ml260
-rw-r--r--stm/stm.mli1
-rw-r--r--stm/stm.mllib1
-rw-r--r--stm/vernac_classifier.ml21
-rw-r--r--tactics/cbn.ml2
-rw-r--r--test-suite/bugs/closed/bug_12414.v13
-rw-r--r--test-suite/bugs/closed/bug_12623.v18
-rw-r--r--test-suite/bugs/closed/bug_12895.v20
-rw-r--r--test-suite/bugs/closed/bug_12970.v4
-rw-r--r--test-suite/bugs/closed/bug_13086.v11
-rw-r--r--test-suite/bugs/closed/bug_13169.v14
-rw-r--r--test-suite/bugs/closed/bug_13171.v10
-rw-r--r--test-suite/bugs/closed/bug_5197.v6
-rw-r--r--test-suite/ide/proof-diffs.fake10
-rw-r--r--test-suite/micromega/int63.v24
-rw-r--r--test-suite/output/Notations3.out17
-rw-r--r--test-suite/output/Record.out40
-rw-r--r--test-suite/output/Record.v31
-rw-r--r--test-suite/output/bug_12908.out5
-rw-r--r--test-suite/output/bug_12908.v7
-rw-r--r--test-suite/output/bug_13112.out4
-rw-r--r--test-suite/output/bug_13112.v5
-rw-r--r--test-suite/output/bug_9180.out3
-rw-r--r--test-suite/output/bug_9682.out9
-rw-r--r--test-suite/output/bug_9682.v28
-rw-r--r--test-suite/output/goal_output.out74
-rw-r--r--test-suite/output/goal_output.v28
-rw-r--r--test-suite/output/locate.out5
-rw-r--r--test-suite/success/Nsatz.v56
-rw-r--r--test-suite/success/Record.v15
-rw-r--r--test-suite/success/polymorphism.v7
-rw-r--r--theories/Reals/RIneq.v60
-rw-r--r--theories/micromega/Zify.v15
-rw-r--r--theories/micromega/ZifyInt63.v178
-rw-r--r--theories/omega/PreOmega.v2
-rw-r--r--theories/ssr/ssrbool.v13
-rw-r--r--topbin/coqtacticworker_bin.ml2
-rw-r--r--toplevel/coqargs.ml1
-rw-r--r--toplevel/coqloop.ml44
-rw-r--r--toplevel/g_toplevel.mlg5
-rw-r--r--toplevel/usage.ml1
-rw-r--r--user-contrib/Ltac2/tac2quote.ml2
-rw-r--r--vernac/comAssumption.ml10
-rw-r--r--vernac/comAssumption.mli9
-rw-r--r--vernac/comDefinition.ml23
-rw-r--r--vernac/comDefinition.mli11
-rw-r--r--vernac/comTactic.ml82
-rw-r--r--vernac/comTactic.mli47
-rw-r--r--vernac/declare.ml19
-rw-r--r--vernac/g_vernac.mlg20
-rw-r--r--vernac/himsg.ml10
-rw-r--r--vernac/metasyntax.ml79
-rw-r--r--vernac/ppvernac.ml15
-rw-r--r--vernac/prettyp.ml2
-rw-r--r--vernac/record.ml76
-rw-r--r--vernac/vernac.mllib1
-rw-r--r--vernac/vernacentries.ml14
-rw-r--r--vernac/vernacexpr.ml7
-rw-r--r--vernac/vernacextend.ml3
-rw-r--r--vernac/vernacextend.mli1
196 files changed, 3566 insertions, 2261 deletions
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 9b208f5a24..b1709e1921 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -19,7 +19,7 @@ stages:
variables:
# Format: $IMAGE-V$DATE [Cache is not used as of today but kept here
# for reference]
- CACHEKEY: "bionic_coq-V2020-09-17-V88"
+ CACHEKEY: "bionic_coq-V2020-10-12-V89"
IMAGE: "$CI_REGISTRY_IMAGE:$CACHEKEY"
# By default, jobs run in the base switch; override to select another switch
OPAM_SWITCH: "base"
diff --git a/Makefile.build b/Makefile.build
index eed3c2813a..526a8c5831 100644
--- a/Makefile.build
+++ b/Makefile.build
@@ -401,6 +401,12 @@ kernel/uint63.ml: kernel/uint63_$(OCAML_INT_SIZE).ml
rm -f $@ && cp $< $@ && chmod a-w $@
###########################################################################
+# Specific rules for Float64
+###########################################################################
+kernel/float64.ml: kernel/float64_$(OCAML_INT_SIZE).ml
+ rm -f $@ && cp $< $@ && chmod a-w $@
+
+###########################################################################
# Main targets (coqtop.opt, coqtop.byte)
###########################################################################
diff --git a/Makefile.make b/Makefile.make
index 51d6d1c3c1..34f5707ae8 100644
--- a/Makefile.make
+++ b/Makefile.make
@@ -107,7 +107,7 @@ GRAMMLIFILES := $(addsuffix .mli, $(GRAMFILES))
GENGRAMMLFILES := $(GRAMMLFILES) gramlib/.pack/gramlib.ml # why is gramlib.ml not in GRAMMLFILES?
GENMLGFILES:= $(MLGFILES:.mlg=.ml)
-GENMLFILES:=$(LEXFILES:.mll=.ml) $(YACCFILES:.mly=.ml) $(GENMLGFILES) $(GENGRAMMLFILES) ide/coqide/coqide_os_specific.ml kernel/vmopcodes.ml kernel/uint63.ml
+GENMLFILES:=$(LEXFILES:.mll=.ml) $(YACCFILES:.mly=.ml) $(GENMLGFILES) $(GENGRAMMLFILES) ide/coqide/coqide_os_specific.ml kernel/vmopcodes.ml kernel/uint63.ml kernel/float64.ml
GENMLIFILES:=$(GRAMMLIFILES)
GENHFILES:=kernel/byterun/coq_instruct.h kernel/byterun/coq_jumptbl.h
GENFILES:=$(GENMLFILES) $(GENMLIFILES) $(GENHFILES) kernel/genOpcodeFiles.exe
diff --git a/dev/bench/gitlab.sh b/dev/bench/gitlab.sh
index 7625e4e7f7..41f204385f 100755
--- a/dev/bench/gitlab.sh
+++ b/dev/bench/gitlab.sh
@@ -428,6 +428,9 @@ for coq_opam_package in $sorted_coq_opam_packages; do
new_base_path=$new_ocaml_switch/.opam-switch/build/$coq_opam_package.dev*/
old_base_path=$old_ocaml_switch/.opam-switch/build/$coq_opam_package.dev*/
for vo in `cd $new_opam_root/$new_base_path/; find -name '*.vo'`; do
+ if [ -e $old_opam_root/$old_base_path/$vo ]; then
+ echo "$coq_opam_package/$vo $(stat -c%s $old_opam_root/$old_base_path/$vo) $(stat -c%s $new_opam_root/$new_base_path/$vo)" >> "$log_dir/vosize.log"
+ fi
if [ -e $old_opam_root/$old_base_path/${vo%%o}.timing -a \
-e $new_opam_root/$new_base_path/${vo%%o}.timing ]; then
mkdir -p $working_dir/html/$coq_opam_package/`dirname $vo`/
diff --git a/dev/build/windows/makecoq_mingw.sh b/dev/build/windows/makecoq_mingw.sh
index fcc585117b..fc8921e63d 100755
--- a/dev/build/windows/makecoq_mingw.sh
+++ b/dev/build/windows/makecoq_mingw.sh
@@ -1204,7 +1204,7 @@ function make_elpi {
make_dune
make_re
- if build_prep https://github.com/LPCIC/elpi/archive v1.11.0 tar.gz 1 elpi; then
+ if build_prep https://github.com/LPCIC/elpi/archive v1.11.4 tar.gz 1 elpi; then
log2 dune build -p elpi
log2 dune install elpi
diff --git a/dev/ci/ci-iris.sh b/dev/ci/ci-iris.sh
index 0256906112..9616f3ce00 100755
--- a/dev/ci/ci-iris.sh
+++ b/dev/ci/ci-iris.sh
@@ -9,13 +9,13 @@ git_download iris_string_ident
git_download iris_examples
# Extract required version of Iris (avoiding "+" which does not work on MacOS :( *)
-iris_CI_REF=$(grep -F '"coq-iris"' < "${CI_BUILD_DIR}/iris_examples/opam" | sed 's/.*"dev\.[0-9][0-9.-]*\.\([0-9a-z][0-9a-z]*\)".*/\1/')
+iris_CI_REF=$(grep -F '"coq-iris"' < "${CI_BUILD_DIR}/iris_examples/coq-iris-examples.opam" | sed 's/.*"dev\.[0-9][0-9.-]*\.\([0-9a-z][0-9a-z]*\)".*/\1/')
# Setup Iris
git_download iris
# Extract required version of std++
-stdpp_CI_REF=$(grep -F '"coq-stdpp"' < "${CI_BUILD_DIR}/iris/opam" | sed 's/.*"dev\.[0-9][0-9.-]*\.\([0-9a-z][0-9a-z]*\)".*/\1/')
+stdpp_CI_REF=$(grep -F '"coq-stdpp"' < "${CI_BUILD_DIR}/iris/coq-iris.opam" | sed 's/.*"dev\.[0-9][0-9.-]*\.\([0-9a-z][0-9a-z]*\)".*/\1/')
# Setup std++
git_download stdpp
diff --git a/dev/ci/docker/bionic_coq/Dockerfile b/dev/ci/docker/bionic_coq/Dockerfile
index f672ead807..c17ec502e7 100644
--- a/dev/ci/docker/bionic_coq/Dockerfile
+++ b/dev/ci/docker/bionic_coq/Dockerfile
@@ -1,4 +1,4 @@
-# CACHEKEY: "bionic_coq-V2020-09-17-V88"
+# CACHEKEY: "bionic_coq-V2020-10-12-V89"
# ^^ Update when modifying this file.
FROM ubuntu:bionic
@@ -43,7 +43,7 @@ ENV COMPILER="4.05.0"
# Common OPAM packages
ENV BASE_OPAM="zarith.1.10 ocamlfind.1.8.1 ounit2.2.2.3 odoc.1.5.1" \
CI_OPAM="menhir.20190626 ocamlgraph.1.8.8" \
- BASE_ONLY_OPAM="elpi.1.11.0"
+ BASE_ONLY_OPAM="elpi.1.11.4"
# BASE switch; CI_OPAM contains Coq's CI dependencies.
ENV COQIDE_OPAM="cairo2.0.6.1 lablgtk3-sourceview3.3.1.0"
diff --git a/dev/ci/user-overlays/12449-SkySkimmer-minim-prop-toset.sh b/dev/ci/user-overlays/12449-SkySkimmer-minim-prop-toset.sh
new file mode 100644
index 0000000000..fb5947d218
--- /dev/null
+++ b/dev/ci/user-overlays/12449-SkySkimmer-minim-prop-toset.sh
@@ -0,0 +1,6 @@
+if [ "$CI_PULL_REQUEST" = "12449" ] || [ "$CI_BRANCH" = "minim-prop-toset" ]; then
+
+ mtac2_CI_REF=janno/coq-12449
+ mtac2_CI_GITURL=https://github.com/mtac2/mtac2
+
+fi
diff --git a/dev/ci/user-overlays/13088-gares-par-to-tactic.sh b/dev/ci/user-overlays/13088-gares-par-to-tactic.sh
new file mode 100644
index 0000000000..4108a1aed1
--- /dev/null
+++ b/dev/ci/user-overlays/13088-gares-par-to-tactic.sh
@@ -0,0 +1,6 @@
+if [ "$CI_PULL_REQUEST" = "13088" ] || [ "$CI_BRANCH" = "par-to-tactic" ]; then
+
+ mtac2_CI_REF=par-to-tactic
+ mtac2_CI_GITURL=https://github.com/gares/Mtac2
+
+fi
diff --git a/dev/ci/user-overlays/13128-SkySkimmer-noinstance.sh b/dev/ci/user-overlays/13128-SkySkimmer-noinstance.sh
new file mode 100644
index 0000000000..654d95f205
--- /dev/null
+++ b/dev/ci/user-overlays/13128-SkySkimmer-noinstance.sh
@@ -0,0 +1,6 @@
+if [ "$CI_PULL_REQUEST" = "13128" ] || [ "$CI_BRANCH" = "noinstance" ]; then
+
+ elpi_CI_REF=noinstance
+ elpi_CI_GITURL=https://github.com/SkySkimmer/coq-elpi
+
+fi
diff --git a/dev/ci/user-overlays/13143-herbelin-master+drop-misleading-arg-hbox.sh b/dev/ci/user-overlays/13143-herbelin-master+drop-misleading-arg-hbox.sh
new file mode 100644
index 0000000000..1b3121781b
--- /dev/null
+++ b/dev/ci/user-overlays/13143-herbelin-master+drop-misleading-arg-hbox.sh
@@ -0,0 +1,9 @@
+if [ "$CI_PULL_REQUEST" = "13143" ] || [ "$CI_BRANCH" = "master+drop-misleading-arg-hbox" ]; then
+
+ aac_tactics_CI_REF=master+adapt-coq-pr13143-hbox-no-argument
+ aac_tactics_CI_GITURL=https://github.com/herbelin/aac-tactics
+
+ equations_CI_REF=master+adapt-coq-pr13143-hbox-no-argument
+ equations_CI_GITURL=https://github.com/herbelin/Coq-Equations
+
+fi
diff --git a/dev/ci/user-overlays/13166-herbelin-master+fixes13165-missing-impargs-defined-fields.sh b/dev/ci/user-overlays/13166-herbelin-master+fixes13165-missing-impargs-defined-fields.sh
new file mode 100644
index 0000000000..7d55cf6883
--- /dev/null
+++ b/dev/ci/user-overlays/13166-herbelin-master+fixes13165-missing-impargs-defined-fields.sh
@@ -0,0 +1,6 @@
+if [ "$CI_PULL_REQUEST" = "13166" ] || [ "$CI_BRANCH" = "master+fixes13165-missing-impargs-defined-fields" ]; then
+
+ elpi_CI_REF=coq-master+adapt-coq-pr13166-impargs-record-fields
+ elpi_CI_GITURL=https://github.com/herbelin/coq-elpi
+
+fi
diff --git a/dev/doc/changes.md b/dev/doc/changes.md
index 59c1623a2d..6a6318f97a 100644
--- a/dev/doc/changes.md
+++ b/dev/doc/changes.md
@@ -1,15 +1,35 @@
## Changes between Coq 8.12 and Coq 8.13
-- Tactic language: TacGeneric now takes an argument to tell if it
- comes from a notation. Use `None` if not and `Some foo` to tell to
- print such TacGeneric surrounded with `foo:( )`.
-
### Code formatting
- The automatic code formatting tool `ocamlformat` has been disabled and its
git hook removed. If desired, automatic formatting can be achieved by calling
the `fmt` target of the dune build system.
+### ML API
+
+Abstract syntax of tactic:
+
+- TacGeneric now takes an argument to tell if it comes from a
+ notation. Use `None` if not and `Some foo` to tell to print such
+ TacGeneric surrounded with `foo:( )`.
+
+Printing functions:
+
+- `Pp.h` does not take a `int` argument anymore (the argument was
+ not used). In general, where `h n` for `n` non zero was used, `hv n`
+ was instead intended. If cancelling the breaking role of cuts in the
+ box was intended, turn `h n c` into `h c`.
+
+Grammar entries:
+
+- `Prim.pattern_identref` is deprecated, use `Prim.pattern_ident`
+ which now returns a located identifier.
+
+Generic arguments:
+
+- Generic arguments: `wit_var` is deprecated, use `wit_hyp`.
+
## Changes between Coq 8.11 and Coq 8.12
### Code formatting
diff --git a/doc/changelog/02-specification-language/10331-minim-prop-toset.rst b/doc/changelog/02-specification-language/10331-minim-prop-toset.rst
new file mode 100644
index 0000000000..6c442ca1aa
--- /dev/null
+++ b/doc/changelog/02-specification-language/10331-minim-prop-toset.rst
@@ -0,0 +1,5 @@
+- **Changed:** Heuristics for universe minimization to :g:`Set`: also
+ use constraints ``Prop <= i`` (`#10331
+ <https://github.com/coq/coq/pull/10331>`_, by Gaëtan Gilbert with
+ help from Maxime Dénès and Matthieu Sozeau, fixes `#12414
+ <https://github.com/coq/coq/issues/12414>`_).
diff --git a/doc/changelog/02-specification-language/13166-master+fixes13165-missing-impargs-defined-fields.rst b/doc/changelog/02-specification-language/13166-master+fixes13165-missing-impargs-defined-fields.rst
new file mode 100644
index 0000000000..006989e6b3
--- /dev/null
+++ b/doc/changelog/02-specification-language/13166-master+fixes13165-missing-impargs-defined-fields.rst
@@ -0,0 +1,5 @@
+- **Fixed:**
+ Implicit arguments taken into account in defined fields of a record type declaration
+ (`#13166 <https://github.com/coq/coq/pull/13166>`_,
+ fixes `#13165 <https://github.com/coq/coq/issues/13165>`_,
+ by Hugo Herbelin).
diff --git a/doc/changelog/03-notations/12950-master+reorganization-notations-only-parsing-only-printing.rst b/doc/changelog/03-notations/12950-master+reorganization-notations-only-parsing-only-printing.rst
new file mode 100644
index 0000000000..16fc91f911
--- /dev/null
+++ b/doc/changelog/03-notations/12950-master+reorganization-notations-only-parsing-only-printing.rst
@@ -0,0 +1,10 @@
+- **Changed:**
+ New model for ``only parsing`` and ``only printing`` notations with
+ support for at most one parsing-and-printing or only-parsing
+ notation per notation and scope, but an arbitrary number of
+ only-printing notations
+ (`#12950 <https://github.com/coq/coq/pull/12950>`_,
+ fixes `#4738 <https://github.com/coq/coq/issues/4738>`_
+ and `#9682 <https://github.com/coq/coq/issues/9682>`_
+ and part 2 of `#12908 <https://github.com/coq/coq/issues/12908>`_,
+ by Hugo Herbelin).
diff --git a/doc/changelog/04-tactics/12648-zify-int63.rst b/doc/changelog/04-tactics/12648-zify-int63.rst
new file mode 100644
index 0000000000..ec7a1273e4
--- /dev/null
+++ b/doc/changelog/04-tactics/12648-zify-int63.rst
@@ -0,0 +1,3 @@
+- **Added:**
+ The :tacn:`zify` tactic provides support for primitive integers (module :g:`ZifyInt63`).
+ (`#12648 <https://github.com/coq/coq/pull/12648>`_, by Frédéric Besson).
diff --git a/doc/changelog/09-coqide/12874-show_proof_diffs.rst b/doc/changelog/09-coqide/12874-show_proof_diffs.rst
new file mode 100644
index 0000000000..51bebad9be
--- /dev/null
+++ b/doc/changelog/09-coqide/12874-show_proof_diffs.rst
@@ -0,0 +1,5 @@
+- **Added:**
+ Support showing diffs for :cmd:`Show Proof` in CoqIDE from the :n:`View` menu.
+ See :ref:`showing_proof_diffs`.
+ (`#12874 <https://github.com/coq/coq/pull/12874>`_,
+ by Jim Fehrle and Enrico Tassi)
diff --git a/doc/sphinx/_static/diffs-show-proof.png b/doc/sphinx/_static/diffs-show-proof.png
new file mode 100644
index 0000000000..62bd9cccd0
--- /dev/null
+++ b/doc/sphinx/_static/diffs-show-proof.png
Binary files differ
diff --git a/doc/sphinx/addendum/micromega.rst b/doc/sphinx/addendum/micromega.rst
index ba5bac6489..b3a33ffeea 100644
--- a/doc/sphinx/addendum/micromega.rst
+++ b/doc/sphinx/addendum/micromega.rst
@@ -283,14 +283,19 @@ obtain :math:`-1`. By Theorem :ref:`Psatz <psatz_thm>`, the goal is valid.
.. tacn:: zify
:name: zify
- This tactic is internally called by :tacn:`lia` to support additional types e.g., :g:`nat`, :g:`positive` and :g:`N`.
- By requiring the module ``ZifyBool``, the boolean type :g:`bool` and some comparison operators are also supported.
+ This tactic is internally called by :tacn:`lia` to support additional types, e.g., :g:`nat`, :g:`positive` and :g:`N`.
+ Additional support is provided by the following modules:
+
+ + For boolean operators (e.g., :g:`Nat.leb`), require the module :g:`ZifyBool`.
+ + For comparison operators (e.g., :g:`Z.compare`), require the module :g:`ZifyComparison`.
+ + For native 63 bit integers, require the module :g:`ZifyInt63`.
+
:tacn:`zify` can also be extended by rebinding the tactics `Zify.zify_pre_hook` and `Zify.zify_post_hook` that are
respectively run in the first and the last steps of :tacn:`zify`.
+ To support :g:`Z.div` and :g:`Z.modulo`: ``Ltac Zify.zify_post_hook ::= Z.div_mod_to_equations``.
+ To support :g:`Z.quot` and :g:`Z.rem`: ``Ltac Zify.zify_post_hook ::= Z.quot_rem_to_equations``.
- + To support :g:`Z.div`, :g:`Z.modulo`, :g:`Z.quot`, and :g:`Z.rem`: ``Ltac Zify.zify_post_hook ::= Z.to_euclidean_division_equations``.
+ + To support :g:`Z.div`, :g:`Z.modulo`, :g:`Z.quot` and :g:`Z.rem`: either ``Ltac Zify.zify_post_hook ::= Z.to_euclidean_division_equations`` or ``Ltac Zify.zify_convert_to_euclidean_division_equations_flag ::= constr:(true)``.
The :tacn:`zify` tactic can be extended with new types and operators by declaring and registering new typeclass instances using the following commands.
The typeclass declarations can be found in the module ``ZifyClasses`` and the default instances can be found in the module ``ZifyInst``.
diff --git a/doc/sphinx/language/core/inductive.rst b/doc/sphinx/language/core/inductive.rst
index 4cdfba146a..39b154de8d 100644
--- a/doc/sphinx/language/core/inductive.rst
+++ b/doc/sphinx/language/core/inductive.rst
@@ -13,7 +13,7 @@ Inductive types
.. prodn::
inductive_definition ::= {? > } @ident_decl {* @binder } {? %| {* @binder } } {? : @type } {? := {? @constructors_or_record } } {? @decl_notations }
constructors_or_record ::= {? %| } {+| @constructor }
- | {? @ident } %{ {*; @record_field } %}
+ | {? @ident } %{ {*; @record_field } {? ; } %}
constructor ::= @ident {* @binder } {? @of_type }
This command defines one or more
diff --git a/doc/sphinx/language/core/records.rst b/doc/sphinx/language/core/records.rst
index cd44d06e67..b2099b8636 100644
--- a/doc/sphinx/language/core/records.rst
+++ b/doc/sphinx/language/core/records.rst
@@ -18,12 +18,12 @@ expressions. In this sense, the :cmd:`Record` construction allows defining
.. insertprodn record_definition field_def
.. prodn::
- record_definition ::= {? > } @ident_decl {* @binder } {? : @type } {? @ident } %{ {*; @record_field } %} {? @decl_notations }
+ record_definition ::= {? > } @ident_decl {* @binder } {? : @type } {? @ident } %{ {*; @record_field } {? ; } %} {? @decl_notations }
record_field ::= {* #[ {*, @attribute } ] } @name {? @field_body } {? %| @natural } {? @decl_notations }
field_body ::= {* @binder } @of_type
| {* @binder } @of_type := @term
| {* @binder } := @term
- term_record ::= %{%| {* @field_def } %|%}
+ term_record ::= %{%| {*; @field_def } {? ; } %|%}
field_def ::= @qualid {* @binder } := @term
diff --git a/doc/sphinx/proof-engine/proof-handling.rst b/doc/sphinx/proof-engine/proof-handling.rst
index f90ebadb3a..edd93f2266 100644
--- a/doc/sphinx/proof-engine/proof-handling.rst
+++ b/doc/sphinx/proof-engine/proof-handling.rst
@@ -590,11 +590,11 @@ Requesting information
constructed. Each hole is an existential variable, which appears as a
question mark followed by an identifier.
- Experimental: Specifying “Diffs” highlights the difference between the
+ Specifying “Diffs” highlights the difference between the
current and previous proof step. By default, the command shows the
output once with additions highlighted. Including “removed” shows
the output twice: once showing removals and once showing additions.
- It does not examine the :opt:`Diffs` option. See :ref:`showing_diffs`.
+ It does not examine the :opt:`Diffs` option. See :ref:`showing_proof_diffs`.
.. cmdv:: Show Conjectures
:name: Show Conjectures
@@ -675,12 +675,9 @@ Requesting information
Showing differences between proof steps
---------------------------------------
-
Coq can automatically highlight the differences between successive proof steps
-and between values in some error messages. Also, as an experimental feature,
-Coq can also highlight differences between proof steps shown in the :cmd:`Show Proof`
-command, but only, for now, when using coqtop and Proof General.
-
+and between values in some error messages. Coq can also highlight differences
+in the proof term.
For example, the following screenshots of CoqIDE and coqtop show the application
of the same :tacn:`intros` tactic. The tactic creates two new hypotheses, highlighted in green.
The conclusion is entirely in pale green because although it’s changed, no tokens were added
@@ -826,14 +823,37 @@ the split because it has not changed.
.. image:: ../_static/diffs-coqide-multigoal.png
:alt: coqide with Set Diffs on with multiple goals
-This is how diffs may appear after applying a :tacn:`intro` tactic that results
-in compacted hypotheses:
+Diffs may appear like this after applying a :tacn:`intro` tactic that results
+in a compacted hypotheses:
..
.. image:: ../_static/diffs-coqide-compacted.png
:alt: coqide with Set Diffs on with compacted hypotheses
+.. _showing_proof_diffs:
+
+"Show Proof" differences
+````````````````````````
+
+To show differences in the proof term:
+
+- In coqtop and Proof General, use the :cmd:`Show Proof` `Diffs` command.
+
+- In CoqIDE, position the cursor on or just after a tactic to compare the proof term
+ after the tactic with the proof term before the tactic, then select
+ `View / Show Proof` from the menu or enter the associated key binding.
+ Differences will be shown applying the current `Show Diffs` setting
+ from the `View` menu. If the current setting is `Don't show diffs`, diffs
+ will not be shown.
+
+ Output with the "added and removed" option looks like this:
+
+ ..
+
+ .. image:: ../_static/diffs-show-proof.png
+ :alt: coqide with Set Diffs on with compacted hypotheses
+
Controlling the effect of proof editing commands
------------------------------------------------
@@ -858,6 +878,11 @@ Controlling the effect of proof editing commands
proved before starting the previous proof) and Coq will switch back to the
proof of the previous assertion.
+.. flag:: Printing Goal Names
+
+ When turned on, the name of the goal is printed in interactive
+ proof mode, which can be useful in cases of cross references
+ between goals.
Controlling memory usage
------------------------
diff --git a/doc/sphinx/user-extensions/syntax-extensions.rst b/doc/sphinx/user-extensions/syntax-extensions.rst
index 5148fa84c9..d6db305300 100644
--- a/doc/sphinx/user-extensions/syntax-extensions.rst
+++ b/doc/sphinx/user-extensions/syntax-extensions.rst
@@ -57,15 +57,14 @@ to represent :g:`(and A B)`:
Notations must be in double quotes, except when the
abbreviation has the form of an ordinary applicative expression;
see :ref:`Abbreviations`. The notation consists of *tokens* separated by
-spaces. Alphanumeric strings (such as ``A`` and ``B``) are the *parameters*
+spaces. Tokens which are identifiers (such as ``A``, ``x0'``, etc.) are the *parameters*
of the notation. Each of them must occur at least once in the abbreviated term. The
other elements of the string (such as ``/\``) are the *symbols*.
-Substrings enclosed in single quotes are treated as literals. This is necessary
-for substrings that would otherwise be interpreted as :n:`@ident`\s. Similarly,
-every symbol of at least 3 characters and starting with a simple quote
-must be quoted (then it starts by two single quotes). Here is an
-example.
+Identifiers enclosed in single quotes are treated as symbols and thus
+lose their role of parameters. In the same vein, every symbol of at
+least 3 characters and starting with a simple quote must be quoted
+(then it starts with two single quotes). Here is an example.
.. coqtop:: in
@@ -82,7 +81,8 @@ associativity rules have to be given.
The right-hand side of a notation is interpreted at the time the notation is
given. In particular, disambiguation of constants, :ref:`implicit arguments
<ImplicitArguments>` and other notations are resolved at the
- time of the declaration of the notation.
+ time of the declaration of the notation. The right-hand side is
+ currently typed only at use time but this may change in the future.
Precedences and associativity
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -299,12 +299,29 @@ Notations disappear when a section is closed. No typing of the denoted
expression is performed at definition time. Type checking is done only
at the time of use of the notation.
-.. note:: Sometimes, a notation is expected only for the parser. To do
- so, the option ``only parsing`` is allowed in the list of :n:`@syntax_modifier`\s
- in :cmd:`Notation`. Conversely, the ``only printing`` :n:`@syntax_modifier` can be
- used to declare that a notation should only be used for printing and
- should not declare a parsing rule. In particular, such notations do
- not modify the parser.
+.. note::
+
+ The default for a notation is to be used both for parsing and
+ printing. It is possible to declare a notation only for parsing by
+ adding the option ``only parsing`` to the list of
+ :n:`@syntax_modifier`\s of :cmd:`Notation`. Symmetrically, the
+ ``only printing`` :n:`@syntax_modifier` can be used to declare that
+ a notation should only be used for printing.
+
+ If a notation to be used both for parsing and printing is
+ overriden, both the parsing and printing are invalided, even if the
+ overriding rule is only parsing.
+
+ If a given notation string occurs only in ``only printing`` rules,
+ the parser is not modified at all.
+
+ To a given notation string and scope can be attached at most one
+ notation with both parsing and printing or with only
+ parsing. Contrastingly, an arbitrary number of ``only printing``
+ notations differing in their right-hand sides but only a unique
+ right-hand side can be attached to a given string and
+ scope. Obviously, expressions printed by means of such extra
+ printing rules will not be reparsed to the same form.
The Infix command
~~~~~~~~~~~~~~~~~~
diff --git a/doc/stdlib/hidden-files b/doc/stdlib/hidden-files
index f39c50238a..4d2972ef8f 100644
--- a/doc/stdlib/hidden-files
+++ b/doc/stdlib/hidden-files
@@ -50,6 +50,7 @@ theories/micromega/ZCoeff.v
theories/micromega/ZMicromega.v
theories/micromega/ZifyInst.v
theories/micromega/ZifyBool.v
+theories/micromega/ZifyInt63.v
theories/micromega/ZifyComparison.v
theories/micromega/ZifyClasses.v
theories/micromega/ZifyPow.v
diff --git a/doc/tools/docgram/common.edit_mlg b/doc/tools/docgram/common.edit_mlg
index a9f9c805d8..1e9be8dded 100644
--- a/doc/tools/docgram/common.edit_mlg
+++ b/doc/tools/docgram/common.edit_mlg
@@ -396,8 +396,8 @@ operconstr0: [
(* @Zimmi48: This rule is a hack, according to Hugo, and should not be shown in the manual. *)
| DELETE "{" binder_constr "}"
| REPLACE "{|" record_declaration bar_cbrace
-| WITH "{|" LIST0 field_def bar_cbrace
-| MOVETO term_record "{|" LIST0 field_def bar_cbrace
+| WITH "{|" LIST0 field_def SEP ";" OPT ";" bar_cbrace
+| MOVETO term_record "{|" LIST0 field_def SEP ";" OPT ";" bar_cbrace
| MOVETO term_generalizing "`{" operconstr200 "}"
| MOVETO term_generalizing "`(" operconstr200 ")"
| MOVETO term_ltac "ltac" ":" "(" tactic_expr5 ")"
@@ -585,7 +585,7 @@ constructor_list_or_record_decl: [
record_fields: [
| REPLACE record_field ";" record_fields
-| WITH LIST0 record_field SEP ";"
+| WITH LIST0 record_field SEP ";" OPT ";"
| DELETE record_field
| DELETE (* empty *)
]
diff --git a/doc/tools/docgram/doc_grammar.ml b/doc/tools/docgram/doc_grammar.ml
index 0ac652c0db..177abe53fc 100644
--- a/doc/tools/docgram/doc_grammar.ml
+++ b/doc/tools/docgram/doc_grammar.ml
@@ -909,14 +909,17 @@ let apply_splice g edit_map =
List.iter (fun b ->
let (nt0, prods0) = b in
let rec splice_loop nt prods cnt =
- let max_cnt = 10 in
- let (nt', prods') = edit_rule g edit_map nt prods in
- if cnt > max_cnt then
- error "Splice for '%s' not done after %d iterations\n" nt0 max_cnt;
- if nt' = nt && prods' = prods then
- (nt', prods')
- else
- splice_loop nt' prods' (cnt+1)
+ if cnt >= 10 then begin
+ error "Splice for '%s' not done after %d iterations. Current value is:\n" nt0 cnt;
+ List.iter (fun prod -> Printf.eprintf " %s\n" (prod_to_str prod)) prods;
+ (nt, prods)
+ end else begin
+ let (nt', prods') = edit_rule g edit_map nt prods in
+ if nt' = nt && prods' = prods then
+ (nt, prods)
+ else
+ splice_loop nt' prods' (cnt+1)
+ end
in
let (nt', prods') = splice_loop nt0 prods0 0 in
g_update_prods g nt' prods')
diff --git a/doc/tools/docgram/fullGrammar b/doc/tools/docgram/fullGrammar
index 067050b4f5..73641976e3 100644
--- a/doc/tools/docgram/fullGrammar
+++ b/doc/tools/docgram/fullGrammar
@@ -1740,11 +1740,11 @@ simple_tactic: [
| "zify_elim_let" (* micromega plugin *)
| "nsatz_compute" constr (* nsatz plugin *)
| "omega" (* omega plugin *)
-| "rtauto"
| "protect_fv" string "in" ident (* ring plugin *)
| "protect_fv" string (* ring plugin *)
| "ring_lookup" tactic0 "[" LIST0 constr "]" LIST1 constr (* ring plugin *)
| "field_lookup" tactic "[" LIST0 constr "]" LIST1 constr (* ring plugin *)
+| "rtauto"
]
mlname: [
diff --git a/doc/tools/docgram/orderedGrammar b/doc/tools/docgram/orderedGrammar
index cbef29fb39..61befe9f1f 100644
--- a/doc/tools/docgram/orderedGrammar
+++ b/doc/tools/docgram/orderedGrammar
@@ -539,7 +539,7 @@ variant_definition: [
]
record_definition: [
-| OPT ">" ident_decl LIST0 binder OPT [ ":" type ] OPT ident "{" LIST0 record_field SEP ";" "}" OPT decl_notations
+| OPT ">" ident_decl LIST0 binder OPT [ ":" type ] OPT ident "{" LIST0 record_field SEP ";" OPT ";" "}" OPT decl_notations
]
record_field: [
@@ -553,7 +553,7 @@ field_body: [
]
term_record: [
-| "{|" LIST0 field_def "|}"
+| "{|" LIST0 field_def SEP ";" OPT ";" "|}"
]
field_def: [
@@ -566,7 +566,7 @@ inductive_definition: [
constructors_or_record: [
| OPT "|" LIST1 constructor SEP "|"
-| OPT ident "{" LIST0 record_field SEP ";" "}"
+| OPT ident "{" LIST0 record_field SEP ";" OPT ";" "}"
]
constructor: [
diff --git a/engine/termops.ml b/engine/termops.ml
index 0923ab6f4b..467b269e37 100644
--- a/engine/termops.ml
+++ b/engine/termops.ml
@@ -233,13 +233,13 @@ let pr_evar_universe_context ctx =
if UState.is_empty ctx then mt ()
else
(str"UNIVERSES:"++brk(0,1)++
- h 0 (Univ.pr_universe_context_set prl (UState.context_set ctx)) ++ fnl () ++
+ h (Univ.pr_universe_context_set prl (UState.context_set ctx)) ++ fnl () ++
str"ALGEBRAIC UNIVERSES:"++brk(0,1)++
- h 0 (Univ.LSet.pr prl (UState.algebraics ctx)) ++ fnl() ++
+ h (Univ.LSet.pr prl (UState.algebraics ctx)) ++ fnl() ++
str"UNDEFINED UNIVERSES:"++brk(0,1)++
- h 0 (UnivSubst.pr_universe_opt_subst (UState.subst ctx)) ++ fnl() ++
+ h (UnivSubst.pr_universe_opt_subst (UState.subst ctx)) ++ fnl() ++
str "WEAK CONSTRAINTS:"++brk(0,1)++
- h 0 (UState.pr_weak prl ctx) ++ fnl ())
+ h (UState.pr_weak prl ctx) ++ fnl ())
let print_env_short env sigma =
let print_constr = print_kconstr in
@@ -316,14 +316,14 @@ let pr_evar_list env sigma l =
| Some ev' -> str " (aliased to " ++ Evar.print ev' ++ str ")"
in
let pr (ev, evi) =
- h 0 (Evar.print ev ++
+ h (Evar.print ev ++
str "==" ++ pr_evar_info env sigma evi ++
pr_alias ev ++
(if evi.evar_body == Evar_empty
then str " {" ++ pr_existential_key sigma ev ++ str "}"
else mt ()))
in
- h 0 (prlist_with_sep fnl pr l)
+ hv 0 (prlist_with_sep fnl pr l)
let to_list d =
let open Evd in
diff --git a/engine/uState.ml b/engine/uState.ml
index 8d1584cd95..9557111cfd 100644
--- a/engine/uState.ml
+++ b/engine/uState.ml
@@ -286,6 +286,10 @@ let process_universe_constraints ctx cstrs =
if not (drop_weak_constraints ()) then weak := UPairSet.add (l,r) !weak; local
| UEq (l, r) -> equalize_universes l r local
in
+ let unify_universes cst local =
+ if not (UGraph.type_in_type univs) then unify_universes cst local
+ else try unify_universes cst local with UniverseInconsistency _ -> local
+ in
let local =
UnivProblem.Set.fold unify_universes cstrs Constraint.empty
in
@@ -671,7 +675,7 @@ let subst_univs_context_with_def def usubst (ctx, cst) =
(LSet.diff ctx def, UnivSubst.subst_univs_constraints usubst cst)
let is_trivial_leq (l,d,r) =
- Level.is_prop l && (d == Le || (d == Lt && Level.is_set r))
+ Level.is_prop l && (d == Le || d == Lt) && Level.is_set r
(* Prop < i <-> Set+1 <= i <-> Set < i *)
let translate_cstr (l,d,r as cstr) =
diff --git a/engine/univMinim.ml b/engine/univMinim.ml
index 1c7e716fc2..4ed6e97526 100644
--- a/engine/univMinim.ml
+++ b/engine/univMinim.ml
@@ -292,22 +292,29 @@ let is_bound l lbound = match lbound with
| UGraph.Bound.Prop -> Level.is_prop l
| UGraph.Bound.Set -> Level.is_set l
+(* if [is_minimal u] then constraints [u <= v] may be dropped and get
+ used only for set_minimization. *)
+let is_minimal ~lbound u =
+ Level.is_sprop u || Level.is_prop u || is_bound u lbound
+
(* TODO check is_small/sprop *)
let normalize_context_set ~lbound g ctx us algs weak =
let (ctx, csts) = ContextSet.levels ctx, ContextSet.constraints ctx in
(* Keep the Prop/Set <= i constraints separate for minimization *)
let smallles, csts =
- Constraint.partition (fun (l,d,r) -> d == Le && (is_bound l lbound || Level.is_sprop l)) csts
+ Constraint.partition (fun (l,d,r) -> d == Le && is_minimal ~lbound l) csts
in
let smallles = if get_set_minimization ()
then Constraint.filter (fun (l,d,r) -> LMap.mem r us && not (Level.is_sprop l)) smallles
else Constraint.empty
in
+ let smallles = Constraint.map (fun (_,_,r) -> Level.set, Le, r) smallles in
let csts, partition =
(* We first put constraints in a normal-form: all self-loops are collapsed
to equalities. *)
+ let g = UGraph.initial_universes_with g in
let g = LSet.fold (fun v g -> UGraph.add_universe ~lbound ~strict:false v g)
- ctx UGraph.initial_universes
+ ctx g
in
let add_soft u g =
if not (Level.is_small u || LSet.mem u ctx)
diff --git a/gramlib/.merlin.in b/gramlib/.merlin.in
new file mode 100644
index 0000000000..cf828efdb7
--- /dev/null
+++ b/gramlib/.merlin.in
@@ -0,0 +1,3 @@
+FLG -open Gramlib
+
+REC
diff --git a/ide/.merlin.in b/ide/.merlin.in
index b8d7953833..50816ae3f5 100644
--- a/ide/.merlin.in
+++ b/ide/.merlin.in
@@ -1,8 +1,10 @@
PKG unix laglgtk3 lablgtk3-sourceview3
-S utils
-B utils
-S protocol
-B protocol
+S coqide/utils
+B coqide/utils
+S coqide/protocol
+B coqide/protocol
+S coqide/
+B coqide/
REC
diff --git a/ide/coqide/coq.ml b/ide/coqide/coq.ml
index 038c8b91a8..1167b8199e 100644
--- a/ide/coqide/coq.ml
+++ b/ide/coqide/coq.ml
@@ -512,6 +512,7 @@ let hints x = eval_call (Xmlprotocol.hints x)
let search flags = eval_call (Xmlprotocol.search flags)
let init x = eval_call (Xmlprotocol.init x)
let stop_worker x = eval_call (Xmlprotocol.stop_worker x)
+let proof_diff x = eval_call (Xmlprotocol.proof_diff x)
let break_coqtop coqtop workers =
if coqtop.status = Busy then
@@ -579,6 +580,9 @@ struct
let set (type a) (opt : a t) (v : a) =
Hashtbl.replace current_state (opt_name opt) (opt_data opt v)
+ let get (type a) (opt : a t) =
+ Hashtbl.find current_state (opt_name opt)
+
let reset () =
let init_descr d = List.iter (fun o -> set o d.init) d.opts in
List.iter init_descr bool_items;
diff --git a/ide/coqide/coq.mli b/ide/coqide/coq.mli
index 82df36c91c..aaaf14e4d0 100644
--- a/ide/coqide/coq.mli
+++ b/ide/coqide/coq.mli
@@ -127,6 +127,7 @@ val hints : Interface.hints_sty -> Interface.hints_rty query
val mkcases : Interface.mkcases_sty -> Interface.mkcases_rty query
val search : Interface.search_sty -> Interface.search_rty query
val init : Interface.init_sty -> Interface.init_rty query
+val proof_diff : Interface.proof_diff_sty -> Interface.proof_diff_rty query
val stop_worker: Interface.stop_worker_sty-> Interface.stop_worker_rty query
@@ -144,6 +145,10 @@ sig
val set : 'a t -> 'a -> unit
+ val get : 'a t -> Interface.option_value
+
+ val diff : string t
+
val printing_unfocused: unit -> bool
(** [enforce] transmits to coq the current option values.
diff --git a/ide/coqide/coqOps.ml b/ide/coqide/coqOps.ml
index 29ea3ce9ea..97076745a3 100644
--- a/ide/coqide/coqOps.ml
+++ b/ide/coqide/coqOps.ml
@@ -142,6 +142,7 @@ object
method handle_reset_initial : unit task
method raw_coq_query :
route_id:int -> next:(query_rty value -> unit task) -> string -> unit task
+ method proof_diff : GText.mark -> next:(Pp.t value -> unit task) -> unit task
method show_goals : unit task
method backtrack_last_phrase : unit task
method initialize : unit task
@@ -361,6 +362,27 @@ object(self)
let query = Coq.query (route_id,(phrase,sid)) in
Coq.bind (Coq.seq action query) next
+ method proof_diff where ~next : unit Coq.task =
+ (* todo: would be nice to ignore comments, too *)
+ let rec back iter =
+ if iter#is_start then iter
+ else
+ let c = iter#char in
+ if Glib.Unichar.isspace c || c = 0 then back (iter#backward_char)
+ else if c = int_of_char '.' then iter#backward_char
+ else iter in
+
+ let where = back (buffer#get_iter_at_mark where) in
+ let until _ start stop =
+ (buffer#get_iter_at_mark stop)#compare where >= 0 &&
+ (buffer#get_iter_at_mark start)#compare where <= 0 in
+ let state_id = fst @@ self#find_id until in
+ let diff_opt = Interface.(match Coq.PrintOpt.(get diff) with
+ | StringValue diffs -> diffs
+ | _ -> "off") in
+ let proof_diff = Coq.proof_diff (diff_opt, state_id) in
+ Coq.bind proof_diff next
+
method private still_valid { edit_id = id } =
try ignore(Doc.find_id document (fun _ { edit_id = id1 } -> id = id1)); true
with Not_found -> false
diff --git a/ide/coqide/coqOps.mli b/ide/coqide/coqOps.mli
index 3a4678ae9c..84911a6aa8 100644
--- a/ide/coqide/coqOps.mli
+++ b/ide/coqide/coqOps.mli
@@ -20,6 +20,7 @@ object
method handle_reset_initial : unit task
method raw_coq_query :
route_id:int -> next:(query_rty value -> unit task) -> string -> unit task
+ method proof_diff : GText.mark -> next:(Pp.t value -> unit task) -> unit task
method show_goals : unit task
method backtrack_last_phrase : unit task
method initialize : unit task
@@ -30,7 +31,6 @@ object
method get_errors : (int * string) list
method get_slaves_status : int * int * string CString.Map.t
-
method handle_failure : handle_exn_rty -> unit task
method destroy : unit -> unit
diff --git a/ide/coqide/coqide.ml b/ide/coqide/coqide.ml
index b66da11e7b..f9e6e74372 100644
--- a/ide/coqide/coqide.ml
+++ b/ide/coqide/coqide.ml
@@ -747,6 +747,24 @@ let coq_icon () =
let dir = List.find chk (Minilib.coqide_data_dirs ()) in
Filename.concat dir name
+let show_proof_diff where sn =
+ sn.messages#default_route#clear;
+ Coq.try_grab sn.coqtop (sn.coqops#proof_diff where
+ ~next:(function
+ | Interface.Fail (_, _, err) ->
+ let err = if (Pp.string_of_ppcmds err) <> "No proofs to diff." then err else
+ Pp.str "Put the cursor over proven lines for \"Show Proof\" diffs"
+ in
+ let err = Ideutils.validate err in
+ sn.messages#default_route#add err;
+ Coq.return ()
+ | Interface.Good diff ->
+ sn.messages#default_route#add diff;
+ Coq.return ()))
+ ignore
+
+let show_proof_diffs _ = cb_on_current_term (show_proof_diff `INSERT) ()
+
let about _ =
let dialog = GWindow.about_dialog () in
let _ = dialog#connect#response ~callback:(fun _ -> dialog#destroy ()) in
@@ -1103,6 +1121,8 @@ let build_ui () =
radio "Set diff" 1 ~label:"Show diffs: only _added";
radio "Set removed diff" 2 ~label:"Show diffs: added and _removed";
];
+ item "Show Proof Diffs" ~label:"_Show Proof (with diffs, if set)" ~accel:(modifier_for_display#get ^ "S")
+ ~callback:MiscMenu.show_proof_diffs;
];
toggle_items view_menu Coq.PrintOpt.bool_items;
@@ -1352,6 +1372,11 @@ let main files =
this default coqtop path *)
let read_coqide_args argv =
+ let set_debug () =
+ Minilib.debug := true;
+ Flags.debug := true;
+ Exninfo.record_backtrace true
+ in
let rec filter_coqtop coqtop project_files bindings_files out = function
|"-unicode-bindings" :: sfilenames :: args ->
let filenames = Str.split (Str.regexp ",") sfilenames in
@@ -1371,10 +1396,12 @@ let read_coqide_args argv =
|"-coqtop" :: [] ->
output_string stderr "Error: missing argument after -coqtop"; exit 1
|"-debug"::args ->
- Minilib.debug := true;
- Flags.debug := true;
- Exninfo.record_backtrace true;
+ set_debug ();
filter_coqtop coqtop project_files bindings_files ("-debug"::out) args
+ |"-xml-debug"::args ->
+ set_debug ();
+ Flags.xml_debug := true;
+ filter_coqtop coqtop project_files bindings_files ("-xml-debug"::out) args
|"-coqtop-flags" :: flags :: args->
Coq.ideslave_coqtop_flags := Some flags;
filter_coqtop coqtop project_files bindings_files out args
diff --git a/ide/coqide/coqide_ui.ml b/ide/coqide/coqide_ui.ml
index e9ff1bbba1..6540fc6fca 100644
--- a/ide/coqide/coqide_ui.ml
+++ b/ide/coqide/coqide_ui.ml
@@ -89,6 +89,7 @@ let init () =
\n <menuitem action='Unset diff' />\
\n <menuitem action='Set diff' />\
\n <menuitem action='Set removed diff' />\
+\n <menuitem action='Show Proof Diffs' />\
\n </menu>\
\n <menu action='Navigation'>\
\n <menuitem action='Forward' />\
diff --git a/ide/coqide/fake_ide.ml b/ide/coqide/fake_ide.ml
index e1736a5fe0..034f5b4e2a 100644
--- a/ide/coqide/fake_ide.ml
+++ b/ide/coqide/fake_ide.ml
@@ -136,7 +136,7 @@ module Parser = struct (* {{{ *)
match g with
| Item (s,_) -> Printf.sprintf "%s" (clean s)
| Opt g -> Printf.sprintf "[%s]" (print g)
- | Alt gs -> Printf.sprintf "( %s )" (String.concat " | " (List.map print gs))
+ | Alt gs -> Printf.sprintf "( %s )" (String.concat "\n| " (List.map print gs))
| Seq gs -> String.concat " " (List.map print gs)
let rec print_toklist = function
@@ -253,6 +253,9 @@ let eval_print l coq =
after_edit_at (to_id, need_unfocus) (base_eval_call (edit_at to_id) coq)
| [ Tok(_,"QUERY"); Top []; Tok(_,phrase) ] ->
eval_call (query (0,(phrase,tip_id()))) coq
+ | [ Tok(_,"PDIFF"); Tok(_,id) ] ->
+ let to_id, _ = get_id id in
+ eval_call (proof_diff ("on",to_id)) coq
| [ Tok(_,"QUERY"); Top [Tok(_,id)]; Tok(_,phrase) ] ->
let to_id, _ = get_id id in
eval_call (query (0,(phrase, to_id))) coq
@@ -282,6 +285,7 @@ let grammar =
; Seq [Item (eat_rex "FAILADD"); Item eat_phrase]
; Seq [Item (eat_rex "EDIT_AT"); Item eat_id]
; Seq [Item (eat_rex "QUERY"); Opt (Item eat_id); Item eat_phrase]
+ ; Seq [Item (eat_rex "PDIFF"); Item eat_id ]
; Seq [Item (eat_rex "WAIT")]
; Seq [Item (eat_rex "JOIN")]
; Seq [Item (eat_rex "GOALS")]
@@ -295,12 +299,11 @@ let grammar =
let read_command inc = Parser.parse grammar inc
let usage () =
- error (Printf.sprintf
- "A fake coqide process talking to a coqtop -toploop coqidetop.\n\
- Usage: %s (file|-) [<coqtop>]\n\
- Input syntax is the following:\n%s\n"
- (Filename.basename Sys.argv.(0))
- (Parser.print grammar))
+ prerr_endline (Printf.sprintf "Usage: %s ( file | - ) [ \"<coqtop arguments>\" ]\n\
+ Input syntax is:\n%s\n"
+ (Filename.basename Sys.argv.(0))
+ (Parser.print grammar));
+ exit 1
module Coqide = Spawn.Sync ()
@@ -308,14 +311,15 @@ let main =
if Sys.os_type = "Unix" then Sys.set_signal Sys.sigpipe
(Sys.Signal_handle
(fun _ -> prerr_endline "Broken Pipe (coqtop died ?)"; exit 1));
- let def_args = ["--xml_format=Ppcmds"] in
let idetop_name = System.get_toplevel_path "coqidetop" in
- let coqtop_args, input_file = match Sys.argv with
- | [| _; f |] -> Array.of_list def_args, f
- | [| _; f; ct |] ->
- let ct = Str.split (Str.regexp " ") ct in
- Array.of_list (def_args @ ct), f
+ let input_file, args = match Sys.argv with
+ | [| _; f |] -> f, []
+ | [| _; f; args |] ->
+ let args = Str.split (Str.regexp " ") args in
+ f, args
| _ -> usage () in
+ let def_coqtop_args = ["--xml_format=Ppcmds"] in
+ let coqtop_args = Array.of_list(def_coqtop_args @ args) in
let inc = if input_file = "-" then stdin else open_in input_file in
prerr_endline ("Running: "^idetop_name^" "^
(String.concat " " (Array.to_list coqtop_args)));
diff --git a/ide/coqide/idetop.ml b/ide/coqide/idetop.ml
index ad21f663e4..297dc3a706 100644
--- a/ide/coqide/idetop.ml
+++ b/ide/coqide/idetop.ml
@@ -367,6 +367,17 @@ let export_option_state s = {
Interface.opt_value = export_option_value s.Goptions.opt_value;
}
+exception NotSupported of string
+
+let proof_diff (diff_opt, sid) =
+ let diff_opt = Proof_diffs.string_to_diffs diff_opt in
+ let doc = get_doc () in
+ match Stm.get_proof ~doc sid with
+ | None -> CErrors.user_err (Pp.str "No proofs to diff.")
+ | Some proof ->
+ let old = Stm.get_prev_proof ~doc sid in
+ Proof_diffs.diff_proofs ~diff_opt ?old proof
+
let get_options () =
let table = Goptions.get_tables () in
let fold key state accu = (key, export_option_state state) :: accu in
@@ -455,6 +466,7 @@ let eval_call c =
Interface.hints = interruptible hints;
Interface.status = interruptible status;
Interface.search = interruptible search;
+ Interface.proof_diff = interruptible proof_diff;
Interface.get_options = interruptible get_options;
Interface.set_options = interruptible set_options;
Interface.mkcases = interruptible idetop_make_cases;
@@ -479,6 +491,8 @@ let print_xml =
let m = Mutex.create () in
fun oc xml ->
Mutex.lock m;
+ if !Flags.xml_debug then
+ Printf.printf "SENT --> %s\n%!" (Xml_printer.to_string_fmt xml);
try Control.protect_sigalrm (Xml_printer.print oc) xml; Mutex.unlock m
with e -> let e = Exninfo.capture e in Mutex.unlock m; Exninfo.iraise e
@@ -507,7 +521,7 @@ let loop run_mode ~opts:_ state =
set_doc state.doc;
init_signal_handler ();
catch_break := false;
- let in_ch, out_ch = Spawned.get_channels () 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
@@ -518,7 +532,8 @@ let loop run_mode ~opts:_ state =
while not !quit do
try
let xml_query = Xml_parser.parse xml_ic in
-(* pr_with_pid (Xml_printer.to_string_fmt xml_query); *)
+ if !Flags.xml_debug then
+ 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 q in
diff --git a/ide/coqide/protocol/interface.ml b/ide/coqide/protocol/interface.ml
index 646012dcaa..86a81446e8 100644
--- a/ide/coqide/protocol/interface.ml
+++ b/ide/coqide/protocol/interface.ml
@@ -187,6 +187,10 @@ type status_rty = status
type search_sty = search_flags
type search_rty = string coq_object list
+(** Diffs between the proof term at a given stateid and the previous one *)
+type proof_diff_sty = string * Stateid.t
+type proof_diff_rty = Pp.t
+
(** Retrieve the list of options of the current toplevel *)
type get_options_sty = unit
type get_options_rty = (option_name * option_state) list
@@ -252,6 +256,7 @@ type handler = {
stop_worker : stop_worker_sty -> stop_worker_rty;
print_ast : print_ast_sty -> print_ast_rty;
annotate : annotate_sty -> annotate_rty;
+ proof_diff : proof_diff_sty -> proof_diff_rty;
handle_exn : handle_exn_sty -> handle_exn_rty;
init : init_sty -> init_rty;
quit : quit_sty -> quit_rty;
diff --git a/ide/coqide/protocol/serialize.ml b/ide/coqide/protocol/serialize.ml
index bdbec5b30f..6a0a3d7f5d 100644
--- a/ide/coqide/protocol/serialize.ml
+++ b/ide/coqide/protocol/serialize.ml
@@ -35,6 +35,11 @@ let singleton = function
| l -> raise (Marshal_error
("singleton",PCData ("list of length " ^ string_of_int (List.length l))))
+let empty = function
+ | [] -> ()
+ | l -> raise (Marshal_error
+ ("empty",PCData ("list of length " ^ string_of_int (List.length l))))
+
let raw_string = function
| [] -> ""
| [PCData s] -> s
diff --git a/ide/coqide/protocol/serialize.mli b/ide/coqide/protocol/serialize.mli
index 5d88defe55..9d09b81d1e 100644
--- a/ide/coqide/protocol/serialize.mli
+++ b/ide/coqide/protocol/serialize.mli
@@ -16,6 +16,7 @@ val massoc: string -> (string * string) list -> string
val constructor: string -> string -> xml list -> xml
val do_match: string -> (string -> xml list -> 'b) -> xml -> 'b
val singleton: 'a list -> 'a
+val empty: 'a list -> unit
val raw_string: xml list -> string
val of_unit: unit -> xml
val to_unit: xml -> unit
diff --git a/ide/coqide/protocol/xmlprotocol.ml b/ide/coqide/protocol/xmlprotocol.ml
index 6cb0cec008..6a33ff8abc 100644
--- a/ide/coqide/protocol/xmlprotocol.ml
+++ b/ide/coqide/protocol/xmlprotocol.ml
@@ -12,7 +12,7 @@
(** WARNING: TO BE UPDATED WHEN MODIFIED! *)
-let protocol_version = "20170413"
+let protocol_version = "20200911"
type msg_format = Richpp of int | Ppcmds
let msg_format = ref (Richpp 72)
@@ -43,7 +43,7 @@ let to_search_cst = do_match "search_cst" (fun s args -> match s with
| "type_pattern" -> Type_Pattern (to_string (singleton args))
| "subtype_pattern" -> SubType_Pattern (to_string (singleton args))
| "in_module" -> In_Module (to_list to_string (singleton args))
- | "include_blacklist" -> Include_Blacklist
+ | "include_blacklist" -> empty args; Include_Blacklist
| x -> raise (Marshal_error("search",PCData x)))
let of_coq_object f ans =
@@ -103,14 +103,14 @@ let to_routeid = function
let of_routeid i = Element ("route_id",["val",string_of_int i],[])
let of_box (ppb : Pp.block_type) = let open Pp in match ppb with
- | Pp_hbox i -> constructor "ppbox" "hbox" [of_int i]
+ | Pp_hbox -> constructor "ppbox" "hbox" []
| 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))
+ | "hbox" -> empty args; Pp_hbox
| "vbox" -> Pp_vbox (to_int (singleton args))
| "hvbox" -> Pp_hvbox (to_int (singleton args))
| "hovbox" -> Pp_hovbox (to_int (singleton args))
@@ -132,7 +132,7 @@ let rec of_pp (pp : Pp.t) = let open Pp in match Pp.repr pp with
let rec to_pp xpp = let open Pp in
Pp.unrepr @@
do_match "ppdoc" (fun s args -> match s with
- | "empty" -> Ppcmd_empty
+ | "empty" -> empty args; 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
@@ -278,6 +278,7 @@ module ReifType : sig
val state_id_t : state_id val_t
val route_id_t : route_id val_t
val search_cst_t : search_constraint val_t
+ val pp_t : Pp.t val_t
val of_value_type : 'a val_t -> 'a -> xml
val to_value_type : 'a val_t -> xml -> 'a
@@ -314,6 +315,7 @@ end = struct
| State_id : state_id val_t
| Route_id : route_id val_t
| Search_cst : search_constraint val_t
+ | Pp : Pp.t val_t
type value_type = Value_type : 'a val_t -> value_type
@@ -340,6 +342,7 @@ end = struct
let state_id_t = State_id
let route_id_t = Route_id
let search_cst_t = Search_cst
+ let pp_t = Pp
let of_value_type (ty : 'a val_t) : 'a -> xml =
let rec convert : type a. a val_t -> a -> xml = function
@@ -362,6 +365,7 @@ end = struct
| State_id -> of_stateid
| Route_id -> of_routeid
| Search_cst -> of_search_cst
+ | Pp -> of_pp
in
convert ty
@@ -386,6 +390,7 @@ end = struct
| State_id -> to_stateid
| Route_id -> to_routeid
| Search_cst -> to_search_cst
+ | Pp -> to_pp
in
convert ty
@@ -443,6 +448,8 @@ end = struct
| In_Module s -> "In_Module " ^ String.concat "." s
| Include_Blacklist -> "Include_Blacklist"
+ let pr_pp = Pp.string_of_ppcmds
+
let rec print : type a. a val_t -> a -> string = function
| Unit -> pr_unit
| Bool -> pr_bool
@@ -463,6 +470,7 @@ end = struct
| Union (t1,t2) -> (pr_union (print t1) (print t2))
| State_id -> pr_state_id
| Route_id -> pr_int
+ | Pp -> pr_pp
(* This is to break if a rename/refactoring makes the strings below outdated *)
type 'a exists = bool
@@ -489,6 +497,7 @@ end = struct
Printf.sprintf "((%s, %s) CSig.union)" (print_val_t t1) (print_val_t t2)
| State_id -> assert(true : Stateid.t exists); "Stateid.t"
| Route_id -> assert(true : route_id exists); "route_id"
+ | Pp -> assert(true : Pp.t exists); "Pp.t"
let print_type = function Value_type ty -> print_val_t ty
@@ -507,6 +516,8 @@ end = struct
(pr_xml (of_pair of_bool of_int (false,3)));
Printf.printf "%s:\n\n%s\n\n" (print_val_t (Union (Bool,Int)))
(pr_xml (of_union of_bool of_int (Inl false)));
+ Printf.printf "%s:\n\n%s\n\n" (print_val_t Pp)
+ (pr_xml (of_pp Pp.(hv 3 (str "foo" ++ spc () ++ str "bar") )));
print_endline ("All other types are records represented by a node named like the OCaml\n"^
"type which contains a flattened n-tuple. We provide one example.\n");
Printf.printf "%s:\n\n%s\n\n" (print_val_t Option_state)
@@ -538,6 +549,7 @@ let interp_sty_t : interp_sty val_t = pair_t (pair_t bool_t bool_t) string_t
let stop_worker_sty_t : stop_worker_sty val_t = string_t
let print_ast_sty_t : print_ast_sty val_t = state_id_t
let annotate_sty_t : annotate_sty val_t = string_t
+let proof_diff_sty_t : proof_diff_sty val_t = pair_t string_t state_id_t
let add_rty_t : add_rty val_t =
pair_t state_id_t (pair_t (union_t unit_t state_id_t) string_t)
@@ -563,6 +575,7 @@ let interp_rty_t : interp_rty val_t = pair_t state_id_t (union_t string_t string
let stop_worker_rty_t : stop_worker_rty val_t = unit_t
let print_ast_rty_t : print_ast_rty val_t = xml_t
let annotate_rty_t : annotate_rty val_t = xml_t
+let proof_diff_rty_t : proof_diff_rty val_t = pp_t
let ($) x = erase x
let calls = [|
@@ -585,6 +598,7 @@ let calls = [|
"StopWorker", ($)stop_worker_sty_t, ($)stop_worker_rty_t;
"PrintAst", ($)print_ast_sty_t, ($)print_ast_rty_t;
"Annotate", ($)annotate_sty_t, ($)annotate_rty_t;
+ "PDiff", ($)proof_diff_sty_t, ($)proof_diff_rty_t;
|]
type 'a call =
@@ -609,7 +623,9 @@ type 'a call =
| Interp : interp_sty -> interp_rty call
| PrintAst : print_ast_sty -> print_ast_rty call
| Annotate : annotate_sty -> annotate_rty call
+ | PDiff : proof_diff_sty -> proof_diff_rty call
+(* the order of the entries must match the order in "calls" above *)
let id_of_call : type a. a call -> int = function
| Add _ -> 0
| Edit_at _ -> 1
@@ -630,6 +646,7 @@ let id_of_call : type a. a call -> int = function
| StopWorker _ -> 16
| PrintAst _ -> 17
| Annotate _ -> 18
+ | PDiff _ -> 19
let str_of_call c = pi1 calls.(id_of_call c)
@@ -652,8 +669,9 @@ let init x : init_rty call = Init x
let wait x : wait_rty call = Wait x
let interp x : interp_rty call = Interp x
let stop_worker x : stop_worker_rty call = StopWorker x
-let print_ast x : print_ast_rty call = PrintAst x
-let annotate x : annotate_rty call = Annotate x
+let print_ast x : print_ast_rty call = PrintAst x
+let annotate x : annotate_rty call = Annotate x
+let proof_diff x : proof_diff_rty call = PDiff x
let abstract_eval_call : type a. _ -> a call -> a value = fun handler c ->
let mkGood : type a. a -> a value = fun x -> Good x in
@@ -678,6 +696,7 @@ let abstract_eval_call : type a. _ -> a call -> a value = fun handler c ->
| StopWorker x -> mkGood (handler.stop_worker x)
| PrintAst x -> mkGood (handler.print_ast x)
| Annotate x -> mkGood (handler.annotate x)
+ | PDiff x -> mkGood (handler.proof_diff x)
with any ->
let any = Exninfo.capture any in
Fail (handler.handle_exn any)
@@ -703,6 +722,7 @@ let of_answer : type a. a call -> a value -> xml = function
| StopWorker _ -> of_value (of_value_type stop_worker_rty_t)
| PrintAst _ -> of_value (of_value_type print_ast_rty_t )
| Annotate _ -> of_value (of_value_type annotate_rty_t )
+ | PDiff _ -> of_value (of_value_type proof_diff_rty_t )
let of_answer msg_fmt =
msg_format := msg_fmt; of_answer
@@ -727,6 +747,7 @@ let to_answer : type a. a call -> xml -> a value = function
| StopWorker _ -> to_value (to_value_type stop_worker_rty_t)
| PrintAst _ -> to_value (to_value_type print_ast_rty_t )
| Annotate _ -> to_value (to_value_type annotate_rty_t )
+ | PDiff _ -> to_value (to_value_type proof_diff_rty_t )
let of_call : type a. a call -> xml = fun q ->
let mkCall x = constructor "call" (str_of_call q) [x] in
@@ -750,6 +771,7 @@ let of_call : type a. a call -> xml = fun q ->
| StopWorker x -> mkCall (of_value_type stop_worker_sty_t x)
| PrintAst x -> mkCall (of_value_type print_ast_sty_t x)
| Annotate x -> mkCall (of_value_type annotate_sty_t x)
+ | PDiff x -> mkCall (of_value_type proof_diff_sty_t x)
let to_call : xml -> unknown_call =
do_match "call" (fun s a ->
@@ -774,6 +796,7 @@ let to_call : xml -> unknown_call =
| "StopWorker" -> Unknown (StopWorker (mkCallArg stop_worker_sty_t a))
| "PrintAst" -> Unknown (PrintAst (mkCallArg print_ast_sty_t a))
| "Annotate" -> Unknown (Annotate (mkCallArg annotate_sty_t a))
+ | "PDiff" -> Unknown (PDiff (mkCallArg proof_diff_sty_t a))
| x -> raise (Marshal_error("call",PCData x)))
(** Debug printing *)
@@ -805,6 +828,7 @@ let pr_full_value : type a. a call -> a value -> string = fun call value -> matc
| StopWorker _ -> pr_value_gen (print stop_worker_rty_t) value
| PrintAst _ -> pr_value_gen (print print_ast_rty_t ) value
| Annotate _ -> pr_value_gen (print annotate_rty_t ) value
+ | PDiff _ -> pr_value_gen (print proof_diff_rty_t ) value
let pr_call : type a. a call -> string = fun call ->
let return what x = str_of_call call ^ " " ^ print what x in
match call with
@@ -827,6 +851,7 @@ let pr_call : type a. a call -> string = fun call ->
| StopWorker x -> return stop_worker_sty_t x
| PrintAst x -> return print_ast_sty_t x
| Annotate x -> return annotate_sty_t x
+ | PDiff x -> return proof_diff_sty_t x
let document to_string_fmt =
Printf.printf "=== Available calls ===\n\n";
@@ -858,11 +883,11 @@ let of_message_level = function
| Error -> Serialize.constructor "message_level" "error" []
let to_message_level =
Serialize.do_match "message_level" (fun s args -> match s with
- | "debug" -> Debug
- | "info" -> Info
- | "notice" -> Notice
- | "warning" -> Warning
- | "error" -> Error
+ | "debug" -> empty args; Debug
+ | "info" -> empty args; Info
+ | "notice" -> empty args; Notice
+ | "warning" -> empty args; Warning
+ | "error" -> empty args; Error
| x -> raise Serialize.(Marshal_error("error level",PCData x)))
let of_message lvl loc msg =
diff --git a/ide/coqide/protocol/xmlprotocol.mli b/ide/coqide/protocol/xmlprotocol.mli
index 44584d44d7..4dc05c18a9 100644
--- a/ide/coqide/protocol/xmlprotocol.mli
+++ b/ide/coqide/protocol/xmlprotocol.mli
@@ -37,6 +37,7 @@ val wait : wait_sty -> wait_rty call
val interp : interp_sty -> interp_rty call
val print_ast : print_ast_sty -> print_ast_rty call
val annotate : annotate_sty -> annotate_rty call
+val proof_diff : proof_diff_sty -> proof_diff_rty call
val abstract_eval_call : handler -> 'a call -> 'a value
diff --git a/interp/constrexpr.ml b/interp/constrexpr.ml
index c98e05370e..d14d156ffc 100644
--- a/interp/constrexpr.ml
+++ b/interp/constrexpr.ml
@@ -108,7 +108,7 @@ and constr_expr_r =
* constr_expr * constr_expr
| CHole of Evar_kinds.t option * Namegen.intro_pattern_naming_expr * Genarg.raw_generic_argument option
| CPatVar of Pattern.patvar
- | CEvar of Glob_term.existential_name * (Id.t * constr_expr) list
+ | CEvar of Glob_term.existential_name CAst.t * (lident * constr_expr) list
| CSort of Glob_term.glob_sort
| CCast of constr_expr * constr_expr Glob_term.cast_type
| CNotation of notation_with_optional_scope option * notation * constr_notation_substitution
diff --git a/interp/constrexpr_ops.ml b/interp/constrexpr_ops.ml
index ce8e7d3c2c..7075d082ee 100644
--- a/interp/constrexpr_ops.ml
+++ b/interp/constrexpr_ops.ml
@@ -156,7 +156,7 @@ let rec constr_expr_eq e1 e2 =
| CPatVar i1, CPatVar i2 ->
Id.equal i1 i2
| CEvar (id1, c1), CEvar (id2, c2) ->
- Id.equal id1 id2 && List.equal instance_eq c1 c2
+ Id.equal id1.CAst.v id2.CAst.v && List.equal instance_eq c1 c2
| CSort s1, CSort s2 ->
Glob_ops.glob_sort_eq s1 s2
| CCast(t1,c1), CCast(t2,c2) ->
@@ -235,7 +235,7 @@ and constr_notation_substitution_eq (e1, el1, b1, bl1) (e2, el2, b2, bl2) =
List.equal (List.equal local_binder_eq) bl1 bl2
and instance_eq (x1,c1) (x2,c2) =
- Id.equal x1 x2 && constr_expr_eq c1 c2
+ Id.equal x1.CAst.v x2.CAst.v && constr_expr_eq c1 c2
and cast_expr_eq c1 c2 = match c1, c2 with
| CastConv t1, CastConv t2
diff --git a/interp/constrextern.ml b/interp/constrextern.ml
index 43fef8685d..7bf1c58148 100644
--- a/interp/constrextern.ml
+++ b/interp/constrextern.ml
@@ -551,7 +551,7 @@ and extern_notation_pattern allscopes vars t = function
| [] -> raise No_match
| (keyrule,pat,n as _rule)::rules ->
try
- if is_inactive_rule keyrule then raise No_match;
+ if is_inactive_rule keyrule || is_printing_inactive_rule keyrule pat then raise No_match;
let loc = t.loc in
match DAst.get t with
| PatCstr (cstr,args,na) ->
@@ -568,7 +568,7 @@ let rec extern_notation_ind_pattern allscopes vars ind args = function
| [] -> raise No_match
| (keyrule,pat,n as _rule)::rules ->
try
- if is_inactive_rule keyrule then raise No_match;
+ if is_inactive_rule keyrule || is_printing_inactive_rule keyrule pat then raise No_match;
apply_notation_to_pattern (GlobRef.IndRef ind)
(match_notation_constr_ind_pattern ind args pat) allscopes vars keyrule
with
@@ -978,7 +978,7 @@ let rec extern inctx ?impargs scopes vars r =
if !print_meta_as_hole then CHole (None, IntroAnonymous, None) else
(match kind with
| Evar_kinds.SecondOrderPatVar n -> CPatVar n
- | Evar_kinds.FirstOrderPatVar n -> CEvar (n,[]))
+ | Evar_kinds.FirstOrderPatVar n -> CEvar (CAst.make n,[]))
| GApp (f,args) ->
(match DAst.get f with
@@ -1103,7 +1103,7 @@ let rec extern inctx ?impargs scopes vars r =
| GFloat f -> extern_float f (snd scopes)
| GArray(u,t,def,ty) ->
- CArray(u,Array.map (extern inctx scopes vars) t, extern inctx scopes vars def, extern_typ scopes vars ty)
+ CArray(extern_universes u,Array.map (extern inctx scopes vars) t, extern inctx scopes vars def, extern_typ scopes vars ty)
in insert_entry_coercion coercion (CAst.make ?loc c)
@@ -1238,7 +1238,7 @@ and extern_notation inctx (custom,scopes as allscopes) vars t rules =
| (keyrule,pat,n as _rule)::rules ->
let loc = Glob_ops.loc_of_glob_constr t in
try
- if is_inactive_rule keyrule then raise No_match;
+ if is_inactive_rule keyrule || is_printing_inactive_rule keyrule pat then raise No_match;
let f,args =
match DAst.get t with
| GApp (f,args) -> f,args
@@ -1391,7 +1391,7 @@ let rec glob_of_pat avoid env sigma pat = DAst.make @@ match pat with
| None -> Id.of_string "__"
| Some id -> id
in
- GEvar (id,List.map (on_snd (glob_of_pat avoid env sigma)) l)
+ GEvar (CAst.make id,List.map (fun (id,c) -> (CAst.make id, glob_of_pat avoid env sigma c)) l)
| PRel n ->
let id = try match lookup_name_of_rel n env with
| Name id -> id
diff --git a/interp/constrintern.ml b/interp/constrintern.ml
index 48fb4a4a5d..959b61a3d7 100644
--- a/interp/constrintern.ml
+++ b/interp/constrintern.ml
@@ -2188,7 +2188,7 @@ let internalize globalenv env pattern_mode (_, ntnvars as lvar) c =
GPatVar (Evar_kinds.SecondOrderPatVar n)
| CEvar (n, []) when pattern_mode ->
DAst.make ?loc @@
- GPatVar (Evar_kinds.FirstOrderPatVar n)
+ GPatVar (Evar_kinds.FirstOrderPatVar n.CAst.v)
(* end *)
(* Parsing existential variables *)
| CEvar (n, l) ->
diff --git a/interp/notation.ml b/interp/notation.ml
index 7e90e15b72..d57c4f3abf 100644
--- a/interp/notation.ml
+++ b/interp/notation.ml
@@ -58,6 +58,31 @@ let notation_with_optional_scope_eq inscope1 inscope2 = match (inscope1,inscope2
let notation_eq (from1,ntn1) (from2,ntn2) =
notation_entry_eq from1 from2 && String.equal ntn1 ntn2
+let pair_eq f g (x1, y1) (x2, y2) = f x1 x2 && g y1 y2
+
+let notation_binder_source_eq s1 s2 = match s1, s2 with
+| NtnParsedAsIdent, NtnParsedAsIdent -> true
+| NtnParsedAsPattern b1, NtnParsedAsPattern b2 -> b1 = b2
+| NtnBinderParsedAsConstr bk1, NtnBinderParsedAsConstr bk2 -> bk1 = bk2
+| (NtnParsedAsIdent | NtnParsedAsPattern _ | NtnBinderParsedAsConstr _), _ -> false
+
+let ntpe_eq t1 t2 = match t1, t2 with
+| NtnTypeConstr, NtnTypeConstr -> true
+| NtnTypeBinder s1, NtnTypeBinder s2 -> notation_binder_source_eq s1 s2
+| NtnTypeConstrList, NtnTypeConstrList -> true
+| NtnTypeBinderList, NtnTypeBinderList -> true
+| (NtnTypeConstr | NtnTypeBinder _ | NtnTypeConstrList | NtnTypeBinderList), _ -> false
+
+let var_attributes_eq (_, ((entry1, sc1), tp1)) (_, ((entry2, sc2), tp2)) =
+ notation_entry_level_eq entry1 entry2 &&
+ pair_eq (Option.equal String.equal) (List.equal String.equal) sc1 sc2 &&
+ ntpe_eq tp1 tp2
+
+let interpretation_eq (vars1, t1 as x1) (vars2, t2 as x2) =
+ x1 == x2 ||
+ List.equal var_attributes_eq vars1 vars2 &&
+ Notation_ops.eq_notation_constr (List.map fst vars1, List.map fst vars2) t1 t2
+
let pr_notation (from,ntn) = qstring ntn ++ match from with InConstrEntry -> mt () | InCustomEntry s -> str " in custom " ++ str s
module NotationOrd =
@@ -90,8 +115,21 @@ type notation_data = {
not_deprecation : Deprecation.t option;
}
+type activation = bool
+
+type extra_printing_notation_data =
+ (activation * notation_data) list
+
+type parsing_notation_data =
+ | NoParsingData
+ | OnlyParsingData of activation * notation_data
+ | ParsingAndPrintingData of
+ activation (* for parsing*) *
+ activation (* for printing *) *
+ notation_data (* common data for both *)
+
type scope = {
- notations: notation_data NotationMap.t;
+ notations: (parsing_notation_data * extra_printing_notation_data) NotationMap.t;
delimiters: delimiters option
}
@@ -300,10 +338,19 @@ type notation_applicative_status =
type notation_rule = interp_rule * interpretation * notation_applicative_status
+let notation_rule_eq (rule1,pat1,s1 as x1) (rule2,pat2,s2 as x2) =
+ x1 == x2 || (rule1 = rule2 && interpretation_eq pat1 pat2 && s1 = s2)
+
let keymap_add key interp map =
let old = try KeyMap.find key map with Not_found -> [] in
+ (* In case of re-import, no need to keep the previous copy *)
+ let old = try List.remove_first (notation_rule_eq interp) old with Not_found -> old in
KeyMap.add key (interp :: old) map
+let keymap_remove key interp map =
+ let old = try KeyMap.find key map with Not_found -> [] in
+ KeyMap.add key (List.remove_first (notation_rule_eq interp) old) map
+
let keymap_find key map =
try KeyMap.find key map
with Not_found -> []
@@ -1225,40 +1272,90 @@ let rec find_without_delimiters find (ntn_scope,ntn) = function
(* The mapping between notations and their interpretation *)
+let pr_optional_scope = function
+ | LastLonelyNotation -> mt ()
+ | NotationInScope scope -> spc () ++ strbrk "in scope" ++ spc () ++ str scope
+
let warn_notation_overridden =
CWarnings.create ~name:"notation-overridden" ~category:"parsing"
- (fun (ntn,which_scope) ->
+ (fun (scope,ntn) ->
str "Notation" ++ spc () ++ pr_notation ntn ++ spc ()
- ++ strbrk "was already used" ++ which_scope ++ str ".")
+ ++ strbrk "was already used" ++ pr_optional_scope scope ++ str ".")
-let declare_notation_interpretation ntn scopt pat df ~onlyprint deprecation =
- let scope = match scopt with Some s -> s | None -> default_scope in
- let sc = find_scope scope in
- if not onlyprint then begin
- let () =
- if NotationMap.mem ntn sc.notations then
- let which_scope = match scopt with
- | None -> mt ()
- | Some _ -> spc () ++ strbrk "in scope" ++ spc () ++ str scope in
- warn_notation_overridden (ntn,which_scope)
- in
- let notdata = {
- not_interp = pat;
- not_location = df;
- not_deprecation = deprecation;
- } in
- let sc = { sc with notations = NotationMap.add ntn notdata sc.notations } in
- scope_map := String.Map.add scope sc !scope_map
- end;
- begin match scopt with
- | None -> scope_stack := LonelyNotationItem ntn :: !scope_stack
- | Some _ -> ()
- end
+let warn_deprecation_overridden =
+ CWarnings.create ~name:"notation-overridden" ~category:"parsing"
+ (fun ((scope,ntn),old,now) ->
+ match old, now with
+ | None, None -> assert false
+ | None, Some _ ->
+ (str "Notation" ++ spc () ++ pr_notation ntn ++ pr_optional_scope scope ++ spc ()
+ ++ strbrk "is now marked as deprecated" ++ str ".")
+ | Some _, None ->
+ (str "Cancelling previous deprecation of notation" ++ spc () ++
+ pr_notation ntn ++ pr_optional_scope scope ++ str ".")
+ | Some _, Some _ ->
+ (str "Amending deprecation of notation" ++ spc () ++
+ pr_notation ntn ++ pr_optional_scope scope ++ str "."))
+
+type notation_use =
+ | OnlyPrinting
+ | OnlyParsing
+ | ParsingAndPrinting
+
+let warn_override_if_needed (scopt,ntn) overridden data old_data =
+ if overridden then warn_notation_overridden (scopt,ntn)
+ else
+ if data.not_deprecation <> old_data.not_deprecation then
+ warn_deprecation_overridden ((scopt,ntn),old_data.not_deprecation,data.not_deprecation)
+
+let check_parsing_override (scopt,ntn) data = function
+ | OnlyParsingData (_,old_data) ->
+ let overridden = not (interpretation_eq data.not_interp old_data.not_interp) in
+ warn_override_if_needed (scopt,ntn) overridden data old_data;
+ None, not overridden
+ | ParsingAndPrintingData (_,on_printing,old_data) ->
+ let overridden = not (interpretation_eq data.not_interp old_data.not_interp) in
+ warn_override_if_needed (scopt,ntn) overridden data old_data;
+ (if on_printing then Some old_data.not_interp else None), not overridden
+ | NoParsingData -> None, false
+
+let check_printing_override (scopt,ntn) data parsingdata printingdata =
+ let parsing_update = match parsingdata with
+ | OnlyParsingData _ | NoParsingData -> parsingdata
+ | ParsingAndPrintingData (_,on_printing,old_data) ->
+ let overridden = not (interpretation_eq data.not_interp old_data.not_interp) in
+ warn_override_if_needed (scopt,ntn) overridden data old_data;
+ if overridden then NoParsingData else parsingdata in
+ let exists = List.exists (fun (on_printing,old_data) ->
+ let exists = interpretation_eq data.not_interp old_data.not_interp in
+ if exists && data.not_deprecation <> old_data.not_deprecation then
+ warn_deprecation_overridden ((scopt,ntn),old_data.not_deprecation,data.not_deprecation);
+ exists) printingdata in
+ parsing_update, exists
+
+let remove_uninterpretation rule (metas,c as pat) =
+ let (key,n) = notation_constr_key c in
+ notations_key_table := keymap_remove key (rule,pat,n) !notations_key_table
let declare_uninterpretation rule (metas,c as pat) =
let (key,n) = notation_constr_key c in
notations_key_table := keymap_add key (rule,pat,n) !notations_key_table
+let update_notation_data (scopt,ntn) use data table =
+ let (parsingdata,printingdata) =
+ try NotationMap.find ntn table with Not_found -> (NoParsingData, []) in
+ match use with
+ | OnlyParsing ->
+ let printing_update, exists = check_parsing_override (scopt,ntn) data parsingdata in
+ NotationMap.add ntn (OnlyParsingData (true,data), printingdata) table, printing_update, exists
+ | ParsingAndPrinting ->
+ let printing_update, exists = check_parsing_override (scopt,ntn) data parsingdata in
+ NotationMap.add ntn (ParsingAndPrintingData (true,true,data), printingdata) table, printing_update, exists
+ | OnlyPrinting ->
+ let parsingdata, exists = check_printing_override (scopt,ntn) data parsingdata printingdata in
+ let printingdata = if exists then printingdata else (true,data) :: printingdata in
+ NotationMap.add ntn (parsingdata, printingdata) table, None, exists
+
let rec find_interpretation ntn find = function
| [] -> raise Not_found
| OpenScopeItem scope :: scopes ->
@@ -1273,7 +1370,9 @@ let rec find_interpretation ntn find = function
find_interpretation ntn find scopes
let find_notation ntn sc =
- NotationMap.find ntn (find_scope sc).notations
+ match fst (NotationMap.find ntn (find_scope sc).notations) with
+ | OnlyParsingData (true,data) | ParsingAndPrintingData (true,_,data) -> data
+ | _ -> raise Not_found
let notation_of_prim_token = function
| Constrexpr.Numeral (SPlus,n) -> InConstrEntry, NumTok.Unsigned.sprint n
@@ -1358,10 +1457,37 @@ let uninterp_cases_pattern_notations c =
let uninterp_ind_pattern_notations ind =
keymap_find (RefKey (canonical_gr (GlobRef.IndRef ind))) !notations_key_table
+let has_active_parsing_rule_in_scope ntn sc =
+ try
+ match NotationMap.find ntn (String.Map.find sc !scope_map).notations with
+ | OnlyParsingData (active,_),_ | ParsingAndPrintingData (active,_,_),_ -> active
+ | _ -> false
+ with Not_found -> false
+
+let is_printing_active_in_scope (scope,ntn) pat =
+ let sc = match scope with NotationInScope sc -> sc | LastLonelyNotation -> default_scope in
+ let is_active extra =
+ try
+ let (_,(active,_)) = List.extract_first (fun (active,d) -> interpretation_eq d.not_interp pat) extra in
+ active
+ with Not_found -> false in
+ try
+ match NotationMap.find ntn (String.Map.find sc !scope_map).notations with
+ | ParsingAndPrintingData (_,active,d), extra ->
+ if interpretation_eq d.not_interp pat then active
+ else is_active extra
+ | _, extra -> is_active extra
+ with Not_found -> false
+
+let is_printing_inactive_rule rule pat =
+ match rule with
+ | NotationRule (scope,ntn) ->
+ not (is_printing_active_in_scope (scope,ntn) pat)
+ | SynDefRule kn ->
+ try let _ = Nametab.path_of_syndef kn in false with Not_found -> true
+
let availability_of_notation (ntn_scope,ntn) scopes =
- let f scope =
- NotationMap.mem ntn (String.Map.find scope !scope_map).notations in
- find_without_delimiters f (ntn_scope,Some ntn) (make_current_scopes scopes)
+ find_without_delimiters (has_active_parsing_rule_in_scope ntn) (ntn_scope,Some ntn) (make_current_scopes scopes)
(* We support coercions from a custom entry at some level to an entry
at some level (possibly the same), and from and to the constr entry. E.g.:
@@ -1484,6 +1610,49 @@ let entry_has_ident = function
| InCustomEntryLevel (s,n) ->
try String.Map.find s !entry_has_ident_map <= n with Not_found -> false
+type entry_coercion_kind =
+ | IsEntryCoercion of notation_entry_level
+ | IsEntryGlobal of string * int
+ | IsEntryIdent of string * int
+
+let declare_notation (scopt,ntn) pat df ~use coe deprecation =
+ (* Register the interpretation *)
+ let scope = match scopt with NotationInScope s -> s | LastLonelyNotation -> default_scope in
+ let sc = find_scope scope in
+ let notdata = {
+ not_interp = pat;
+ not_location = df;
+ not_deprecation = deprecation;
+ } in
+ let notation_update,printing_update, exists = update_notation_data (scopt,ntn) use notdata sc.notations in
+ if not exists then
+ let sc = { sc with notations = notation_update } in
+ scope_map := String.Map.add scope sc !scope_map;
+ (* Update the uninterpretation cache *)
+ begin match printing_update with
+ | Some pat -> remove_uninterpretation (NotationRule (scopt,ntn)) pat
+ | None -> ()
+ end;
+ if not exists && use <> OnlyParsing then declare_uninterpretation (NotationRule (scopt,ntn)) pat;
+ (* Register visibility of lonely notations *)
+ if not exists then begin match scopt with
+ | LastLonelyNotation -> scope_stack := LonelyNotationItem ntn :: !scope_stack
+ | NotationInScope _ -> ()
+ end;
+ (* Declare a possible coercion *)
+ if not exists then begin match coe with
+ | Some (IsEntryCoercion entry) ->
+ let (_,level,_) = level_of_notation ntn in
+ let level = match fst ntn with
+ | InConstrEntry -> None
+ | InCustomEntry _ -> Some level
+ in
+ declare_entry_coercion (scopt,ntn) level entry
+ | Some (IsEntryGlobal (entry,n)) -> declare_custom_entry_has_global entry n
+ | Some (IsEntryIdent (entry,n)) -> declare_custom_entry_has_ident entry n
+ | None -> ()
+ end
+
let availability_of_prim_token n printer_scope local_scopes =
let f scope =
try
@@ -1561,38 +1730,6 @@ let uninterp_prim_token_cases_pattern c local_scopes =
(* Miscellaneous *)
-let pair_eq f g (x1, y1) (x2, y2) = f x1 x2 && g y1 y2
-
-let notation_binder_source_eq s1 s2 = match s1, s2 with
-| NtnParsedAsIdent, NtnParsedAsIdent -> true
-| NtnParsedAsPattern b1, NtnParsedAsPattern b2 -> b1 = b2
-| NtnBinderParsedAsConstr bk1, NtnBinderParsedAsConstr bk2 -> bk1 = bk2
-| (NtnParsedAsIdent | NtnParsedAsPattern _ | NtnBinderParsedAsConstr _), _ -> false
-
-let ntpe_eq t1 t2 = match t1, t2 with
-| NtnTypeConstr, NtnTypeConstr -> true
-| NtnTypeBinder s1, NtnTypeBinder s2 -> notation_binder_source_eq s1 s2
-| NtnTypeConstrList, NtnTypeConstrList -> true
-| NtnTypeBinderList, NtnTypeBinderList -> true
-| (NtnTypeConstr | NtnTypeBinder _ | NtnTypeConstrList | NtnTypeBinderList), _ -> false
-
-let var_attributes_eq (_, ((entry1, sc1), tp1)) (_, ((entry2, sc2), tp2)) =
- notation_entry_level_eq entry1 entry2 &&
- pair_eq (Option.equal String.equal) (List.equal String.equal) sc1 sc2 &&
- ntpe_eq tp1 tp2
-
-let interpretation_eq (vars1, t1) (vars2, t2) =
- List.equal var_attributes_eq vars1 vars2 &&
- Notation_ops.eq_notation_constr (List.map fst vars1, List.map fst vars2) t1 t2
-
-let exists_notation_in_scope scopt ntn onlyprint r =
- let scope = match scopt with Some s -> s | None -> default_scope in
- try
- let sc = String.Map.find scope !scope_map in
- let n = NotationMap.find ntn sc.notations in
- interpretation_eq n.not_interp r
- with Not_found -> false
-
let isNVar_or_NHole = function NVar _ | NHole _ -> true | _ -> false
(**********************************************************************)
@@ -1846,38 +1983,63 @@ let pr_scope_classes sc =
| _ :: ll ->
let opt_s = match ll with [] -> mt () | _ -> str "es" in
hov 0 (str "Bound to class" ++ opt_s ++
- spc() ++ prlist_with_sep spc pr_scope_class l) ++ fnl()
+ spc() ++ prlist_with_sep spc pr_scope_class l)
let pr_notation_info prglob ntn c =
- str "\"" ++ str ntn ++ str "\" := " ++
+ str "\"" ++ str ntn ++ str "\" :=" ++ brk (1,2) ++
prglob (Notation_ops.glob_constr_of_notation_constr c)
-let pr_named_scope prglob scope sc =
+let pr_notation_status on_parsing on_printing =
+ let deactivated b = if b then [] else ["deactivated"] in
+ let l = match on_parsing, on_printing with
+ | Some on, None -> "only parsing" :: deactivated on
+ | None, Some on -> "only printing" :: deactivated on
+ | Some false, Some false -> ["deactivated"]
+ | Some true, Some false -> ["deactivated for printing"]
+ | Some false, Some true -> ["deactivated for parsing"]
+ | Some true, Some true -> []
+ | None, None -> assert false in
+ match l with
+ | [] -> mt ()
+ | l -> str "(" ++ prlist_with_sep pr_comma str l ++ str ")"
+
+let pr_non_empty spc pp =
+ if pp = mt () then mt () else spc ++ pp
+
+let pr_notation_data prglob (on_parsing,on_printing,{ not_interp = (_, r); not_location = (_, df) }) =
+ hov 0 (pr_notation_info prglob df r ++ pr_non_empty (brk(1,2)) (pr_notation_status on_parsing on_printing))
+
+let extract_notation_data (main,extra) =
+ let main = match main with
+ | NoParsingData -> []
+ | ParsingAndPrintingData (on_parsing, on_printing, d) ->
+ [Some on_parsing, Some on_printing, d]
+ | OnlyParsingData (on_parsing, d) ->
+ [Some on_parsing, None, d] in
+ let extra = List.map (fun (on_printing, d) -> (None, Some on_printing, d)) extra in
+ main @ extra
+
+let pr_named_scope prglob (scope,sc) =
(if String.equal scope default_scope then
match NotationMap.cardinal sc.notations with
| 0 -> str "No lonely notation"
| n -> str "Lonely notation" ++ (if Int.equal n 1 then mt() else str"s")
else
str "Scope " ++ str scope ++ fnl () ++ pr_delimiters_info sc.delimiters)
- ++ fnl ()
- ++ pr_scope_classes scope
- ++ NotationMap.fold
- (fun ntn { not_interp = (_, r); not_location = (_, df) } strm ->
- pr_notation_info prglob df r ++ fnl () ++ strm)
- sc.notations (mt ())
+ ++ pr_non_empty (fnl ()) (pr_scope_classes scope)
+ ++ prlist (fun a -> fnl () ++ pr_notation_data prglob a)
+ (NotationMap.fold (fun ntn data l -> extract_notation_data data @ l) sc.notations [])
-let pr_scope prglob scope = pr_named_scope prglob scope (find_scope scope)
+let pr_scope prglob scope = pr_named_scope prglob (scope, find_scope scope)
let pr_scopes prglob =
- String.Map.fold
- (fun scope sc strm -> pr_named_scope prglob scope sc ++ fnl () ++ strm)
- !scope_map (mt ())
+ let l = String.Map.bindings !scope_map in
+ prlist_with_sep (fun () -> fnl () ++ fnl ()) (pr_named_scope prglob) l
let rec find_default ntn = function
| [] -> None
| OpenScopeItem scope :: scopes ->
- if NotationMap.mem ntn (find_scope scope).notations then
- Some scope
+ if has_active_parsing_rule_in_scope ntn scope then Some scope
else find_default ntn scopes
| LonelyNotationItem ntn' :: scopes ->
if notation_eq ntn ntn' then Some default_scope
@@ -1885,12 +2047,12 @@ let rec find_default ntn = function
let factorize_entries = function
| [] -> []
- | (ntn,c)::l ->
+ | (ntn,sc',c)::l ->
let (ntn,l_of_ntn,rest) =
List.fold_left
- (fun (a',l,rest) (a,c) ->
- if notation_eq a a' then (a',c::l,rest) else (a,[c],(a',l)::rest))
- (ntn,[c],[]) l in
+ (fun (a',l,rest) (a,sc,c) ->
+ if notation_eq a a' then (a',(sc,c)::l,rest) else (a,[sc,c],(a',l)::rest))
+ (ntn,[sc',c],[]) l in
(ntn,l_of_ntn)::rest
type symbol_token = WhiteSpace of int | String of string
@@ -1961,16 +2123,18 @@ let browse_notation strict ntn map =
let l =
String.Map.fold
(fun scope_name sc ->
- NotationMap.fold (fun ntn { not_interp = (_, r); not_location = df } l ->
- if List.exists (find ntn) ntns then (ntn,(scope_name,r,df))::l else l) sc.notations)
+ NotationMap.fold (fun ntn data l ->
+ if List.exists (find ntn) ntns
+ then List.map (fun d -> (ntn,scope_name,d)) (extract_notation_data data) @ l
+ else l) sc.notations)
map [] in
- List.sort (fun x y -> String.compare (snd (fst x)) (snd (fst y))) l
+ List.sort (fun x y -> String.compare (snd (pi1 x)) (snd (pi1 y))) l
-let global_reference_of_notation ~head test (ntn,(sc,c,_)) =
+let global_reference_of_notation ~head test (ntn,sc,(on_parsing,on_printing,{not_interp = (_,c)})) =
match c with
- | NRef ref when test ref -> Some (ntn,sc,ref)
+ | NRef ref when test ref -> Some (on_parsing,on_printing,ntn,sc,ref)
| NApp (NRef ref, l) when head || List.for_all isNVar_or_NHole l && test ref ->
- Some (ntn,sc,ref)
+ Some (on_parsing,on_printing,ntn,sc,ref)
| _ -> None
let error_ambiguous_notation ?loc _ntn =
@@ -1990,17 +2154,17 @@ let interp_notation_as_global_reference ?loc ~head test ntn sc =
let ntns = browse_notation true ntn scopes in
let refs = List.map (global_reference_of_notation ~head test) ntns in
match Option.List.flatten refs with
- | [_,_,ref] -> ref
+ | [Some true,_ (* why not if the only one? *),_,_,ref] -> ref
| [] -> error_notation_not_reference ?loc ntn
| refs ->
- let f (ntn,sc,ref) =
+ let f (on_parsing,_,ntn,sc,ref) =
let def = find_default ntn !scope_stack in
match def with
| None -> false
- | Some sc' -> String.equal sc sc'
+ | Some sc' -> on_parsing = Some true && String.equal sc sc'
in
match List.filter f refs with
- | [_,_,ref] -> ref
+ | [_,_,_,_,ref] -> ref
| [] -> error_notation_not_reference ?loc ntn
| _ -> error_ambiguous_notation ?loc ntn
@@ -2010,24 +2174,25 @@ let locate_notation prglob ntn scope =
match ntns with
| [] -> str "Unknown notation"
| _ ->
- str "Notation" ++ fnl () ++
prlist_with_sep fnl (fun (ntn,l) ->
let scope = find_default ntn scopes in
prlist_with_sep fnl
- (fun (sc,r,(_,df)) ->
+ (fun (sc,(on_parsing,on_printing,{ not_interp = (_, r); not_location = (_, df) })) ->
hov 0 (
+ str "Notation" ++ brk (1,2) ++
pr_notation_info prglob df r ++
(if String.equal sc default_scope then mt ()
- else (spc () ++ str ": " ++ str sc)) ++
+ else (brk (1,2) ++ str ": " ++ str sc)) ++
(if Option.equal String.equal (Some sc) scope
- then spc () ++ str "(default interpretation)" else mt ())))
+ then brk (1,2) ++ str "(default interpretation)" else mt ()) ++
+ pr_non_empty (brk (1,2)) (pr_notation_status on_parsing on_printing)))
l) ntns
let collect_notation_in_scope scope sc known =
assert (not (String.equal scope default_scope));
NotationMap.fold
- (fun ntn { not_interp = (_, r); not_location = (_, df) } (l,known as acc) ->
- if List.mem_f notation_eq ntn known then acc else ((df,r)::l,ntn::known))
+ (fun ntn d (l,known as acc) ->
+ if List.mem_f notation_eq ntn known then acc else (extract_notation_data d @ l,ntn::known))
sc.notations ([],known)
let collect_notations stack =
@@ -2043,13 +2208,13 @@ let collect_notations stack =
if List.mem_f notation_eq ntn knownntn then (all,knownntn)
else
try
- let { not_interp = (_, r); not_location = (_, df) } =
- NotationMap.find ntn (find_scope default_scope).notations in
+ let datas = extract_notation_data
+ (NotationMap.find ntn (find_scope default_scope).notations) in
let all' = match all with
| (s,lonelyntn)::rest when String.equal s default_scope ->
- (s,(df,r)::lonelyntn)::rest
+ (s,datas@lonelyntn)::rest
| _ ->
- (default_scope,[df,r])::all in
+ (default_scope,datas)::all in
(all',ntn::knownntn)
with Not_found -> (* e.g. if only printing *) (all,knownntn))
([],[]) stack)
@@ -2057,7 +2222,7 @@ let collect_notations stack =
let pr_visible_in_scope prglob (scope,ntns) =
let strm =
List.fold_right
- (fun (df,r) strm -> pr_notation_info prglob df r ++ fnl () ++ strm)
+ (fun d strm -> pr_notation_data prglob d ++ fnl () ++ strm)
ntns (mt ()) in
(if String.equal scope default_scope then
str "Lonely notation" ++ (match ntns with [_] -> mt () | _ -> str "s")
@@ -2066,9 +2231,7 @@ let pr_visible_in_scope prglob (scope,ntns) =
++ fnl () ++ strm
let pr_scope_stack prglob stack =
- List.fold_left
- (fun strm scntns -> strm ++ pr_visible_in_scope prglob scntns ++ fnl ())
- (mt ()) (collect_notations stack)
+ prlist_with_sep fnl (pr_visible_in_scope prglob) (collect_notations stack)
let pr_visibility prglob = function
| Some scope -> pr_scope_stack prglob (push_scope scope !scope_stack)
diff --git a/interp/notation.mli b/interp/notation.mli
index 948831b317..d744ff41d9 100644
--- a/interp/notation.mli
+++ b/interp/notation.mli
@@ -229,12 +229,24 @@ type interp_rule =
| NotationRule of specific_notation
| SynDefRule of KerName.t
-val declare_notation_interpretation : notation -> scope_name option ->
- interpretation -> notation_location -> onlyprint:bool ->
- Deprecation.t option -> unit
+type notation_use =
+ | OnlyPrinting
+ | OnlyParsing
+ | ParsingAndPrinting
val declare_uninterpretation : interp_rule -> interpretation -> unit
+type entry_coercion_kind =
+ | IsEntryCoercion of notation_entry_level
+ | IsEntryGlobal of string * int
+ | IsEntryIdent of string * int
+
+val declare_notation : notation_with_optional_scope * notation ->
+ interpretation -> notation_location -> use:notation_use ->
+ entry_coercion_kind option ->
+ Deprecation.t option -> unit
+
+
(** Return the interpretation bound to a notation *)
val interp_notation : ?loc:Loc.t -> notation -> subscopes ->
interpretation * (notation_location * scope_name option)
@@ -257,16 +269,14 @@ val uninterp_ind_pattern_notations : inductive -> notation_rule list
val availability_of_notation : specific_notation -> subscopes ->
(scope_name option * delimiters option) option
+val is_printing_inactive_rule : interp_rule -> interpretation -> bool
+
(** {6 Miscellaneous} *)
(** If head is true, also allows applied global references. *)
val interp_notation_as_global_reference : ?loc:Loc.t -> head:bool -> (GlobRef.t -> bool) ->
notation_key -> delimiters option -> GlobRef.t
-(** Checks for already existing notations *)
-val exists_notation_in_scope : scope_name option -> notation ->
- bool -> interpretation -> bool
-
(** Declares and looks for scopes associated to arguments of a global ref *)
val declare_arguments_scope :
bool (** true=local *) -> GlobRef.t -> scope_name option list -> unit
diff --git a/interp/notation_ops.ml b/interp/notation_ops.ml
index 22531b0016..354809252e 100644
--- a/interp/notation_ops.ml
+++ b/interp/notation_ops.ml
@@ -27,7 +27,9 @@ open Notation_term
(* helper for NVar, NVar case in eq_notation_constr *)
let get_var_ndx id vs = try Some (List.index Id.equal id vs) with Not_found -> None
-let rec eq_notation_constr (vars1,vars2 as vars) t1 t2 = match t1, t2 with
+let rec eq_notation_constr (vars1,vars2 as vars) t1 t2 =
+(vars1 == vars2 && t1 == t2) ||
+match t1, t2 with
| NRef gr1, NRef gr2 -> GlobRef.equal gr1 gr2
| NVar id1, NVar id2 -> (
match (get_var_ndx id1 vars1,get_var_ndx id2 vars2) with
diff --git a/interp/stdarg.ml b/interp/stdarg.ml
index 343f85be03..70be55f843 100644
--- a/interp/stdarg.ml
+++ b/interp/stdarg.ml
@@ -40,8 +40,10 @@ let wit_int_or_var =
let wit_ident =
make0 "ident"
-let wit_var =
- make0 ~dyn:(val_tag (topwit wit_ident)) "var"
+let wit_hyp =
+ make0 ~dyn:(val_tag (topwit wit_ident)) "hyp"
+
+let wit_var = wit_hyp
let wit_ref = make0 "ref"
diff --git a/interp/stdarg.mli b/interp/stdarg.mli
index 3ae8b7d73f..bd34af5543 100644
--- a/interp/stdarg.mli
+++ b/interp/stdarg.mli
@@ -37,7 +37,10 @@ val wit_int_or_var : (int or_var, int or_var, int) genarg_type
val wit_ident : Id.t uniform_genarg_type
+val wit_hyp : (lident, lident, Id.t) genarg_type
+
val wit_var : (lident, lident, Id.t) genarg_type
+[@@ocaml.deprecated "Use Stdarg.wit_hyp"]
val wit_ref : (qualid, GlobRef.t located or_var, GlobRef.t) genarg_type
diff --git a/kernel/dune b/kernel/dune
index ce6fdc03df..bd663974da 100644
--- a/kernel/dune
+++ b/kernel/dune
@@ -3,7 +3,7 @@
(synopsis "The Coq Kernel")
(public_name coq.kernel)
(wrapped false)
- (modules (:standard \ genOpcodeFiles uint63_31 uint63_63))
+ (modules (:standard \ genOpcodeFiles uint63_31 uint63_63 float64_31 float64_63))
(libraries lib byterun dynlink))
(executable
@@ -19,6 +19,11 @@
(deps (:gen-file uint63_%{ocaml-config:int_size}.ml))
(action (copy# %{gen-file} %{targets})))
+(rule
+ (targets float64.ml)
+ (deps (:gen-file float64_%{ocaml-config:int_size}.ml))
+ (action (copy# %{gen-file} %{targets})))
+
(documentation
(package coq))
diff --git a/kernel/environ.ml b/kernel/environ.ml
index 03c9cb4be6..dec9e1deb8 100644
--- a/kernel/environ.ml
+++ b/kernel/environ.ml
@@ -274,6 +274,11 @@ let is_impredicative_sort env = function
let is_impredicative_univ env u = is_impredicative_sort env (Sorts.sort_of_univ u)
+let is_impredicative_family env = function
+ | Sorts.InSProp | Sorts.InProp -> true
+ | Sorts.InSet -> is_impredicative_set env
+ | Sorts.InType -> false
+
let type_in_type env = not (typing_flags env).check_universes
let deactivated_guard env = not (typing_flags env).check_guarded
@@ -467,14 +472,22 @@ let same_flags {
[@warning "+9"]
let set_cumulative_sprop b = map_universes (UGraph.set_cumulative_sprop b)
+let set_type_in_type b = map_universes (UGraph.set_type_in_type b)
let set_typing_flags c env =
if same_flags env.env_typing_flags c then env
- else set_cumulative_sprop c.cumulative_sprop { env with env_typing_flags = c }
+ else
+ let env = { env with env_typing_flags = c } in
+ let env = set_cumulative_sprop c.cumulative_sprop env in
+ let env = set_type_in_type (not c.check_universes) env in
+ env
let set_cumulative_sprop b env =
set_typing_flags {env.env_typing_flags with cumulative_sprop=b} env
+let set_type_in_type b env =
+ set_typing_flags {env.env_typing_flags with check_universes=not b} env
+
let set_allow_sprop b env =
{ env with env_stratification =
{ env.env_stratification with env_sprop_allowed = b } }
diff --git a/kernel/environ.mli b/kernel/environ.mli
index 974e794c6b..f443ba38e1 100644
--- a/kernel/environ.mli
+++ b/kernel/environ.mli
@@ -122,6 +122,7 @@ val indices_matter : env -> bool
val is_impredicative_sort : env -> Sorts.t -> bool
val is_impredicative_univ : env -> Univ.Universe.t -> bool
+val is_impredicative_family : env -> Sorts.family -> bool
(** is the local context empty *)
val empty_context : env -> bool
@@ -320,6 +321,7 @@ val push_subgraph : Univ.ContextSet.t -> env -> env
val set_engagement : engagement -> env -> env
val set_typing_flags : typing_flags -> env -> env
val set_cumulative_sprop : bool -> env -> env
+val set_type_in_type : bool -> env -> env
val set_allow_sprop : bool -> env -> env
val sprop_allowed : env -> bool
diff --git a/kernel/float64_31.ml b/kernel/float64_31.ml
new file mode 100644
index 0000000000..09b28e6cf0
--- /dev/null
+++ b/kernel/float64_31.ml
@@ -0,0 +1,35 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * Copyright INRIA, CNRS and contributors *)
+(* <O___,, * (see version control and CREDITS file for authors & dates) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+include Float64_common
+
+external mul : float -> float -> float = "coq_fmul_byte" "coq_fmul"
+[@@unboxed] [@@noalloc]
+
+external add : float -> float -> float = "coq_fadd_byte" "coq_fadd"
+[@@unboxed] [@@noalloc]
+
+external sub : float -> float -> float = "coq_fsub_byte" "coq_fsub"
+[@@unboxed] [@@noalloc]
+
+external div : float -> float -> float = "coq_fdiv_byte" "coq_fdiv"
+[@@unboxed] [@@noalloc]
+
+external sqrt : float -> float = "coq_fsqrt_byte" "coq_fsqrt"
+[@@unboxed] [@@noalloc]
+
+(*** Test at runtime that no harmful double rounding seems to
+ be performed with an intermediate 80 bits representation (x87). *)
+let () =
+ let b = ldexp 1. 53 in
+ let s = add 1. (ldexp 1. (-52)) in
+ if add b s <= b || add b 1. <> b || ldexp 1. (-1074) <= 0. then
+ failwith "Detected non IEEE-754 compliant architecture (or wrong \
+ rounding mode). Use of Float is thus unsafe."
diff --git a/kernel/float64_63.ml b/kernel/float64_63.ml
new file mode 100644
index 0000000000..0025531cb1
--- /dev/null
+++ b/kernel/float64_63.ml
@@ -0,0 +1,35 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * Copyright INRIA, CNRS and contributors *)
+(* <O___,, * (see version control and CREDITS file for authors & dates) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+include Float64_common
+
+let mul (x : float) (y : float) : float = x *. y
+[@@ocaml.inline always]
+
+let add (x : float) (y : float) : float = x +. y
+[@@ocaml.inline always]
+
+let sub (x : float) (y : float) : float = x -. y
+[@@ocaml.inline always]
+
+let div (x : float) (y : float) : float = x /. y
+[@@ocaml.inline always]
+
+let sqrt (x : float) : float = sqrt x
+[@@ocaml.inline always]
+
+(*** Test at runtime that no harmful double rounding seems to
+ be performed with an intermediate 80 bits representation (x87). *)
+let () =
+ let b = ldexp 1. 53 in
+ let s = add 1. (ldexp 1. (-52)) in
+ if add b s <= b || add b 1. <> b || ldexp 1. (-1074) <= 0. then
+ failwith "Detected non IEEE-754 compliant architecture (or wrong \
+ rounding mode). Use of Float is thus unsafe."
diff --git a/kernel/float64.ml b/kernel/float64_common.ml
index 76005a3dc6..2991a20b49 100644
--- a/kernel/float64.ml
+++ b/kernel/float64_common.ml
@@ -88,21 +88,6 @@ let classify x =
| FP_nan -> NaN
[@@ocaml.inline always]
-external mul : float -> float -> float = "coq_fmul_byte" "coq_fmul"
-[@@unboxed] [@@noalloc]
-
-external add : float -> float -> float = "coq_fadd_byte" "coq_fadd"
-[@@unboxed] [@@noalloc]
-
-external sub : float -> float -> float = "coq_fsub_byte" "coq_fsub"
-[@@unboxed] [@@noalloc]
-
-external div : float -> float -> float = "coq_fdiv_byte" "coq_fdiv"
-[@@unboxed] [@@noalloc]
-
-external sqrt : float -> float = "coq_fsqrt_byte" "coq_fsqrt"
-[@@unboxed] [@@noalloc]
-
let of_int63 x = Uint63.to_float x
[@@ocaml.inline always]
@@ -157,12 +142,3 @@ let total_compare f1 f2 =
let is_float64 t =
Obj.tag t = Obj.double_tag
[@@ocaml.inline always]
-
-(*** Test at runtime that no harmful double rounding seems to
- be performed with an intermediate 80 bits representation (x87). *)
-let () =
- let b = ldexp 1. 53 in
- let s = add 1. (ldexp 1. (-52)) in
- if add b s <= b || add b 1. <> b || ldexp 1. (-1074) <= 0. then
- failwith "Detected non IEEE-754 compliant architecture (or wrong \
- rounding mode). Use of Float is thus unsafe."
diff --git a/kernel/float64_common.mli b/kernel/float64_common.mli
new file mode 100644
index 0000000000..4fb1c114a5
--- /dev/null
+++ b/kernel/float64_common.mli
@@ -0,0 +1,95 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * Copyright INRIA, CNRS and contributors *)
+(* <O___,, * (see version control and CREDITS file for authors & dates) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+(** [t] is currently implemented by OCaml's [float] type.
+
+Beware: NaNs have a sign and a payload, while they should be
+indistinguishable from Coq's perspective. *)
+type t = float
+
+(** Test functions for special values to avoid calling [classify] *)
+val is_nan : t -> bool
+val is_infinity : t -> bool
+val is_neg_infinity : t -> bool
+
+val of_string : string -> t
+
+(** Print a float exactly as an hexadecimal value (exact decimal
+ * printing would be possible but sometimes requires more than 700
+ * digits). *)
+val to_hex_string : t -> string
+
+(** Print a float as a decimal value. The printing is not exact (the
+ * real value printed is not always the given floating-point value),
+ * however printing is precise enough that forall float [f],
+ * [of_string (to_decimal_string f) = f]. *)
+val to_string : t -> string
+
+val compile : t -> string
+
+val of_float : float -> t
+
+(** Return [true] for "-", [false] for "+". *)
+val sign : t -> bool
+
+val opp : t -> t
+val abs : t -> t
+
+type float_comparison = FEq | FLt | FGt | FNotComparable
+
+val eq : t -> t -> bool
+
+val lt : t -> t -> bool
+
+val le : t -> t -> bool
+
+(** The IEEE 754 float comparison.
+ * NotComparable is returned if there is a NaN in the arguments *)
+val compare : t -> t -> float_comparison
+[@@ocaml.inline always]
+
+type float_class =
+ | PNormal | NNormal | PSubn | NSubn | PZero | NZero | PInf | NInf | NaN
+
+val classify : t -> float_class
+[@@ocaml.inline always]
+
+(** Link with integers *)
+val of_int63 : Uint63.t -> t
+[@@ocaml.inline always]
+
+val normfr_mantissa : t -> Uint63.t
+[@@ocaml.inline always]
+
+(** Shifted exponent extraction *)
+val eshift : int
+
+val frshiftexp : t -> t * Uint63.t (* float remainder, shifted exponent *)
+[@@ocaml.inline always]
+
+val ldshiftexp : t -> Uint63.t -> t
+[@@ocaml.inline always]
+
+val next_up : t -> t
+
+val next_down : t -> t
+
+(** Return true if two floats are equal.
+ * All NaN values are considered equal. *)
+val equal : t -> t -> bool
+[@@ocaml.inline always]
+
+val hash : t -> int
+
+(** Total order relation over float values. Behaves like [Pervasives.compare].*)
+val total_compare : t -> t -> int
+
+val is_float64 : Obj.t -> bool
+[@@ocaml.inline always]
diff --git a/kernel/indTyping.ml b/kernel/indTyping.ml
index 179353d3f0..b2520b780f 100644
--- a/kernel/indTyping.ml
+++ b/kernel/indTyping.ml
@@ -77,7 +77,7 @@ let check_univ_leq ?(is_real_arg=false) env u info =
else info
in
(* Inductive types provide explicit lifting from SProp to other universes, so allow SProp <= any. *)
- if type_in_type env || Univ.Universe.is_sprop u || UGraph.check_leq (universes env) u ind_univ
+ if Univ.Universe.is_sprop u || UGraph.check_leq (universes env) u ind_univ
then { info with ind_min_univ = Option.map (Universe.sup u) info.ind_min_univ }
else if is_impredicative_univ env ind_univ
&& Option.is_empty info.ind_min_univ then { info with ind_squashed = true }
diff --git a/kernel/kernel.mllib b/kernel/kernel.mllib
index d4d7150222..5b2a7bd9c2 100644
--- a/kernel/kernel.mllib
+++ b/kernel/kernel.mllib
@@ -2,6 +2,7 @@ Names
TransparentState
Uint63
Parray
+Float64_common
Float64
Univ
UGraph
diff --git a/kernel/mod_typing.ml b/kernel/mod_typing.ml
index 5873d1f502..c7b866179b 100644
--- a/kernel/mod_typing.ml
+++ b/kernel/mod_typing.ml
@@ -80,12 +80,11 @@ let rec check_with_def env struc (idl,(c,ctx)) mp equiv =
let j = Typeops.infer env' c in
assert (j.uj_val == c); (* relevances should already be correct here *)
let typ = cb.const_type in
- let cst' = Reduction.infer_conv_leq env' (Environ.universes env')
- j.uj_type typ in
+ let cst' = Reduction.infer_conv_leq env' j.uj_type typ in
j.uj_val, cst'
| Def cs ->
let c' = Mod_subst.force_constr cs in
- c, Reduction.infer_conv env' (Environ.universes env') c c'
+ c, Reduction.infer_conv env' c c'
| Primitive _ ->
error_incorrect_with_constraint lab
in
@@ -103,12 +102,11 @@ let rec check_with_def env struc (idl,(c,ctx)) mp equiv =
let j = Typeops.infer env' c in
assert (j.uj_val == c); (* relevances should already be correct here *)
let typ = cb.const_type in
- let cst' = Reduction.infer_conv_leq env' (Environ.universes env')
- j.uj_type typ in
+ let cst' = Reduction.infer_conv_leq env' j.uj_type typ in
cst'
| Def cs ->
let c' = Mod_subst.force_constr cs in
- let cst' = Reduction.infer_conv env' (Environ.universes env') c c' in
+ let cst' = Reduction.infer_conv env' c c' in
cst'
| Primitive _ ->
error_incorrect_with_constraint lab
diff --git a/kernel/nativeconv.ml b/kernel/nativeconv.ml
index 01e9550ec5..fc6afb79d4 100644
--- a/kernel/nativeconv.ml
+++ b/kernel/nativeconv.ml
@@ -176,7 +176,7 @@ let native_conv cv_pb sigma env t1 t2 =
else Constr.eq_constr_univs univs t1 t2
in
if not b then
- let univs = (univs, checked_universes) in
+ let state = (univs, checked_universes) in
let t1 = Term.it_mkLambda_or_LetIn t1 (Environ.rel_context env) in
let t2 = Term.it_mkLambda_or_LetIn t2 (Environ.rel_context env) in
- let _ = native_conv_gen cv_pb sigma env univs t1 t2 in ()
+ let _ = native_conv_gen cv_pb sigma env state t1 t2 in ()
diff --git a/kernel/reduction.ml b/kernel/reduction.ml
index 7c6b869b4a..96bf370342 100644
--- a/kernel/reduction.ml
+++ b/kernel/reduction.ml
@@ -189,7 +189,7 @@ type 'a kernel_conversion_function = env -> 'a -> 'a -> unit
(* functions of this type can be called from outside the kernel *)
type 'a extended_conversion_function =
?l2r:bool -> ?reds:TransparentState.t -> env ->
- ?evars:((existential->constr option) * UGraph.t) ->
+ ?evars:(existential->constr option) ->
'a -> 'a -> unit
exception NotConvertible
@@ -210,9 +210,6 @@ type conv_pb =
let is_cumul = function CUMUL -> true | CONV -> false
type 'a universe_compare = {
- (* used in reduction *)
- compare_graph : 'a -> UGraph.t;
-
(* Might raise NotConvertible *)
compare_sorts : env -> conv_pb -> Sorts.t -> Sorts.t -> 'a -> 'a;
compare_instances: flex:bool -> Univ.Instance.t -> Univ.Instance.t -> 'a -> 'a;
@@ -224,7 +221,7 @@ type 'a universe_state = 'a * 'a universe_compare
type ('a,'b) generic_conversion_function = env -> 'b universe_state -> 'a -> 'a -> 'b
-type 'a infer_conversion_function = env -> UGraph.t -> 'a -> 'a -> Univ.Constraint.t
+type 'a infer_conversion_function = env -> 'a -> 'a -> Univ.Constraint.t
let sort_cmp_universes env pb s0 s1 (u, check) =
(check.compare_sorts env pb s0 s1 u, check)
@@ -765,9 +762,8 @@ and convert_list l2r infos lft1 lft2 v1 v2 cuniv = match v1, v2 with
convert_list l2r infos lft1 lft2 v1 v2 cuniv
| _, _ -> raise NotConvertible
-let clos_gen_conv trans cv_pb l2r evars env univs t1 t2 =
+let clos_gen_conv trans cv_pb l2r evars env graph univs t1 t2 =
let reds = CClosure.RedFlags.red_add_transparent betaiotazeta trans in
- let graph = (snd univs).compare_graph (fst univs) in
let infos = create_clos_infos ~univs:graph ~evars reds env in
let infos = {
cnv_inf = infos;
@@ -815,8 +811,7 @@ let check_inductive_instances cv_pb variance u1 u2 univs =
else raise NotConvertible
let checked_universes =
- { compare_graph = (fun x -> x);
- compare_sorts = checked_sort_cmp_universes;
+ { compare_sorts = checked_sort_cmp_universes;
compare_instances = check_convert_instances;
compare_cumul_instances = check_inductive_instances; }
@@ -878,8 +873,7 @@ let infer_inductive_instances cv_pb variance u1 u2 (univs,csts') =
(univs, Univ.Constraint.union csts csts')
let inferred_universes : (UGraph.t * Univ.Constraint.t) universe_compare =
- { compare_graph = (fun (x,_) -> x);
- compare_sorts = infer_cmp_universes;
+ { compare_sorts = infer_cmp_universes;
compare_instances = infer_convert_instances;
compare_cumul_instances = infer_inductive_instances; }
@@ -890,12 +884,12 @@ let gen_conv cv_pb l2r reds env evars univs t1 t2 =
in
if b then ()
else
- let _ = clos_gen_conv reds cv_pb l2r evars env (univs, checked_universes) t1 t2 in
+ let _ = clos_gen_conv reds cv_pb l2r evars env univs (univs, checked_universes) t1 t2 in
()
(* Profiling *)
-let gen_conv cv_pb ?(l2r=false) ?(reds=TransparentState.full) env ?(evars=(fun _->None), universes env) =
- let evars, univs = evars in
+let gen_conv cv_pb ?(l2r=false) ?(reds=TransparentState.full) env ?(evars=(fun _->None)) =
+ let univs = Environ.universes env in
if Flags.profile then
let fconv_universes_key = CProfile.declare_profile "trans_fconv_universes" in
CProfile.profile8 fconv_universes_key gen_conv cv_pb l2r reds env evars univs
@@ -906,35 +900,37 @@ let conv = gen_conv CONV
let conv_leq = gen_conv CUMUL
let generic_conv cv_pb ~l2r evars reds env univs t1 t2 =
+ let graph = Environ.universes env in
let (s, _) =
- clos_gen_conv reds cv_pb l2r evars env univs t1 t2
+ clos_gen_conv reds cv_pb l2r evars env graph univs t1 t2
in s
-let infer_conv_universes cv_pb l2r evars reds env univs t1 t2 =
+let infer_conv_universes cv_pb l2r evars reds env t1 t2 =
+ let univs = Environ.universes env in
let b, cstrs =
if cv_pb == CUMUL then Constr.leq_constr_univs_infer univs t1 t2
else Constr.eq_constr_univs_infer univs t1 t2
in
if b then cstrs
else
- let univs = ((univs, Univ.Constraint.empty), inferred_universes) in
- let ((_,cstrs), _) = clos_gen_conv reds cv_pb l2r evars env univs t1 t2 in
+ let state = ((univs, Univ.Constraint.empty), inferred_universes) in
+ let ((_,cstrs), _) = clos_gen_conv reds cv_pb l2r evars env univs state t1 t2 in
cstrs
(* Profiling *)
let infer_conv_universes =
if Flags.profile then
let infer_conv_universes_key = CProfile.declare_profile "infer_conv_universes" in
- CProfile.profile8 infer_conv_universes_key infer_conv_universes
+ CProfile.profile7 infer_conv_universes_key infer_conv_universes
else infer_conv_universes
let infer_conv ?(l2r=false) ?(evars=fun _ -> None) ?(ts=TransparentState.full)
- env univs t1 t2 =
- infer_conv_universes CONV l2r evars ts env univs t1 t2
+ env t1 t2 =
+ infer_conv_universes CONV l2r evars ts env t1 t2
let infer_conv_leq ?(l2r=false) ?(evars=fun _ -> None) ?(ts=TransparentState.full)
- env univs t1 t2 =
- infer_conv_universes CUMUL l2r evars ts env univs t1 t2
+ env t1 t2 =
+ infer_conv_universes CUMUL l2r evars ts env t1 t2
let default_conv cv_pb ?l2r:_ env t1 t2 =
gen_conv cv_pb env t1 t2
diff --git a/kernel/reduction.mli b/kernel/reduction.mli
index 4ae3838691..7d32596f74 100644
--- a/kernel/reduction.mli
+++ b/kernel/reduction.mli
@@ -31,14 +31,12 @@ exception NotConvertible
type 'a kernel_conversion_function = env -> 'a -> 'a -> unit
type 'a extended_conversion_function =
?l2r:bool -> ?reds:TransparentState.t -> env ->
- ?evars:((existential->constr option) * UGraph.t) ->
+ ?evars:(existential->constr option) ->
'a -> 'a -> unit
type conv_pb = CONV | CUMUL
type 'a universe_compare = {
- compare_graph : 'a -> UGraph.t; (* used for case inversion in reduction *)
-
(* Might raise NotConvertible *)
compare_sorts : env -> conv_pb -> Sorts.t -> Sorts.t -> 'a -> 'a;
compare_instances: flex:bool -> Univ.Instance.t -> Univ.Instance.t -> 'a -> 'a;
@@ -50,7 +48,7 @@ type 'a universe_state = 'a * 'a universe_compare
type ('a,'b) generic_conversion_function = env -> 'b universe_state -> 'a -> 'a -> 'b
-type 'a infer_conversion_function = env -> UGraph.t -> 'a -> 'a -> Univ.Constraint.t
+type 'a infer_conversion_function = env -> 'a -> 'a -> Univ.Constraint.t
val get_cumulativity_constraints : conv_pb -> Univ.Variance.t array ->
Univ.Instance.t -> Univ.Instance.t -> Univ.Constraint.t
diff --git a/kernel/safe_typing.ml b/kernel/safe_typing.ml
index da77a2882e..3dee3d2b2f 100644
--- a/kernel/safe_typing.ml
+++ b/kernel/safe_typing.ml
@@ -79,8 +79,10 @@ module NamedDecl = Context.Named.Declaration
* STRUCT (params,oldsenv) : inside a local module, with
module parameters [params] and earlier environment [oldsenv]
* SIG (params,oldsenv) : same for a local module type
- - [modresolver] : delta_resolver concerning the module content
- - [paramresolver] : delta_resolver concerning the module parameters
+ - [modresolver] : delta_resolver concerning the module content, that needs to
+ be marshalled on disk
+ - [paramresolver] : delta_resolver in scope but not part of the library per
+ se, that is from functor parameters and required libraries
- [revstruct] : current module content, most recent declarations first
- [modlabels] and [objlabels] : names defined in the current module,
either for modules/modtypes or for constants/inductives.
@@ -1301,7 +1303,9 @@ let import lib cst vodigest senv =
mp,
{ senv with
env;
- modresolver = Mod_subst.add_delta_resolver mb.mod_delta senv.modresolver;
+ (* Do NOT store the name quotient from the dependencies in the set of
+ constraints that will be marshalled on disk. *)
+ paramresolver = Mod_subst.add_delta_resolver mb.mod_delta senv.paramresolver;
required = DPmap.add lib.comp_name vodigest senv.required;
loads = (mp,mb)::senv.loads;
sections;
diff --git a/kernel/subtyping.ml b/kernel/subtyping.ml
index 28baa82666..76a1c190be 100644
--- a/kernel/subtyping.ml
+++ b/kernel/subtyping.ml
@@ -85,7 +85,7 @@ let make_labmap mp list =
let check_conv_error error why cst poly f env a1 a2 =
try
- let cst' = f env (Environ.universes env) a1 a2 in
+ let cst' = f env a1 a2 in
if poly then
if Constraint.is_empty cst' then cst
else error (IncompatiblePolymorphism (env, a1, a2))
diff --git a/kernel/typeops.mli b/kernel/typeops.mli
index 87a5666fcc..d381e55dd6 100644
--- a/kernel/typeops.mli
+++ b/kernel/typeops.mli
@@ -111,7 +111,7 @@ val type_of_global_in_context : env -> GlobRef.t -> types * Univ.AUContext.t
(** {6 Miscellaneous. } *)
(** Check that hyps are included in env and fails with error otherwise *)
-val check_hyps_inclusion : env -> ?evars:((existential->constr option) * UGraph.t) ->
+val check_hyps_inclusion : env -> ?evars:(existential->constr option) ->
GlobRef.t -> Constr.named_context -> unit
(** Types for primitives *)
diff --git a/kernel/uGraph.ml b/kernel/uGraph.ml
index 52e93a9e22..096e458ec4 100644
--- a/kernel/uGraph.ml
+++ b/kernel/uGraph.ml
@@ -29,7 +29,12 @@ module G = AcyclicGraph.Make(struct
code (eg add_universe with a constraint vs G.add with no
constraint) *)
-type t = { graph: G.t; sprop_cumulative : bool }
+type t = {
+ graph: G.t;
+ sprop_cumulative : bool;
+ type_in_type : bool;
+}
+
type 'a check_function = t -> 'a -> 'a -> bool
let g_map f g =
@@ -39,6 +44,10 @@ let g_map f g =
let set_cumulative_sprop b g = {g with sprop_cumulative=b}
+let set_type_in_type b g = {g with type_in_type=b}
+
+let type_in_type g = g.type_in_type
+
let check_smaller_expr g (u,n) (v,m) =
let diff = n - m in
match diff with
@@ -55,28 +64,33 @@ let real_check_leq g u v =
Universe.for_all (fun ul -> exists_bigger g ul v) u
let check_leq g u v =
+ type_in_type g ||
Universe.equal u v || (g.sprop_cumulative && Universe.is_sprop u) ||
(not (Universe.is_sprop u) && not (Universe.is_sprop v) &&
(is_type0m_univ u ||
real_check_leq g u v))
let check_eq g u v =
+ type_in_type g ||
Universe.equal u v ||
(not (Universe.is_sprop u || Universe.is_sprop v) &&
(real_check_leq g u v && real_check_leq g v u))
let check_eq_level g u v =
u == v ||
+ type_in_type g ||
(not (Level.is_sprop u || Level.is_sprop v) && G.check_eq g.graph u v)
-let empty_universes = {graph=G.empty; sprop_cumulative=false}
+let empty_universes = {graph=G.empty; sprop_cumulative=false; type_in_type=false}
let initial_universes =
let big_rank = 1000000 in
let g = G.empty in
let g = G.add ~rank:big_rank Level.prop g in
let g = G.add ~rank:big_rank Level.set g in
- {graph=G.enforce_lt Level.prop Level.set g; sprop_cumulative=false}
+ {empty_universes with graph=G.enforce_lt Level.prop Level.set g}
+
+let initial_universes_with g = {g with graph=initial_universes.graph}
let enforce_constraint (u,d,v) g =
match d with
@@ -91,6 +105,10 @@ let enforce_constraint (u,d,v as cst) g =
| true, Le, false when g.sprop_cumulative -> g
| _ -> raise (UniverseInconsistency (d,Universe.make u, Universe.make v, None))
+let enforce_constraint cst g =
+ if not (type_in_type g) then enforce_constraint cst g
+ else try enforce_constraint cst g with UniverseInconsistency _ -> g
+
let merge_constraints csts g = Constraint.fold enforce_constraint csts g
let check_constraint g (u,d,v) =
@@ -103,8 +121,8 @@ let check_constraint g (u,d,v as cst) =
match Level.is_sprop u, d, Level.is_sprop v with
| false, _, false -> check_constraint g.graph cst
| true, (Eq|Le), true -> true
- | true, Le, false -> g.sprop_cumulative
- | _ -> false
+ | true, Le, false -> g.sprop_cumulative || type_in_type g
+ | _ -> type_in_type g
let check_constraints csts g = Constraint.for_all (check_constraint g) csts
@@ -145,8 +163,10 @@ let enforce_leq_alg u v g =
let enforce_leq_alg u v g =
match Universe.is_sprop u, Universe.is_sprop v with
| true, true -> Constraint.empty, g
- | true, false | false, true -> raise (UniverseInconsistency (Le, u, v, None))
| false, false -> enforce_leq_alg u v g
+ | left, _ ->
+ if left && g.sprop_cumulative then Constraint.empty, g
+ else raise (UniverseInconsistency (Le, u, v, None))
(* sanity check wrapper *)
let enforce_leq_alg u v g =
diff --git a/kernel/uGraph.mli b/kernel/uGraph.mli
index c9fbd7f694..87b3634e28 100644
--- a/kernel/uGraph.mli
+++ b/kernel/uGraph.mli
@@ -16,6 +16,15 @@ type t
val set_cumulative_sprop : bool -> t -> t
(** Makes the system incomplete. *)
+val set_type_in_type : bool -> t -> t
+
+(** When [type_in_type], functions adding constraints do not fail and
+ may instead ignore inconsistent constraints.
+
+ Checking functions such as [check_leq] always return [true].
+*)
+val type_in_type : t -> bool
+
type 'a check_function = t -> 'a -> 'a -> bool
val check_leq : Universe.t check_function
@@ -25,6 +34,9 @@ val check_eq_level : Level.t check_function
(** The initial graph of universes: Prop < Set *)
val initial_universes : t
+(** Initial universes, but keeping options such as type in type from the argument. *)
+val initial_universes_with : t -> t
+
(** Check equality of instances w.r.t. a universe graph *)
val check_eq_instances : Instance.t check_function
diff --git a/kernel/univ.ml b/kernel/univ.ml
index 6d8aa02dff..a2fd14025e 100644
--- a/kernel/univ.ml
+++ b/kernel/univ.ml
@@ -205,12 +205,6 @@ module Level = struct
let pr u = str (to_string u)
- let apart u v =
- match data u, data v with
- | SProp, _ | _, SProp
- | Prop, Set | Set, Prop -> true
- | _ -> false
-
let vars = Array.init 20 (fun i -> make (Var i))
let var n =
@@ -250,7 +244,7 @@ module LMap = struct
ext empty
let pr f m =
- h 0 (prlist_with_sep fnl (fun (u, v) ->
+ h (prlist_with_sep fnl (fun (u, v) ->
Level.pr u ++ f v) (bindings m))
end
@@ -568,16 +562,6 @@ let constraint_type_ord c1 c2 = match c1, c2 with
| Eq, Eq -> 0
| Eq, _ -> 1
-(* Universe inconsistency: error raised when trying to enforce a relation
- that would create a cycle in the graph of universes. *)
-
-type univ_inconsistency = constraint_type * universe * universe * explanation Lazy.t option
-
-exception UniverseInconsistency of univ_inconsistency
-
-let error_inconsistency o u v p =
- raise (UniverseInconsistency (o,Universe.make u,Universe.make v,p))
-
(* Constraints and sets of constraints. *)
type univ_constraint = Level.t * constraint_type * Level.t
@@ -660,8 +644,6 @@ type 'a constraint_function = 'a -> 'a -> constraints -> constraints
let enforce_eq_level u v c =
(* We discard trivial constraints like u=u *)
if Level.equal u v then c
- else if Level.apart u v then
- error_inconsistency Eq u v None
else Constraint.add (u,Eq,v) c
let enforce_eq u v c =
@@ -684,9 +666,9 @@ let constraint_add_leq v u c =
let j = m - n in
if j = -1 (* n = m+1, v+1 <= u <-> v < u *) then
Constraint.add (x,Lt,y) c
- else if j <= -1 (* n = m+k, v+k <= u <-> v+(k-1) < u *) then
- if Level.equal x y then (* u+(k+1) <= u *)
- raise (UniverseInconsistency (Le, Universe.tip v, Universe.tip u, None))
+ else if j <= -1 (* n = m+k, v+k <= u and k>0 *) then
+ if Level.equal x y then (* u+k <= u with k>0 *)
+ Constraint.add (x,Lt,x) c
else anomaly (Pp.str"Unable to handle arbitrary u+k <= v constraints.")
else if j = 0 then
Constraint.add (x,Le,y) c
@@ -703,8 +685,8 @@ let check_univ_leq u v =
let enforce_leq u v c =
match Universe.is_sprop u, Universe.is_sprop v with
| true, true -> c
- | true, false | false, true ->
- raise (UniverseInconsistency (Le, u, v, None))
+ | true, false -> Constraint.add (Level.sprop,Le,Level.prop) c
+ | false, true -> Constraint.add (Level.prop,Le,Level.sprop) c
| false, false ->
List.fold_left (fun c v -> (List.fold_left (fun c u -> constraint_add_leq u v c) c u)) c v
@@ -961,7 +943,7 @@ struct
let pr prl ?variance (univs, cst as ctx) =
if is_empty ctx then mt() else
- h 0 (Instance.pr prl ?variance univs ++ str " |= ") ++ h 0 (v 0 (Constraint.pr prl cst))
+ h (Instance.pr prl ?variance univs ++ str " |= ") ++ h (v 0 (Constraint.pr prl cst))
let hcons (univs, cst) =
(Instance.hcons univs, hcons_constraints cst)
@@ -1076,7 +1058,7 @@ struct
let pr prl (univs, cst as ctx) =
if is_empty ctx then mt() else
- h 0 (LSet.pr prl univs ++ str " |= ") ++ h 0 (v 0 (Constraint.pr prl cst))
+ h (LSet.pr prl univs ++ str " |= ") ++ h (v 0 (Constraint.pr prl cst))
let constraints (_univs, cst) = cst
let levels (univs, _cst) = univs
@@ -1232,6 +1214,14 @@ let hcons_universe_context_set (v, c) =
let hcons_univ x = Universe.hcons x
+(* Universe inconsistency: error raised when trying to enforce a relation
+ that would create a cycle in the graph of universes. *)
+
+type univ_inconsistency = constraint_type * universe * universe * explanation Lazy.t option
+
+(* Do not use in this file as we may be type-in-type *)
+exception UniverseInconsistency of univ_inconsistency
+
let explain_universe_inconsistency prl (o,u,v,p : univ_inconsistency) =
let pr_uni = Universe.pr_with prl in
let pr_rel = function
diff --git a/kernel/vconv.ml b/kernel/vconv.ml
index cc2c2c0b4b..948195797e 100644
--- a/kernel/vconv.ml
+++ b/kernel/vconv.ml
@@ -211,5 +211,5 @@ let vm_conv cv_pb env t1 t2 =
else Constr.eq_constr_univs univs t1 t2
in
if not b then
- let univs = (univs, checked_universes) in
- let _ = vm_conv_gen cv_pb env univs t1 t2 in ()
+ let state = (univs, checked_universes) in
+ let _ = vm_conv_gen cv_pb env state t1 t2 in ()
diff --git a/kernel/vmbytecodes.ml b/kernel/vmbytecodes.ml
index 74405a0105..c156a21c86 100644
--- a/kernel/vmbytecodes.ml
+++ b/kernel/vmbytecodes.ml
@@ -106,14 +106,14 @@ let rec pp_instr i =
| Kclosure(lbl, n) ->
str "closure " ++ pp_lbl lbl ++ str ", " ++ int n
| Kclosurerec(fv,init,lblt,lblb) ->
- h 1 (str "closurerec " ++
+ hv 1 (str "closurerec " ++
int fv ++ str ", " ++ int init ++
str " types = " ++
prlist_with_sep spc pp_lbl (Array.to_list lblt) ++
str " bodies = " ++
prlist_with_sep spc pp_lbl (Array.to_list lblb))
| Kclosurecofix (fv,init,lblt,lblb) ->
- h 1 (str "closurecofix " ++
+ hv 1 (str "closurecofix " ++
int fv ++ str ", " ++ int init ++
str " types = " ++
prlist_with_sep spc pp_lbl (Array.to_list lblt) ++
@@ -129,7 +129,7 @@ let rec pp_instr i =
str "makeswitchblock " ++ pp_lbl lblt ++ str ", " ++
pp_lbl lbls ++ str ", " ++ int sz
| Kswitch(lblc,lblb) ->
- h 1 (str "switch " ++
+ hv 1 (str "switch " ++
prlist_with_sep spc pp_lbl (Array.to_list lblc) ++
str " | " ++
prlist_with_sep spc pp_lbl (Array.to_list lblb))
diff --git a/lib/explore.ml b/lib/explore.ml
index b3ffef6ac2..139de488e2 100644
--- a/lib/explore.ml
+++ b/lib/explore.ml
@@ -29,7 +29,7 @@ module Make = functor(S : SearchProblem) -> struct
| [i] -> int i
| i :: l -> pp_rec l ++ str "." ++ int i
in
- Feedback.msg_debug (h 0 (pp_rec p) ++ pp)
+ Feedback.msg_debug (h (pp_rec p) ++ pp)
(*s Depth first search. *)
diff --git a/lib/flags.ml b/lib/flags.ml
index 1d9d6d49bc..83733cf00d 100644
--- a/lib/flags.ml
+++ b/lib/flags.ml
@@ -47,6 +47,7 @@ let async_proofs_is_worker () = !async_proofs_worker_id <> "master"
let load_vos_libraries = ref false
let debug = ref false
+let xml_debug = ref false
let in_debugger = ref false
let in_toplevel = ref false
diff --git a/lib/flags.mli b/lib/flags.mli
index 30d1b5b2bd..ebd23a4d20 100644
--- a/lib/flags.mli
+++ b/lib/flags.mli
@@ -41,6 +41,7 @@ val load_vos_libraries : bool ref
(** Debug flags *)
val debug : bool ref
+val xml_debug : bool ref
val in_debugger : bool ref
val in_toplevel : bool ref
diff --git a/lib/pp.ml b/lib/pp.ml
index 78c5186449..a9994ac6fd 100644
--- a/lib/pp.ml
+++ b/lib/pp.ml
@@ -22,7 +22,7 @@
type pp_tag = string
type block_type =
- | Pp_hbox of int
+ | Pp_hbox
| Pp_vbox of int
| Pp_hvbox of int
| Pp_hovbox of int
@@ -131,7 +131,7 @@ let strbrk s =
let ismt = function | Ppcmd_empty -> true | _ -> false
(* boxing commands *)
-let h n s = Ppcmd_box(Pp_hbox n,s)
+let h s = Ppcmd_box(Pp_hbox,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)
@@ -151,7 +151,7 @@ let escape_string s =
let qstring s = str "\"" ++ str (escape_string s) ++ str "\""
let qs = qstring
-let quote s = h 0 (str "\"" ++ s ++ str "\"")
+let quote s = h (str "\"" ++ s ++ str "\"")
let rec pr_com ft s =
let (s1,os) =
@@ -181,7 +181,7 @@ let split_tag tag =
(* pretty printing functions *)
let pp_with ft pp =
let cpp_open_box = function
- | Pp_hbox n -> Format.pp_open_hbox ft ()
+ | Pp_hbox -> 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
@@ -309,12 +309,14 @@ let db_print_pp fmt pp =
let block_type fmt btype =
let (bt, v) =
match btype with
- | Pp_hbox v -> ("Pp_hbox", v)
- | Pp_vbox v -> ("Pp_vbox", v)
- | Pp_hvbox v -> ("Pp_hvbox", v)
- | Pp_hovbox v -> ("Pp_hovbox", v)
+ | Pp_hbox -> ("Pp_hbox", None)
+ | Pp_vbox v -> ("Pp_vbox", Some v)
+ | Pp_hvbox v -> ("Pp_hvbox", Some v)
+ | Pp_hovbox v -> ("Pp_hovbox", Some v)
in
- fprintf fmt "%s %d" bt v
+ match v with
+ | None -> fprintf fmt "%s" bt
+ | Some v -> fprintf fmt "%s %d" bt v
in
let rec db_print_pp_r indent pp =
let ind () = fprintf fmt "%s" (String.make (2 * indent) ' ') in
diff --git a/lib/pp.mli b/lib/pp.mli
index b265537728..12f1ba9bb2 100644
--- a/lib/pp.mli
+++ b/lib/pp.mli
@@ -43,7 +43,7 @@ type pp_tag = string
type t
type block_type =
- | Pp_hbox of int
+ | Pp_hbox
| Pp_vbox of int
| Pp_hvbox of int
| Pp_hovbox of int
@@ -99,7 +99,7 @@ val strbrk : string -> t
(** {6 Boxing commands} *)
-val h : int -> t -> t
+val h : t -> t
val v : int -> t -> t
val hv : int -> t -> t
val hov : int -> t -> t
diff --git a/lib/pp_diff.ml b/lib/pp_diff.ml
index 988e8e4303..4593bf4b07 100644
--- a/lib/pp_diff.ml
+++ b/lib/pp_diff.ml
@@ -109,7 +109,7 @@ let shorten_diff_span dtype diff_list =
iter 0 len (<) 1; (* left to right *)
iter (len-1) (-1) (>) (-1); (* right to left *)
- if !changed then Array.to_list diffs else diff_list;;
+ if !changed then Array.to_list diffs else diff_list
let has_changes diffs =
let rec has_changes_r diffs added removed =
@@ -118,12 +118,12 @@ let has_changes diffs =
| `Removed _ :: t -> has_changes_r t added true
| h :: t -> has_changes_r t added removed
| [] -> (added, removed) in
- has_changes_r diffs false false;;
+ has_changes_r diffs false false
(* get the Myers diff of 2 lists of strings *)
let diff_strs old_strs new_strs =
let diffs = List.rev (StringDiff.diff old_strs new_strs) in
- shorten_diff_span `Removed (shorten_diff_span `Added diffs);;
+ shorten_diff_span `Removed (shorten_diff_span `Added diffs)
(* Default string tokenizer. Makes each character a separate strin.
Whitespace is not ignored. Doesn't handle UTF-8 differences well. *)
@@ -139,7 +139,7 @@ let def_tokenize_string s =
let diff_str ?(tokenize_string=def_tokenize_string) old_str new_str =
let old_toks = Array.of_list (tokenize_string old_str)
and new_toks = Array.of_list (tokenize_string new_str) in
- diff_strs old_toks new_toks;;
+ diff_strs old_toks new_toks
let get_dinfo = function
| `Common (_, _, s) -> (`Common, s)
@@ -281,14 +281,14 @@ let add_diff_tags which pp diffs =
skip ();
if !diffs <> [] then
raise (Diff_Failure "left-over diff info at end of Pp.t, should be impossible");
- if has_added || has_removed then wrap_in_bg diff_tag rv else rv;;
+ if has_added || has_removed then wrap_in_bg diff_tag rv else rv
let diff_pp ?(tokenize_string=def_tokenize_string) o_pp n_pp =
let open Pp in
let o_str = string_of_ppcmds o_pp in
let n_str = string_of_ppcmds n_pp in
let diffs = diff_str ~tokenize_string o_str n_str in
- (add_diff_tags `Removed o_pp diffs, add_diff_tags `Added n_pp diffs);;
+ (add_diff_tags `Removed o_pp diffs, add_diff_tags `Added n_pp diffs)
let diff_pp_combined ?(tokenize_string=def_tokenize_string) ?(show_removed=false) o_pp n_pp =
let open Pp in
@@ -300,4 +300,4 @@ let diff_pp_combined ?(tokenize_string=def_tokenize_string) ?(show_removed=false
if show_removed && has_removed then
let removed = add_diff_tags `Removed o_pp diffs in
(v 0 (removed ++ cut() ++ added))
- else added;;
+ else added
diff --git a/parsing/g_constr.mlg b/parsing/g_constr.mlg
index 1ec83c496a..644493a010 100644
--- a/parsing/g_constr.mlg
+++ b/parsing/g_constr.mlg
@@ -154,7 +154,7 @@ GRAMMAR EXTEND Gram
| "10" LEFTA
[ f = operconstr; args = LIST1 appl_arg -> { CAst.make ~loc @@ CApp((None,f),args) }
| "@"; f = global; i = univ_instance; args = LIST0 NEXT -> { CAst.make ~loc @@ CAppExpl((None,f,i),args) }
- | "@"; lid = pattern_identref; args = LIST1 identref ->
+ | "@"; lid = pattern_ident; args = LIST1 identref ->
{ let { CAst.loc = locid; v = id } = lid in
let args = List.map (fun x -> CAst.make @@ CRef (qualid_of_ident ?loc:x.CAst.loc x.CAst.v, None), None) args in
CAst.make ~loc @@ CApp((None, CAst.make ?loc:locid @@ CPatVar id),args) } ]
@@ -252,7 +252,7 @@ GRAMMAR EXTEND Gram
| "cofix"; c = cofix_decls -> { let (id,dcls) = c in CAst.make ~loc @@ CCoFix (id,dcls) } ] ]
;
appl_arg:
- [ [ test_lpar_id_coloneq; "("; id = ident; ":="; c = lconstr; ")" -> { (c,Some (CAst.make ~loc @@ ExplByName id)) }
+ [ [ test_lpar_id_coloneq; "("; id = identref; ":="; c = lconstr; ")" -> { (c,Some (CAst.make ?loc:id.CAst.loc @@ ExplByName id.CAst.v)) }
| c=operconstr LEVEL "9" -> { (c,None) } ] ]
;
atomic_constr:
@@ -261,12 +261,12 @@ GRAMMAR EXTEND Gram
| n = NUMBER-> { CAst.make ~loc @@ CPrim (Numeral (NumTok.SPlus,n)) }
| s = string -> { CAst.make ~loc @@ CPrim (String s) }
| "_" -> { CAst.make ~loc @@ CHole (None, IntroAnonymous, None) }
- | "?"; "["; id = ident; "]" -> { CAst.make ~loc @@ CHole (None, IntroIdentifier id, None) }
- | "?"; "["; id = pattern_ident; "]" -> { CAst.make ~loc @@ CHole (None, IntroFresh id, None) }
+ | "?"; "["; id = identref; "]" -> { CAst.make ~loc @@ CHole (None, IntroIdentifier id.CAst.v, None) }
+ | "?"; "["; id = pattern_ident; "]" -> { CAst.make ~loc @@ CHole (None, IntroFresh id.CAst.v, None) }
| id = pattern_ident; inst = evar_instance -> { CAst.make ~loc @@ CEvar(id,inst) } ] ]
;
inst:
- [ [ id = ident; ":="; c = lconstr -> { (id,c) } ] ]
+ [ [ id = identref; ":="; c = lconstr -> { (id,c) } ] ]
;
evar_instance:
[ [ "@{"; l = LIST1 inst SEP ";"; "}" -> { l }
diff --git a/parsing/g_prim.mlg b/parsing/g_prim.mlg
index 270662b824..1701830cd2 100644
--- a/parsing/g_prim.mlg
+++ b/parsing/g_prim.mlg
@@ -45,9 +45,9 @@ let test_minus_nat =
GRAMMAR EXTEND Gram
GLOBAL:
- bignat bigint natural integer identref name ident var preident
+ bignat bigint natural integer identref name ident hyp preident
fullyqualid qualid reference dirpath ne_lstring
- ne_string string lstring pattern_ident pattern_identref by_notation
+ ne_string string lstring pattern_ident by_notation
smart_global bar_cbrace strategy_level;
preident:
[ [ s = IDENT -> { s } ] ]
@@ -56,17 +56,14 @@ GRAMMAR EXTEND Gram
[ [ s = IDENT -> { Id.of_string s } ] ]
;
pattern_ident:
- [ [ LEFTQMARK; id = ident -> { id } ] ]
- ;
- pattern_identref:
- [ [ id = pattern_ident -> { CAst.make ~loc id } ] ]
- ;
- var: (* as identref, but interpret as a term identifier in ltac *)
- [ [ id = ident -> { CAst.make ~loc id } ] ]
+ [ [ LEFTQMARK; id = ident -> { CAst.make ~loc id } ] ]
;
identref:
[ [ id = ident -> { CAst.make ~loc id } ] ]
;
+ hyp: (* as identref, but interpreted as an hypothesis in tactic notations *)
+ [ [ id = identref -> { id } ] ]
+ ;
field:
[ [ s = FIELD -> { Id.of_string s } ] ]
;
diff --git a/parsing/pcoq.ml b/parsing/pcoq.ml
index 723f08413e..996aa0925c 100644
--- a/parsing/pcoq.ml
+++ b/parsing/pcoq.ml
@@ -279,14 +279,15 @@ module Prim =
let strategy_level = Entry.create "strategy_level"
(* parsed like ident but interpreted as a term *)
- let var = Entry.create "var"
+ let hyp = Entry.create "hyp"
+ let var = hyp
let name = Entry.create "name"
let identref = Entry.create "identref"
let univ_decl = Entry.create "univ_decl"
let ident_decl = Entry.create "ident_decl"
let pattern_ident = Entry.create "pattern_ident"
- let pattern_identref = Entry.create "pattern_identref"
+ let pattern_identref = pattern_ident (* To remove in 8.14 *)
(* A synonym of ident - maybe ident will be located one day *)
let base_ident = Entry.create "base_ident"
@@ -504,7 +505,7 @@ let () =
Grammar.register0 wit_string (Prim.string);
Grammar.register0 wit_pre_ident (Prim.preident);
Grammar.register0 wit_ident (Prim.ident);
- Grammar.register0 wit_var (Prim.var);
+ Grammar.register0 wit_hyp (Prim.hyp);
Grammar.register0 wit_ref (Prim.reference);
Grammar.register0 wit_smart_global (Prim.smart_global);
Grammar.register0 wit_sort_family (Constr.sort_family);
diff --git a/parsing/pcoq.mli b/parsing/pcoq.mli
index ae9a7423c2..8e60bbf504 100644
--- a/parsing/pcoq.mli
+++ b/parsing/pcoq.mli
@@ -156,8 +156,8 @@ module Prim :
val identref : lident Entry.t
val univ_decl : universe_decl_expr Entry.t
val ident_decl : ident_decl Entry.t
- val pattern_ident : Id.t Entry.t
- val pattern_identref : lident Entry.t
+ val pattern_ident : lident Entry.t
+ val pattern_identref : lident Entry.t [@@ocaml.deprecated "Use Prim.pattern_identref"]
val base_ident : Id.t Entry.t
val bignat : string Entry.t
val natural : int Entry.t
@@ -173,7 +173,8 @@ module Prim :
val dirpath : DirPath.t Entry.t
val ne_string : string Entry.t
val ne_lstring : lstring Entry.t
- val var : lident Entry.t
+ val hyp : lident Entry.t
+ val var : lident Entry.t [@@ocaml.deprecated "Use Prim.hyp"]
val bar_cbrace : unit Entry.t
val strategy_level : Conv_oracle.level Entry.t
end
diff --git a/parsing/ppextend.ml b/parsing/ppextend.ml
index fe6e8360c1..aab385a707 100644
--- a/parsing/ppextend.ml
+++ b/parsing/ppextend.ml
@@ -17,7 +17,7 @@ open Constrexpr
(*s Pretty-print. *)
type ppbox =
- | PpHB of int
+ | PpHB
| PpHOVB of int
| PpHVB of int
| PpVB of int
@@ -27,7 +27,7 @@ type ppcut =
| PpFnl
let ppcmd_of_box = function
- | PpHB n -> h n
+ | PpHB -> h
| PpHOVB n -> hov n
| PpHVB n -> hv n
| PpVB n -> v n
diff --git a/parsing/ppextend.mli b/parsing/ppextend.mli
index ee8180c7aa..56a3fc8e3c 100644
--- a/parsing/ppextend.mli
+++ b/parsing/ppextend.mli
@@ -13,7 +13,7 @@ open Constrexpr
(** {6 Pretty-print. } *)
type ppbox =
- | PpHB of int
+ | PpHB
| PpHOVB of int
| PpHVB of int
| PpVB of int
diff --git a/plugins/extraction/scheme.ml b/plugins/extraction/scheme.ml
index ee50476b10..f671860bd5 100644
--- a/plugins/extraction/scheme.ml
+++ b/plugins/extraction/scheme.ml
@@ -28,7 +28,7 @@ let keywords =
"error"; "delay"; "force"; "_"; "__"]
Id.Set.empty
-let pp_comment s = str";; "++h 0 s++fnl ()
+let pp_comment s = str ";; " ++ h s ++ fnl ()
let pp_header_comment = function
| None -> mt ()
diff --git a/plugins/funind/gen_principle.ml b/plugins/funind/gen_principle.ml
index 1ea803f561..012fcee486 100644
--- a/plugins/funind/gen_principle.ml
+++ b/plugins/funind/gen_principle.ml
@@ -1860,13 +1860,13 @@ let do_generate_principle_aux pconstants on_error register_built
let warn_cannot_define_graph =
CWarnings.create ~name:"funind-cannot-define-graph" ~category:"funind"
(fun (names, error) ->
- Pp.(strbrk "Cannot define graph(s) for " ++ h 1 names ++ error))
+ Pp.(strbrk "Cannot define graph(s) for " ++ hv 1 names ++ error))
let warn_cannot_define_principle =
CWarnings.create ~name:"funind-cannot-define-principle" ~category:"funind"
(fun (names, error) ->
Pp.(
- strbrk "Cannot define induction principle(s) for " ++ h 1 names ++ error))
+ strbrk "Cannot define induction principle(s) for " ++ hv 1 names ++ error))
let warning_error names e =
let e_explain e =
@@ -1898,7 +1898,7 @@ let error_error names e =
CErrors.user_err
Pp.(
str "Cannot define graph(s) for "
- ++ h 1
+ ++ hv 1
(prlist_with_sep (fun _ -> str "," ++ spc ()) Ppconstr.pr_id names)
++ e_explain e)
| _ -> raise e
diff --git a/plugins/ltac/coretactics.mlg b/plugins/ltac/coretactics.mlg
index f1f538ab39..b7ac71181a 100644
--- a/plugins/ltac/coretactics.mlg
+++ b/plugins/ltac/coretactics.mlg
@@ -20,8 +20,6 @@ open Tacarg
open Names
open Logic
-let wit_hyp = wit_var
-
}
DECLARE PLUGIN "ltac_plugin"
diff --git a/plugins/ltac/extraargs.mlg b/plugins/ltac/extraargs.mlg
index 863c4d37d8..ad4374dba3 100644
--- a/plugins/ltac/extraargs.mlg
+++ b/plugins/ltac/extraargs.mlg
@@ -47,7 +47,7 @@ let () =
let () =
let register name entry = Tacentries.register_tactic_notation_entry name entry in
- register "hyp" wit_var;
+ register "hyp" wit_hyp;
register "simple_intropattern" wit_simple_intropattern;
register "integer" wit_integer;
register "reference" wit_ref;
@@ -140,7 +140,7 @@ ARGUMENT EXTEND occurrences
GLOB_PRINTED BY { pr_occurrences }
| [ ne_integer_list(l) ] -> { ArgArg l }
-| [ var(id) ] -> { ArgVar id }
+| [ hyp(id) ] -> { ArgVar id }
END
{
diff --git a/plugins/ltac/extratactics.mlg b/plugins/ltac/extratactics.mlg
index 4f20e5a800..a2a47c0bf4 100644
--- a/plugins/ltac/extratactics.mlg
+++ b/plugins/ltac/extratactics.mlg
@@ -33,8 +33,6 @@ open Proofview.Notations
open Attributes
open Vernacextend
-let wit_hyp = wit_var
-
}
DECLARE PLUGIN "ltac_plugin"
@@ -450,7 +448,7 @@ END
(* Subst *)
TACTIC EXTEND subst
-| [ "subst" ne_var_list(l) ] -> { subst l }
+| [ "subst" ne_hyp_list(l) ] -> { subst l }
| [ "subst" ] -> { subst_all () }
END
diff --git a/plugins/ltac/g_auto.mlg b/plugins/ltac/g_auto.mlg
index 2e72ceae5a..44472a1995 100644
--- a/plugins/ltac/g_auto.mlg
+++ b/plugins/ltac/g_auto.mlg
@@ -18,8 +18,6 @@ open Pcoq.Constr
open Pltac
open Hints
-let wit_hyp = wit_var
-
}
DECLARE PLUGIN "ltac_plugin"
diff --git a/plugins/ltac/g_class.mlg b/plugins/ltac/g_class.mlg
index 8d197e6056..8c2e633be5 100644
--- a/plugins/ltac/g_class.mlg
+++ b/plugins/ltac/g_class.mlg
@@ -31,12 +31,12 @@ let set_transparency cl b =
}
VERNAC COMMAND EXTEND Typeclasses_Unfold_Settings CLASSIFIED AS SIDEFF
-| [ "Typeclasses" "Transparent" reference_list(cl) ] -> {
+| [ "Typeclasses" "Transparent" ne_reference_list(cl) ] -> {
set_transparency cl true }
END
VERNAC COMMAND EXTEND Typeclasses_Rigid_Settings CLASSIFIED AS SIDEFF
-| [ "Typeclasses" "Opaque" reference_list(cl) ] -> {
+| [ "Typeclasses" "Opaque" ne_reference_list(cl) ] -> {
set_transparency cl false }
END
@@ -77,7 +77,7 @@ END
(* true = All transparent, false = Opaque if possible *)
VERNAC COMMAND EXTEND Typeclasses_Settings CLASSIFIED AS SIDEFF
- | [ "Typeclasses" "eauto" ":=" debug(d) eauto_search_strategy(s) integer_opt(depth) ] -> {
+ | [ "Typeclasses" "eauto" ":=" debug(d) eauto_search_strategy(s) natural_opt(depth) ] -> {
set_typeclasses_debug d;
Option.iter set_typeclasses_strategy s;
set_typeclasses_depth depth
@@ -87,11 +87,13 @@ END
(** Compatibility: typeclasses eauto has 8.5 and 8.6 modes *)
TACTIC EXTEND typeclasses_eauto
| [ "typeclasses" "eauto" "bfs" int_or_var_opt(d) "with" ne_preident_list(l) ] ->
- { typeclasses_eauto ~strategy:Bfs ~depth:d l }
+ { typeclasses_eauto ~depth:d ~strategy:Bfs l }
| [ "typeclasses" "eauto" int_or_var_opt(d) "with" ne_preident_list(l) ] ->
{ typeclasses_eauto ~depth:d l }
+ | [ "typeclasses" "eauto" "bfs" int_or_var_opt(d) ] -> {
+ typeclasses_eauto ~depth:d ~strategy:Bfs ~only_classes:true [Class_tactics.typeclasses_db] }
| [ "typeclasses" "eauto" int_or_var_opt(d) ] -> {
- typeclasses_eauto ~only_classes:true ~depth:d [Class_tactics.typeclasses_db] }
+ typeclasses_eauto ~depth:d ~only_classes:true [Class_tactics.typeclasses_db] }
END
TACTIC EXTEND head_of_constr
diff --git a/plugins/ltac/g_ltac.mlg b/plugins/ltac/g_ltac.mlg
index be0d71ad46..6cf5d30a95 100644
--- a/plugins/ltac/g_ltac.mlg
+++ b/plugins/ltac/g_ltac.mlg
@@ -355,28 +355,8 @@ GRAMMAR EXTEND Gram
open Stdarg
open Tacarg
open Vernacextend
-open Goptions
open Libnames
-let print_info_trace =
- declare_intopt_option_and_ref ~depr:false ~key:["Info" ; "Level"]
-
-let vernac_solve ~pstate n info tcom b =
- let open Goal_select in
- let pstate, status = Declare.Proof.map_fold_endline ~f:(fun etac p ->
- let with_end_tac = if b then Some etac else None in
- let global = match n with SelectAll | SelectList _ -> true | _ -> false in
- let info = Option.append info (print_info_trace ()) in
- let (p,status) =
- Proof.solve n info (Tacinterp.hide_interp global tcom None) ?with_end_tac p
- in
- (* in case a strict subtree was completed,
- go back to the top of the prooftree *)
- let p = Proof.maximal_unfocus Vernacentries.command_focus p in
- p,status) pstate in
- if not status then Feedback.feedback Feedback.AddedAxiom;
- pstate
-
let pr_ltac_selector s = Pptactic.pr_goal_selector ~toplevel:true s
}
@@ -409,34 +389,34 @@ END
{
-let is_anonymous_abstract = function
- | TacAbstract (_,None) -> true
- | TacSolve [TacAbstract (_,None)] -> true
- | _ -> false
let rm_abstract = function
- | TacAbstract (t,_) -> t
- | TacSolve [TacAbstract (t,_)] -> TacSolve [t]
- | x -> x
+ | TacAbstract (t,_) -> t, true
+ | TacSolve [TacAbstract (t,_)] -> TacSolve [t], true
+ | x -> x, false
let is_explicit_terminator = function TacSolve _ -> true | _ -> false
}
VERNAC { tactic_mode } EXTEND VernacSolve STATE proof
-| [ ltac_selector_opt(g) ltac_info_opt(n) tactic(t) ltac_use_default(def) ] =>
+| [ ltac_selector_opt(g) ltac_info_opt(info) tactic(t) ltac_use_default(with_end_tac) ] =>
{ classify_as_proofstep } -> {
let g = Option.default (Goal_select.get_default_goal_selector ()) g in
- vernac_solve g n t def
+ let global = match g with Goal_select.SelectAll | Goal_select.SelectList _ -> true | _ -> false in
+ let t = ComTactic.I (Tacinterp.hide_interp, { Tacinterp.global; ast = t; }) in
+ ComTactic.solve g ~info t ~with_end_tac
}
-| [ "par" ":" ltac_info_opt(n) tactic(t) ltac_use_default(def) ] =>
+END
+
+VERNAC { tactic_mode } EXTEND VernacSolveParallel STATE proof
+| [ "par" ":" ltac_info_opt(info) tactic(t) ltac_use_default(with_end_tac) ] =>
{
- let anon_abstracting_tac = is_anonymous_abstract t in
let solving_tac = is_explicit_terminator t in
- let parallel = `Yes (solving_tac,anon_abstracting_tac) in
let pbr = if solving_tac then Some "par" else None in
- VtProofStep{ parallel = parallel; proof_block_detection = pbr }
+ VtProofStep{ proof_block_detection = pbr }
} -> {
- let t = rm_abstract t in
- vernac_solve Goal_select.SelectAll n t def
+ let t, abstract = rm_abstract t in
+ let t = ComTactic.I (Tacinterp.hide_interp, { Tacinterp.global = true; ast = t; }) in
+ ComTactic.solve_parallel ~info t ~abstract ~with_end_tac
}
END
diff --git a/plugins/ltac/g_obligations.mlg b/plugins/ltac/g_obligations.mlg
index fc24475a62..6bf330c830 100644
--- a/plugins/ltac/g_obligations.mlg
+++ b/plugins/ltac/g_obligations.mlg
@@ -111,6 +111,8 @@ END
VERNAC COMMAND EXTEND Solve_Obligations CLASSIFIED AS SIDEFF STATE program
| [ "Solve" "Obligations" "of" ident(name) "with" tactic(t) ] ->
{ try_solve_obligations (Some name) (Some (Tacinterp.interp t)) }
+| [ "Solve" "Obligations" "of" ident(name) ] ->
+ { try_solve_obligations (Some name) None }
| [ "Solve" "Obligations" "with" tactic(t) ] ->
{ try_solve_obligations None (Some (Tacinterp.interp t)) }
| [ "Solve" "Obligations" ] ->
diff --git a/plugins/ltac/g_rewrite.mlg b/plugins/ltac/g_rewrite.mlg
index 8331927cda..ee94fd565a 100644
--- a/plugins/ltac/g_rewrite.mlg
+++ b/plugins/ltac/g_rewrite.mlg
@@ -29,8 +29,6 @@ open Pvernac.Vernac_
open Pltac
open Vernacextend
-let wit_hyp = wit_var
-
}
DECLARE PLUGIN "ltac_plugin"
diff --git a/plugins/ltac/g_tactic.mlg b/plugins/ltac/g_tactic.mlg
index e51b1f051d..c186a83a5c 100644
--- a/plugins/ltac/g_tactic.mlg
+++ b/plugins/ltac/g_tactic.mlg
@@ -280,7 +280,7 @@ GRAMMAR EXTEND Gram
| "[="; tc = intropatterns; "]" -> { IntroInjection tc } ] ]
;
naming_intropattern:
- [ [ prefix = pattern_ident -> { IntroFresh prefix }
+ [ [ prefix = pattern_ident -> { IntroFresh prefix.CAst.v }
| "?" -> { IntroAnonymous }
| id = ident -> { IntroIdentifier id } ] ]
;
diff --git a/plugins/ltac/pptactic.ml b/plugins/ltac/pptactic.ml
index 85bb901046..fe896f9351 100644
--- a/plugins/ltac/pptactic.ml
+++ b/plugins/ltac/pptactic.ml
@@ -179,7 +179,7 @@ let string_of_genarg_arg (ArgumentType arg) =
| ConstrTypeOf c ->
hov 1 (keyword "type of" ++ spc() ++ prc env sigma c)
| ConstrTerm c when test c ->
- h 0 (str "(" ++ prc env sigma c ++ str ")")
+ h (str "(" ++ prc env sigma c ++ str ")")
| ConstrTerm c ->
prc env sigma c
@@ -1323,7 +1323,7 @@ let () =
register_basic_print0 wit_smart_global
(pr_or_by_notation pr_qualid) (pr_or_var (pr_located pr_global)) pr_global;
register_basic_print0 wit_ident pr_id pr_id pr_id;
- register_basic_print0 wit_var pr_lident pr_lident pr_id;
+ register_basic_print0 wit_hyp pr_lident pr_lident pr_id;
register_print0 wit_intropattern pr_raw_intro_pattern pr_glob_intro_pattern pr_intro_pattern_env [@warning "-3"];
register_print0 wit_simple_intropattern pr_raw_intro_pattern pr_glob_intro_pattern pr_intro_pattern_env;
Genprint.register_print0
diff --git a/plugins/ltac/profile_ltac.ml b/plugins/ltac/profile_ltac.ml
index 0dbf16a821..9c15d24dd3 100644
--- a/plugins/ltac/profile_ltac.ml
+++ b/plugins/ltac/profile_ltac.ml
@@ -146,7 +146,7 @@ let header =
fnl ()
let rec print_node ~filter all_total indent prefix (s, e) =
- h 0 (
+ h (
padr_with '-' 40 (prefix ^ s ^ " ")
++ padl 7 (format_ratio (e.local /. all_total))
++ padl 7 (format_ratio (e.total /. all_total))
@@ -212,7 +212,7 @@ let to_string ~filter ?(cutoff=0.0) node =
in
let filter s n = filter s && (all_total <= 0.0 || n /. all_total >= cutoff /. 100.0) in
let msg =
- h 0 (str "total time: " ++ padl 11 (format_sec (all_total))) ++
+ h (str "total time: " ++ padl 11 (format_sec (all_total))) ++
fnl () ++
fnl () ++
header ++
diff --git a/plugins/ltac/taccoerce.ml b/plugins/ltac/taccoerce.ml
index f7037176d2..ee28229cb7 100644
--- a/plugins/ltac/taccoerce.ml
+++ b/plugins/ltac/taccoerce.ml
@@ -161,8 +161,8 @@ let coerce_var_to_ident fresh env sigma v =
match out_gen (topwit wit_intro_pattern) v with
| { CAst.v=IntroNaming (IntroIdentifier id)} -> id
| _ -> fail ()
- else if has_type v (topwit wit_var) then
- out_gen (topwit wit_var) v
+ else if has_type v (topwit wit_hyp) then
+ out_gen (topwit wit_hyp) v
else match Value.to_constr v with
| None -> fail ()
| Some c ->
@@ -184,8 +184,8 @@ let id_of_name = function
| Some (IntroNaming (IntroIdentifier id)) -> id
| Some _ -> fail ()
| None ->
- if has_type v (topwit wit_var) then
- out_gen (topwit wit_var) v
+ if has_type v (topwit wit_hyp) then
+ out_gen (topwit wit_hyp) v
else
match Value.to_constr v with
| None -> fail ()
@@ -222,8 +222,8 @@ let coerce_to_intro_pattern sigma v =
match is_intro_pattern v with
| Some pat -> pat
| None ->
- if has_type v (topwit wit_var) then
- let id = out_gen (topwit wit_var) v in
+ if has_type v (topwit wit_hyp) then
+ let id = out_gen (topwit wit_hyp) v in
IntroNaming (IntroIdentifier id)
else match Value.to_constr v with
| Some c when isVar sigma c ->
@@ -259,8 +259,8 @@ let coerce_to_constr env v =
([], c)
else if has_type v (topwit wit_constr_under_binders) then
out_gen (topwit wit_constr_under_binders) v
- else if has_type v (topwit wit_var) then
- let id = out_gen (topwit wit_var) v in
+ else if has_type v (topwit wit_hyp) then
+ let id = out_gen (topwit wit_hyp) v in
(try [], constr_of_id env id with Not_found -> fail ())
else fail ()
@@ -282,8 +282,8 @@ let coerce_to_evaluable_ref env sigma v =
| Some (IntroNaming (IntroIdentifier id)) when is_variable env id -> EvalVarRef id
| Some _ -> fail ()
| None ->
- if has_type v (topwit wit_var) then
- let id = out_gen (topwit wit_var) v in
+ if has_type v (topwit wit_hyp) then
+ let id = out_gen (topwit wit_hyp) v in
if Id.List.mem id (Termops.ids_of_context env) then EvalVarRef id
else fail ()
else if has_type v (topwit wit_ref) then
@@ -328,8 +328,8 @@ let coerce_to_hyp env sigma v =
| Some (IntroNaming (IntroIdentifier id)) when is_variable env id -> id
| Some _ -> fail ()
| None ->
- if has_type v (topwit wit_var) then
- let id = out_gen (topwit wit_var) v in
+ if has_type v (topwit wit_hyp) then
+ let id = out_gen (topwit wit_hyp) v in
if is_variable env id then id else fail ()
else match Value.to_constr v with
| Some c when isVar sigma c -> destVar sigma c
@@ -360,8 +360,8 @@ let coerce_to_quantified_hypothesis sigma v =
| Some (IntroNaming (IntroIdentifier id)) -> NamedHyp id
| Some _ -> raise (CannotCoerceTo "a quantified hypothesis")
| None ->
- if has_type v (topwit wit_var) then
- let id = out_gen (topwit wit_var) v in
+ if has_type v (topwit wit_hyp) then
+ let id = out_gen (topwit wit_hyp) v in
NamedHyp id
else if has_type v (topwit wit_int) then
AnonHyp (out_gen (topwit wit_int) v)
diff --git a/plugins/ltac/tacentries.ml b/plugins/ltac/tacentries.ml
index f0ca813b08..d58a76fe13 100644
--- a/plugins/ltac/tacentries.ml
+++ b/plugins/ltac/tacentries.ml
@@ -219,7 +219,9 @@ let interp_prod_item = function
| None ->
if String.Map.mem s !entry_names then String.Map.find s !entry_names
else begin match ArgT.name s with
- | None -> user_err Pp.(str ("Unknown entry "^s^"."))
+ | None ->
+ if s = "var" then user_err Pp.(str ("var is deprecated, use hyp.")) (* to remove in 8.14 *)
+ else user_err Pp.(str ("Unknown entry "^s^"."))
| Some arg -> arg
end
| Some n ->
diff --git a/plugins/ltac/tacintern.ml b/plugins/ltac/tacintern.ml
index dea216045e..9c3b05fdf1 100644
--- a/plugins/ltac/tacintern.ml
+++ b/plugins/ltac/tacintern.ml
@@ -835,7 +835,7 @@ let () =
Genintern.register_intern0 wit_ref (lift intern_global_reference);
Genintern.register_intern0 wit_pre_ident (fun ist c -> (ist,c));
Genintern.register_intern0 wit_ident intern_ident';
- Genintern.register_intern0 wit_var (lift intern_hyp);
+ Genintern.register_intern0 wit_hyp (lift intern_hyp);
Genintern.register_intern0 wit_tactic (lift intern_tactic_or_tacarg);
Genintern.register_intern0 wit_ltac (lift intern_ltac);
Genintern.register_intern0 wit_quant_hyp (lift intern_quantified_hypothesis);
diff --git a/plugins/ltac/tacinterp.ml b/plugins/ltac/tacinterp.ml
index ff6a36a049..12bfb4d09e 100644
--- a/plugins/ltac/tacinterp.ml
+++ b/plugins/ltac/tacinterp.ml
@@ -971,8 +971,8 @@ let interp_destruction_arg ist gl arg =
match v with
| {v=IntroNaming (IntroIdentifier id)} -> try_cast_id id
| _ -> error ()
- else if has_type v (topwit wit_var) then
- let id = out_gen (topwit wit_var) v in
+ else if has_type v (topwit wit_hyp) then
+ let id = out_gen (topwit wit_hyp) v in
try_cast_id id
else if has_type v (topwit wit_int) then
keep,ElimOnAnonHyp (out_gen (topwit wit_int) v)
@@ -1238,7 +1238,7 @@ and interp_ltac_reference ?loc' mustbetac ist r : Val.t Ftactic.t =
| ArgVar {loc;v=id} ->
let v =
try Id.Map.find id ist.lfun
- with Not_found -> in_gen (topwit wit_var) id
+ with Not_found -> in_gen (topwit wit_hyp) id
in
let open Ftactic in
force_vrec ist v >>= begin fun v ->
@@ -1529,7 +1529,7 @@ and interp_genarg ist x : Val.t Ftactic.t =
let open Ftactic.Notations in
(* Ad-hoc handling of some types. *)
let tag = genarg_tag x in
- if argument_type_eq tag (unquote (topwit (wit_list wit_var))) then
+ if argument_type_eq tag (unquote (topwit (wit_list wit_hyp))) then
interp_genarg_var_list ist x
else if argument_type_eq tag (unquote (topwit (wit_list wit_constr))) then
interp_genarg_constr_list ist x
@@ -1573,9 +1573,9 @@ and interp_genarg_var_list ist x =
Ftactic.enter begin fun gl ->
let env = Proofview.Goal.env gl in
let sigma = Proofview.Goal.sigma gl in
- let lc = Genarg.out_gen (glbwit (wit_list wit_var)) x in
+ let lc = Genarg.out_gen (glbwit (wit_list wit_hyp)) x in
let lc = interp_hyp_list ist env sigma lc in
- let lc = in_list (val_tag wit_var) lc in
+ let lc = in_list (val_tag wit_hyp) lc in
Ftactic.return lc
end
@@ -1996,16 +1996,20 @@ let interp_tac_gen lfun avoid_ids debug t =
let interp t = interp_tac_gen Id.Map.empty Id.Set.empty (get_debug()) t
+(* MUST be marshallable! *)
+type tactic_expr = {
+ global: bool;
+ ast: Tacexpr.raw_tactic_expr;
+}
+
(* Used to hide interpretation for pretty-print, now just launch tactics *)
(* [global] means that [t] should be internalized outside of goals. *)
-let hide_interp global t ot =
+let hide_interp {global;ast} =
let hide_interp env =
let ist = Genintern.empty_glob_sign env in
- let te = intern_pure_tactic ist t in
+ let te = intern_pure_tactic ist ast in
let t = eval_tactic te in
- match ot with
- | None -> t
- | Some t' -> Tacticals.New.tclTHEN t t'
+ t
in
if global then
Proofview.tclENV >>= fun env ->
@@ -2015,6 +2019,8 @@ let hide_interp global t ot =
hide_interp (Proofview.Goal.env gl)
end
+let hide_interp = ComTactic.register_tactic_interpreter "ltac1" hide_interp
+
(***************************************************************************)
(** Register standard arguments *)
@@ -2090,7 +2096,7 @@ let () =
register_interp0 wit_ref (lift interp_reference);
register_interp0 wit_pre_ident (lift interp_pre_ident);
register_interp0 wit_ident (lift interp_ident);
- register_interp0 wit_var (lift interp_hyp);
+ register_interp0 wit_hyp (lift interp_hyp);
register_interp0 wit_intropattern (lifts interp_intro_pattern) [@warning "-3"];
register_interp0 wit_simple_intropattern (lifts interp_intro_pattern);
register_interp0 wit_clause_dft_concl (lift interp_clause);
diff --git a/plugins/ltac/tacinterp.mli b/plugins/ltac/tacinterp.mli
index cbb17bf0fa..01d7306c9d 100644
--- a/plugins/ltac/tacinterp.mli
+++ b/plugins/ltac/tacinterp.mli
@@ -126,8 +126,12 @@ val interp_tac_gen : value Id.Map.t -> Id.Set.t ->
val interp : raw_tactic_expr -> unit Proofview.tactic
(** Hides interpretation for pretty-print *)
+type tactic_expr = {
+ global: bool;
+ ast: Tacexpr.raw_tactic_expr;
+}
-val hide_interp : bool -> raw_tactic_expr -> unit Proofview.tactic option -> unit Proofview.tactic
+val hide_interp : tactic_expr ComTactic.tactic_interpreter
(** Internals that can be useful for syntax extensions. *)
diff --git a/plugins/ltac/tacsubst.ml b/plugins/ltac/tacsubst.ml
index fd869b225f..ec44ae4698 100644
--- a/plugins/ltac/tacsubst.ml
+++ b/plugins/ltac/tacsubst.ml
@@ -282,7 +282,7 @@ let () =
Genintern.register_subst0 wit_smart_global subst_global_reference;
Genintern.register_subst0 wit_pre_ident (fun _ v -> v);
Genintern.register_subst0 wit_ident (fun _ v -> v);
- Genintern.register_subst0 wit_var (fun _ v -> v);
+ Genintern.register_subst0 wit_hyp (fun _ v -> v);
Genintern.register_subst0 wit_intropattern subst_intro_pattern [@warning "-3"];
Genintern.register_subst0 wit_simple_intropattern subst_intro_pattern;
Genintern.register_subst0 wit_tactic subst_tactic;
diff --git a/plugins/micromega/coq_micromega.ml b/plugins/micromega/coq_micromega.ml
index d2c49c4432..542b99075d 100644
--- a/plugins/micromega/coq_micromega.ml
+++ b/plugins/micromega/coq_micromega.ml
@@ -134,166 +134,161 @@ let selecti s m =
*)
(**
- * MODULE END: M
- *)
-module M = struct
- (**
* Initialization : a large amount of Caml symbols are derived from
* ZMicromega.v
*)
- let constr_of_ref str =
- EConstr.of_constr
- (UnivGen.constr_of_monomorphic_global (Coqlib.lib_ref str))
-
- let coq_and = lazy (constr_of_ref "core.and.type")
- let coq_or = lazy (constr_of_ref "core.or.type")
- let coq_not = lazy (constr_of_ref "core.not.type")
- let coq_iff = lazy (constr_of_ref "core.iff.type")
- let coq_True = lazy (constr_of_ref "core.True.type")
- let coq_False = lazy (constr_of_ref "core.False.type")
- let coq_bool = lazy (constr_of_ref "core.bool.type")
- let coq_true = lazy (constr_of_ref "core.bool.true")
- let coq_false = lazy (constr_of_ref "core.bool.false")
- let coq_andb = lazy (constr_of_ref "core.bool.andb")
- let coq_orb = lazy (constr_of_ref "core.bool.orb")
- let coq_implb = lazy (constr_of_ref "core.bool.implb")
- let coq_eqb = lazy (constr_of_ref "core.bool.eqb")
- let coq_negb = lazy (constr_of_ref "core.bool.negb")
- let coq_cons = lazy (constr_of_ref "core.list.cons")
- let coq_nil = lazy (constr_of_ref "core.list.nil")
- let coq_list = lazy (constr_of_ref "core.list.type")
- let coq_O = lazy (constr_of_ref "num.nat.O")
- let coq_S = lazy (constr_of_ref "num.nat.S")
- let coq_nat = lazy (constr_of_ref "num.nat.type")
- let coq_unit = lazy (constr_of_ref "core.unit.type")
-
- (* let coq_option = lazy (init_constant "option")*)
- let coq_None = lazy (constr_of_ref "core.option.None")
- let coq_tt = lazy (constr_of_ref "core.unit.tt")
- let coq_Inl = lazy (constr_of_ref "core.sum.inl")
- let coq_Inr = lazy (constr_of_ref "core.sum.inr")
- let coq_N0 = lazy (constr_of_ref "num.N.N0")
- let coq_Npos = lazy (constr_of_ref "num.N.Npos")
- let coq_xH = lazy (constr_of_ref "num.pos.xH")
- let coq_xO = lazy (constr_of_ref "num.pos.xO")
- let coq_xI = lazy (constr_of_ref "num.pos.xI")
- let coq_Z = lazy (constr_of_ref "num.Z.type")
- let coq_ZERO = lazy (constr_of_ref "num.Z.Z0")
- let coq_POS = lazy (constr_of_ref "num.Z.Zpos")
- let coq_NEG = lazy (constr_of_ref "num.Z.Zneg")
- let coq_Q = lazy (constr_of_ref "rat.Q.type")
- let coq_Qmake = lazy (constr_of_ref "rat.Q.Qmake")
- let coq_R = lazy (constr_of_ref "reals.R.type")
- let coq_Rcst = lazy (constr_of_ref "micromega.Rcst.type")
- let coq_C0 = lazy (constr_of_ref "micromega.Rcst.C0")
- let coq_C1 = lazy (constr_of_ref "micromega.Rcst.C1")
- let coq_CQ = lazy (constr_of_ref "micromega.Rcst.CQ")
- let coq_CZ = lazy (constr_of_ref "micromega.Rcst.CZ")
- let coq_CPlus = lazy (constr_of_ref "micromega.Rcst.CPlus")
- let coq_CMinus = lazy (constr_of_ref "micromega.Rcst.CMinus")
- let coq_CMult = lazy (constr_of_ref "micromega.Rcst.CMult")
- let coq_CPow = lazy (constr_of_ref "micromega.Rcst.CPow")
- let coq_CInv = lazy (constr_of_ref "micromega.Rcst.CInv")
- let coq_COpp = lazy (constr_of_ref "micromega.Rcst.COpp")
- let coq_R0 = lazy (constr_of_ref "reals.R.R0")
- let coq_R1 = lazy (constr_of_ref "reals.R.R1")
- let coq_proofTerm = lazy (constr_of_ref "micromega.ZArithProof.type")
- let coq_doneProof = lazy (constr_of_ref "micromega.ZArithProof.DoneProof")
- let coq_ratProof = lazy (constr_of_ref "micromega.ZArithProof.RatProof")
- let coq_cutProof = lazy (constr_of_ref "micromega.ZArithProof.CutProof")
- let coq_enumProof = lazy (constr_of_ref "micromega.ZArithProof.EnumProof")
- let coq_ExProof = lazy (constr_of_ref "micromega.ZArithProof.ExProof")
- let coq_IsProp = lazy (constr_of_ref "micromega.kind.isProp")
- let coq_IsBool = lazy (constr_of_ref "micromega.kind.isBool")
- let coq_Zgt = lazy (constr_of_ref "num.Z.gt")
- let coq_Zge = lazy (constr_of_ref "num.Z.ge")
- let coq_Zle = lazy (constr_of_ref "num.Z.le")
- let coq_Zlt = lazy (constr_of_ref "num.Z.lt")
- let coq_Zgtb = lazy (constr_of_ref "num.Z.gtb")
- let coq_Zgeb = lazy (constr_of_ref "num.Z.geb")
- let coq_Zleb = lazy (constr_of_ref "num.Z.leb")
- let coq_Zltb = lazy (constr_of_ref "num.Z.ltb")
- let coq_Zeqb = lazy (constr_of_ref "num.Z.eqb")
- let coq_eq = lazy (constr_of_ref "core.eq.type")
- let coq_Zplus = lazy (constr_of_ref "num.Z.add")
- let coq_Zminus = lazy (constr_of_ref "num.Z.sub")
- let coq_Zopp = lazy (constr_of_ref "num.Z.opp")
- let coq_Zmult = lazy (constr_of_ref "num.Z.mul")
- let coq_Zpower = lazy (constr_of_ref "num.Z.pow")
- let coq_Qle = lazy (constr_of_ref "rat.Q.Qle")
- let coq_Qlt = lazy (constr_of_ref "rat.Q.Qlt")
- let coq_Qeq = lazy (constr_of_ref "rat.Q.Qeq")
- let coq_Qplus = lazy (constr_of_ref "rat.Q.Qplus")
- let coq_Qminus = lazy (constr_of_ref "rat.Q.Qminus")
- let coq_Qopp = lazy (constr_of_ref "rat.Q.Qopp")
- let coq_Qmult = lazy (constr_of_ref "rat.Q.Qmult")
- let coq_Qpower = lazy (constr_of_ref "rat.Q.Qpower")
- let coq_Rgt = lazy (constr_of_ref "reals.R.Rgt")
- let coq_Rge = lazy (constr_of_ref "reals.R.Rge")
- let coq_Rle = lazy (constr_of_ref "reals.R.Rle")
- let coq_Rlt = lazy (constr_of_ref "reals.R.Rlt")
- let coq_Rplus = lazy (constr_of_ref "reals.R.Rplus")
- let coq_Rminus = lazy (constr_of_ref "reals.R.Rminus")
- let coq_Ropp = lazy (constr_of_ref "reals.R.Ropp")
- let coq_Rmult = lazy (constr_of_ref "reals.R.Rmult")
- let coq_Rinv = lazy (constr_of_ref "reals.R.Rinv")
- let coq_Rpower = lazy (constr_of_ref "reals.R.pow")
- let coq_powerZR = lazy (constr_of_ref "reals.R.powerRZ")
- let coq_IZR = lazy (constr_of_ref "reals.R.IZR")
- let coq_IQR = lazy (constr_of_ref "reals.R.Q2R")
- let coq_PEX = lazy (constr_of_ref "micromega.PExpr.PEX")
- let coq_PEc = lazy (constr_of_ref "micromega.PExpr.PEc")
- let coq_PEadd = lazy (constr_of_ref "micromega.PExpr.PEadd")
- let coq_PEopp = lazy (constr_of_ref "micromega.PExpr.PEopp")
- let coq_PEmul = lazy (constr_of_ref "micromega.PExpr.PEmul")
- let coq_PEsub = lazy (constr_of_ref "micromega.PExpr.PEsub")
- let coq_PEpow = lazy (constr_of_ref "micromega.PExpr.PEpow")
- let coq_PX = lazy (constr_of_ref "micromega.Pol.PX")
- let coq_Pc = lazy (constr_of_ref "micromega.Pol.Pc")
- let coq_Pinj = lazy (constr_of_ref "micromega.Pol.Pinj")
- let coq_OpEq = lazy (constr_of_ref "micromega.Op2.OpEq")
- let coq_OpNEq = lazy (constr_of_ref "micromega.Op2.OpNEq")
- let coq_OpLe = lazy (constr_of_ref "micromega.Op2.OpLe")
- let coq_OpLt = lazy (constr_of_ref "micromega.Op2.OpLt")
- let coq_OpGe = lazy (constr_of_ref "micromega.Op2.OpGe")
- let coq_OpGt = lazy (constr_of_ref "micromega.Op2.OpGt")
- let coq_PsatzIn = lazy (constr_of_ref "micromega.Psatz.PsatzIn")
- let coq_PsatzSquare = lazy (constr_of_ref "micromega.Psatz.PsatzSquare")
- let coq_PsatzMulE = lazy (constr_of_ref "micromega.Psatz.PsatzMulE")
- let coq_PsatzMultC = lazy (constr_of_ref "micromega.Psatz.PsatzMulC")
- let coq_PsatzAdd = lazy (constr_of_ref "micromega.Psatz.PsatzAdd")
- let coq_PsatzC = lazy (constr_of_ref "micromega.Psatz.PsatzC")
- let coq_PsatzZ = lazy (constr_of_ref "micromega.Psatz.PsatzZ")
-
- (* let coq_GT = lazy (m_constant "GT")*)
-
- let coq_DeclaredConstant =
- lazy (constr_of_ref "micromega.DeclaredConstant.type")
-
- let coq_TT = lazy (constr_of_ref "micromega.GFormula.TT")
- let coq_FF = lazy (constr_of_ref "micromega.GFormula.FF")
- let coq_AND = lazy (constr_of_ref "micromega.GFormula.AND")
- let coq_OR = lazy (constr_of_ref "micromega.GFormula.OR")
- let coq_NOT = lazy (constr_of_ref "micromega.GFormula.NOT")
- let coq_Atom = lazy (constr_of_ref "micromega.GFormula.A")
- let coq_X = lazy (constr_of_ref "micromega.GFormula.X")
- let coq_IMPL = lazy (constr_of_ref "micromega.GFormula.IMPL")
- let coq_IFF = lazy (constr_of_ref "micromega.GFormula.IFF")
- let coq_EQ = lazy (constr_of_ref "micromega.GFormula.EQ")
- let coq_Formula = lazy (constr_of_ref "micromega.BFormula.type")
- let coq_eKind = lazy (constr_of_ref "micromega.eKind")
-
- (**
+let constr_of_ref str =
+ EConstr.of_constr (UnivGen.constr_of_monomorphic_global (Coqlib.lib_ref str))
+
+let coq_and = lazy (constr_of_ref "core.and.type")
+let coq_or = lazy (constr_of_ref "core.or.type")
+let coq_not = lazy (constr_of_ref "core.not.type")
+let coq_iff = lazy (constr_of_ref "core.iff.type")
+let coq_True = lazy (constr_of_ref "core.True.type")
+let coq_False = lazy (constr_of_ref "core.False.type")
+let coq_bool = lazy (constr_of_ref "core.bool.type")
+let coq_true = lazy (constr_of_ref "core.bool.true")
+let coq_false = lazy (constr_of_ref "core.bool.false")
+let coq_andb = lazy (constr_of_ref "core.bool.andb")
+let coq_orb = lazy (constr_of_ref "core.bool.orb")
+let coq_implb = lazy (constr_of_ref "core.bool.implb")
+let coq_eqb = lazy (constr_of_ref "core.bool.eqb")
+let coq_negb = lazy (constr_of_ref "core.bool.negb")
+let coq_cons = lazy (constr_of_ref "core.list.cons")
+let coq_nil = lazy (constr_of_ref "core.list.nil")
+let coq_list = lazy (constr_of_ref "core.list.type")
+let coq_O = lazy (constr_of_ref "num.nat.O")
+let coq_S = lazy (constr_of_ref "num.nat.S")
+let coq_nat = lazy (constr_of_ref "num.nat.type")
+let coq_unit = lazy (constr_of_ref "core.unit.type")
+
+(* let coq_option = lazy (init_constant "option")*)
+let coq_None = lazy (constr_of_ref "core.option.None")
+let coq_tt = lazy (constr_of_ref "core.unit.tt")
+let coq_Inl = lazy (constr_of_ref "core.sum.inl")
+let coq_Inr = lazy (constr_of_ref "core.sum.inr")
+let coq_N0 = lazy (constr_of_ref "num.N.N0")
+let coq_Npos = lazy (constr_of_ref "num.N.Npos")
+let coq_xH = lazy (constr_of_ref "num.pos.xH")
+let coq_xO = lazy (constr_of_ref "num.pos.xO")
+let coq_xI = lazy (constr_of_ref "num.pos.xI")
+let coq_Z = lazy (constr_of_ref "num.Z.type")
+let coq_ZERO = lazy (constr_of_ref "num.Z.Z0")
+let coq_POS = lazy (constr_of_ref "num.Z.Zpos")
+let coq_NEG = lazy (constr_of_ref "num.Z.Zneg")
+let coq_Q = lazy (constr_of_ref "rat.Q.type")
+let coq_Qmake = lazy (constr_of_ref "rat.Q.Qmake")
+let coq_R = lazy (constr_of_ref "reals.R.type")
+let coq_Rcst = lazy (constr_of_ref "micromega.Rcst.type")
+let coq_C0 = lazy (constr_of_ref "micromega.Rcst.C0")
+let coq_C1 = lazy (constr_of_ref "micromega.Rcst.C1")
+let coq_CQ = lazy (constr_of_ref "micromega.Rcst.CQ")
+let coq_CZ = lazy (constr_of_ref "micromega.Rcst.CZ")
+let coq_CPlus = lazy (constr_of_ref "micromega.Rcst.CPlus")
+let coq_CMinus = lazy (constr_of_ref "micromega.Rcst.CMinus")
+let coq_CMult = lazy (constr_of_ref "micromega.Rcst.CMult")
+let coq_CPow = lazy (constr_of_ref "micromega.Rcst.CPow")
+let coq_CInv = lazy (constr_of_ref "micromega.Rcst.CInv")
+let coq_COpp = lazy (constr_of_ref "micromega.Rcst.COpp")
+let coq_R0 = lazy (constr_of_ref "reals.R.R0")
+let coq_R1 = lazy (constr_of_ref "reals.R.R1")
+let coq_proofTerm = lazy (constr_of_ref "micromega.ZArithProof.type")
+let coq_doneProof = lazy (constr_of_ref "micromega.ZArithProof.DoneProof")
+let coq_ratProof = lazy (constr_of_ref "micromega.ZArithProof.RatProof")
+let coq_cutProof = lazy (constr_of_ref "micromega.ZArithProof.CutProof")
+let coq_enumProof = lazy (constr_of_ref "micromega.ZArithProof.EnumProof")
+let coq_ExProof = lazy (constr_of_ref "micromega.ZArithProof.ExProof")
+let coq_IsProp = lazy (constr_of_ref "micromega.kind.isProp")
+let coq_IsBool = lazy (constr_of_ref "micromega.kind.isBool")
+let coq_Zgt = lazy (constr_of_ref "num.Z.gt")
+let coq_Zge = lazy (constr_of_ref "num.Z.ge")
+let coq_Zle = lazy (constr_of_ref "num.Z.le")
+let coq_Zlt = lazy (constr_of_ref "num.Z.lt")
+let coq_Zgtb = lazy (constr_of_ref "num.Z.gtb")
+let coq_Zgeb = lazy (constr_of_ref "num.Z.geb")
+let coq_Zleb = lazy (constr_of_ref "num.Z.leb")
+let coq_Zltb = lazy (constr_of_ref "num.Z.ltb")
+let coq_Zeqb = lazy (constr_of_ref "num.Z.eqb")
+let coq_eq = lazy (constr_of_ref "core.eq.type")
+let coq_Zplus = lazy (constr_of_ref "num.Z.add")
+let coq_Zminus = lazy (constr_of_ref "num.Z.sub")
+let coq_Zopp = lazy (constr_of_ref "num.Z.opp")
+let coq_Zmult = lazy (constr_of_ref "num.Z.mul")
+let coq_Zpower = lazy (constr_of_ref "num.Z.pow")
+let coq_Qle = lazy (constr_of_ref "rat.Q.Qle")
+let coq_Qlt = lazy (constr_of_ref "rat.Q.Qlt")
+let coq_Qeq = lazy (constr_of_ref "rat.Q.Qeq")
+let coq_Qplus = lazy (constr_of_ref "rat.Q.Qplus")
+let coq_Qminus = lazy (constr_of_ref "rat.Q.Qminus")
+let coq_Qopp = lazy (constr_of_ref "rat.Q.Qopp")
+let coq_Qmult = lazy (constr_of_ref "rat.Q.Qmult")
+let coq_Qpower = lazy (constr_of_ref "rat.Q.Qpower")
+let coq_Rgt = lazy (constr_of_ref "reals.R.Rgt")
+let coq_Rge = lazy (constr_of_ref "reals.R.Rge")
+let coq_Rle = lazy (constr_of_ref "reals.R.Rle")
+let coq_Rlt = lazy (constr_of_ref "reals.R.Rlt")
+let coq_Rplus = lazy (constr_of_ref "reals.R.Rplus")
+let coq_Rminus = lazy (constr_of_ref "reals.R.Rminus")
+let coq_Ropp = lazy (constr_of_ref "reals.R.Ropp")
+let coq_Rmult = lazy (constr_of_ref "reals.R.Rmult")
+let coq_Rinv = lazy (constr_of_ref "reals.R.Rinv")
+let coq_Rpower = lazy (constr_of_ref "reals.R.pow")
+let coq_powerZR = lazy (constr_of_ref "reals.R.powerRZ")
+let coq_IZR = lazy (constr_of_ref "reals.R.IZR")
+let coq_IQR = lazy (constr_of_ref "reals.R.Q2R")
+let coq_PEX = lazy (constr_of_ref "micromega.PExpr.PEX")
+let coq_PEc = lazy (constr_of_ref "micromega.PExpr.PEc")
+let coq_PEadd = lazy (constr_of_ref "micromega.PExpr.PEadd")
+let coq_PEopp = lazy (constr_of_ref "micromega.PExpr.PEopp")
+let coq_PEmul = lazy (constr_of_ref "micromega.PExpr.PEmul")
+let coq_PEsub = lazy (constr_of_ref "micromega.PExpr.PEsub")
+let coq_PEpow = lazy (constr_of_ref "micromega.PExpr.PEpow")
+let coq_PX = lazy (constr_of_ref "micromega.Pol.PX")
+let coq_Pc = lazy (constr_of_ref "micromega.Pol.Pc")
+let coq_Pinj = lazy (constr_of_ref "micromega.Pol.Pinj")
+let coq_OpEq = lazy (constr_of_ref "micromega.Op2.OpEq")
+let coq_OpNEq = lazy (constr_of_ref "micromega.Op2.OpNEq")
+let coq_OpLe = lazy (constr_of_ref "micromega.Op2.OpLe")
+let coq_OpLt = lazy (constr_of_ref "micromega.Op2.OpLt")
+let coq_OpGe = lazy (constr_of_ref "micromega.Op2.OpGe")
+let coq_OpGt = lazy (constr_of_ref "micromega.Op2.OpGt")
+let coq_PsatzIn = lazy (constr_of_ref "micromega.Psatz.PsatzIn")
+let coq_PsatzSquare = lazy (constr_of_ref "micromega.Psatz.PsatzSquare")
+let coq_PsatzMulE = lazy (constr_of_ref "micromega.Psatz.PsatzMulE")
+let coq_PsatzMultC = lazy (constr_of_ref "micromega.Psatz.PsatzMulC")
+let coq_PsatzAdd = lazy (constr_of_ref "micromega.Psatz.PsatzAdd")
+let coq_PsatzC = lazy (constr_of_ref "micromega.Psatz.PsatzC")
+let coq_PsatzZ = lazy (constr_of_ref "micromega.Psatz.PsatzZ")
+
+(* let coq_GT = lazy (m_constant "GT")*)
+
+let coq_DeclaredConstant =
+ lazy (constr_of_ref "micromega.DeclaredConstant.type")
+
+let coq_TT = lazy (constr_of_ref "micromega.GFormula.TT")
+let coq_FF = lazy (constr_of_ref "micromega.GFormula.FF")
+let coq_AND = lazy (constr_of_ref "micromega.GFormula.AND")
+let coq_OR = lazy (constr_of_ref "micromega.GFormula.OR")
+let coq_NOT = lazy (constr_of_ref "micromega.GFormula.NOT")
+let coq_Atom = lazy (constr_of_ref "micromega.GFormula.A")
+let coq_X = lazy (constr_of_ref "micromega.GFormula.X")
+let coq_IMPL = lazy (constr_of_ref "micromega.GFormula.IMPL")
+let coq_IFF = lazy (constr_of_ref "micromega.GFormula.IFF")
+let coq_EQ = lazy (constr_of_ref "micromega.GFormula.EQ")
+let coq_Formula = lazy (constr_of_ref "micromega.BFormula.type")
+let coq_eKind = lazy (constr_of_ref "micromega.eKind")
+
+(**
* Initialization : a few Caml symbols are derived from other libraries;
* QMicromega, ZArithRing, RingMicromega.
*)
- let coq_QWitness = lazy (constr_of_ref "micromega.QWitness.type")
- let coq_Build = lazy (constr_of_ref "micromega.Formula.Build_Formula")
- let coq_Cstr = lazy (constr_of_ref "micromega.Formula.type")
+let coq_QWitness = lazy (constr_of_ref "micromega.QWitness.type")
+let coq_Build = lazy (constr_of_ref "micromega.Formula.Build_Formula")
+let coq_Cstr = lazy (constr_of_ref "micromega.Formula.type")
- (**
+(**
* Parsing and dumping : transformation functions between Caml and Coq
* data-structures.
*
@@ -302,1048 +297,1018 @@ module M = struct
* pp_* functions pretty-print Coq terms.
*)
- exception ParseError
+exception ParseError
- (* A simple but useful getter function *)
+(* A simple but useful getter function *)
- let get_left_construct sigma term =
- match EConstr.kind sigma term with
- | Construct ((_, i), _) -> (i, [||])
- | App (l, rst) -> (
- match EConstr.kind sigma l with
- | Construct ((_, i), _) -> (i, rst)
- | _ -> raise ParseError )
- | _ -> raise ParseError
+let get_left_construct sigma term =
+ match EConstr.kind sigma term with
+ | Construct ((_, i), _) -> (i, [||])
+ | App (l, rst) -> (
+ match EConstr.kind sigma l with
+ | Construct ((_, i), _) -> (i, rst)
+ | _ -> raise ParseError )
+ | _ -> raise ParseError
- (* Access the Micromega module *)
+(* Access the Micromega module *)
- (* parse/dump/print from numbers up to expressions and formulas *)
+(* parse/dump/print from numbers up to expressions and formulas *)
- let rec parse_nat sigma term =
- let i, c = get_left_construct sigma term in
- match i with
- | 1 -> Mc.O
- | 2 -> Mc.S (parse_nat sigma c.(0))
- | i -> raise ParseError
+let rec parse_nat sigma term =
+ let i, c = get_left_construct sigma term in
+ match i with
+ | 1 -> Mc.O
+ | 2 -> Mc.S (parse_nat sigma c.(0))
+ | i -> raise ParseError
- let pp_nat o n = Printf.fprintf o "%i" (CoqToCaml.nat n)
+let pp_nat o n = Printf.fprintf o "%i" (CoqToCaml.nat n)
- let rec dump_nat x =
- match x with
- | Mc.O -> Lazy.force coq_O
- | Mc.S p -> EConstr.mkApp (Lazy.force coq_S, [|dump_nat p|])
+let rec dump_nat x =
+ match x with
+ | Mc.O -> Lazy.force coq_O
+ | Mc.S p -> EConstr.mkApp (Lazy.force coq_S, [|dump_nat p|])
- let rec parse_positive sigma term =
- let i, c = get_left_construct sigma term in
- match i with
- | 1 -> Mc.XI (parse_positive sigma c.(0))
- | 2 -> Mc.XO (parse_positive sigma c.(0))
- | 3 -> Mc.XH
- | i -> raise ParseError
+let rec parse_positive sigma term =
+ let i, c = get_left_construct sigma term in
+ match i with
+ | 1 -> Mc.XI (parse_positive sigma c.(0))
+ | 2 -> Mc.XO (parse_positive sigma c.(0))
+ | 3 -> Mc.XH
+ | i -> raise ParseError
- let rec dump_positive x =
- match x with
- | Mc.XH -> Lazy.force coq_xH
- | Mc.XO p -> EConstr.mkApp (Lazy.force coq_xO, [|dump_positive p|])
- | Mc.XI p -> EConstr.mkApp (Lazy.force coq_xI, [|dump_positive p|])
+let rec dump_positive x =
+ match x with
+ | Mc.XH -> Lazy.force coq_xH
+ | Mc.XO p -> EConstr.mkApp (Lazy.force coq_xO, [|dump_positive p|])
+ | Mc.XI p -> EConstr.mkApp (Lazy.force coq_xI, [|dump_positive p|])
- let pp_positive o x = Printf.fprintf o "%i" (CoqToCaml.positive x)
+let pp_positive o x = Printf.fprintf o "%i" (CoqToCaml.positive x)
- let dump_n x =
- match x with
- | Mc.N0 -> Lazy.force coq_N0
- | Mc.Npos p -> EConstr.mkApp (Lazy.force coq_Npos, [|dump_positive p|])
+let dump_n x =
+ match x with
+ | Mc.N0 -> Lazy.force coq_N0
+ | Mc.Npos p -> EConstr.mkApp (Lazy.force coq_Npos, [|dump_positive p|])
- (** [is_ground_term env sigma term] holds if the term [term]
+(** [is_ground_term env sigma term] holds if the term [term]
is an instance of the typeclass [DeclConstant.GT term]
i.e. built from user-defined constants and functions.
NB: This mechanism can be used to customise the reification process to decide
what to consider as a constant (see [parse_constant])
*)
- let is_declared_term env evd t =
- match EConstr.kind evd t with
- | Const _ | Construct _ -> (
- (* Restrict typeclass resolution to trivial cases *)
- let typ = Retyping.get_type_of env evd t in
- try
- ignore
- (Typeclasses.resolve_one_typeclass env evd
- (EConstr.mkApp (Lazy.force coq_DeclaredConstant, [|typ; t|])));
- true
- with Not_found -> false )
- | _ -> false
-
- let rec is_ground_term env evd term =
- match EConstr.kind evd term with
- | App (c, args) ->
- is_declared_term env evd c && Array.for_all (is_ground_term env evd) args
- | Const _ | Construct _ -> is_declared_term env evd term
- | _ -> false
-
- let parse_z sigma term =
- let i, c = get_left_construct sigma term in
- match i with
- | 1 -> Mc.Z0
- | 2 -> Mc.Zpos (parse_positive sigma c.(0))
- | 3 -> Mc.Zneg (parse_positive sigma c.(0))
- | i -> raise ParseError
-
- let dump_z x =
- match x with
- | Mc.Z0 -> Lazy.force coq_ZERO
- | Mc.Zpos p -> EConstr.mkApp (Lazy.force coq_POS, [|dump_positive p|])
- | Mc.Zneg p -> EConstr.mkApp (Lazy.force coq_NEG, [|dump_positive p|])
-
- let pp_z o x =
- Printf.fprintf o "%s" (NumCompat.Z.to_string (CoqToCaml.z_big_int x))
-
- let dump_q q =
+let is_declared_term env evd t =
+ match EConstr.kind evd t with
+ | Const _ | Construct _ -> (
+ (* Restrict typeclass resolution to trivial cases *)
+ let typ = Retyping.get_type_of env evd t in
+ try
+ ignore
+ (Typeclasses.resolve_one_typeclass env evd
+ (EConstr.mkApp (Lazy.force coq_DeclaredConstant, [|typ; t|])));
+ true
+ with Not_found -> false )
+ | _ -> false
+
+let rec is_ground_term env evd term =
+ match EConstr.kind evd term with
+ | App (c, args) ->
+ is_declared_term env evd c && Array.for_all (is_ground_term env evd) args
+ | Const _ | Construct _ -> is_declared_term env evd term
+ | _ -> false
+
+let parse_z sigma term =
+ let i, c = get_left_construct sigma term in
+ match i with
+ | 1 -> Mc.Z0
+ | 2 -> Mc.Zpos (parse_positive sigma c.(0))
+ | 3 -> Mc.Zneg (parse_positive sigma c.(0))
+ | i -> raise ParseError
+
+let dump_z x =
+ match x with
+ | Mc.Z0 -> Lazy.force coq_ZERO
+ | Mc.Zpos p -> EConstr.mkApp (Lazy.force coq_POS, [|dump_positive p|])
+ | Mc.Zneg p -> EConstr.mkApp (Lazy.force coq_NEG, [|dump_positive p|])
+
+let pp_z o x =
+ Printf.fprintf o "%s" (NumCompat.Z.to_string (CoqToCaml.z_big_int x))
+
+let dump_q q =
+ EConstr.mkApp
+ ( Lazy.force coq_Qmake
+ , [|dump_z q.Micromega.qnum; dump_positive q.Micromega.qden|] )
+
+let parse_q sigma term =
+ match EConstr.kind sigma term with
+ | App (c, args) ->
+ if EConstr.eq_constr sigma c (Lazy.force coq_Qmake) then
+ {Mc.qnum = parse_z sigma args.(0); Mc.qden = parse_positive sigma args.(1)}
+ else raise ParseError
+ | _ -> raise ParseError
+
+let rec pp_Rcst o cst =
+ match cst with
+ | Mc.C0 -> output_string o "C0"
+ | Mc.C1 -> output_string o "C1"
+ | Mc.CQ q -> output_string o "CQ _"
+ | Mc.CZ z -> pp_z o z
+ | Mc.CPlus (x, y) -> Printf.fprintf o "(%a + %a)" pp_Rcst x pp_Rcst y
+ | Mc.CMinus (x, y) -> Printf.fprintf o "(%a - %a)" pp_Rcst x pp_Rcst y
+ | Mc.CMult (x, y) -> Printf.fprintf o "(%a * %a)" pp_Rcst x pp_Rcst y
+ | Mc.CPow (x, y) -> Printf.fprintf o "(%a ^ _)" pp_Rcst x
+ | Mc.CInv t -> Printf.fprintf o "(/ %a)" pp_Rcst t
+ | Mc.COpp t -> Printf.fprintf o "(- %a)" pp_Rcst t
+
+let rec dump_Rcst cst =
+ match cst with
+ | Mc.C0 -> Lazy.force coq_C0
+ | Mc.C1 -> Lazy.force coq_C1
+ | Mc.CQ q -> EConstr.mkApp (Lazy.force coq_CQ, [|dump_q q|])
+ | Mc.CZ z -> EConstr.mkApp (Lazy.force coq_CZ, [|dump_z z|])
+ | Mc.CPlus (x, y) ->
+ EConstr.mkApp (Lazy.force coq_CPlus, [|dump_Rcst x; dump_Rcst y|])
+ | Mc.CMinus (x, y) ->
+ EConstr.mkApp (Lazy.force coq_CMinus, [|dump_Rcst x; dump_Rcst y|])
+ | Mc.CMult (x, y) ->
+ EConstr.mkApp (Lazy.force coq_CMult, [|dump_Rcst x; dump_Rcst y|])
+ | Mc.CPow (x, y) ->
EConstr.mkApp
- ( Lazy.force coq_Qmake
- , [|dump_z q.Micromega.qnum; dump_positive q.Micromega.qden|] )
-
- let parse_q sigma term =
- match EConstr.kind sigma term with
- | App (c, args) ->
- if EConstr.eq_constr sigma c (Lazy.force coq_Qmake) then
- { Mc.qnum = parse_z sigma args.(0)
- ; Mc.qden = parse_positive sigma args.(1) }
- else raise ParseError
- | _ -> raise ParseError
+ ( Lazy.force coq_CPow
+ , [| dump_Rcst x
+ ; ( match y with
+ | Mc.Inl z ->
+ EConstr.mkApp
+ ( Lazy.force coq_Inl
+ , [|Lazy.force coq_Z; Lazy.force coq_nat; dump_z z|] )
+ | Mc.Inr n ->
+ EConstr.mkApp
+ ( Lazy.force coq_Inr
+ , [|Lazy.force coq_Z; Lazy.force coq_nat; dump_nat n|] ) ) |] )
+ | Mc.CInv t -> EConstr.mkApp (Lazy.force coq_CInv, [|dump_Rcst t|])
+ | Mc.COpp t -> EConstr.mkApp (Lazy.force coq_COpp, [|dump_Rcst t|])
+
+let rec dump_list typ dump_elt l =
+ match l with
+ | [] -> EConstr.mkApp (Lazy.force coq_nil, [|typ|])
+ | e :: l ->
+ EConstr.mkApp
+ (Lazy.force coq_cons, [|typ; dump_elt e; dump_list typ dump_elt l|])
- let rec pp_Rcst o cst =
- match cst with
- | Mc.C0 -> output_string o "C0"
- | Mc.C1 -> output_string o "C1"
- | Mc.CQ q -> output_string o "CQ _"
- | Mc.CZ z -> pp_z o z
- | Mc.CPlus (x, y) -> Printf.fprintf o "(%a + %a)" pp_Rcst x pp_Rcst y
- | Mc.CMinus (x, y) -> Printf.fprintf o "(%a - %a)" pp_Rcst x pp_Rcst y
- | Mc.CMult (x, y) -> Printf.fprintf o "(%a * %a)" pp_Rcst x pp_Rcst y
- | Mc.CPow (x, y) -> Printf.fprintf o "(%a ^ _)" pp_Rcst x
- | Mc.CInv t -> Printf.fprintf o "(/ %a)" pp_Rcst t
- | Mc.COpp t -> Printf.fprintf o "(- %a)" pp_Rcst t
-
- let rec dump_Rcst cst =
- match cst with
- | Mc.C0 -> Lazy.force coq_C0
- | Mc.C1 -> Lazy.force coq_C1
- | Mc.CQ q -> EConstr.mkApp (Lazy.force coq_CQ, [|dump_q q|])
- | Mc.CZ z -> EConstr.mkApp (Lazy.force coq_CZ, [|dump_z z|])
- | Mc.CPlus (x, y) ->
- EConstr.mkApp (Lazy.force coq_CPlus, [|dump_Rcst x; dump_Rcst y|])
- | Mc.CMinus (x, y) ->
- EConstr.mkApp (Lazy.force coq_CMinus, [|dump_Rcst x; dump_Rcst y|])
- | Mc.CMult (x, y) ->
- EConstr.mkApp (Lazy.force coq_CMult, [|dump_Rcst x; dump_Rcst y|])
- | Mc.CPow (x, y) ->
- EConstr.mkApp
- ( Lazy.force coq_CPow
- , [| dump_Rcst x
- ; ( match y with
- | Mc.Inl z ->
- EConstr.mkApp
- ( Lazy.force coq_Inl
- , [|Lazy.force coq_Z; Lazy.force coq_nat; dump_z z|] )
- | Mc.Inr n ->
- EConstr.mkApp
- ( Lazy.force coq_Inr
- , [|Lazy.force coq_Z; Lazy.force coq_nat; dump_nat n|] ) ) |]
- )
- | Mc.CInv t -> EConstr.mkApp (Lazy.force coq_CInv, [|dump_Rcst t|])
- | Mc.COpp t -> EConstr.mkApp (Lazy.force coq_COpp, [|dump_Rcst t|])
-
- let rec dump_list typ dump_elt l =
+let pp_list op cl elt o l =
+ let rec _pp o l =
match l with
- | [] -> EConstr.mkApp (Lazy.force coq_nil, [|typ|])
- | e :: l ->
- EConstr.mkApp
- (Lazy.force coq_cons, [|typ; dump_elt e; dump_list typ dump_elt l|])
-
- let pp_list op cl elt o l =
- let rec _pp o l =
- match l with
- | [] -> ()
- | [e] -> Printf.fprintf o "%a" elt e
- | e :: l -> Printf.fprintf o "%a ,%a" elt e _pp l
- in
- Printf.fprintf o "%s%a%s" op _pp l cl
+ | [] -> ()
+ | [e] -> Printf.fprintf o "%a" elt e
+ | e :: l -> Printf.fprintf o "%a ,%a" elt e _pp l
+ in
+ Printf.fprintf o "%s%a%s" op _pp l cl
- let dump_var = dump_positive
+let dump_var = dump_positive
- let dump_expr typ dump_z e =
- let rec dump_expr e =
- match e with
- | Mc.PEX n -> EConstr.mkApp (Lazy.force coq_PEX, [|typ; dump_var n|])
- | Mc.PEc z -> EConstr.mkApp (Lazy.force coq_PEc, [|typ; dump_z z|])
- | Mc.PEadd (e1, e2) ->
- EConstr.mkApp (Lazy.force coq_PEadd, [|typ; dump_expr e1; dump_expr e2|])
- | Mc.PEsub (e1, e2) ->
- EConstr.mkApp (Lazy.force coq_PEsub, [|typ; dump_expr e1; dump_expr e2|])
- | Mc.PEopp e -> EConstr.mkApp (Lazy.force coq_PEopp, [|typ; dump_expr e|])
- | Mc.PEmul (e1, e2) ->
- EConstr.mkApp (Lazy.force coq_PEmul, [|typ; dump_expr e1; dump_expr e2|])
- | Mc.PEpow (e, n) ->
- EConstr.mkApp (Lazy.force coq_PEpow, [|typ; dump_expr e; dump_n n|])
- in
- dump_expr e
+let dump_expr typ dump_z e =
+ let rec dump_expr e =
+ match e with
+ | Mc.PEX n -> EConstr.mkApp (Lazy.force coq_PEX, [|typ; dump_var n|])
+ | Mc.PEc z -> EConstr.mkApp (Lazy.force coq_PEc, [|typ; dump_z z|])
+ | Mc.PEadd (e1, e2) ->
+ EConstr.mkApp (Lazy.force coq_PEadd, [|typ; dump_expr e1; dump_expr e2|])
+ | Mc.PEsub (e1, e2) ->
+ EConstr.mkApp (Lazy.force coq_PEsub, [|typ; dump_expr e1; dump_expr e2|])
+ | Mc.PEopp e -> EConstr.mkApp (Lazy.force coq_PEopp, [|typ; dump_expr e|])
+ | Mc.PEmul (e1, e2) ->
+ EConstr.mkApp (Lazy.force coq_PEmul, [|typ; dump_expr e1; dump_expr e2|])
+ | Mc.PEpow (e, n) ->
+ EConstr.mkApp (Lazy.force coq_PEpow, [|typ; dump_expr e; dump_n n|])
+ in
+ dump_expr e
- let dump_pol typ dump_c e =
- let rec dump_pol e =
- match e with
- | Mc.Pc n -> EConstr.mkApp (Lazy.force coq_Pc, [|typ; dump_c n|])
- | Mc.Pinj (p, pol) ->
- EConstr.mkApp
- (Lazy.force coq_Pinj, [|typ; dump_positive p; dump_pol pol|])
- | Mc.PX (pol1, p, pol2) ->
- EConstr.mkApp
- ( Lazy.force coq_PX
- , [|typ; dump_pol pol1; dump_positive p; dump_pol pol2|] )
- in
- dump_pol e
-
- let pp_pol pp_c o e =
- let rec pp_pol o e =
- match e with
- | Mc.Pc n -> Printf.fprintf o "Pc %a" pp_c n
- | Mc.Pinj (p, pol) ->
- Printf.fprintf o "Pinj(%a,%a)" pp_positive p pp_pol pol
- | Mc.PX (pol1, p, pol2) ->
- Printf.fprintf o "PX(%a,%a,%a)" pp_pol pol1 pp_positive p pp_pol pol2
- in
- pp_pol o e
-
- (* let pp_clause pp_c o (f: 'cst clause) =
- List.iter (fun ((p,_),(t,_)) -> Printf.fprintf o "(%a @%a)" (pp_pol pp_c) p Tag.pp t) f *)
-
- let pp_clause_tag o (f : 'cst clause) =
- List.iter (fun ((p, _), (t, _)) -> Printf.fprintf o "(_ @%a)" Tag.pp t) f
-
- (* let pp_cnf pp_c o (f:'cst cnf) =
- List.iter (fun l -> Printf.fprintf o "[%a]" (pp_clause pp_c) l) f *)
-
- let pp_cnf_tag o (f : 'cst cnf) =
- List.iter (fun l -> Printf.fprintf o "[%a]" pp_clause_tag l) f
-
- let dump_psatz typ dump_z e =
- let z = Lazy.force typ in
- let rec dump_cone e =
- match e with
- | Mc.PsatzIn n -> EConstr.mkApp (Lazy.force coq_PsatzIn, [|z; dump_nat n|])
- | Mc.PsatzMulC (e, c) ->
- EConstr.mkApp
- (Lazy.force coq_PsatzMultC, [|z; dump_pol z dump_z e; dump_cone c|])
- | Mc.PsatzSquare e ->
- EConstr.mkApp (Lazy.force coq_PsatzSquare, [|z; dump_pol z dump_z e|])
- | Mc.PsatzAdd (e1, e2) ->
- EConstr.mkApp
- (Lazy.force coq_PsatzAdd, [|z; dump_cone e1; dump_cone e2|])
- | Mc.PsatzMulE (e1, e2) ->
- EConstr.mkApp
- (Lazy.force coq_PsatzMulE, [|z; dump_cone e1; dump_cone e2|])
- | Mc.PsatzC p -> EConstr.mkApp (Lazy.force coq_PsatzC, [|z; dump_z p|])
- | Mc.PsatzZ -> EConstr.mkApp (Lazy.force coq_PsatzZ, [|z|])
- in
- dump_cone e
-
- let pp_psatz pp_z o e =
- let rec pp_cone o e =
- match e with
- | Mc.PsatzIn n -> Printf.fprintf o "(In %a)%%nat" pp_nat n
- | Mc.PsatzMulC (e, c) ->
- Printf.fprintf o "( %a [*] %a)" (pp_pol pp_z) e pp_cone c
- | Mc.PsatzSquare e -> Printf.fprintf o "(%a^2)" (pp_pol pp_z) e
- | Mc.PsatzAdd (e1, e2) ->
- Printf.fprintf o "(%a [+] %a)" pp_cone e1 pp_cone e2
- | Mc.PsatzMulE (e1, e2) ->
- Printf.fprintf o "(%a [*] %a)" pp_cone e1 pp_cone e2
- | Mc.PsatzC p -> Printf.fprintf o "(%a)%%positive" pp_z p
- | Mc.PsatzZ -> Printf.fprintf o "0"
- in
- pp_cone o e
+let dump_pol typ dump_c e =
+ let rec dump_pol e =
+ match e with
+ | Mc.Pc n -> EConstr.mkApp (Lazy.force coq_Pc, [|typ; dump_c n|])
+ | Mc.Pinj (p, pol) ->
+ EConstr.mkApp (Lazy.force coq_Pinj, [|typ; dump_positive p; dump_pol pol|])
+ | Mc.PX (pol1, p, pol2) ->
+ EConstr.mkApp
+ ( Lazy.force coq_PX
+ , [|typ; dump_pol pol1; dump_positive p; dump_pol pol2|] )
+ in
+ dump_pol e
- let dump_op = function
- | Mc.OpEq -> Lazy.force coq_OpEq
- | Mc.OpNEq -> Lazy.force coq_OpNEq
- | Mc.OpLe -> Lazy.force coq_OpLe
- | Mc.OpGe -> Lazy.force coq_OpGe
- | Mc.OpGt -> Lazy.force coq_OpGt
- | Mc.OpLt -> Lazy.force coq_OpLt
+let pp_pol pp_c o e =
+ let rec pp_pol o e =
+ match e with
+ | Mc.Pc n -> Printf.fprintf o "Pc %a" pp_c n
+ | Mc.Pinj (p, pol) ->
+ Printf.fprintf o "Pinj(%a,%a)" pp_positive p pp_pol pol
+ | Mc.PX (pol1, p, pol2) ->
+ Printf.fprintf o "PX(%a,%a,%a)" pp_pol pol1 pp_positive p pp_pol pol2
+ in
+ pp_pol o e
- let dump_cstr typ dump_constant {Mc.flhs = e1; Mc.fop = o; Mc.frhs = e2} =
- EConstr.mkApp
- ( Lazy.force coq_Build
- , [| typ
- ; dump_expr typ dump_constant e1
- ; dump_op o
- ; dump_expr typ dump_constant e2 |] )
+(* let pp_clause pp_c o (f: 'cst clause) =
+ List.iter (fun ((p,_),(t,_)) -> Printf.fprintf o "(%a @%a)" (pp_pol pp_c) p Tag.pp t) f *)
- let assoc_const sigma x l =
- try
- snd
- (List.find (fun (x', y) -> EConstr.eq_constr sigma x (Lazy.force x')) l)
- with Not_found -> raise ParseError
-
- let zop_table_prop =
- [ (coq_Zgt, Mc.OpGt)
- ; (coq_Zge, Mc.OpGe)
- ; (coq_Zlt, Mc.OpLt)
- ; (coq_Zle, Mc.OpLe) ]
-
- let zop_table_bool =
- [ (coq_Zgtb, Mc.OpGt)
- ; (coq_Zgeb, Mc.OpGe)
- ; (coq_Zltb, Mc.OpLt)
- ; (coq_Zleb, Mc.OpLe)
- ; (coq_Zeqb, Mc.OpEq) ]
-
- let rop_table_prop =
- [ (coq_Rgt, Mc.OpGt)
- ; (coq_Rge, Mc.OpGe)
- ; (coq_Rlt, Mc.OpLt)
- ; (coq_Rle, Mc.OpLe) ]
-
- let rop_table_bool = []
-
- let qop_table_prop =
- [(coq_Qlt, Mc.OpLt); (coq_Qle, Mc.OpLe); (coq_Qeq, Mc.OpEq)]
-
- let qop_table_bool = []
-
- type gl = {env : Environ.env; sigma : Evd.evar_map}
-
- let is_convertible gl t1 t2 = Reductionops.is_conv gl.env gl.sigma t1 t2
-
- let parse_operator table_prop table_bool has_equality typ gl k (op, args) =
- let sigma = gl.sigma in
- match args with
- | [|a1; a2|] ->
- ( assoc_const sigma op
- (match k with Mc.IsProp -> table_prop | Mc.IsBool -> table_bool)
- , a1
- , a2 )
- | [|ty; a1; a2|] ->
- if
- has_equality
- && EConstr.eq_constr sigma op (Lazy.force coq_eq)
- && is_convertible gl ty (Lazy.force typ)
- then (Mc.OpEq, args.(1), args.(2))
- else raise ParseError
- | _ -> raise ParseError
+let pp_clause_tag o (f : 'cst clause) =
+ List.iter (fun ((p, _), (t, _)) -> Printf.fprintf o "(_ @%a)" Tag.pp t) f
- let parse_zop = parse_operator zop_table_prop zop_table_bool true coq_Z
- let parse_rop = parse_operator rop_table_prop [] true coq_R
- let parse_qop = parse_operator qop_table_prop [] false coq_R
+(* let pp_cnf pp_c o (f:'cst cnf) =
+ List.iter (fun l -> Printf.fprintf o "[%a]" (pp_clause pp_c) l) f *)
- type 'a op =
- | Binop of ('a Mc.pExpr -> 'a Mc.pExpr -> 'a Mc.pExpr)
- | Opp
- | Power
- | Ukn of string
+let pp_cnf_tag o (f : 'cst cnf) =
+ List.iter (fun l -> Printf.fprintf o "[%a]" pp_clause_tag l) f
- let assoc_ops sigma x l =
- try
- snd
- (List.find (fun (x', y) -> EConstr.eq_constr sigma x (Lazy.force x')) l)
- with Not_found -> Ukn "Oups"
+let dump_psatz typ dump_z e =
+ let z = Lazy.force typ in
+ let rec dump_cone e =
+ match e with
+ | Mc.PsatzIn n -> EConstr.mkApp (Lazy.force coq_PsatzIn, [|z; dump_nat n|])
+ | Mc.PsatzMulC (e, c) ->
+ EConstr.mkApp
+ (Lazy.force coq_PsatzMultC, [|z; dump_pol z dump_z e; dump_cone c|])
+ | Mc.PsatzSquare e ->
+ EConstr.mkApp (Lazy.force coq_PsatzSquare, [|z; dump_pol z dump_z e|])
+ | Mc.PsatzAdd (e1, e2) ->
+ EConstr.mkApp (Lazy.force coq_PsatzAdd, [|z; dump_cone e1; dump_cone e2|])
+ | Mc.PsatzMulE (e1, e2) ->
+ EConstr.mkApp (Lazy.force coq_PsatzMulE, [|z; dump_cone e1; dump_cone e2|])
+ | Mc.PsatzC p -> EConstr.mkApp (Lazy.force coq_PsatzC, [|z; dump_z p|])
+ | Mc.PsatzZ -> EConstr.mkApp (Lazy.force coq_PsatzZ, [|z|])
+ in
+ dump_cone e
- (**
+let pp_psatz pp_z o e =
+ let rec pp_cone o e =
+ match e with
+ | Mc.PsatzIn n -> Printf.fprintf o "(In %a)%%nat" pp_nat n
+ | Mc.PsatzMulC (e, c) ->
+ Printf.fprintf o "( %a [*] %a)" (pp_pol pp_z) e pp_cone c
+ | Mc.PsatzSquare e -> Printf.fprintf o "(%a^2)" (pp_pol pp_z) e
+ | Mc.PsatzAdd (e1, e2) ->
+ Printf.fprintf o "(%a [+] %a)" pp_cone e1 pp_cone e2
+ | Mc.PsatzMulE (e1, e2) ->
+ Printf.fprintf o "(%a [*] %a)" pp_cone e1 pp_cone e2
+ | Mc.PsatzC p -> Printf.fprintf o "(%a)%%positive" pp_z p
+ | Mc.PsatzZ -> Printf.fprintf o "0"
+ in
+ pp_cone o e
+
+let dump_op = function
+ | Mc.OpEq -> Lazy.force coq_OpEq
+ | Mc.OpNEq -> Lazy.force coq_OpNEq
+ | Mc.OpLe -> Lazy.force coq_OpLe
+ | Mc.OpGe -> Lazy.force coq_OpGe
+ | Mc.OpGt -> Lazy.force coq_OpGt
+ | Mc.OpLt -> Lazy.force coq_OpLt
+
+let dump_cstr typ dump_constant {Mc.flhs = e1; Mc.fop = o; Mc.frhs = e2} =
+ EConstr.mkApp
+ ( Lazy.force coq_Build
+ , [| typ
+ ; dump_expr typ dump_constant e1
+ ; dump_op o
+ ; dump_expr typ dump_constant e2 |] )
+
+let assoc_const sigma x l =
+ try
+ snd (List.find (fun (x', y) -> EConstr.eq_constr sigma x (Lazy.force x')) l)
+ with Not_found -> raise ParseError
+
+let zop_table_prop =
+ [ (coq_Zgt, Mc.OpGt)
+ ; (coq_Zge, Mc.OpGe)
+ ; (coq_Zlt, Mc.OpLt)
+ ; (coq_Zle, Mc.OpLe) ]
+
+let zop_table_bool =
+ [ (coq_Zgtb, Mc.OpGt)
+ ; (coq_Zgeb, Mc.OpGe)
+ ; (coq_Zltb, Mc.OpLt)
+ ; (coq_Zleb, Mc.OpLe)
+ ; (coq_Zeqb, Mc.OpEq) ]
+
+let rop_table_prop =
+ [ (coq_Rgt, Mc.OpGt)
+ ; (coq_Rge, Mc.OpGe)
+ ; (coq_Rlt, Mc.OpLt)
+ ; (coq_Rle, Mc.OpLe) ]
+
+let rop_table_bool = []
+let qop_table_prop = [(coq_Qlt, Mc.OpLt); (coq_Qle, Mc.OpLe); (coq_Qeq, Mc.OpEq)]
+let qop_table_bool = []
+
+type gl = Environ.env * Evd.evar_map
+
+let is_convertible env sigma t1 t2 = Reductionops.is_conv env sigma t1 t2
+
+let parse_operator table_prop table_bool has_equality typ (env, sigma) k
+ (op, args) =
+ match args with
+ | [|a1; a2|] ->
+ ( assoc_const sigma op
+ (match k with Mc.IsProp -> table_prop | Mc.IsBool -> table_bool)
+ , a1
+ , a2 )
+ | [|ty; a1; a2|] ->
+ if
+ has_equality
+ && EConstr.eq_constr sigma op (Lazy.force coq_eq)
+ && is_convertible env sigma ty (Lazy.force typ)
+ then (Mc.OpEq, args.(1), args.(2))
+ else raise ParseError
+ | _ -> raise ParseError
+
+let parse_zop = parse_operator zop_table_prop zop_table_bool true coq_Z
+let parse_rop = parse_operator rop_table_prop [] true coq_R
+let parse_qop = parse_operator qop_table_prop [] false coq_R
+
+type 'a op =
+ | Binop of ('a Mc.pExpr -> 'a Mc.pExpr -> 'a Mc.pExpr)
+ | Opp
+ | Power
+ | Ukn of string
+
+let assoc_ops sigma x l =
+ try
+ snd (List.find (fun (x', y) -> EConstr.eq_constr sigma x (Lazy.force x')) l)
+ with Not_found -> Ukn "Oups"
+
+(**
* MODULE: Env is for environment.
*)
- module Env = struct
- type t =
- { vars : (EConstr.t * Mc.kind) list
- ; (* The list represents a mapping from EConstr.t to indexes. *)
- gl : gl
- (* The evar_map may be updated due to unification of universes *) }
-
- let empty gl = {vars = []; gl}
-
- (** [eq_constr gl x y] returns an updated [gl] if x and y can be unified *)
- let eq_constr gl x y =
- let evd = gl.sigma in
- match EConstr.eq_constr_universes_proj gl.env evd x y with
- | Some csts -> (
- let csts =
- UnivProblem.to_constraints ~force_weak:false (Evd.universes evd) csts
- in
- match Evd.add_constraints evd csts with
- | evd -> Some {gl with sigma = evd}
- | exception Univ.UniverseInconsistency _ -> None )
- | None -> None
-
- let compute_rank_add env v is_prop =
- let rec _add gl vars n v =
- match vars with
- | [] -> (gl, [(v, is_prop)], n)
- | (e, b) :: l -> (
- match eq_constr gl e v with
- | Some gl' -> (gl', vars, n)
- | None ->
- let gl, l', n = _add gl l (n + 1) v in
- (gl, (e, b) :: l', n) )
- in
- let gl', vars', n = _add env.gl env.vars 1 v in
- ({vars = vars'; gl = gl'}, CamlToCoq.positive n)
-
- let get_rank env v =
- let gl = env.gl in
- let rec _get_rank env n =
- match env with
- | [] -> raise (Invalid_argument "get_rank")
- | (e, _) :: l -> (
- match eq_constr gl e v with Some _ -> n | None -> _get_rank l (n + 1)
- )
- in
- _get_rank env.vars 1
-
- let elements env = env.vars
-
- (* let string_of_env gl env =
- let rec string_of_env i env acc =
- match env with
- | [] -> acc
- | e::env -> string_of_env (i+1) env
- (IMap.add i
- (Pp.string_of_ppcmds
- (Printer.pr_econstr_env gl.env gl.sigma e)) acc) in
- string_of_env 1 env IMap.empty
- *)
- let pp gl env =
- let ppl =
- List.mapi
- (fun i (e, _) ->
- Pp.str "x"
- ++ Pp.int (i + 1)
- ++ Pp.str ":"
- ++ Printer.pr_econstr_env gl.env gl.sigma e)
- env
+module Env = struct
+ type t =
+ { vars : (EConstr.t * Mc.kind) list
+ ; (* The list represents a mapping from EConstr.t to indexes. *)
+ gl : gl (* The evar_map may be updated due to unification of universes *)
+ }
+
+ let empty gl = {vars = []; gl}
+
+ (** [eq_constr gl x y] returns an updated [gl] if x and y can be unified *)
+ let eq_constr (env, sigma) x y =
+ match EConstr.eq_constr_universes_proj env sigma x y with
+ | Some csts -> (
+ let csts =
+ UnivProblem.to_constraints ~force_weak:false (Evd.universes sigma) csts
in
- List.fold_right (fun e p -> e ++ Pp.str " ; " ++ p) ppl (Pp.str "\n")
- end
+ match Evd.add_constraints sigma csts with
+ | sigma -> Some (env, sigma)
+ | exception Univ.UniverseInconsistency _ -> None )
+ | None -> None
+
+ let compute_rank_add env v is_prop =
+ let rec _add gl vars n v =
+ match vars with
+ | [] -> (gl, [(v, is_prop)], n)
+ | (e, b) :: l -> (
+ match eq_constr gl e v with
+ | Some gl' -> (gl', vars, n)
+ | None ->
+ let gl, l', n = _add gl l (n + 1) v in
+ (gl, (e, b) :: l', n) )
+ in
+ let gl', vars', n = _add env.gl env.vars 1 v in
+ ({vars = vars'; gl = gl'}, CamlToCoq.positive n)
+
+ let get_rank env v =
+ let gl = env.gl in
+ let rec _get_rank env n =
+ match env with
+ | [] -> raise (Invalid_argument "get_rank")
+ | (e, _) :: l -> (
+ match eq_constr gl e v with Some _ -> n | None -> _get_rank l (n + 1) )
+ in
+ _get_rank env.vars 1
+
+ let elements env = env.vars
+
+ (* let string_of_env gl env =
+ let rec string_of_env i env acc =
+ match env with
+ | [] -> acc
+ | e::env -> string_of_env (i+1) env
+ (IMap.add i
+ (Pp.string_of_ppcmds
+ (Printer.pr_econstr_env gl.env gl.sigma e)) acc) in
+ string_of_env 1 env IMap.empty
+ *)
+ let pp (genv, sigma) env =
+ let ppl =
+ List.mapi
+ (fun i (e, _) ->
+ Pp.str "x"
+ ++ Pp.int (i + 1)
+ ++ Pp.str ":"
+ ++ Printer.pr_econstr_env genv sigma e)
+ env
+ in
+ List.fold_right (fun e p -> e ++ Pp.str " ; " ++ p) ppl (Pp.str "\n")
+end
- (* MODULE END: Env *)
+(* MODULE END: Env *)
- (**
+(**
* This is the big generic function for expression parsers.
*)
- let parse_expr gl parse_constant parse_exp ops_spec env term =
- if debug then
- Feedback.msg_debug
- (Pp.str "parse_expr: " ++ Printer.pr_leconstr_env gl.env gl.sigma term);
- let parse_variable env term =
- let env, n = Env.compute_rank_add env term Mc.IsBool in
- (Mc.PEX n, env)
+let parse_expr (genv, sigma) parse_constant parse_exp ops_spec env term =
+ if debug then
+ Feedback.msg_debug
+ (Pp.str "parse_expr: " ++ Printer.pr_leconstr_env genv sigma term);
+ let parse_variable env term =
+ let env, n = Env.compute_rank_add env term Mc.IsBool in
+ (Mc.PEX n, env)
+ in
+ let rec parse_expr env term =
+ let combine env op (t1, t2) =
+ let expr1, env = parse_expr env t1 in
+ let expr2, env = parse_expr env t2 in
+ (op expr1 expr2, env)
in
- let rec parse_expr env term =
- let combine env op (t1, t2) =
- let expr1, env = parse_expr env t1 in
- let expr2, env = parse_expr env t2 in
- (op expr1 expr2, env)
- in
- try (Mc.PEc (parse_constant gl term), env)
- with ParseError -> (
- match EConstr.kind gl.sigma term with
- | App (t, args) -> (
- match EConstr.kind gl.sigma t with
- | Const c -> (
- match assoc_ops gl.sigma t ops_spec with
- | Binop f -> combine env f (args.(0), args.(1))
- | Opp ->
+ try (Mc.PEc (parse_constant (genv, sigma) term), env)
+ with ParseError -> (
+ match EConstr.kind sigma term with
+ | App (t, args) -> (
+ match EConstr.kind sigma t with
+ | Const c -> (
+ match assoc_ops sigma t ops_spec with
+ | Binop f -> combine env f (args.(0), args.(1))
+ | Opp ->
+ let expr, env = parse_expr env args.(0) in
+ (Mc.PEopp expr, env)
+ | Power -> (
+ try
let expr, env = parse_expr env args.(0) in
- (Mc.PEopp expr, env)
- | Power -> (
- try
- let expr, env = parse_expr env args.(0) in
- let power = parse_exp expr args.(1) in
- (power, env)
- with ParseError ->
- (* if the exponent is a variable *)
- let env, n = Env.compute_rank_add env term Mc.IsBool in
- (Mc.PEX n, env) )
- | Ukn s ->
- if debug then (
- Printf.printf "unknown op: %s\n" s;
- flush stdout );
+ let power = parse_exp expr args.(1) in
+ (power, env)
+ with ParseError ->
+ (* if the exponent is a variable *)
let env, n = Env.compute_rank_add env term Mc.IsBool in
(Mc.PEX n, env) )
- | _ -> parse_variable env term )
+ | Ukn s ->
+ if debug then (
+ Printf.printf "unknown op: %s\n" s;
+ flush stdout );
+ let env, n = Env.compute_rank_add env term Mc.IsBool in
+ (Mc.PEX n, env) )
| _ -> parse_variable env term )
- in
- parse_expr env term
-
- let zop_spec =
- [ (coq_Zplus, Binop (fun x y -> Mc.PEadd (x, y)))
- ; (coq_Zminus, Binop (fun x y -> Mc.PEsub (x, y)))
- ; (coq_Zmult, Binop (fun x y -> Mc.PEmul (x, y)))
- ; (coq_Zopp, Opp)
- ; (coq_Zpower, Power) ]
-
- let qop_spec =
- [ (coq_Qplus, Binop (fun x y -> Mc.PEadd (x, y)))
- ; (coq_Qminus, Binop (fun x y -> Mc.PEsub (x, y)))
- ; (coq_Qmult, Binop (fun x y -> Mc.PEmul (x, y)))
- ; (coq_Qopp, Opp)
- ; (coq_Qpower, Power) ]
-
- let rop_spec =
- [ (coq_Rplus, Binop (fun x y -> Mc.PEadd (x, y)))
- ; (coq_Rminus, Binop (fun x y -> Mc.PEsub (x, y)))
- ; (coq_Rmult, Binop (fun x y -> Mc.PEmul (x, y)))
- ; (coq_Ropp, Opp)
- ; (coq_Rpower, Power) ]
-
- let parse_constant parse gl t = parse gl.sigma t
-
- (** [parse_more_constant parse gl t] returns the reification of term [t].
+ | _ -> parse_variable env term )
+ in
+ parse_expr env term
+
+let zop_spec =
+ [ (coq_Zplus, Binop (fun x y -> Mc.PEadd (x, y)))
+ ; (coq_Zminus, Binop (fun x y -> Mc.PEsub (x, y)))
+ ; (coq_Zmult, Binop (fun x y -> Mc.PEmul (x, y)))
+ ; (coq_Zopp, Opp)
+ ; (coq_Zpower, Power) ]
+
+let qop_spec =
+ [ (coq_Qplus, Binop (fun x y -> Mc.PEadd (x, y)))
+ ; (coq_Qminus, Binop (fun x y -> Mc.PEsub (x, y)))
+ ; (coq_Qmult, Binop (fun x y -> Mc.PEmul (x, y)))
+ ; (coq_Qopp, Opp)
+ ; (coq_Qpower, Power) ]
+
+let rop_spec =
+ [ (coq_Rplus, Binop (fun x y -> Mc.PEadd (x, y)))
+ ; (coq_Rminus, Binop (fun x y -> Mc.PEsub (x, y)))
+ ; (coq_Rmult, Binop (fun x y -> Mc.PEmul (x, y)))
+ ; (coq_Ropp, Opp)
+ ; (coq_Rpower, Power) ]
+
+let parse_constant parse ((genv : Environ.env), sigma) t = parse sigma t
+
+(** [parse_more_constant parse gl t] returns the reification of term [t].
If [t] is a ground term, then it is first reduced to normal form
before using a 'syntactic' parser *)
- let parse_more_constant parse gl t =
- try parse gl t
- with ParseError ->
- if debug then Feedback.msg_debug Pp.(str "try harder");
- if is_ground_term gl.env gl.sigma t then
- parse gl (Redexpr.cbv_vm gl.env gl.sigma t)
- else raise ParseError
-
- let zconstant = parse_constant parse_z
- let qconstant = parse_constant parse_q
- let nconstant = parse_constant parse_nat
-
- (** [parse_more_zexpr parse_constant gl] improves the parsing of exponent
+let parse_more_constant parse (genv, sigma) t =
+ try parse (genv, sigma) t
+ with ParseError ->
+ if debug then Feedback.msg_debug Pp.(str "try harder");
+ if is_ground_term genv sigma t then
+ parse (genv, sigma) (Redexpr.cbv_vm genv sigma t)
+ else raise ParseError
+
+let zconstant = parse_constant parse_z
+let qconstant = parse_constant parse_q
+let nconstant = parse_constant parse_nat
+
+(** [parse_more_zexpr parse_constant gl] improves the parsing of exponent
which can be arithmetic expressions (without variables).
[parse_constant_expr] returns a constant if the argument is an expression without variables. *)
- let rec parse_zexpr gl =
- parse_expr gl zconstant
- (fun expr (x : EConstr.t) ->
- let z = parse_zconstant gl x in
- match z with
- | Mc.Zneg _ -> Mc.PEc Mc.Z0
- | _ -> Mc.PEpow (expr, Mc.Z.to_N z))
- zop_spec
-
- and parse_zconstant gl e =
- let e, _ = parse_zexpr gl (Env.empty gl) e in
- match Mc.zeval_const e with None -> raise ParseError | Some z -> z
-
- (* NB: R is a different story.
- Because it is axiomatised, reducing would not be effective.
- Therefore, there is a specific parser for constant over R
- *)
+let rec parse_zexpr gl =
+ parse_expr gl zconstant
+ (fun expr (x : EConstr.t) ->
+ let z = parse_zconstant gl x in
+ match z with
+ | Mc.Zneg _ -> Mc.PEc Mc.Z0
+ | _ -> Mc.PEpow (expr, Mc.Z.to_N z))
+ zop_spec
+
+and parse_zconstant gl e =
+ let e, _ = parse_zexpr gl (Env.empty gl) e in
+ match Mc.zeval_const e with None -> raise ParseError | Some z -> z
+
+(* NB: R is a different story.
+ Because it is axiomatised, reducing would not be effective.
+ Therefore, there is a specific parser for constant over R
+*)
- let rconst_assoc =
- [ (coq_Rplus, fun x y -> Mc.CPlus (x, y))
- ; (coq_Rminus, fun x y -> Mc.CMinus (x, y))
- ; (coq_Rmult, fun x y -> Mc.CMult (x, y))
- (* coq_Rdiv , (fun x y -> Mc.CMult(x,Mc.CInv y)) ;*) ]
+let rconst_assoc =
+ [ (coq_Rplus, fun x y -> Mc.CPlus (x, y))
+ ; (coq_Rminus, fun x y -> Mc.CMinus (x, y))
+ ; (coq_Rmult, fun x y -> Mc.CMult (x, y))
+ (* coq_Rdiv , (fun x y -> Mc.CMult(x,Mc.CInv y)) ;*) ]
- let rconstant gl term =
- let sigma = gl.sigma in
- let rec rconstant term =
- match EConstr.kind sigma term with
- | Const x ->
- if EConstr.eq_constr sigma term (Lazy.force coq_R0) then Mc.C0
- else if EConstr.eq_constr sigma term (Lazy.force coq_R1) then Mc.C1
- else raise ParseError
- | App (op, args) -> (
- try
- (* the evaluation order is important in the following *)
- let f = assoc_const sigma op rconst_assoc in
- let a = rconstant args.(0) in
- let b = rconstant args.(1) in
- f a b
- with ParseError -> (
- match op with
- | op when EConstr.eq_constr sigma op (Lazy.force coq_Rinv) ->
- let arg = rconstant args.(0) in
- if Mc.qeq_bool (Mc.q_of_Rcst arg) {Mc.qnum = Mc.Z0; Mc.qden = Mc.XH}
- then raise ParseError
- (* This is a division by zero -- no semantics *)
- else Mc.CInv arg
- | op when EConstr.eq_constr sigma op (Lazy.force coq_Rpower) ->
- Mc.CPow
- ( rconstant args.(0)
- , Mc.Inr (parse_more_constant nconstant gl args.(1)) )
- | op when EConstr.eq_constr sigma op (Lazy.force coq_IQR) ->
- Mc.CQ (qconstant gl args.(0))
- | op when EConstr.eq_constr sigma op (Lazy.force coq_IZR) ->
- Mc.CZ (parse_more_constant zconstant gl args.(0))
- | _ -> raise ParseError ) )
- | _ -> raise ParseError
- in
- rconstant term
-
- let rconstant gl term =
- if debug then
- Feedback.msg_debug
- ( Pp.str "rconstant: "
- ++ Printer.pr_leconstr_env gl.env gl.sigma term
- ++ fnl () );
- let res = rconstant gl term in
- if debug then (
- Printf.printf "rconstant -> %a\n" pp_Rcst res;
- flush stdout );
- res
+let rconstant (genv, sigma) term =
+ let rec rconstant term =
+ match EConstr.kind sigma term with
+ | Const x ->
+ if EConstr.eq_constr sigma term (Lazy.force coq_R0) then Mc.C0
+ else if EConstr.eq_constr sigma term (Lazy.force coq_R1) then Mc.C1
+ else raise ParseError
+ | App (op, args) -> (
+ try
+ (* the evaluation order is important in the following *)
+ let f = assoc_const sigma op rconst_assoc in
+ let a = rconstant args.(0) in
+ let b = rconstant args.(1) in
+ f a b
+ with ParseError -> (
+ match op with
+ | op when EConstr.eq_constr sigma op (Lazy.force coq_Rinv) ->
+ let arg = rconstant args.(0) in
+ if Mc.qeq_bool (Mc.q_of_Rcst arg) {Mc.qnum = Mc.Z0; Mc.qden = Mc.XH}
+ then raise ParseError (* This is a division by zero -- no semantics *)
+ else Mc.CInv arg
+ | op when EConstr.eq_constr sigma op (Lazy.force coq_Rpower) ->
+ Mc.CPow
+ ( rconstant args.(0)
+ , Mc.Inr (parse_more_constant nconstant (genv, sigma) args.(1)) )
+ | op when EConstr.eq_constr sigma op (Lazy.force coq_IQR) ->
+ Mc.CQ (qconstant (genv, sigma) args.(0))
+ | op when EConstr.eq_constr sigma op (Lazy.force coq_IZR) ->
+ Mc.CZ (parse_more_constant zconstant (genv, sigma) args.(0))
+ | _ -> raise ParseError ) )
+ | _ -> raise ParseError
+ in
+ rconstant term
+
+let rconstant (genv, sigma) term =
+ if debug then
+ Feedback.msg_debug
+ (Pp.str "rconstant: " ++ Printer.pr_leconstr_env genv sigma term ++ fnl ());
+ let res = rconstant (genv, sigma) term in
+ if debug then (
+ Printf.printf "rconstant -> %a\n" pp_Rcst res;
+ flush stdout );
+ res
- let parse_qexpr gl =
- parse_expr gl qconstant
- (fun expr x ->
- let exp = zconstant gl x in
- match exp with
- | Mc.Zneg _ -> (
- match expr with
- | Mc.PEc q -> Mc.PEc (Mc.qpower q exp)
- | _ -> raise ParseError )
- | _ ->
- let exp = Mc.Z.to_N exp in
- Mc.PEpow (expr, exp))
- qop_spec
-
- let parse_rexpr gl =
- parse_expr gl rconstant
- (fun expr x ->
- let exp = Mc.N.of_nat (parse_nat gl.sigma x) in
+let parse_qexpr gl =
+ parse_expr gl qconstant
+ (fun expr x ->
+ let exp = zconstant gl x in
+ match exp with
+ | Mc.Zneg _ -> (
+ match expr with
+ | Mc.PEc q -> Mc.PEc (Mc.qpower q exp)
+ | _ -> raise ParseError )
+ | _ ->
+ let exp = Mc.Z.to_N exp in
Mc.PEpow (expr, exp))
- rop_spec
-
- let parse_arith parse_op parse_expr (k : Mc.kind) env cstr gl =
- let sigma = gl.sigma in
- if debug then
- Feedback.msg_debug
- ( Pp.str "parse_arith: "
- ++ Printer.pr_leconstr_env gl.env sigma cstr
- ++ fnl () );
- match EConstr.kind sigma cstr with
- | App (op, args) ->
- let op, lhs, rhs = parse_op gl k (op, args) in
- let e1, env = parse_expr gl env lhs in
- let e2, env = parse_expr gl env rhs in
- ({Mc.flhs = e1; Mc.fop = op; Mc.frhs = e2}, env)
- | _ -> failwith "error : parse_arith(2)"
-
- let parse_zarith = parse_arith parse_zop parse_zexpr
- let parse_qarith = parse_arith parse_qop parse_qexpr
- let parse_rarith = parse_arith parse_rop parse_rexpr
-
- (* generic parsing of arithmetic expressions *)
-
- let mkAND b f1 f2 = Mc.AND (b, f1, f2)
- let mkOR b f1 f2 = Mc.OR (b, f1, f2)
- let mkIff b f1 f2 = Mc.IFF (b, f1, f2)
- let mkIMPL b f1 f2 = Mc.IMPL (b, f1, None, f2)
- let mkEQ f1 f2 = Mc.EQ (f1, f2)
-
- let mkformula_binary b g term f1 f2 =
- match (f1, f2) with
- | Mc.X (b1, _), Mc.X (b2, _) -> Mc.X (b, term)
- | _ -> g f1 f2
+ qop_spec
+
+let parse_rexpr (genv, sigma) =
+ parse_expr (genv, sigma) rconstant
+ (fun expr x ->
+ let exp = Mc.N.of_nat (parse_nat sigma x) in
+ Mc.PEpow (expr, exp))
+ rop_spec
+
+let parse_arith parse_op parse_expr (k : Mc.kind) env cstr (genv, sigma) =
+ if debug then
+ Feedback.msg_debug
+ ( Pp.str "parse_arith: "
+ ++ Printer.pr_leconstr_env genv sigma cstr
+ ++ fnl () );
+ match EConstr.kind sigma cstr with
+ | App (op, args) ->
+ let op, lhs, rhs = parse_op (genv, sigma) k (op, args) in
+ let e1, env = parse_expr (genv, sigma) env lhs in
+ let e2, env = parse_expr (genv, sigma) env rhs in
+ ({Mc.flhs = e1; Mc.fop = op; Mc.frhs = e2}, env)
+ | _ -> failwith "error : parse_arith(2)"
+
+let parse_zarith = parse_arith parse_zop parse_zexpr
+let parse_qarith = parse_arith parse_qop parse_qexpr
+let parse_rarith = parse_arith parse_rop parse_rexpr
+
+(* generic parsing of arithmetic expressions *)
+
+let mkAND b f1 f2 = Mc.AND (b, f1, f2)
+let mkOR b f1 f2 = Mc.OR (b, f1, f2)
+let mkIff b f1 f2 = Mc.IFF (b, f1, f2)
+let mkIMPL b f1 f2 = Mc.IMPL (b, f1, None, f2)
+let mkEQ f1 f2 = Mc.EQ (f1, f2)
+
+let mkformula_binary b g term f1 f2 =
+ match (f1, f2) with
+ | Mc.X (b1, _), Mc.X (b2, _) -> Mc.X (b, term)
+ | _ -> g f1 f2
- (**
+(**
* This is the big generic function for formula parsers.
*)
- let is_prop env sigma term =
- let sort = Retyping.get_sort_of env sigma term in
- Sorts.is_prop sort
+let is_prop env sigma term =
+ let sort = Retyping.get_sort_of env sigma term in
+ Sorts.is_prop sort
- type formula_op =
- { op_and : EConstr.t
- ; op_or : EConstr.t
- ; op_iff : EConstr.t
- ; op_not : EConstr.t
- ; op_tt : EConstr.t
- ; op_ff : EConstr.t }
+type formula_op =
+ { op_and : EConstr.t
+ ; op_or : EConstr.t
+ ; op_iff : EConstr.t
+ ; op_not : EConstr.t
+ ; op_tt : EConstr.t
+ ; op_ff : EConstr.t }
- let prop_op =
- lazy
- { op_and = Lazy.force coq_and
- ; op_or = Lazy.force coq_or
- ; op_iff = Lazy.force coq_iff
- ; op_not = Lazy.force coq_not
- ; op_tt = Lazy.force coq_True
- ; op_ff = Lazy.force coq_False }
-
- let bool_op =
- lazy
- { op_and = Lazy.force coq_andb
- ; op_or = Lazy.force coq_orb
- ; op_iff = Lazy.force coq_eqb
- ; op_not = Lazy.force coq_negb
- ; op_tt = Lazy.force coq_true
- ; op_ff = Lazy.force coq_false }
-
- let parse_formula gl parse_atom env tg term =
- let sigma = gl.sigma in
- let parse_atom b env tg t =
- try
- let at, env = parse_atom b env t gl in
- (Mc.A (b, at, (tg, t)), env, Tag.next tg)
- with ParseError -> (Mc.X (b, t), env, tg)
- in
- let prop_op = Lazy.force prop_op in
- let bool_op = Lazy.force bool_op in
- let eq = Lazy.force coq_eq in
- let bool = Lazy.force coq_bool in
- let rec xparse_formula op k env tg term =
- match EConstr.kind sigma term with
- | App (l, rst) -> (
- match rst with
- | [|a; b|] when EConstr.eq_constr sigma l op.op_and ->
- let f, env, tg = xparse_formula op k env tg a in
- let g, env, tg = xparse_formula op k env tg b in
- (mkformula_binary k (mkAND k) term f g, env, tg)
- | [|a; b|] when EConstr.eq_constr sigma l op.op_or ->
- let f, env, tg = xparse_formula op k env tg a in
- let g, env, tg = xparse_formula op k env tg b in
- (mkformula_binary k (mkOR k) term f g, env, tg)
- | [|a; b|] when EConstr.eq_constr sigma l op.op_iff ->
- let f, env, tg = xparse_formula op k env tg a in
- let g, env, tg = xparse_formula op k env tg b in
- (mkformula_binary k (mkIff k) term f g, env, tg)
- | [|ty; a; b|]
- when EConstr.eq_constr sigma l eq && is_convertible gl ty bool ->
- let f, env, tg = xparse_formula bool_op Mc.IsBool env tg a in
- let g, env, tg = xparse_formula bool_op Mc.IsBool env tg b in
- (mkformula_binary Mc.IsProp mkEQ term f g, env, tg)
- | [|a|] when EConstr.eq_constr sigma l op.op_not ->
- let f, env, tg = xparse_formula op k env tg a in
- (Mc.NOT (k, f), env, tg)
- | _ -> parse_atom k env tg term )
- | Prod (typ, a, b)
- when kind_is_prop k
- && (typ.binder_name = Anonymous || EConstr.Vars.noccurn sigma 1 b)
- ->
+let prop_op =
+ lazy
+ { op_and = Lazy.force coq_and
+ ; op_or = Lazy.force coq_or
+ ; op_iff = Lazy.force coq_iff
+ ; op_not = Lazy.force coq_not
+ ; op_tt = Lazy.force coq_True
+ ; op_ff = Lazy.force coq_False }
+
+let bool_op =
+ lazy
+ { op_and = Lazy.force coq_andb
+ ; op_or = Lazy.force coq_orb
+ ; op_iff = Lazy.force coq_eqb
+ ; op_not = Lazy.force coq_negb
+ ; op_tt = Lazy.force coq_true
+ ; op_ff = Lazy.force coq_false }
+
+let parse_formula (genv, sigma) parse_atom env tg term =
+ let parse_atom b env tg t =
+ try
+ let at, env = parse_atom b env t (genv, sigma) in
+ (Mc.A (b, at, (tg, t)), env, Tag.next tg)
+ with ParseError -> (Mc.X (b, t), env, tg)
+ in
+ let prop_op = Lazy.force prop_op in
+ let bool_op = Lazy.force bool_op in
+ let eq = Lazy.force coq_eq in
+ let bool = Lazy.force coq_bool in
+ let rec xparse_formula op k env tg term =
+ match EConstr.kind sigma term with
+ | App (l, rst) -> (
+ match rst with
+ | [|a; b|] when EConstr.eq_constr sigma l op.op_and ->
let f, env, tg = xparse_formula op k env tg a in
let g, env, tg = xparse_formula op k env tg b in
- (mkformula_binary Mc.IsProp (mkIMPL Mc.IsProp) term f g, env, tg)
- | _ ->
- if EConstr.eq_constr sigma term op.op_tt then (Mc.TT k, env, tg)
- else if EConstr.eq_constr sigma term op.op_ff then Mc.(FF k, env, tg)
- else (Mc.X (k, term), env, tg)
- in
- xparse_formula prop_op Mc.IsProp env tg (*Reductionops.whd_zeta*) term
+ (mkformula_binary k (mkAND k) term f g, env, tg)
+ | [|a; b|] when EConstr.eq_constr sigma l op.op_or ->
+ let f, env, tg = xparse_formula op k env tg a in
+ let g, env, tg = xparse_formula op k env tg b in
+ (mkformula_binary k (mkOR k) term f g, env, tg)
+ | [|a; b|] when EConstr.eq_constr sigma l op.op_iff ->
+ let f, env, tg = xparse_formula op k env tg a in
+ let g, env, tg = xparse_formula op k env tg b in
+ (mkformula_binary k (mkIff k) term f g, env, tg)
+ | [|ty; a; b|]
+ when EConstr.eq_constr sigma l eq && is_convertible genv sigma ty bool
+ ->
+ let f, env, tg = xparse_formula bool_op Mc.IsBool env tg a in
+ let g, env, tg = xparse_formula bool_op Mc.IsBool env tg b in
+ (mkformula_binary Mc.IsProp mkEQ term f g, env, tg)
+ | [|a|] when EConstr.eq_constr sigma l op.op_not ->
+ let f, env, tg = xparse_formula op k env tg a in
+ (Mc.NOT (k, f), env, tg)
+ | _ -> parse_atom k env tg term )
+ | Prod (typ, a, b)
+ when kind_is_prop k
+ && (typ.binder_name = Anonymous || EConstr.Vars.noccurn sigma 1 b) ->
+ let f, env, tg = xparse_formula op k env tg a in
+ let g, env, tg = xparse_formula op k env tg b in
+ (mkformula_binary Mc.IsProp (mkIMPL Mc.IsProp) term f g, env, tg)
+ | _ ->
+ if EConstr.eq_constr sigma term op.op_tt then (Mc.TT k, env, tg)
+ else if EConstr.eq_constr sigma term op.op_ff then Mc.(FF k, env, tg)
+ else (Mc.X (k, term), env, tg)
+ in
+ xparse_formula prop_op Mc.IsProp env tg (*Reductionops.whd_zeta*) term
- (* let dump_bool b = Lazy.force (if b then coq_true else coq_false)*)
+(* let dump_bool b = Lazy.force (if b then coq_true else coq_false)*)
- let dump_kind k =
- Lazy.force (match k with Mc.IsProp -> coq_IsProp | Mc.IsBool -> coq_IsBool)
+let dump_kind k =
+ Lazy.force (match k with Mc.IsProp -> coq_IsProp | Mc.IsBool -> coq_IsBool)
- let dump_formula typ dump_atom f =
- let app_ctor c args =
- EConstr.mkApp
- ( Lazy.force c
- , Array.of_list
- ( typ :: Lazy.force coq_eKind :: Lazy.force coq_unit
- :: Lazy.force coq_unit :: args ) )
- in
- let rec xdump f =
- match f with
- | Mc.TT k -> app_ctor coq_TT [dump_kind k]
- | Mc.FF k -> app_ctor coq_FF [dump_kind k]
- | Mc.AND (k, x, y) -> app_ctor coq_AND [dump_kind k; xdump x; xdump y]
- | Mc.OR (k, x, y) -> app_ctor coq_OR [dump_kind k; xdump x; xdump y]
- | Mc.IMPL (k, x, _, y) ->
- app_ctor coq_IMPL
- [ dump_kind k
- ; xdump x
- ; EConstr.mkApp (Lazy.force coq_None, [|Lazy.force coq_unit|])
- ; xdump y ]
- | Mc.NOT (k, x) -> app_ctor coq_NOT [dump_kind k; xdump x]
- | Mc.IFF (k, x, y) -> app_ctor coq_IFF [dump_kind k; xdump x; xdump y]
- | Mc.EQ (x, y) -> app_ctor coq_EQ [xdump x; xdump y]
- | Mc.A (k, x, _) ->
- app_ctor coq_Atom [dump_kind k; dump_atom x; Lazy.force coq_tt]
- | Mc.X (k, t) -> app_ctor coq_X [dump_kind k; t]
- in
- xdump f
-
- let prop_env_of_formula gl form =
- Mc.(
- let rec doit env = function
- | TT _ | FF _ | A (_, _, _) -> env
- | X (b, t) -> fst (Env.compute_rank_add env t b)
- | AND (b, f1, f2)
- |OR (b, f1, f2)
- |IMPL (b, f1, _, f2)
- |IFF (b, f1, f2) ->
- doit (doit env f1) f2
- | NOT (b, f) -> doit env f
- | EQ (f1, f2) -> doit (doit env f1) f2
- in
- doit (Env.empty gl) form)
-
- let var_env_of_formula form =
- let rec vars_of_expr = function
- | Mc.PEX n -> ISet.singleton (CoqToCaml.positive n)
- | Mc.PEc z -> ISet.empty
- | Mc.PEadd (e1, e2) | Mc.PEmul (e1, e2) | Mc.PEsub (e1, e2) ->
- ISet.union (vars_of_expr e1) (vars_of_expr e2)
- | Mc.PEopp e | Mc.PEpow (e, _) -> vars_of_expr e
- in
- let vars_of_atom {Mc.flhs; Mc.fop; Mc.frhs} =
- ISet.union (vars_of_expr flhs) (vars_of_expr frhs)
+let dump_formula typ dump_atom f =
+ let app_ctor c args =
+ EConstr.mkApp
+ ( Lazy.force c
+ , Array.of_list
+ ( typ :: Lazy.force coq_eKind :: Lazy.force coq_unit
+ :: Lazy.force coq_unit :: args ) )
+ in
+ let rec xdump f =
+ match f with
+ | Mc.TT k -> app_ctor coq_TT [dump_kind k]
+ | Mc.FF k -> app_ctor coq_FF [dump_kind k]
+ | Mc.AND (k, x, y) -> app_ctor coq_AND [dump_kind k; xdump x; xdump y]
+ | Mc.OR (k, x, y) -> app_ctor coq_OR [dump_kind k; xdump x; xdump y]
+ | Mc.IMPL (k, x, _, y) ->
+ app_ctor coq_IMPL
+ [ dump_kind k
+ ; xdump x
+ ; EConstr.mkApp (Lazy.force coq_None, [|Lazy.force coq_unit|])
+ ; xdump y ]
+ | Mc.NOT (k, x) -> app_ctor coq_NOT [dump_kind k; xdump x]
+ | Mc.IFF (k, x, y) -> app_ctor coq_IFF [dump_kind k; xdump x; xdump y]
+ | Mc.EQ (x, y) -> app_ctor coq_EQ [xdump x; xdump y]
+ | Mc.A (k, x, _) ->
+ app_ctor coq_Atom [dump_kind k; dump_atom x; Lazy.force coq_tt]
+ | Mc.X (k, t) -> app_ctor coq_X [dump_kind k; t]
+ in
+ xdump f
+
+let prop_env_of_formula gl form =
+ Mc.(
+ let rec doit env = function
+ | TT _ | FF _ | A (_, _, _) -> env
+ | X (b, t) -> fst (Env.compute_rank_add env t b)
+ | AND (b, f1, f2) | OR (b, f1, f2) | IMPL (b, f1, _, f2) | IFF (b, f1, f2)
+ ->
+ doit (doit env f1) f2
+ | NOT (b, f) -> doit env f
+ | EQ (f1, f2) -> doit (doit env f1) f2
in
- Mc.(
- let rec doit = function
- | TT _ | FF _ | X _ -> ISet.empty
- | A (_, a, (t, c)) -> vars_of_atom a
- | AND (_, f1, f2)
- |OR (_, f1, f2)
- |IMPL (_, f1, _, f2)
- |IFF (_, f1, f2)
- |EQ (f1, f2) ->
- ISet.union (doit f1) (doit f2)
- | NOT (_, f) -> doit f
- in
- doit form)
-
- type 'cst dump_expr =
- { (* 'cst is the type of the syntactic constants *)
- interp_typ : EConstr.constr
- ; dump_cst : 'cst -> EConstr.constr
- ; dump_add : EConstr.constr
- ; dump_sub : EConstr.constr
- ; dump_opp : EConstr.constr
- ; dump_mul : EConstr.constr
- ; dump_pow : EConstr.constr
- ; dump_pow_arg : Mc.n -> EConstr.constr
- ; dump_op_prop : (Mc.op2 * EConstr.constr) list
- ; dump_op_bool : (Mc.op2 * EConstr.constr) list }
-
- let dump_zexpr =
- lazy
- { interp_typ = Lazy.force coq_Z
- ; dump_cst = dump_z
- ; dump_add = Lazy.force coq_Zplus
- ; dump_sub = Lazy.force coq_Zminus
- ; dump_opp = Lazy.force coq_Zopp
- ; dump_mul = Lazy.force coq_Zmult
- ; dump_pow = Lazy.force coq_Zpower
- ; dump_pow_arg = (fun n -> dump_z (CamlToCoq.z (CoqToCaml.n n)))
- ; dump_op_prop = List.map (fun (x, y) -> (y, Lazy.force x)) zop_table_prop
- ; dump_op_bool = List.map (fun (x, y) -> (y, Lazy.force x)) zop_table_bool
- }
-
- let dump_qexpr =
- lazy
- { interp_typ = Lazy.force coq_Q
- ; dump_cst = dump_q
- ; dump_add = Lazy.force coq_Qplus
- ; dump_sub = Lazy.force coq_Qminus
- ; dump_opp = Lazy.force coq_Qopp
- ; dump_mul = Lazy.force coq_Qmult
- ; dump_pow = Lazy.force coq_Qpower
- ; dump_pow_arg = (fun n -> dump_z (CamlToCoq.z (CoqToCaml.n n)))
- ; dump_op_prop = List.map (fun (x, y) -> (y, Lazy.force x)) qop_table_prop
- ; dump_op_bool = List.map (fun (x, y) -> (y, Lazy.force x)) qop_table_bool
- }
-
- let rec dump_Rcst_as_R cst =
- match cst with
- | Mc.C0 -> Lazy.force coq_R0
- | Mc.C1 -> Lazy.force coq_R1
- | Mc.CQ q -> EConstr.mkApp (Lazy.force coq_IQR, [|dump_q q|])
- | Mc.CZ z -> EConstr.mkApp (Lazy.force coq_IZR, [|dump_z z|])
- | Mc.CPlus (x, y) ->
- EConstr.mkApp
- (Lazy.force coq_Rplus, [|dump_Rcst_as_R x; dump_Rcst_as_R y|])
- | Mc.CMinus (x, y) ->
- EConstr.mkApp
- (Lazy.force coq_Rminus, [|dump_Rcst_as_R x; dump_Rcst_as_R y|])
- | Mc.CMult (x, y) ->
- EConstr.mkApp
- (Lazy.force coq_Rmult, [|dump_Rcst_as_R x; dump_Rcst_as_R y|])
- | Mc.CPow (x, y) -> (
- match y with
- | Mc.Inl z ->
- EConstr.mkApp (Lazy.force coq_powerZR, [|dump_Rcst_as_R x; dump_z z|])
- | Mc.Inr n ->
- EConstr.mkApp (Lazy.force coq_Rpower, [|dump_Rcst_as_R x; dump_nat n|])
- )
- | Mc.CInv t -> EConstr.mkApp (Lazy.force coq_Rinv, [|dump_Rcst_as_R t|])
- | Mc.COpp t -> EConstr.mkApp (Lazy.force coq_Ropp, [|dump_Rcst_as_R t|])
-
- let dump_rexpr =
- lazy
- { interp_typ = Lazy.force coq_R
- ; dump_cst = dump_Rcst_as_R
- ; dump_add = Lazy.force coq_Rplus
- ; dump_sub = Lazy.force coq_Rminus
- ; dump_opp = Lazy.force coq_Ropp
- ; dump_mul = Lazy.force coq_Rmult
- ; dump_pow = Lazy.force coq_Rpower
- ; dump_pow_arg = (fun n -> dump_nat (CamlToCoq.nat (CoqToCaml.n n)))
- ; dump_op_prop = List.map (fun (x, y) -> (y, Lazy.force x)) rop_table_prop
- ; dump_op_bool = List.map (fun (x, y) -> (y, Lazy.force x)) rop_table_bool
- }
-
- let prodn n env b =
- let rec prodrec = function
- | 0, env, b -> b
- | n, (v, t) :: l, b ->
- prodrec (n - 1, l, EConstr.mkProd (make_annot v Sorts.Relevant, t, b))
- | _ -> assert false
+ doit (Env.empty gl) form)
+
+let var_env_of_formula form =
+ let rec vars_of_expr = function
+ | Mc.PEX n -> ISet.singleton (CoqToCaml.positive n)
+ | Mc.PEc z -> ISet.empty
+ | Mc.PEadd (e1, e2) | Mc.PEmul (e1, e2) | Mc.PEsub (e1, e2) ->
+ ISet.union (vars_of_expr e1) (vars_of_expr e2)
+ | Mc.PEopp e | Mc.PEpow (e, _) -> vars_of_expr e
+ in
+ let vars_of_atom {Mc.flhs; Mc.fop; Mc.frhs} =
+ ISet.union (vars_of_expr flhs) (vars_of_expr frhs)
+ in
+ Mc.(
+ let rec doit = function
+ | TT _ | FF _ | X _ -> ISet.empty
+ | A (_, a, (t, c)) -> vars_of_atom a
+ | AND (_, f1, f2)
+ |OR (_, f1, f2)
+ |IMPL (_, f1, _, f2)
+ |IFF (_, f1, f2)
+ |EQ (f1, f2) ->
+ ISet.union (doit f1) (doit f2)
+ | NOT (_, f) -> doit f
in
- prodrec (n, env, b)
+ doit form)
+
+type 'cst dump_expr =
+ { (* 'cst is the type of the syntactic constants *)
+ interp_typ : EConstr.constr
+ ; dump_cst : 'cst -> EConstr.constr
+ ; dump_add : EConstr.constr
+ ; dump_sub : EConstr.constr
+ ; dump_opp : EConstr.constr
+ ; dump_mul : EConstr.constr
+ ; dump_pow : EConstr.constr
+ ; dump_pow_arg : Mc.n -> EConstr.constr
+ ; dump_op_prop : (Mc.op2 * EConstr.constr) list
+ ; dump_op_bool : (Mc.op2 * EConstr.constr) list }
+
+let dump_zexpr =
+ lazy
+ { interp_typ = Lazy.force coq_Z
+ ; dump_cst = dump_z
+ ; dump_add = Lazy.force coq_Zplus
+ ; dump_sub = Lazy.force coq_Zminus
+ ; dump_opp = Lazy.force coq_Zopp
+ ; dump_mul = Lazy.force coq_Zmult
+ ; dump_pow = Lazy.force coq_Zpower
+ ; dump_pow_arg = (fun n -> dump_z (CamlToCoq.z (CoqToCaml.n n)))
+ ; dump_op_prop = List.map (fun (x, y) -> (y, Lazy.force x)) zop_table_prop
+ ; dump_op_bool = List.map (fun (x, y) -> (y, Lazy.force x)) zop_table_bool
+ }
+
+let dump_qexpr =
+ lazy
+ { interp_typ = Lazy.force coq_Q
+ ; dump_cst = dump_q
+ ; dump_add = Lazy.force coq_Qplus
+ ; dump_sub = Lazy.force coq_Qminus
+ ; dump_opp = Lazy.force coq_Qopp
+ ; dump_mul = Lazy.force coq_Qmult
+ ; dump_pow = Lazy.force coq_Qpower
+ ; dump_pow_arg = (fun n -> dump_z (CamlToCoq.z (CoqToCaml.n n)))
+ ; dump_op_prop = List.map (fun (x, y) -> (y, Lazy.force x)) qop_table_prop
+ ; dump_op_bool = List.map (fun (x, y) -> (y, Lazy.force x)) qop_table_bool
+ }
+
+let rec dump_Rcst_as_R cst =
+ match cst with
+ | Mc.C0 -> Lazy.force coq_R0
+ | Mc.C1 -> Lazy.force coq_R1
+ | Mc.CQ q -> EConstr.mkApp (Lazy.force coq_IQR, [|dump_q q|])
+ | Mc.CZ z -> EConstr.mkApp (Lazy.force coq_IZR, [|dump_z z|])
+ | Mc.CPlus (x, y) ->
+ EConstr.mkApp (Lazy.force coq_Rplus, [|dump_Rcst_as_R x; dump_Rcst_as_R y|])
+ | Mc.CMinus (x, y) ->
+ EConstr.mkApp (Lazy.force coq_Rminus, [|dump_Rcst_as_R x; dump_Rcst_as_R y|])
+ | Mc.CMult (x, y) ->
+ EConstr.mkApp (Lazy.force coq_Rmult, [|dump_Rcst_as_R x; dump_Rcst_as_R y|])
+ | Mc.CPow (x, y) -> (
+ match y with
+ | Mc.Inl z ->
+ EConstr.mkApp (Lazy.force coq_powerZR, [|dump_Rcst_as_R x; dump_z z|])
+ | Mc.Inr n ->
+ EConstr.mkApp (Lazy.force coq_Rpower, [|dump_Rcst_as_R x; dump_nat n|]) )
+ | Mc.CInv t -> EConstr.mkApp (Lazy.force coq_Rinv, [|dump_Rcst_as_R t|])
+ | Mc.COpp t -> EConstr.mkApp (Lazy.force coq_Ropp, [|dump_Rcst_as_R t|])
+
+let dump_rexpr =
+ lazy
+ { interp_typ = Lazy.force coq_R
+ ; dump_cst = dump_Rcst_as_R
+ ; dump_add = Lazy.force coq_Rplus
+ ; dump_sub = Lazy.force coq_Rminus
+ ; dump_opp = Lazy.force coq_Ropp
+ ; dump_mul = Lazy.force coq_Rmult
+ ; dump_pow = Lazy.force coq_Rpower
+ ; dump_pow_arg = (fun n -> dump_nat (CamlToCoq.nat (CoqToCaml.n n)))
+ ; dump_op_prop = List.map (fun (x, y) -> (y, Lazy.force x)) rop_table_prop
+ ; dump_op_bool = List.map (fun (x, y) -> (y, Lazy.force x)) rop_table_bool
+ }
+
+let prodn n env b =
+ let rec prodrec = function
+ | 0, env, b -> b
+ | n, (v, t) :: l, b ->
+ prodrec (n - 1, l, EConstr.mkProd (make_annot v Sorts.Relevant, t, b))
+ | _ -> assert false
+ in
+ prodrec (n, env, b)
- (** [make_goal_of_formula depxr vars props form] where
+(** [make_goal_of_formula depxr vars props form] where
- vars is an environment for the arithmetic variables occurring in form
- props is an environment for the propositions occurring in form
@return a goal where all the variables and propositions of the formula are quantified
*)
- let eKind = function
- | Mc.IsProp -> EConstr.mkProp
- | Mc.IsBool -> Lazy.force coq_bool
+let eKind = function
+ | Mc.IsProp -> EConstr.mkProp
+ | Mc.IsBool -> Lazy.force coq_bool
- let make_goal_of_formula gl dexpr form =
- let vars_idx =
- List.mapi
- (fun i v -> (v, i + 1))
- (ISet.elements (var_env_of_formula form))
- in
- (* List.iter (fun (v,i) -> Printf.fprintf stdout "var %i has index %i\n" v i) vars_idx ;*)
- let props = prop_env_of_formula gl form in
- let fresh_var str i = Names.Id.of_string (str ^ string_of_int i) in
- let fresh_prop str i = Names.Id.of_string (str ^ string_of_int i) in
- let vars_n =
- List.map (fun (_, i) -> (fresh_var "__x" i, dexpr.interp_typ)) vars_idx
- in
- let props_n =
- List.mapi
- (fun i (_, k) -> (fresh_prop "__p" (i + 1), eKind k))
- (Env.elements props)
- in
- let var_name_pos =
- List.map2 (fun (idx, _) (id, _) -> (id, idx)) vars_idx vars_n
- in
- let dump_expr i e =
- let rec dump_expr = function
- | Mc.PEX n ->
- EConstr.mkRel (i + List.assoc (CoqToCaml.positive n) vars_idx)
- | Mc.PEc z -> dexpr.dump_cst z
- | Mc.PEadd (e1, e2) ->
- EConstr.mkApp (dexpr.dump_add, [|dump_expr e1; dump_expr e2|])
- | Mc.PEsub (e1, e2) ->
- EConstr.mkApp (dexpr.dump_sub, [|dump_expr e1; dump_expr e2|])
- | Mc.PEopp e -> EConstr.mkApp (dexpr.dump_opp, [|dump_expr e|])
- | Mc.PEmul (e1, e2) ->
- EConstr.mkApp (dexpr.dump_mul, [|dump_expr e1; dump_expr e2|])
- | Mc.PEpow (e, n) ->
- EConstr.mkApp (dexpr.dump_pow, [|dump_expr e; dexpr.dump_pow_arg n|])
- in
- dump_expr e
- in
- let mkop_prop op e1 e2 =
- try EConstr.mkApp (List.assoc op dexpr.dump_op_prop, [|e1; e2|])
- with Not_found ->
- EConstr.mkApp (Lazy.force coq_eq, [|dexpr.interp_typ; e1; e2|])
- in
- let dump_cstr_prop i {Mc.flhs; Mc.fop; Mc.frhs} =
- mkop_prop fop (dump_expr i flhs) (dump_expr i frhs)
- in
- let mkop_bool op e1 e2 =
- try EConstr.mkApp (List.assoc op dexpr.dump_op_bool, [|e1; e2|])
- with Not_found ->
- EConstr.mkApp (Lazy.force coq_eq, [|dexpr.interp_typ; e1; e2|])
- in
- let dump_cstr_bool i {Mc.flhs; Mc.fop; Mc.frhs} =
- mkop_bool fop (dump_expr i flhs) (dump_expr i frhs)
- in
- let rec xdump_prop pi xi f =
- match f with
- | Mc.TT _ -> Lazy.force coq_True
- | Mc.FF _ -> Lazy.force coq_False
- | Mc.AND (_, x, y) ->
- EConstr.mkApp
- (Lazy.force coq_and, [|xdump_prop pi xi x; xdump_prop pi xi y|])
- | Mc.OR (_, x, y) ->
- EConstr.mkApp
- (Lazy.force coq_or, [|xdump_prop pi xi x; xdump_prop pi xi y|])
- | Mc.IFF (_, x, y) ->
- EConstr.mkApp
- (Lazy.force coq_iff, [|xdump_prop pi xi x; xdump_prop pi xi y|])
- | Mc.IMPL (_, x, _, y) ->
- EConstr.mkArrow (xdump_prop pi xi x) Sorts.Relevant
- (xdump_prop (pi + 1) (xi + 1) y)
- | Mc.NOT (_, x) ->
- EConstr.mkArrow (xdump_prop pi xi x) Sorts.Relevant
- (Lazy.force coq_False)
- | Mc.EQ (x, y) ->
- EConstr.mkApp
- ( Lazy.force coq_eq
- , [|Lazy.force coq_bool; xdump_bool pi xi x; xdump_bool pi xi y|] )
- | Mc.A (_, x, _) -> dump_cstr_prop xi x
- | Mc.X (_, t) ->
- let idx = Env.get_rank props t in
- EConstr.mkRel (pi + idx)
- and xdump_bool pi xi f =
- match f with
- | Mc.TT _ -> Lazy.force coq_true
- | Mc.FF _ -> Lazy.force coq_false
- | Mc.AND (_, x, y) ->
- EConstr.mkApp
- (Lazy.force coq_andb, [|xdump_bool pi xi x; xdump_bool pi xi y|])
- | Mc.OR (_, x, y) ->
- EConstr.mkApp
- (Lazy.force coq_orb, [|xdump_bool pi xi x; xdump_bool pi xi y|])
- | Mc.IFF (_, x, y) ->
- EConstr.mkApp
- (Lazy.force coq_eqb, [|xdump_bool pi xi x; xdump_bool pi xi y|])
- | Mc.IMPL (_, x, _, y) ->
- EConstr.mkApp
- (Lazy.force coq_implb, [|xdump_bool pi xi x; xdump_bool pi xi y|])
- | Mc.NOT (_, x) ->
- EConstr.mkApp (Lazy.force coq_negb, [|xdump_bool pi xi x|])
- | Mc.EQ (x, y) -> assert false
- | Mc.A (_, x, _) -> dump_cstr_bool xi x
- | Mc.X (_, t) ->
- let idx = Env.get_rank props t in
- EConstr.mkRel (pi + idx)
- in
- let nb_vars = List.length vars_n in
- let nb_props = List.length props_n in
- (* Printf.fprintf stdout "NBProps : %i\n" nb_props ;*)
- let subst_prop p =
- let idx = Env.get_rank props p in
- EConstr.mkVar (Names.Id.of_string (Printf.sprintf "__p%i" idx))
+let make_goal_of_formula gl dexpr form =
+ let vars_idx =
+ List.mapi (fun i v -> (v, i + 1)) (ISet.elements (var_env_of_formula form))
+ in
+ (* List.iter (fun (v,i) -> Printf.fprintf stdout "var %i has index %i\n" v i) vars_idx ;*)
+ let props = prop_env_of_formula gl form in
+ let fresh_var str i = Names.Id.of_string (str ^ string_of_int i) in
+ let fresh_prop str i = Names.Id.of_string (str ^ string_of_int i) in
+ let vars_n =
+ List.map (fun (_, i) -> (fresh_var "__x" i, dexpr.interp_typ)) vars_idx
+ in
+ let props_n =
+ List.mapi
+ (fun i (_, k) -> (fresh_prop "__p" (i + 1), eKind k))
+ (Env.elements props)
+ in
+ let var_name_pos =
+ List.map2 (fun (idx, _) (id, _) -> (id, idx)) vars_idx vars_n
+ in
+ let dump_expr i e =
+ let rec dump_expr = function
+ | Mc.PEX n ->
+ EConstr.mkRel (i + List.assoc (CoqToCaml.positive n) vars_idx)
+ | Mc.PEc z -> dexpr.dump_cst z
+ | Mc.PEadd (e1, e2) ->
+ EConstr.mkApp (dexpr.dump_add, [|dump_expr e1; dump_expr e2|])
+ | Mc.PEsub (e1, e2) ->
+ EConstr.mkApp (dexpr.dump_sub, [|dump_expr e1; dump_expr e2|])
+ | Mc.PEopp e -> EConstr.mkApp (dexpr.dump_opp, [|dump_expr e|])
+ | Mc.PEmul (e1, e2) ->
+ EConstr.mkApp (dexpr.dump_mul, [|dump_expr e1; dump_expr e2|])
+ | Mc.PEpow (e, n) ->
+ EConstr.mkApp (dexpr.dump_pow, [|dump_expr e; dexpr.dump_pow_arg n|])
in
- let form' = Mc.mapX (fun _ p -> subst_prop p) Mc.IsProp form in
- ( prodn nb_props
- (List.map (fun (x, y) -> (Name.Name x, y)) props_n)
- (prodn nb_vars
- (List.map (fun (x, y) -> (Name.Name x, y)) vars_n)
- (xdump_prop (List.length vars_n) 0 form))
- , List.rev props_n
- , List.rev var_name_pos
- , form' )
-
- (**
+ dump_expr e
+ in
+ let mkop_prop op e1 e2 =
+ try EConstr.mkApp (List.assoc op dexpr.dump_op_prop, [|e1; e2|])
+ with Not_found ->
+ EConstr.mkApp (Lazy.force coq_eq, [|dexpr.interp_typ; e1; e2|])
+ in
+ let dump_cstr_prop i {Mc.flhs; Mc.fop; Mc.frhs} =
+ mkop_prop fop (dump_expr i flhs) (dump_expr i frhs)
+ in
+ let mkop_bool op e1 e2 =
+ try EConstr.mkApp (List.assoc op dexpr.dump_op_bool, [|e1; e2|])
+ with Not_found ->
+ EConstr.mkApp (Lazy.force coq_eq, [|dexpr.interp_typ; e1; e2|])
+ in
+ let dump_cstr_bool i {Mc.flhs; Mc.fop; Mc.frhs} =
+ mkop_bool fop (dump_expr i flhs) (dump_expr i frhs)
+ in
+ let rec xdump_prop pi xi f =
+ match f with
+ | Mc.TT _ -> Lazy.force coq_True
+ | Mc.FF _ -> Lazy.force coq_False
+ | Mc.AND (_, x, y) ->
+ EConstr.mkApp
+ (Lazy.force coq_and, [|xdump_prop pi xi x; xdump_prop pi xi y|])
+ | Mc.OR (_, x, y) ->
+ EConstr.mkApp
+ (Lazy.force coq_or, [|xdump_prop pi xi x; xdump_prop pi xi y|])
+ | Mc.IFF (_, x, y) ->
+ EConstr.mkApp
+ (Lazy.force coq_iff, [|xdump_prop pi xi x; xdump_prop pi xi y|])
+ | Mc.IMPL (_, x, _, y) ->
+ EConstr.mkArrow (xdump_prop pi xi x) Sorts.Relevant
+ (xdump_prop (pi + 1) (xi + 1) y)
+ | Mc.NOT (_, x) ->
+ EConstr.mkArrow (xdump_prop pi xi x) Sorts.Relevant (Lazy.force coq_False)
+ | Mc.EQ (x, y) ->
+ EConstr.mkApp
+ ( Lazy.force coq_eq
+ , [|Lazy.force coq_bool; xdump_bool pi xi x; xdump_bool pi xi y|] )
+ | Mc.A (_, x, _) -> dump_cstr_prop xi x
+ | Mc.X (_, t) ->
+ let idx = Env.get_rank props t in
+ EConstr.mkRel (pi + idx)
+ and xdump_bool pi xi f =
+ match f with
+ | Mc.TT _ -> Lazy.force coq_true
+ | Mc.FF _ -> Lazy.force coq_false
+ | Mc.AND (_, x, y) ->
+ EConstr.mkApp
+ (Lazy.force coq_andb, [|xdump_bool pi xi x; xdump_bool pi xi y|])
+ | Mc.OR (_, x, y) ->
+ EConstr.mkApp
+ (Lazy.force coq_orb, [|xdump_bool pi xi x; xdump_bool pi xi y|])
+ | Mc.IFF (_, x, y) ->
+ EConstr.mkApp
+ (Lazy.force coq_eqb, [|xdump_bool pi xi x; xdump_bool pi xi y|])
+ | Mc.IMPL (_, x, _, y) ->
+ EConstr.mkApp
+ (Lazy.force coq_implb, [|xdump_bool pi xi x; xdump_bool pi xi y|])
+ | Mc.NOT (_, x) ->
+ EConstr.mkApp (Lazy.force coq_negb, [|xdump_bool pi xi x|])
+ | Mc.EQ (x, y) -> assert false
+ | Mc.A (_, x, _) -> dump_cstr_bool xi x
+ | Mc.X (_, t) ->
+ let idx = Env.get_rank props t in
+ EConstr.mkRel (pi + idx)
+ in
+ let nb_vars = List.length vars_n in
+ let nb_props = List.length props_n in
+ (* Printf.fprintf stdout "NBProps : %i\n" nb_props ;*)
+ let subst_prop p =
+ let idx = Env.get_rank props p in
+ EConstr.mkVar (Names.Id.of_string (Printf.sprintf "__p%i" idx))
+ in
+ let form' = Mc.mapX (fun _ p -> subst_prop p) Mc.IsProp form in
+ ( prodn nb_props
+ (List.map (fun (x, y) -> (Name.Name x, y)) props_n)
+ (prodn nb_vars
+ (List.map (fun (x, y) -> (Name.Name x, y)) vars_n)
+ (xdump_prop (List.length vars_n) 0 form))
+ , List.rev props_n
+ , List.rev var_name_pos
+ , form' )
+
+(**
* Given a conclusion and a list of affectations, rebuild a term prefixed by
* the appropriate letins.
* TODO: reverse the list of bindings!
*)
- let set l concl =
- let rec xset acc = function
- | [] -> acc
- | e :: l ->
- let name, expr, typ = e in
- xset
- (EConstr.mkNamedLetIn
- (make_annot (Names.Id.of_string name) Sorts.Relevant)
- expr typ acc)
- l
- in
- xset concl l
-end
-
-open M
+let set l concl =
+ let rec xset acc = function
+ | [] -> acc
+ | e :: l ->
+ let name, expr, typ = e in
+ xset
+ (EConstr.mkNamedLetIn
+ (make_annot (Names.Id.of_string name) Sorts.Relevant)
+ expr typ acc)
+ l
+ in
+ xset concl l
let coq_Branch = lazy (constr_of_ref "micromega.VarMap.Branch")
let coq_Elt = lazy (constr_of_ref "micromega.VarMap.Elt")
@@ -1424,14 +1389,14 @@ let rec pp_proof_term o = function
| Micromega.ExProof (p, prf) ->
Printf.fprintf o "Ex[%a,%a]" pp_positive p pp_proof_term prf
-let rec parse_hyps gl parse_arith env tg hyps =
+let rec parse_hyps (genv, sigma) parse_arith env tg hyps =
match hyps with
| [] -> ([], env, tg)
| (i, t) :: l ->
- let lhyps, env, tg = parse_hyps gl parse_arith env tg l in
- if is_prop gl.env gl.sigma t then
+ let lhyps, env, tg = parse_hyps (genv, sigma) parse_arith env tg l in
+ if is_prop genv sigma t then
try
- let c, env, tg = parse_formula gl parse_arith env tg t in
+ let c, env, tg = parse_formula (genv, sigma) parse_arith env tg t in
((i, c) :: lhyps, env, tg)
with ParseError -> (lhyps, env, tg)
else (lhyps, env, tg)
@@ -1852,19 +1817,22 @@ let clear_all_no_check =
let micromega_gen parse_arith pre_process cnf spec dumpexpr prover tac =
Proofview.Goal.enter (fun gl ->
let sigma = Tacmach.New.project gl in
+ let genv = Tacmach.New.pf_env gl in
let concl = Tacmach.New.pf_concl gl in
let hyps = Tacmach.New.pf_hyps_types gl in
try
- let gl0 = {env = Tacmach.New.pf_env gl; sigma} in
let hyps, concl, env =
- parse_goal gl0 parse_arith (Env.empty gl0) hyps concl
+ parse_goal (genv, sigma) parse_arith
+ (Env.empty (genv, sigma))
+ hyps concl
in
let env = Env.elements env in
let spec = Lazy.force spec in
let dumpexpr = Lazy.force dumpexpr in
- if debug then Feedback.msg_debug (Pp.str "Env " ++ Env.pp gl0 env);
+ if debug then
+ Feedback.msg_debug (Pp.str "Env " ++ Env.pp (genv, sigma) env);
match
- micromega_tauto pre_process cnf spec prover env hyps concl gl0
+ micromega_tauto pre_process cnf spec prover env hyps concl (env, sigma)
with
| Unknown ->
flush stdout;
@@ -1873,7 +1841,7 @@ let micromega_gen parse_arith pre_process cnf spec dumpexpr prover tac =
Tacticals.New.tclFAIL 0 (Pp.str " Cannot find witness")
| Prf (ids, ff', res') ->
let arith_goal, props, vars, ff_arith =
- make_goal_of_formula gl0 dumpexpr ff'
+ make_goal_of_formula (genv, sigma) dumpexpr ff'
in
let intro (id, _) = Tactics.introduction id in
let intro_vars = Tacticals.New.tclTHENLIST (List.map intro vars) in
@@ -1893,7 +1861,9 @@ let micromega_gen parse_arith pre_process cnf spec dumpexpr prover tac =
env' ff_arith ]
in
let goal_props =
- List.rev (List.map fst (Env.elements (prop_env_of_formula gl0 ff')))
+ List.rev
+ (List.map fst
+ (Env.elements (prop_env_of_formula (genv, sigma) ff')))
in
let goal_vars =
List.map (fun (_, i) -> fst (List.nth env (i - 1))) vars
@@ -1971,12 +1941,14 @@ let micromega_genr prover tac =
in
Proofview.Goal.enter (fun gl ->
let sigma = Tacmach.New.project gl in
+ let genv = Tacmach.New.pf_env gl in
let concl = Tacmach.New.pf_concl gl in
let hyps = Tacmach.New.pf_hyps_types gl in
try
- let gl0 = {env = Tacmach.New.pf_env gl; sigma} in
let hyps, concl, env =
- parse_goal gl0 parse_arith (Env.empty gl0) hyps concl
+ parse_goal (genv, sigma) parse_arith
+ (Env.empty (genv, sigma))
+ hyps concl
in
let env = Env.elements env in
let spec = Lazy.force spec in
@@ -1997,7 +1969,7 @@ let micromega_genr prover tac =
match
micromega_tauto
(fun _ x -> x)
- Mc.cnfQ spec prover env hyps' concl' gl0
+ Mc.cnfQ spec prover env hyps' concl' (genv, sigma)
with
| Unknown | Model _ ->
flush stdout;
@@ -2010,7 +1982,7 @@ let micromega_genr prover tac =
in
let ff' = abstract_wrt_formula ff' ff in
let arith_goal, props, vars, ff_arith =
- make_goal_of_formula gl0 (Lazy.force dump_rexpr) ff'
+ make_goal_of_formula (genv, sigma) (Lazy.force dump_rexpr) ff'
in
let intro (id, _) = Tactics.introduction id in
let intro_vars = Tacticals.New.tclTHENLIST (List.map intro vars) in
@@ -2030,7 +2002,9 @@ let micromega_genr prover tac =
; micromega_order_changer res' env' ff_arith ]
in
let goal_props =
- List.rev (List.map fst (Env.elements (prop_env_of_formula gl0 ff')))
+ List.rev
+ (List.map fst
+ (Env.elements (prop_env_of_formula (genv, sigma) ff')))
in
let goal_vars =
List.map (fun (_, i) -> fst (List.nth env (i - 1))) vars
diff --git a/plugins/micromega/zify.ml b/plugins/micromega/zify.ml
index fa29e6080e..917961fdcd 100644
--- a/plugins/micromega/zify.ml
+++ b/plugins/micromega/zify.ml
@@ -464,13 +464,18 @@ module ECstOp = struct
let cast x = CstOp x
let dest = function CstOp x -> Some x | _ -> None
+ let isConstruct evd c =
+ match EConstr.kind evd c with
+ | Construct _ | Int _ | Float _ -> true
+ | _ -> false
+
let mk_elt evd i a =
{ source = a.(0)
; target = a.(1)
; inj = get_inj evd a.(3)
; cst = a.(4)
; cstinj = a.(5)
- ; is_construct = EConstr.isConstruct evd a.(2) }
+ ; is_construct = isConstruct evd a.(2) }
let get_key = 2
end
@@ -979,17 +984,21 @@ let is_arrow env evd a p1 p2 =
where c is the head symbol and [a] is the array of arguments.
The function also transforms (x -> y) as (arrow x y) *)
let get_operator barrow env evd e =
- match EConstr.kind evd e with
+ let e' = EConstr.whd_evar evd e in
+ match EConstr.kind evd e' with
| Prod (a, p1, p2) ->
- if barrow && is_arrow env evd a p1 p2 then (arrow, [|p1; p2|])
+ if barrow && is_arrow env evd a p1 p2 then (arrow, [|p1; p2|], false)
else raise Not_found
| App (c, a) -> (
- match EConstr.kind evd c with
+ let c' = EConstr.whd_evar evd c in
+ match EConstr.kind evd c' with
| Construct _ (* e.g. Z0 , Z.pos *) | Const _ (* e.g. Z.max *) | Proj _
|Lambda _ (* e.g projections *) | Ind _ (* e.g. eq *) ->
- (c, a)
+ (c', a, false)
| _ -> raise Not_found )
- | Construct _ -> (EConstr.whd_evar evd e, [||])
+ | Const _ -> (e', [||], false)
+ | Construct _ -> (e', [||], true)
+ | Int _ | Float _ -> (e', [||], true)
| _ -> raise Not_found
let decompose_app env evd e =
@@ -1065,37 +1074,41 @@ let rec trans_expr env evd e =
let inj = e.inj in
let e = e.constr in
try
- let c, a = get_operator false env evd e in
- let k, t =
- find_option (match_operator env evd c a) (HConstr.find_all c !table_cache)
- in
- let n = Array.length a in
- match k with
- | CstOp {deriv = c'} ->
- ECstOpT.(if c'.is_construct then Term else Prf (c'.cst, c'.cstinj))
- | UnOp {deriv = unop} ->
- let prf =
- trans_expr env evd
- { constr = a.(n - 1)
- ; typ = unop.EUnOpT.source1
- ; inj = unop.EUnOpT.inj1_t }
- in
- app_unop evd e unop a.(n - 1) prf
- | BinOp {deriv = binop} ->
- let prf1 =
- trans_expr env evd
- { constr = a.(n - 2)
- ; typ = binop.EBinOpT.source1
- ; inj = binop.EBinOpT.inj1 }
- in
- let prf2 =
- trans_expr env evd
- { constr = a.(n - 1)
- ; typ = binop.EBinOpT.source2
- ; inj = binop.EBinOpT.inj2 }
+ let c, a, is_constant = get_operator false env evd e in
+ if is_constant then Term
+ else
+ let k, t =
+ find_option
+ (match_operator env evd c a)
+ (HConstr.find_all c !table_cache)
in
- app_binop evd e binop a.(n - 2) prf1 a.(n - 1) prf2
- | d -> mkvar evd inj e
+ let n = Array.length a in
+ match k with
+ | CstOp {deriv = c'} ->
+ ECstOpT.(if c'.is_construct then Term else Prf (c'.cst, c'.cstinj))
+ | UnOp {deriv = unop} ->
+ let prf =
+ trans_expr env evd
+ { constr = a.(n - 1)
+ ; typ = unop.EUnOpT.source1
+ ; inj = unop.EUnOpT.inj1_t }
+ in
+ app_unop evd e unop a.(n - 1) prf
+ | BinOp {deriv = binop} ->
+ let prf1 =
+ trans_expr env evd
+ { constr = a.(n - 2)
+ ; typ = binop.EBinOpT.source1
+ ; inj = binop.EBinOpT.inj1 }
+ in
+ let prf2 =
+ trans_expr env evd
+ { constr = a.(n - 1)
+ ; typ = binop.EBinOpT.source2
+ ; inj = binop.EBinOpT.inj2 }
+ in
+ app_binop evd e binop a.(n - 2) prf1 a.(n - 1) prf2
+ | d -> mkvar evd inj e
with Not_found ->
(* Feedback.msg_debug
Pp.(str "Not found " ++ Termops.Internal.debug_print_constr e); *)
diff --git a/plugins/ssr/ssrcommon.ml b/plugins/ssr/ssrcommon.ml
index d859fe51ab..cb58b9bcb8 100644
--- a/plugins/ssr/ssrcommon.ml
+++ b/plugins/ssr/ssrcommon.ml
@@ -280,7 +280,7 @@ let interp_wit wit ist gl x =
sigma, Tacinterp.Value.cast (topwit wit) arg
let interp_hyp ist gl (SsrHyp (loc, id)) =
- let s, id' = interp_wit wit_var ist gl CAst.(make ?loc id) in
+ let s, id' = interp_wit wit_hyp ist gl CAst.(make ?loc id) in
if not_section_id id' then s, SsrHyp (loc, id') else
hyp_err ?loc "Can't clear section hypothesis " id'
diff --git a/plugins/ssr/ssrparser.mlg b/plugins/ssr/ssrparser.mlg
index 89e0c9fcbe..7b584b5159 100644
--- a/plugins/ssr/ssrparser.mlg
+++ b/plugins/ssr/ssrparser.mlg
@@ -155,7 +155,7 @@ let pr_ssrhyp _ _ _ = pr_hyp
let wit_ssrhyprep = add_genarg "ssrhyprep" (fun env sigma -> pr_hyp)
let intern_hyp ist (SsrHyp (loc, id) as hyp) =
- let _ = Tacintern.intern_genarg ist (in_gen (rawwit wit_var) CAst.(make ?loc id)) in
+ let _ = Tacintern.intern_genarg ist (in_gen (rawwit wit_hyp) CAst.(make ?loc id)) in
if not_section_id id then hyp else
hyp_err ?loc "Can't clear section hypothesis " id
diff --git a/plugins/ssrmatching/ssrmatching.ml b/plugins/ssrmatching/ssrmatching.ml
index 5dedae6388..cdd15acb0d 100644
--- a/plugins/ssrmatching/ssrmatching.ml
+++ b/plugins/ssrmatching/ssrmatching.ml
@@ -204,7 +204,8 @@ exception NoProgress
(* comparison can be much faster than the HO one. *)
let unif_EQ env sigma p c =
- let evars = existential_opt_value0 sigma, Evd.universes sigma in
+ let env = Environ.set_universes (Evd.universes sigma) env in
+ let evars = existential_opt_value0 sigma in
try let _ = Reduction.conv env p ~evars c in true with _ -> false
let unif_EQ_args env sigma pa a =
diff --git a/pretyping/detyping.ml b/pretyping/detyping.ml
index 7fcb0795bd..a12a832f76 100644
--- a/pretyping/detyping.ml
+++ b/pretyping/detyping.ml
@@ -715,9 +715,9 @@ and detype_r d flags avoid env sigma t =
(* Meta in constr are not user-parsable and are mapped to Evar *)
if n = Constr_matching.special_meta then
(* Using a dash to be unparsable *)
- GEvar (Id.of_string_soft "CONTEXT-HOLE", [])
+ GEvar (CAst.make @@ Id.of_string_soft "CONTEXT-HOLE", [])
else
- GEvar (Id.of_string_soft ("M" ^ string_of_int n), [])
+ GEvar (CAst.make @@ Id.of_string_soft ("M" ^ string_of_int n), [])
| Var id ->
(* Discriminate between section variable and non-section variable *)
(try let _ = Global.lookup_named id in GRef (GlobRef.VarRef id, None)
@@ -788,12 +788,12 @@ and detype_r d flags avoid env sigma t =
let l = Evd.evar_instance_array bound_to_itself_or_letin (Evd.find sigma evk) cl in
let fvs,rels = List.fold_left (fun (fvs,rels) (_,c) -> match EConstr.kind sigma c with Rel n -> (fvs,Int.Set.add n rels) | Var id -> (Id.Set.add id fvs,rels) | _ -> (fvs,rels)) (Id.Set.empty,Int.Set.empty) l in
let l = Evd.evar_instance_array (fun d c -> not !print_evar_arguments && (bound_to_itself_or_letin d c && not (isRel sigma c && Int.Set.mem (destRel sigma c) rels || isVar sigma c && (Id.Set.mem (destVar sigma c) fvs)))) (Evd.find sigma evk) cl in
- id,l
+ id,List.map (fun (id,c) -> (CAst.make id,c)) l
with Not_found ->
Id.of_string ("X" ^ string_of_int (Evar.repr evk)),
- (List.map (fun c -> (Id.of_string "__",c)) cl)
+ (List.map (fun c -> (CAst.make @@ Id.of_string "__",c)) cl)
in
- GEvar (id,
+ GEvar (CAst.make id,
List.map (on_snd (detype d flags avoid env sigma)) l)
| Ind (ind_sp,u) ->
GRef (GlobRef.IndRef ind_sp, detype_instance sigma u)
@@ -883,7 +883,12 @@ and detype_binder d flags bk avoid env sigma decl c =
| BLetIn ->
let c = detype d { flags with flg_isgoal = 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 s =
+ (* It can fail if ty is an evar, or if run inside ocamldebug or the
+ OCaml toplevel since their printers don't have access to the proper sigma/env *)
+ try Retyping.get_sort_family_of (snd env) sigma ty
+ with Retyping.RetypeError _ -> InType
+ in
let t = if s != InProp && not !Flags.raw_print then None else Some (detype d { flags with flg_isgoal = false } avoid env sigma ty) in
GLetIn (na', c, t, r)
diff --git a/pretyping/evardefine.ml b/pretyping/evardefine.ml
index f33030d6a4..eaf8c65811 100644
--- a/pretyping/evardefine.ml
+++ b/pretyping/evardefine.ml
@@ -175,10 +175,7 @@ let define_evar_as_sort env evd (ev,args) =
let evd' = Evd.define ev (mkSort s) evd in
Evd.set_leq_sort env evd' (Sorts.super s) (ESorts.kind evd' sort), s
-(* Propagation of constraints through application and abstraction:
- Given a type constraint on a functional term, returns the type
- constraint on its domain and codomain. If the input constraint is
- an evar instantiate it with the product of 2 new evars. *)
+(* Unify with unknown array *)
let rec presplit env sigma c =
let c = Reductionops.whd_all env sigma c in
@@ -189,25 +186,6 @@ let rec presplit env sigma c =
presplit env sigma (mkApp (lam, args))
| _ -> sigma, c
-let split_tycon ?loc env evd tycon =
- match tycon with
- | None -> evd,(make_annot Anonymous Relevant,None,None)
- | Some c ->
- let evd, c = presplit env evd c in
- let evd, na, dom, rng = match EConstr.kind evd c with
- | Prod (na,dom,rng) -> evd, na, dom, rng
- | Evar ev ->
- let (evd,prod) = define_evar_as_product env evd ev in
- let (na,dom,rng) = destProd evd prod in
- let anon = {na with binder_name = Anonymous} in
- evd, anon, dom, rng
- | _ ->
- (* XXX no error to allow later coercion? Not sure if possible with funclass *)
- error_not_product ?loc env evd c
- in
- evd, (na, mk_tycon dom, mk_tycon rng)
-
-
let define_pure_evar_as_array env sigma evk =
let evi = Evd.find_undefined sigma evk in
let evenv = evar_env env evi in
diff --git a/pretyping/evardefine.mli b/pretyping/evardefine.mli
index e5c3f8baa1..5702e169c8 100644
--- a/pretyping/evardefine.mli
+++ b/pretyping/evardefine.mli
@@ -8,7 +8,6 @@
(* * (see LICENSE file for the text of the license) *)
(************************************************************************)
-open Names
open EConstr
open Evd
open Environ
@@ -31,10 +30,6 @@ val mk_valcon : constr -> val_constraint
val evar_absorb_arguments : env -> evar_map -> existential -> constr list ->
evar_map * existential
-val split_tycon :
- ?loc:Loc.t -> env -> evar_map -> type_constraint ->
- evar_map * (Name.t Context.binder_annot * type_constraint * type_constraint)
-
val split_as_array : env -> evar_map -> type_constraint ->
evar_map * type_constraint
(** If the constraint can be made to look like [array A] return [A],
@@ -51,3 +46,6 @@ val define_evar_as_sort : env -> evar_map -> existential -> evar_map * Sorts.t
val pr_tycon : env -> evar_map -> type_constraint -> Pp.t
+(** Used for bidi heuristic when typing lambdas. Transforms an applied
+ evar to an evar with bigger context (ie ?X e to ?X'@{y=e}). *)
+val presplit : env -> evar_map -> EConstr.t -> evar_map * EConstr.t
diff --git a/pretyping/glob_ops.ml b/pretyping/glob_ops.ml
index 5bd26be823..dc5fd80f9e 100644
--- a/pretyping/glob_ops.ml
+++ b/pretyping/glob_ops.ml
@@ -128,7 +128,7 @@ let fix_kind_eq k1 k2 = match k1, k2 with
| (GFix _ | GCoFix _), _ -> false
let instance_eq f (x1,c1) (x2,c2) =
- Id.equal x1 x2 && f c1 c2
+ Id.equal x1.CAst.v x2.CAst.v && f c1 c2
let mk_glob_constr_eq f c1 c2 = match DAst.get c1, DAst.get c2 with
| GRef (gr1, u1), GRef (gr2, u2) ->
@@ -136,7 +136,7 @@ let mk_glob_constr_eq f c1 c2 = match DAst.get c1, DAst.get c2 with
Option.equal (List.equal glob_level_eq) u1 u2
| GVar id1, GVar id2 -> Id.equal id1 id2
| GEvar (id1, arg1), GEvar (id2, arg2) ->
- Id.equal id1 id2 && List.equal (instance_eq f) arg1 arg2
+ Id.equal id1.CAst.v id2.CAst.v && List.equal (instance_eq f) arg1 arg2
| GPatVar k1, GPatVar k2 -> matching_var_kind_eq k1 k2
| GApp (f1, arg1), GApp (f2, arg2) ->
f f1 f2 && List.equal f arg1 arg2
diff --git a/pretyping/glob_term.ml b/pretyping/glob_term.ml
index 526eac6f1e..a49c8abe26 100644
--- a/pretyping/glob_term.ml
+++ b/pretyping/glob_term.ml
@@ -75,7 +75,7 @@ type 'a glob_constr_r =
| GVar of Id.t
(** An identifier that cannot be regarded as "GRef".
Bound variables are typically represented this way. *)
- | GEvar of existential_name * (Id.t * 'a glob_constr_g) list
+ | GEvar of existential_name CAst.t * (lident * 'a glob_constr_g) list
| GPatVar of Evar_kinds.matching_var_kind (** Used for patterns only *)
| GApp of 'a glob_constr_g * 'a glob_constr_g list
| GLambda of Name.t * binding_kind * 'a glob_constr_g * 'a glob_constr_g
diff --git a/pretyping/pretype_errors.ml b/pretyping/pretype_errors.ml
index 1e8441dd8a..1dddc5622d 100644
--- a/pretyping/pretype_errors.ml
+++ b/pretyping/pretype_errors.ml
@@ -48,7 +48,7 @@ type pretype_error =
| CannotUnifyBindingType of constr * constr
| CannotGeneralize of constr
| NoOccurrenceFound of constr * Id.t option
- | CannotFindWellTypedAbstraction of constr * constr list * (env * type_error) option
+ | CannotFindWellTypedAbstraction of constr * constr list * (env * pretype_error) option
| WrongAbstractionType of Name.t * constr * types * types
| AbstractionOverMeta of Name.t * Name.t
| NonLinearUnification of Name.t * constr
diff --git a/pretyping/pretype_errors.mli b/pretyping/pretype_errors.mli
index 45997e9a66..714d68165e 100644
--- a/pretyping/pretype_errors.mli
+++ b/pretyping/pretype_errors.mli
@@ -54,7 +54,7 @@ type pretype_error =
| CannotUnifyBindingType of constr * constr
| CannotGeneralize of constr
| NoOccurrenceFound of constr * Id.t option
- | CannotFindWellTypedAbstraction of constr * constr list * (env * type_error) option
+ | CannotFindWellTypedAbstraction of constr * constr list * (env * pretype_error) option
| WrongAbstractionType of Name.t * constr * types * types
| AbstractionOverMeta of Name.t * Name.t
| NonLinearUnification of Name.t * constr
@@ -132,7 +132,7 @@ val error_cannot_unify : ?loc:Loc.t -> env -> Evd.evar_map ->
val error_cannot_unify_local : env -> Evd.evar_map -> constr * constr * constr -> 'b
val error_cannot_find_well_typed_abstraction : env -> Evd.evar_map ->
- constr -> constr list -> (env * type_error) option -> 'b
+ constr -> constr list -> (env * pretype_error) option -> 'b
val error_wrong_abstraction_type : env -> Evd.evar_map ->
Name.t -> constr -> types -> types -> 'b
diff --git a/pretyping/pretyping.ml b/pretyping/pretyping.ml
index b9825b6a92..268ad2ae56 100644
--- a/pretyping/pretyping.ml
+++ b/pretyping/pretyping.ml
@@ -365,9 +365,9 @@ let inh_conv_coerce_to_tycon ?loc ~program_mode resolve_tc env sigma j = functio
| Some t ->
Coercion.inh_conv_coerce_to ?loc ~program_mode resolve_tc !!env sigma j t
-let check_instance loc subst = function
+let check_instance subst = function
| [] -> ()
- | (id,_) :: _ ->
+ | (CAst.{loc;v=id},_) :: _ ->
if List.mem_assoc id subst then
user_err ?loc (Id.print id ++ str "appears more than once.")
else
@@ -493,7 +493,7 @@ type 'a pretype_fun = ?loc:Loc.t -> program_mode:bool -> poly:bool -> bool -> ty
type pretyper = {
pretype_ref : pretyper -> GlobRef.t * glob_level list option -> unsafe_judgment pretype_fun;
pretype_var : pretyper -> Id.t -> unsafe_judgment pretype_fun;
- pretype_evar : pretyper -> existential_name * (Id.t * glob_constr) list -> unsafe_judgment pretype_fun;
+ pretype_evar : pretyper -> existential_name CAst.t * (lident * glob_constr) list -> unsafe_judgment pretype_fun;
pretype_patvar : pretyper -> Evar_kinds.matching_var_kind -> unsafe_judgment pretype_fun;
pretype_app : pretyper -> glob_constr * glob_constr list -> unsafe_judgment pretype_fun;
pretype_lambda : pretyper -> Name.t * binding_kind * glob_constr * glob_constr -> unsafe_judgment pretype_fun;
@@ -587,10 +587,10 @@ let pretype_instance self ~program_mode ~poly resolve_tc env sigma loc hyps evk
strbrk " is not well-typed.") in
let sigma, c, update =
try
- let c = List.assoc id update in
+ let c = snd (List.find (fun (CAst.{v=id'},c) -> Id.equal id id') update) in
let sigma, c = eval_pretyper self ~program_mode ~poly resolve_tc (mk_tycon t) env sigma c in
check_body sigma id (Some c.uj_val);
- sigma, c.uj_val, List.remove_assoc id update
+ sigma, c.uj_val, List.remove_first (fun (CAst.{v=id'},_) -> Id.equal id id') update
with Not_found ->
try
let (n,b',t') = lookup_rel_id id (rel_context !!env) in
@@ -609,7 +609,7 @@ let pretype_instance self ~program_mode ~poly resolve_tc env sigma loc hyps evk
str " in current context: no binding for " ++ Id.print id ++ str ".") in
((id,c)::subst, update, sigma) in
let subst,inst,sigma = List.fold_right f hyps ([],update,sigma) in
- check_instance loc subst inst;
+ check_instance subst inst;
sigma, List.map snd subst
module Default =
@@ -628,13 +628,13 @@ struct
let sigma, t_id = pretype_id (fun e r t -> pretype tycon e r t) loc env sigma id in
discard_trace @@ inh_conv_coerce_to_tycon ?loc ~program_mode resolve_tc env sigma t_id tycon
- let pretype_evar self (id, inst) ?loc ~program_mode ~poly resolve_tc tycon env sigma =
+ let pretype_evar self (CAst.{v=id;loc=locid}, inst) ?loc ~program_mode ~poly resolve_tc tycon env sigma =
(* Ne faudrait-il pas s'assurer que hyps est bien un
sous-contexte du contexte courant, et qu'il n'y a pas de Rel "caché" *)
let id = interp_ltac_id env id in
let evk =
try Evd.evar_key id sigma
- with Not_found -> error_evar_not_found ?loc !!env sigma id in
+ with Not_found -> error_evar_not_found ?loc:locid !!env sigma id in
let hyps = evar_filtered_context (Evd.find sigma evk) in
let sigma, args = pretype_instance self ~program_mode ~poly resolve_tc env sigma loc hyps evk inst in
let c = mkEvar (evk, args) in
@@ -857,7 +857,7 @@ struct
typing the argument, so we replace it by an existential
variable *)
let sigma, c_hole = new_evar env sigma ~src:(loc,Evar_kinds.InternalHole) c1 in
- (sigma, make_judge c_hole c1), (c_hole, c, trace) :: bidiargs
+ (sigma, make_judge c_hole c1), (c_hole, c1, c, trace) :: bidiargs
else
let tycon = Some c1 in
pretype tycon env sigma c, bidiargs
@@ -886,12 +886,10 @@ struct
let sigma, resj, resj_before_bidi, bidiargs = apply_rec env sigma 0 fj fj candargs [] args in
let sigma, resj = refresh_template env sigma resj in
let sigma, resj, otrace = inh_conv_coerce_to_tycon ?loc ~program_mode resolve_tc env sigma resj tycon in
- let refine_arg n (sigma,t) (newarg,origarg,trace) =
+ let refine_arg n (sigma,t) (newarg,ty,origarg,trace) =
(* Refine an argument (originally `origarg`) represented by an evar
(`newarg`) to use typing information from the context *)
- (* Recover the expected type of the argument *)
- let ty = Retyping.get_type_of !!env sigma newarg in
- (* Type the argument using this expected type *)
+ (* Type the argument using the expected type *)
let sigma, j = pretype (Some ty) env sigma origarg in
(* Unify the (possibly refined) existential variable with the
(typechecked) original value *)
@@ -925,7 +923,32 @@ struct
let sigma, ty' = Coercion.inh_coerce_to_prod ?loc ~program_mode !!env sigma ty in
sigma, Some ty'
in
- let sigma, (name',dom,rng) = split_tycon ?loc !!env sigma tycon' in
+ let sigma,name',dom,rng =
+ match tycon' with
+ | None -> sigma,Anonymous, None, None
+ | Some ty ->
+ let sigma, ty = Evardefine.presplit !!env sigma ty in
+ match EConstr.kind sigma ty with
+ | Prod (na,dom,rng) ->
+ sigma, na.binder_name, Some dom, Some rng
+ | Evar ev ->
+ (* define_evar_as_product works badly when impredicativity
+ is possible but not known (#12623). OTOH if we know we
+ are impredicative (typically Prop) we want to keep the
+ information when typing the body. *)
+ let s = Retyping.get_sort_of !!env sigma ty in
+ if Environ.is_impredicative_sort !!env s
+ || Evd.check_leq sigma (Univ.Universe.type1) (Sorts.univ_of_sort s)
+ then
+ let sigma, prod = define_evar_as_product !!env sigma ev in
+ let na,dom,rng = destProd sigma prod in
+ sigma, na.binder_name, Some dom, Some rng
+ else
+ sigma, Anonymous, None, None
+ | _ ->
+ (* XXX no error to allow later coercion? Not sure if possible with funclass *)
+ error_not_product ?loc !!env sigma ty
+ in
let dom_valcon = valcon_of_tycon dom in
let sigma, j = eval_type_pretyper self ~program_mode ~poly resolve_tc dom_valcon env sigma c1 in
let name = {binder_name=name; binder_relevance=Sorts.relevance_of_sort j.utj_type} in
@@ -934,7 +957,7 @@ struct
let var',env' = push_rel ~hypnaming sigma var env in
let sigma, j' = eval_pretyper self ~program_mode ~poly resolve_tc rng env' sigma c2 in
let name = get_name var' in
- let resj = judge_of_abstraction !!env (orelse_name name name'.binder_name) j j' in
+ let resj = judge_of_abstraction !!env (orelse_name name name') j j' in
discard_trace @@ inh_conv_coerce_to_tycon ?loc ~program_mode resolve_tc env sigma resj tycon
let pretype_prod self (name, bk, c1, c2) =
diff --git a/pretyping/pretyping.mli b/pretyping/pretyping.mli
index c03374c59f..7bb4a6e273 100644
--- a/pretyping/pretyping.mli
+++ b/pretyping/pretyping.mli
@@ -148,7 +148,7 @@ type 'a pretype_fun = ?loc:Loc.t -> program_mode:bool -> poly:bool -> bool -> Ev
type pretyper = {
pretype_ref : pretyper -> GlobRef.t * glob_level list option -> unsafe_judgment pretype_fun;
pretype_var : pretyper -> Id.t -> unsafe_judgment pretype_fun;
- pretype_evar : pretyper -> existential_name * (Id.t * glob_constr) list -> unsafe_judgment pretype_fun;
+ pretype_evar : pretyper -> existential_name CAst.t * (lident * glob_constr) list -> unsafe_judgment pretype_fun;
pretype_patvar : pretyper -> Evar_kinds.matching_var_kind -> unsafe_judgment pretype_fun;
pretype_app : pretyper -> glob_constr * glob_constr list -> unsafe_judgment pretype_fun;
pretype_lambda : pretyper -> Name.t * binding_kind * glob_constr * glob_constr -> unsafe_judgment pretype_fun;
diff --git a/pretyping/reductionops.ml b/pretyping/reductionops.ml
index aeb18ec322..3352bfce38 100644
--- a/pretyping/reductionops.ml
+++ b/pretyping/reductionops.ml
@@ -445,7 +445,7 @@ type state_reduction_function =
let pr_state env sigma (tm,sk) =
let open Pp in
let pr c = Termops.Internal.print_constr_env env sigma c in
- h 0 (pr tm ++ str "|" ++ cut () ++ Stack.pr pr sk)
+ h (pr tm ++ str "|" ++ cut () ++ Stack.pr pr sk)
(*************************************)
(*** Reduction Functions Operators ***)
@@ -705,7 +705,7 @@ let rec whd_state_gen flags env sigma =
let open Pp in
let pr c = Termops.Internal.print_constr_env env sigma c in
Feedback.msg_debug
- (h 0 (str "<<" ++ pr x ++
+ (h (str "<<" ++ pr x ++
str "|" ++ cut () ++ Stack.pr pr stack ++
str ">>"))
in
@@ -1094,7 +1094,8 @@ let f_conv_leq ?l2r ?reds env ?evars x y =
let test_trans_conversion (f: constr Reduction.extended_conversion_function) reds env sigma x y =
try
let evars ev = safe_evar_value sigma ev in
- let _ = f ~reds env ~evars:(evars, Evd.universes sigma) x y in
+ let env = Environ.set_universes (Evd.universes sigma) env in
+ let _ = f ~reds env ~evars x y in
true
with Reduction.NotConvertible -> false
| e ->
@@ -1112,7 +1113,8 @@ let check_conv ?(pb=Reduction.CUMUL) ?(ts=TransparentState.full) env sigma x y =
| Reduction.CONV -> f_conv
| Reduction.CUMUL -> f_conv_leq
in
- try f ~reds:ts env ~evars:(safe_evar_value sigma, Evd.universes sigma) x y; true
+ let env = Environ.set_universes (Evd.universes sigma) env in
+ try f ~reds:ts env ~evars:(safe_evar_value sigma) x y; true
with Reduction.NotConvertible -> false
| Univ.UniverseInconsistency _ -> false
| e ->
@@ -1138,8 +1140,7 @@ let sigma_check_inductive_instances cv_pb variance u1 u2 sigma =
let sigma_univ_state =
let open Reduction in
- { compare_graph = Evd.universes;
- compare_sorts = sigma_compare_sorts;
+ { compare_sorts = sigma_compare_sorts;
compare_instances = sigma_compare_instances;
compare_cumul_instances = sigma_check_inductive_instances; }
@@ -1164,6 +1165,7 @@ let infer_conv_gen conv_fun ?(catch_incon=true) ?(pb=Reduction.CUMUL)
| None ->
let x = EConstr.Unsafe.to_constr x in
let y = EConstr.Unsafe.to_constr y in
+ let env = Environ.set_universes (Evd.universes sigma) env in
let sigma' =
conv_fun pb ~l2r:false sigma ts
env (sigma, sigma_univ_state) x y in
diff --git a/pretyping/typing.ml b/pretyping/typing.ml
index 756ccd3438..aeb3873de7 100644
--- a/pretyping/typing.ml
+++ b/pretyping/typing.ml
@@ -220,14 +220,15 @@ let check_allowed_sort env sigma ind c p =
else
Sorts.relevance_of_sort_family ksort
+let check_actual_type env sigma cj t =
+ try Evarconv.unify_leq_delay env sigma cj.uj_type t
+ with Evarconv.UnableToUnify (sigma,e) -> error_actual_type env sigma cj t e
+
let judge_of_cast env sigma cj k tj =
let expected_type = tj.utj_val in
- match Evarconv.unify_leq_delay env sigma cj.uj_type expected_type with
- | exception Evarconv.UnableToUnify _ ->
- error_actual_type_core env sigma cj expected_type;
- | sigma ->
- sigma, { uj_val = mkCast (cj.uj_val, k, expected_type);
- uj_type = expected_type }
+ let sigma = check_actual_type env sigma cj expected_type in
+ sigma, { uj_val = mkCast (cj.uj_val, k, expected_type);
+ uj_type = expected_type }
let check_fix env sigma pfix =
let inj c = EConstr.to_constr ~abort_on_undefined_evars:false sigma c in
@@ -296,7 +297,8 @@ let judge_of_letin env name defj typj j =
uj_type = subst1 defj.uj_val j.uj_type }
let check_hyps_inclusion env sigma x hyps =
- let evars = Evarutil.safe_evar_value sigma, Evd.universes sigma in
+ let env = Environ.set_universes (Evd.universes sigma) env in
+ let evars = Evarutil.safe_evar_value sigma in
Typeops.check_hyps_inclusion env ~evars x hyps
let type_of_constant env sigma (c,u) =
@@ -340,7 +342,7 @@ let judge_of_array env sigma u tj defj tyj =
let sigma = Evd.set_leq_sort env sigma tyj.utj_type
(Sorts.sort_of_univ (Univ.Universe.make ulev))
in
- let check_one sigma j = Evarconv.unify_leq_delay env sigma j.uj_type tyj.utj_val in
+ let check_one sigma j = check_actual_type env sigma j tyj.utj_val in
let sigma = check_one sigma defj in
let sigma = Array.fold_left check_one sigma tj in
let arr = EConstr.of_constr @@ type_of_array env u in
@@ -391,7 +393,7 @@ let rec execute env sigma cstr =
let t = mkApp (mkIndU (ci.ci_ind,univs), args) in
let sigma, tj = execute env sigma t in
let sigma, tj = type_judgment env sigma tj in
- let sigma = Evarconv.unify_leq_delay env sigma cj.uj_type tj.utj_val in
+ let sigma = check_actual_type env sigma cj tj.utj_val in
sigma
in
judge_of_case env sigma ci pj iv cj lfj
@@ -492,10 +494,7 @@ and execute_array env = Array.fold_left_map (execute env)
let check env sigma c t =
let sigma, j = execute env sigma c in
- match Evarconv.unify_leq_delay env sigma j.uj_type t with
- | exception Evarconv.UnableToUnify _ ->
- error_actual_type_core env sigma j t
- | sigma -> sigma
+ check_actual_type env sigma j t
(* Type of a constr *)
diff --git a/pretyping/unification.ml b/pretyping/unification.ml
index 207a03d80f..ccfb508964 100644
--- a/pretyping/unification.ml
+++ b/pretyping/unification.ml
@@ -134,8 +134,8 @@ let abstract_list_all env evd typ c l =
| Type_errors.TypeError (env',x) ->
(* FIXME: plug back the typing information *)
error_cannot_find_well_typed_abstraction env evd p l None
- | Pretype_errors.PretypeError (env',evd,TypingError x) ->
- error_cannot_find_well_typed_abstraction env evd p l (Some (env',x)) in
+ | Pretype_errors.PretypeError (env',evd,e) ->
+ error_cannot_find_well_typed_abstraction env evd p l (Some (env',e)) in
evd,(p,typp)
let set_occurrences_of_last_arg n =
diff --git a/pretyping/vnorm.ml b/pretyping/vnorm.ml
index 900ba0edb9..1420401875 100644
--- a/pretyping/vnorm.ml
+++ b/pretyping/vnorm.ml
@@ -218,7 +218,8 @@ and nf_evar env sigma evk stk =
let t = List.fold_left fold concl hyps in
let t, args = nf_args env sigma args t in
let inst, args = Array.chop (List.length hyps) args in
- let inst = Array.to_list inst in
+ (* Evar instances are reversed w.r.t. argument order *)
+ let inst = Array.rev_to_list inst in
let c = mkApp (mkEvar (evk, inst), args) in
nf_stk env sigma c t stk
| _ ->
diff --git a/printing/ppconstr.ml b/printing/ppconstr.ml
index af105f4d63..8da1d636f0 100644
--- a/printing/ppconstr.ml
+++ b/printing/ppconstr.ml
@@ -227,13 +227,49 @@ let tag_var = tag Tag.variable
let pr_evar pr id l =
hov 0 (
- tag_evar (str "?" ++ pr_id id) ++
+ tag_evar (str "?" ++ pr_lident id) ++
(match l with
| [] -> mt()
| l ->
- let f (id,c) = pr_id id ++ str ":=" ++ pr ltop c in
+ let f (id,c) = pr_lident id ++ str ":=" ++ pr ltop c in
str"@{" ++ hov 0 (prlist_with_sep pr_semicolon f (List.rev l)) ++ str"}"))
+ (* Assuming "{" and "}" brackets, prints
+ - if there is enough room
+ { a; b; c }
+ - otherwise
+ {
+ a;
+ b;
+ c
+ }
+ Alternatively, replace outer hv with h to get instead:
+ { a;
+ b;
+ c }
+ Replace the inner hv with hov to respectively get instead (if enough room):
+ {
+ a; b;
+ c
+ }
+ or
+ { a; b;
+ c }
+ *)
+ let pr_record left right pr = function
+ | [] -> str left ++ str " " ++ str right
+ | l ->
+ hv 0 (
+ str left ++
+ brk (1,String.length left) ++
+ hv 0 (prlist_with_sep pr_semicolon pr l) ++
+ brk (1,0) ++
+ str right)
+
+ let pr_record_body left right pr l =
+ let pr_defined_field (id, c) = hov 2 (pr_reference id ++ str" :=" ++ pr c) in
+ pr_record left right pr_defined_field l
+
let las = lapp
let lpator = 0
let lpatrec = 0
@@ -242,11 +278,7 @@ let tag_var = tag Tag.variable
let rec pr_patt sep inh p =
let (strm,prec) = match CAst.(p.v) with
| CPatRecord l ->
- let pp (c, p) =
- pr_reference c ++ spc() ++ str ":=" ++ pr_patt spc lpattop p
- in
- (if l = [] then str "{| |}"
- else str "{| " ++ prlist_with_sep pr_semicolon pp l ++ str " |}"), lpatrec
+ pr_record_body "{|" "|}" (pr_patt spc lpattop) l, lpatrec
| CPatAlias (p, na) ->
pr_patt mt (LevelLe las) p ++ str " as " ++ pr_lname na, las
@@ -287,6 +319,7 @@ let tag_var = tag Tag.variable
| CPatDelimiters (k,p) ->
pr_delimiters k (pr_patt mt lsimplepatt p), 1
+
| CPatCast _ ->
assert false
in
@@ -464,11 +497,6 @@ let tag_var = tag Tag.variable
pr (LevelLt lapp) a ++
prlist (fun a -> spc () ++ pr_expl_args pr a) l)
- let pr_record_body_gen pr l =
- spc () ++
- prlist_with_sep pr_semicolon
- (fun (id, c) -> h 1 (pr_reference id ++ spc () ++ str":=" ++ pr ltop c)) l
-
let pr_forall n = keyword "forall" ++ pr_com_at n ++ spc ()
let pr_fun n = keyword "fun" ++ pr_com_at n ++ spc ()
@@ -568,10 +596,7 @@ let tag_var = tag Tag.variable
| CApp ((None,a),l) ->
return (pr_app (pr mt) a l, lapp)
| CRecord l ->
- return (
- hv 0 (str"{|" ++ pr_record_body_gen (pr spc) l ++ str" |}"),
- latom
- )
+ return (pr_record_body "{|" "|}" (pr spc ltop) l, latom)
| CCases (Constr.LetPatternStyle,rtntypopt,[c,as_clause,in_clause],[{v=([[p]],b)}]) ->
return (
hv 0 (
@@ -717,7 +742,5 @@ let tag_var = tag Tag.variable
let pr_cases_pattern_expr = pr_patt ltop
- let pr_record_body = pr_record_body_gen pr
-
let pr_binders env sigma = pr_undelimited_binders spc (pr_expr env sigma ltop)
diff --git a/printing/ppconstr.mli b/printing/ppconstr.mli
index 2850e4bfa0..02e04573f8 100644
--- a/printing/ppconstr.mli
+++ b/printing/ppconstr.mli
@@ -41,7 +41,8 @@ val pr_guard_annot
-> recursion_order_expr option
-> Pp.t
-val pr_record_body : (qualid * constr_expr) list -> Pp.t
+val pr_record : string -> string -> ('a -> Pp.t) -> 'a list -> Pp.t
+val pr_record_body : string -> string -> ('a -> Pp.t) -> (Libnames.qualid * 'a) list -> Pp.t
val pr_binders : Environ.env -> Evd.evar_map -> local_binder_expr list -> Pp.t
val pr_constr_pattern_expr : Environ.env -> Evd.evar_map -> constr_pattern_expr -> Pp.t
val pr_lconstr_pattern_expr : Environ.env -> Evd.evar_map -> constr_pattern_expr -> Pp.t
diff --git a/printing/printer.ml b/printing/printer.ml
index a1a2d9ae51..bc26caefbe 100644
--- a/printing/printer.ml
+++ b/printing/printer.ml
@@ -765,9 +765,9 @@ let pr_subgoals ?(pr_first=true) ?(diffs=false) ?os_map
v 0 (
int ngoals ++ focused_if_needed ++ str(String.plural ngoals "subgoal")
++ print_extra
- ++ str (if (should_gname()) then ", subgoal 1" else "")
- ++ (if should_tag() then pr_goal_tag g1 else str"")
- ++ pr_goal_name sigma g1 ++ cut () ++ goals
+ ++ str (if pr_first && (should_gname()) && ngoals > 1 then ", subgoal 1" else "")
+ ++ (if pr_first && should_tag() then pr_goal_tag g1 else str"")
+ ++ (if pr_first then pr_goal_name sigma g1 else mt()) ++ cut () ++ goals
++ (if unfocused=[] then str ""
else (cut() ++ cut() ++ str "*** Unfocused goals:" ++ cut()
++ pr_rec (List.length rest + 2) unfocused))
diff --git a/printing/proof_diffs.ml b/printing/proof_diffs.ml
index 43f70dfecc..b2ebc61b4e 100644
--- a/printing/proof_diffs.ml
+++ b/printing/proof_diffs.ml
@@ -252,6 +252,9 @@ let pp_of_type env sigma ty =
let pr_leconstr_env ?lax ?inctx ?scope env sigma t =
Ppconstr.pr_lconstr_expr env sigma (Constrextern.extern_constr ?lax ?inctx ?scope env sigma t)
+let pr_econstr_env ?lax ?inctx ?scope env sigma t =
+ Ppconstr.pr_constr_expr env sigma (Constrextern.extern_constr ?lax ?inctx ?scope env sigma t)
+
let pr_lconstr_env ?lax ?inctx ?scope env sigma c =
pr_leconstr_env ?lax ?inctx ?scope env sigma (EConstr.of_constr c)
@@ -511,12 +514,12 @@ let match_goals ot nt =
| CHole (k,naming,solve), CHole (k2,naming2,solve2) -> ()
| CPatVar _, CPatVar _ -> ()
| CEvar (n,l), CEvar (n2,l2) ->
- let oevar = if ogname = "" then Id.to_string n else ogname in
- nevar_to_oevar := CString.Map.add (Id.to_string n2) oevar !nevar_to_oevar;
+ let oevar = if ogname = "" then Id.to_string n.CAst.v else ogname in
+ nevar_to_oevar := CString.Map.add (Id.to_string n2.CAst.v) oevar !nevar_to_oevar;
iter2 (fun x x2 -> let (_, g) = x and (_, g2) = x2 in constr_expr ogname g g2) l l2
| CEvar (n,l), nt' ->
(* pass down the old goal evar name *)
- match_goals_r (Id.to_string n) nt' nt'
+ match_goals_r (Id.to_string n.CAst.v) nt' nt'
| CSort s, CSort s2 -> ()
| CCast (c,c'), CCast (c2,c'2) ->
constr_expr ogname c c2;
@@ -660,3 +663,22 @@ let make_goal_map op np =
let ng_to_og = make_goal_map_i op np in
(*db_goal_map op np ng_to_og;*)
ng_to_og
+
+let diff_proofs ~diff_opt ?old proof =
+ let pp_proof p =
+ let sigma, env = Proof.get_proof_context p in
+ let pprf = Proof.partial_proof p in
+ Pp.prlist_with_sep Pp.fnl (pr_econstr_env env sigma) pprf in
+ match diff_opt with
+ | DiffOff -> pp_proof proof
+ | _ -> begin
+ try
+ let n_pp = pp_proof proof in
+ let o_pp = match old with
+ | None -> Pp.mt()
+ | Some old -> pp_proof old in
+ let show_removed = Some (diff_opt = DiffRemoved) in
+ Pp_diff.diff_pp_combined ~tokenize_string ?show_removed o_pp n_pp
+ with
+ | Pp_diff.Diff_Failure msg -> Pp.str msg
+ end
diff --git a/printing/proof_diffs.mli b/printing/proof_diffs.mli
index ea64439456..6bdd7004fb 100644
--- a/printing/proof_diffs.mli
+++ b/printing/proof_diffs.mli
@@ -25,6 +25,10 @@ val write_color_enabled : bool -> unit
(** true indicates that color output is enabled *)
val color_enabled : unit -> bool
+type diffOpt = DiffOff | DiffOn | DiffRemoved
+
+val string_to_diffs : string -> diffOpt
+
open Evd
open Environ
open Constr
@@ -84,3 +88,5 @@ type hyp_info = {
}
val diff_hyps : string list list -> hyp_info CString.Map.t -> string list list -> hyp_info CString.Map.t -> Pp.t list
+
+val diff_proofs : diff_opt:diffOpt -> ?old:Proof.t -> Proof.t -> Pp.t
diff --git a/proofs/clenv.ml b/proofs/clenv.ml
index 31bc698830..387f0f6f5f 100644
--- a/proofs/clenv.ml
+++ b/proofs/clenv.ml
@@ -720,7 +720,7 @@ let make_clenv_binding env sigma = make_clenv_binding_gen false None env sigma
(* Pretty-print *)
let pr_clenv clenv =
- h 0
+ h
(str"TEMPL: " ++ Termops.Internal.print_constr_env clenv.env clenv.evd clenv.templval.rebus ++
str" : " ++ Termops.Internal.print_constr_env clenv.env clenv.evd clenv.templtyp.rebus ++ fnl () ++
pr_evar_map (Some 2) clenv.env clenv.evd)
diff --git a/stm/asyncTaskQueue.ml b/stm/asyncTaskQueue.ml
index a8088dae36..4f04b9fe1c 100644
--- a/stm/asyncTaskQueue.ml
+++ b/stm/asyncTaskQueue.ml
@@ -386,3 +386,8 @@ end
module MakeQueue(T : Task) () = struct include Make(T) () end
module MakeWorker(T : Task) () = struct include Make(T) () end
+
+exception RemoteException of Pp.t
+let _ = CErrors.register_handler (function
+ | RemoteException ppcmd -> Some ppcmd
+ | _ -> None)
diff --git a/stm/asyncTaskQueue.mli b/stm/asyncTaskQueue.mli
index cf174d0c93..a1fa6f7268 100644
--- a/stm/asyncTaskQueue.mli
+++ b/stm/asyncTaskQueue.mli
@@ -220,3 +220,6 @@ module MakeWorker(T : Task) () : sig
val main_loop : unit -> unit
end
+
+(** convenience exception to marshall to master *)
+exception RemoteException of Pp.t
diff --git a/stm/partac.ml b/stm/partac.ml
new file mode 100644
index 0000000000..8232b017f9
--- /dev/null
+++ b/stm/partac.ml
@@ -0,0 +1,178 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * Copyright INRIA, CNRS and contributors *)
+(* <O___,, * (see version control and CREDITS file for authors & dates) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+open Pp
+
+let stm_pr_err s = Format.eprintf "%s] %s\n%!" (Spawned.process_id ()) s
+
+module TacTask : sig
+
+ type output = (Constr.constr * UState.t) option
+ type task = {
+ t_state : Vernacstate.t;
+ t_assign : output Future.assignment -> unit;
+ t_ast : ComTactic.interpretable;
+ t_goalno : int;
+ t_goal : Goal.goal;
+ t_kill : unit -> unit;
+ t_name : string }
+
+ include AsyncTaskQueue.Task with type task := task
+
+end = struct (* {{{ *)
+
+ let forward_feedback { Feedback.doc_id = did; span_id = id; route; contents } =
+ Feedback.feedback ~did ~id ~route contents
+
+ type output = (Constr.constr * UState.t) option
+
+ type task = {
+ t_state : Vernacstate.t;
+ t_assign : output Future.assignment -> unit;
+ t_ast : ComTactic.interpretable;
+ t_goalno : int;
+ t_goal : Goal.goal;
+ t_kill : unit -> unit;
+ t_name : string }
+
+ type request = {
+ r_state : Vernacstate.t option;
+ r_ast : ComTactic.interpretable;
+ r_goalno : int;
+ r_goal : Goal.goal;
+ r_name : string }
+
+ type response =
+ | RespBuiltSubProof of (Constr.constr * UState.t)
+ | RespError of Pp.t
+ | RespNoProgress
+
+ let name = ref "tacticworker"
+ let extra_env () = [||]
+ type competence = unit
+ type worker_status = Fresh | Old of competence
+
+ let task_match _ _ = true
+
+ (* run by the master, on a thread *)
+ let request_of_task age { t_state; t_ast; t_goalno; t_goal; t_name } =
+ Some {
+ r_state = if age <> Fresh then None else Some t_state;
+ r_ast = t_ast;
+ r_goalno = t_goalno;
+ r_goal = t_goal;
+ r_name = t_name }
+
+ let use_response _ { t_assign; t_kill } resp =
+ match resp with
+ | RespBuiltSubProof o -> t_assign (`Val (Some o)); `Stay ((),[])
+ | RespNoProgress ->
+ t_assign (`Val None);
+ t_kill ();
+ `Stay ((),[])
+ | RespError msg ->
+ let e = (AsyncTaskQueue.RemoteException msg, Exninfo.null) in
+ t_assign (`Exn e);
+ t_kill ();
+ `Stay ((),[])
+
+ let on_marshal_error err { t_name } =
+ stm_pr_err ("Fatal marshal error: " ^ t_name );
+ flush_all (); exit 1
+
+ let on_task_cancellation_or_expiration_or_slave_death = function
+ | Some { t_kill } -> t_kill ()
+ | _ -> ()
+
+ let command_focus = Proof.new_focus_kind ()
+ let focus_cond = Proof.no_cond command_focus
+
+ let state = ref None
+ let receive_state = function
+ | None -> ()
+ | Some st -> state := Some st
+
+ let perform { r_state = st; r_ast = tactic; r_goal; r_goalno } =
+ receive_state st;
+ Vernacstate.unfreeze_interp_state (Option.get !state);
+ try
+ Vernacstate.LemmaStack.with_top (Option.get (Option.get !state).Vernacstate.lemmas) ~f:(fun pstate ->
+ let pstate =
+ Declare.Proof.map pstate ~f:(Proof.focus focus_cond () r_goalno) in
+ let pstate =
+ ComTactic.solve ~pstate
+ Goal_select.SelectAll ~info:None tactic ~with_end_tac:false in
+ let { Proof.sigma } = Declare.Proof.fold pstate ~f:Proof.data in
+ match Evd.(evar_body (find sigma r_goal)) with
+ | Evd.Evar_empty -> RespNoProgress
+ | Evd.Evar_defined t ->
+ let t = Evarutil.nf_evar sigma t in
+ let evars = Evarutil.undefined_evars_of_term sigma t in
+ if Evar.Set.is_empty evars then
+ let t = EConstr.Unsafe.to_constr t in
+ RespBuiltSubProof (t, Evd.evar_universe_context sigma)
+ else
+ CErrors.user_err ~hdr:"STM"
+ Pp.(str"The par: selector requires a tactic that makes no progress or fully" ++
+ str" solves the goal and leaves no unresolved existential variables. The following" ++
+ str" existentials remain unsolved: " ++ prlist (Termops.pr_existential_key sigma) (Evar.Set.elements evars))
+ )
+ with e when CErrors.noncritical e ->
+ RespError (CErrors.print e ++ spc() ++ str "(for subgoal "++int r_goalno ++ str ")")
+
+ let name_of_task { t_name } = t_name
+ let name_of_request { r_name } = r_name
+
+end (* }}} *)
+
+module TaskQueue = AsyncTaskQueue.MakeQueue(TacTask) ()
+
+let assign_tac ~abstract res : unit Proofview.tactic =
+ Proofview.(Goal.enter begin fun g ->
+ let gid = Goal.goal g in
+ let g_solution =
+ try List.assoc gid res
+ with Not_found -> CErrors.anomaly(str"Partac: wrong focus.") in
+ if not (Future.is_over g_solution) then
+ tclUNIT ()
+ else
+ let open Notations in
+ match Future.join g_solution with
+ | Some (pt, uc) ->
+ let push_state ctx =
+ Proofview.tclEVARMAP >>= fun sigma ->
+ Proofview.Unsafe.tclEVARS (Evd.merge_universe_context sigma ctx)
+ in
+ (if abstract then Abstract.tclABSTRACT None else (fun x -> x))
+ (push_state uc <*> Tactics.exact_no_check (EConstr.of_constr pt))
+ | None -> tclUNIT ()
+ end)
+
+let enable_par ~nworkers = ComTactic.set_par_implementation
+ (fun ~pstate ~info t_ast ~abstract ~with_end_tac ->
+ let t_state = Vernacstate.freeze_interp_state ~marshallable:true in
+ TaskQueue.with_n_workers nworkers CoqworkmgrApi.High (fun queue ->
+ Declare.Proof.map pstate ~f:(fun p ->
+ let open TacTask in
+ let results = (Proof.data p).Proof.goals |> CList.map_i (fun i g ->
+ let g_solution, t_assign =
+ Future.create_delegate ~name:(Printf.sprintf "subgoal %d" i)
+ (fun x -> x) in
+ TaskQueue.enqueue_task queue
+ ~cancel_switch:(ref false)
+ { t_state; t_assign; t_ast;
+ t_goalno = i; t_goal = g; t_name = Goal.uid g;
+ t_kill = (fun () -> TaskQueue.cancel_all queue) };
+ g, g_solution) 1 in
+ TaskQueue.join queue;
+ let p,_,() =
+ Proof.run_tactic (Global.env())
+ (assign_tac ~abstract results) p in
+ p)))
diff --git a/stm/partac.mli b/stm/partac.mli
new file mode 100644
index 0000000000..a206b2e5d8
--- /dev/null
+++ b/stm/partac.mli
@@ -0,0 +1,13 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * Copyright INRIA, CNRS and contributors *)
+(* <O___,, * (see version control and CREDITS file for authors & dates) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+val enable_par : nworkers:int -> unit
+
+module TacTask : AsyncTaskQueue.Task
diff --git a/stm/stm.ml b/stm/stm.ml
index 4ca0c365bf..85f889c879 100644
--- a/stm/stm.ml
+++ b/stm/stm.ml
@@ -159,9 +159,9 @@ type cmd_t = {
cids : Names.Id.t list;
cblock : proof_block_name option;
cqueue : [ `MainQueue
- | `TacQueue of solving_tac * anon_abstracting_tac * AsyncTaskQueue.cancel_switch
- | `QueryQueue of AsyncTaskQueue.cancel_switch
- | `SkipQueue ] }
+ | `QueryQueue
+ | `SkipQueue ];
+ cancel_switch : AsyncTaskQueue.cancel_switch; }
type fork_t = aast * Vcs_.Branch.t * opacity_guarantee * Names.Id.t list
type qed_t = {
qast : aast;
@@ -190,10 +190,10 @@ type step =
type visit = { step : step; next : Stateid.t }
let mkTransTac cast cblock cqueue =
- Cmd { ctac = true; cast; cblock; cqueue; cids = []; ceff = false }
+ Cmd { ctac = true; cast; cblock; cqueue; cids = []; ceff = false; cancel_switch = ref false }
let mkTransCmd cast cids ceff cqueue =
- Cmd { ctac = false; cast; cblock = None; cqueue; cids; ceff }
+ Cmd { ctac = false; cast; cblock = None; cqueue; cids; ceff; cancel_switch = ref false }
type cached_state =
| EmptyState
@@ -742,8 +742,7 @@ end = struct (* {{{ *)
Stateid.Set.iter (fun id ->
match (Vcs_aux.visit old_vcs id).step with
| `Qed ({ fproof = Some (_, cancel_switch) }, _)
- | `Cmd { cqueue = `TacQueue (_,_,cancel_switch) }
- | `Cmd { cqueue = `QueryQueue cancel_switch } ->
+ | `Cmd { cancel_switch } ->
cancel_switch := true
| _ -> ())
erased_nodes;
@@ -1222,11 +1221,6 @@ let record_pb_time ?loc proof_name time =
hints := Aux_file.set !hints proof_name proof_build_time
end
-exception RemoteException of Pp.t
-let _ = CErrors.register_handler (function
- | RemoteException ppcmd -> Some ppcmd
- | _ -> None)
-
(****************** proof structure for error recovery ************************)
(******************************************************************************)
@@ -1429,7 +1423,7 @@ end = struct (* {{{ *)
RespError { e_error_at; e_safe_id = valid; e_msg; e_safe_states } ->
feedback (InProgress ~-1);
let info = Stateid.add ~valid Exninfo.null e_error_at in
- let e = (RemoteException e_msg, info) in
+ let e = (AsyncTaskQueue.RemoteException e_msg, info) in
t_assign (`Exn e);
`Stay(t_states,[States e_safe_states])
| _ -> assert false
@@ -1440,7 +1434,7 @@ end = struct (* {{{ *)
| Some (BuildProof { t_start = start; t_assign }) ->
let s = "Worker dies or task expired" in
let info = Stateid.add ~valid:start Exninfo.null start in
- let e = (RemoteException (Pp.strbrk s), info) in
+ let e = (AsyncTaskQueue.RemoteException (Pp.strbrk s), info) in
t_assign (`Exn e);
execution_error start (Pp.strbrk s);
feedback (InProgress ~-1)
@@ -1792,225 +1786,6 @@ end = struct (* {{{ *)
end (* }}} *)
-and TacTask : sig
-
- type output = (Constr.constr * UState.t) option
- type task = {
- t_state : Stateid.t;
- t_state_fb : Stateid.t;
- t_assign : output Future.assignment -> unit;
- t_ast : int * aast;
- t_goal : Goal.goal;
- t_kill : unit -> unit;
- t_name : string }
-
- include AsyncTaskQueue.Task with type task := task
-
-end = struct (* {{{ *)
-
- type output = (Constr.constr * UState.t) option
-
- let forward_feedback msg = Hooks.(call forward_feedback msg)
-
- type task = {
- t_state : Stateid.t;
- t_state_fb : Stateid.t;
- t_assign : output Future.assignment -> unit;
- t_ast : int * aast;
- t_goal : Goal.goal;
- t_kill : unit -> unit;
- t_name : string }
-
- type request = {
- r_state : Stateid.t;
- r_state_fb : Stateid.t;
- r_document : VCS.vcs option;
- r_ast : int * aast;
- r_goal : Goal.goal;
- r_name : string }
-
- type response =
- | RespBuiltSubProof of (Constr.constr * UState.t)
- | RespError of Pp.t
- | RespNoProgress
-
- let name = ref "tacticworker"
- let extra_env () = [||]
- type competence = unit
- type worker_status = Fresh | Old of competence
-
- let task_match _ _ = true
-
- (* run by the master, on a thread *)
- let request_of_task age { t_state; t_state_fb; t_ast; t_goal; t_name } =
- try Some {
- r_state = t_state;
- r_state_fb = t_state_fb;
- r_document =
- if age <> Fresh then None
- else Some (VCS.slice ~block_start:t_state ~block_stop:t_state);
- r_ast = t_ast;
- r_goal = t_goal;
- r_name = t_name }
- with VCS.Expired -> None
-
- let use_response _ { t_assign; t_state; t_state_fb; t_kill } resp =
- match resp with
- | RespBuiltSubProof o -> t_assign (`Val (Some o)); `Stay ((),[])
- | RespNoProgress ->
- t_assign (`Val None);
- t_kill ();
- `Stay ((),[])
- | RespError msg ->
- let e = (RemoteException msg, Exninfo.null) in
- t_assign (`Exn e);
- t_kill ();
- `Stay ((),[])
-
- let on_marshal_error err { t_name } =
- stm_pr_err ("Fatal marshal error: " ^ t_name );
- flush_all (); exit 1
-
- let on_task_cancellation_or_expiration_or_slave_death = function
- | Some { t_kill } -> t_kill ()
- | _ -> ()
-
- let command_focus = Proof.new_focus_kind ()
- let focus_cond = Proof.no_cond command_focus
-
- let perform { r_state = id; r_state_fb; r_document = vcs; r_ast; r_goal } =
- Option.iter VCS.restore vcs;
- try
- Reach.known_state ~doc:dummy_doc (* XXX should be vcs *) ~cache:false id;
- State.purify (fun () ->
- let Proof.{sigma=sigma0} = Proof.data (PG_compat.give_me_the_proof ()) in
- let g = Evd.find sigma0 r_goal in
- let is_ground c = Evarutil.is_ground_term sigma0 c in
- if not (
- is_ground Evd.(evar_concl g) &&
- List.for_all (Context.Named.Declaration.for_all is_ground)
- Evd.(evar_context g))
- then
- CErrors.user_err ~hdr:"STM" Pp.(strbrk("The par: goal selector does not support goals with existential variables"))
- else begin
- let (i, ast) = r_ast in
- PG_compat.map_proof (fun p -> Proof.focus focus_cond () i p);
- (* STATE SPEC:
- * - start : id
- * - return: id
- * => captures state id in a future closure, which will
- discard execution state but for the proof + univs.
- *)
- let st = Vernacstate.freeze_interp_state ~marshallable:false in
- ignore(stm_vernac_interp r_state_fb st ast);
- let Proof.{sigma} = Proof.data (PG_compat.give_me_the_proof ()) in
- match Evd.(evar_body (find sigma r_goal)) with
- | Evd.Evar_empty -> RespNoProgress
- | Evd.Evar_defined t ->
- let t = Evarutil.nf_evar sigma t in
- let evars = Evarutil.undefined_evars_of_term sigma t in
- if Evar.Set.is_empty evars then
- let t = EConstr.Unsafe.to_constr t in
- RespBuiltSubProof (t, Evd.evar_universe_context sigma)
- else
- CErrors.user_err ~hdr:"STM"
- Pp.(str"The par: selector requires a tactic that makes no progress or fully" ++
- str" solves the goal and leaves no unresolved existential variables. The following" ++
- str" existentials remain unsolved: " ++ prlist (Termops.pr_existential_key sigma) (Evar.Set.elements evars))
- end) ()
- with e when CErrors.noncritical e ->
- RespError (CErrors.print e ++ spc() ++ str "(for subgoal "++int (fst r_ast) ++ str ")")
-
- let name_of_task { t_name } = t_name
- let name_of_request { r_name } = r_name
-
-end (* }}} *)
-
-and Partac : sig
-
- val vernac_interp :
- solve:bool -> abstract:bool -> cancel_switch:AsyncTaskQueue.cancel_switch ->
- int -> CoqworkmgrApi.priority -> Stateid.t -> Stateid.t -> aast -> unit
-
-end = struct (* {{{ *)
-
- module TaskQueue = AsyncTaskQueue.MakeQueue(TacTask) ()
-
- let stm_fail ~st fail f =
- if fail then
- Vernacinterp.with_fail ~st f
- else
- f ()
-
- let vernac_interp ~solve ~abstract ~cancel_switch nworkers priority safe_id id
- { indentation; verbose; expr = e; strlen } : unit
- =
- let cl, time, batch, fail =
- let rec find ~time ~batch ~fail cl = match cl with
- | ControlTime batch :: cl -> find ~time:true ~batch ~fail cl
- | ControlRedirect _ :: cl -> find ~time ~batch ~fail cl
- | ControlFail :: cl -> find ~time ~batch ~fail:true cl
- | cl -> cl, time, batch, fail in
- find ~time:false ~batch:false ~fail:false e.CAst.v.control in
- let e = CAst.map (fun cmd -> { cmd with control = cl }) e in
- let st = Vernacstate.freeze_interp_state ~marshallable:false in
- stm_fail ~st fail (fun () ->
- (if time then System.with_time ~batch ~header:(Pp.mt ()) else (fun x -> x)) (fun () ->
- TaskQueue.with_n_workers nworkers priority (fun queue ->
- PG_compat.map_proof (fun p ->
- let Proof.{goals} = Proof.data p in
- let open TacTask in
- let res = CList.map_i (fun i g ->
- let f, assign =
- Future.create_delegate
- ~name:(Printf.sprintf "subgoal %d" i)
- (State.exn_on id ~valid:safe_id) in
- let t_ast = (i, { indentation; verbose; expr = e; strlen }) in
- let t_name = Goal.uid g in
- TaskQueue.enqueue_task queue
- { t_state = safe_id; t_state_fb = id;
- t_assign = assign; t_ast; t_goal = g; t_name;
- t_kill = (fun () -> if solve then TaskQueue.cancel_all queue) }
- ~cancel_switch;
- g,f)
- 1 goals in
- TaskQueue.join queue;
- let assign_tac : unit Proofview.tactic =
- Proofview.(Goal.enter begin fun g ->
- let gid = Goal.goal g in
- let f =
- try List.assoc gid res
- with Not_found -> CErrors.anomaly(str"Partac: wrong focus.") in
- if not (Future.is_over f) then
- (* One has failed and cancelled the others, but not this one *)
- if solve then Tacticals.New.tclZEROMSG
- (str"Interrupted by the failure of another goal")
- else tclUNIT ()
- else
- let open Notations in
- match Future.join f with
- | Some (pt, uc) ->
- let sigma, env = PG_compat.get_current_context () in
- let push_state ctx =
- Proofview.tclEVARMAP >>= fun sigma ->
- Proofview.Unsafe.tclEVARS (Evd.merge_universe_context sigma ctx)
- in
- stm_pperr_endline (fun () -> hov 0 (
- str"g=" ++ int (Evar.repr gid) ++ spc () ++
- str"t=" ++ (Printer.pr_constr_env env sigma pt) ++ spc () ++
- str"uc=" ++ Termops.pr_evar_universe_context uc));
- (if abstract then Abstract.tclABSTRACT None else (fun x -> x))
- (push_state uc <*>
- Tactics.exact_no_check (EConstr.of_constr pt))
- | None ->
- if solve then Tacticals.New.tclSOLVE [] else tclUNIT ()
- end)
- in
- let p,_,() = Proof.run_tactic (Global.env()) assign_tac p in
- p))) ())
-
-end (* }}} *)
-
and QueryTask : sig
type task = { t_where : Stateid.t; t_for : Stateid.t ; t_what : aast }
@@ -2361,15 +2136,7 @@ let known_state ~doc ?(redefine_qed=false) ~cache id =
), cache, true
| `Cmd { cast = x; cqueue = `SkipQueue } -> (fun () ->
reach view.next), cache, true
- | `Cmd { cast = x; cqueue = `TacQueue (solve,abstract,cancel_switch); cblock } ->
- (fun () ->
- resilient_tactic id cblock (fun () ->
- reach ~cache:true view.next;
- Partac.vernac_interp ~solve ~abstract ~cancel_switch
- !cur_opt.async_proofs_n_tacworkers
- !cur_opt.async_proofs_worker_priority view.next id x)
- ), cache, true
- | `Cmd { cast = x; cqueue = `QueryQueue cancel_switch }
+ | `Cmd { cast = x; cqueue = `QueryQueue; cancel_switch }
when async_proofs_is_master !cur_opt -> (fun () ->
reach view.next;
Query.vernac_interp ~cancel_switch view.next id x
@@ -2377,7 +2144,6 @@ let known_state ~doc ?(redefine_qed=false) ~cache id =
| `Cmd { cast = x; ceff = eff; ctac = true; cblock } -> (fun () ->
resilient_tactic id cblock (fun () ->
reach view.next;
- (* State resulting from reach *)
let st = Vernacstate.freeze_interp_state ~marshallable:false in
ignore(stm_vernac_interp id st x)
)
@@ -2588,6 +2354,7 @@ let doc_type_module_name (std : stm_doc_type) =
let init_core () =
if !cur_opt.async_proofs_mode = APon then Control.enable_thread_delay := true;
+ if !Flags.async_proofs_worker_id = "master" then Partac.enable_par ~nworkers:!cur_opt.async_proofs_n_tacworkers;
State.register_root_state ()
let dirpath_of_file f =
@@ -2938,12 +2705,9 @@ let process_transaction ~doc ?(newtip=Stateid.fresh ())
VCS.set_parsing_state id head_parsing;
Backtrack.record (); `Ok
- | VtProofStep { parallel; proof_block_detection = cblock } ->
+ | VtProofStep { proof_block_detection = cblock } ->
let id = VCS.new_node ~id:newtip proof_mode () in
- let queue =
- match parallel with
- | `Yes(solve,abstract) -> `TacQueue (solve, abstract, ref false)
- | `No -> `MainQueue in
+ let queue = `MainQueue in
VCS.commit id (mkTransTac x cblock queue);
(* Static proof block detection delayed until an error really occurs.
If/when and UI will make something useful with this piece of info,
diff --git a/stm/stm.mli b/stm/stm.mli
index 9780c96512..097bcbe0ca 100644
--- a/stm/stm.mli
+++ b/stm/stm.mli
@@ -195,7 +195,6 @@ val set_perspective : doc:doc -> Stateid.t list -> unit
(** workers **************************************************************** **)
module ProofTask : AsyncTaskQueue.Task
-module TacTask : AsyncTaskQueue.Task
module QueryTask : AsyncTaskQueue.Task
(** document structure customization *************************************** **)
diff --git a/stm/stm.mllib b/stm/stm.mllib
index 4b254e8113..831369625f 100644
--- a/stm/stm.mllib
+++ b/stm/stm.mllib
@@ -6,6 +6,7 @@ WorkerPool
Vernac_classifier
CoqworkmgrApi
AsyncTaskQueue
+Partac
Stm
ProofBlockDelimiter
Vio_checking
diff --git a/stm/vernac_classifier.ml b/stm/vernac_classifier.ml
index f89fb9f52d..ffae2866c0 100644
--- a/stm/vernac_classifier.ml
+++ b/stm/vernac_classifier.ml
@@ -15,11 +15,6 @@ open CAst
open Vernacextend
open Vernacexpr
-let string_of_parallel = function
- | `Yes (solve,abs) ->
- "par" ^ if solve then "solve" else "" ^ if abs then "abs" else ""
- | `No -> ""
-
let string_of_vernac_when = function
| VtLater -> "Later"
| VtNow -> "Now"
@@ -30,9 +25,8 @@ let string_of_vernac_classification = function
| VtQed (VtKeep VtKeepAxiom) -> "Qed(admitted)"
| VtQed (VtKeep (VtKeepOpaque | VtKeepDefined)) -> "Qed(keep)"
| VtQed VtDrop -> "Qed(drop)"
- | VtProofStep { parallel; proof_block_detection } ->
- "ProofStep " ^ string_of_parallel parallel ^
- Option.default "" proof_block_detection
+ | VtProofStep { proof_block_detection } ->
+ "ProofStep " ^ Option.default "" proof_block_detection
| VtQuery -> "Query"
| VtMeta -> "Meta "
| VtProofMode _ -> "Proof Mode"
@@ -80,12 +74,11 @@ let classify_vernac e =
| VernacCheckGuard
| VernacUnfocused
| VernacSolveExistential _ ->
- VtProofStep { parallel = `No; proof_block_detection = None }
+ VtProofStep { proof_block_detection = None }
| VernacBullet _ ->
- VtProofStep { parallel = `No; proof_block_detection = Some "bullet" }
+ VtProofStep { proof_block_detection = Some "bullet" }
| VernacEndSubproof ->
- VtProofStep { parallel = `No;
- proof_block_detection = Some "curly" }
+ VtProofStep { proof_block_detection = Some "curly" }
(* StartProof *)
| VernacDefinition ((DoDischarge,_),({v=i},_),ProveBody _) ->
VtStartProof(Doesn'tGuaranteeOpacity, idents_of_name i)
@@ -135,7 +128,7 @@ let classify_vernac e =
| Constructors l -> List.map (fun (_,({v=id},_)) -> id) l
| RecordDecl (oid,l) -> (match oid with Some {v=x} -> [x] | _ -> []) @
CList.map_filter (function
- | AssumExpr({v=Names.Name n},_), _ -> Some n
+ | AssumExpr({v=Names.Name n},_,_), _ -> Some n
| _ -> None) l) l in
VtSideff (List.flatten ids, VtLater)
| VernacScheme l ->
@@ -213,7 +206,7 @@ let classify_vernac e =
(match static_classifier ~atts:v.attrs v.expr with
| VtQuery | VtProofStep _ | VtSideff _
| VtMeta as x -> x
- | VtQed _ -> VtProofStep { parallel = `No; proof_block_detection = None }
+ | VtQed _ -> VtProofStep { proof_block_detection = None }
| VtStartProof _ | VtProofMode _ -> VtQuery)
else
static_classifier ~atts:v.attrs v.expr
diff --git a/tactics/cbn.ml b/tactics/cbn.ml
index 8f0966a486..0b13f4763a 100644
--- a/tactics/cbn.ml
+++ b/tactics/cbn.ml
@@ -543,7 +543,7 @@ let rec whd_state_gen ?csts ~refold ~tactic_mode flags env sigma =
let open Pp in
let pr c = Termops.Internal.print_constr_env env sigma c in
Feedback.msg_debug
- (h 0 (str "<<" ++ pr x ++
+ (h (str "<<" ++ pr x ++
str "|" ++ cut () ++ Cst_stack.pr env sigma cst_l ++
str "|" ++ cut () ++ Stack.pr pr stack ++
str ">>"))
diff --git a/test-suite/bugs/closed/bug_12414.v b/test-suite/bugs/closed/bug_12414.v
new file mode 100644
index 0000000000..50b4b86eff
--- /dev/null
+++ b/test-suite/bugs/closed/bug_12414.v
@@ -0,0 +1,13 @@
+Set Universe Polymorphism.
+Set Printing Universes.
+Inductive list {T} : Type := | cons (t : T) : list -> list. (* who needs nil anyway? *)
+Arguments list : clear implicits.
+
+Fixpoint map {A B} (f: A -> B) (l : list A) : list B :=
+ let '(cons t l) := l in cons (f t) (map f l).
+About map@{_ _}.
+(* Two universes, as expected. *)
+
+Definition map_Set@{} {A B : Set} := @map A B.
+
+Definition map_Prop@{} {A B : Prop} := @map A B.
diff --git a/test-suite/bugs/closed/bug_12623.v b/test-suite/bugs/closed/bug_12623.v
new file mode 100644
index 0000000000..9fdcb94e0c
--- /dev/null
+++ b/test-suite/bugs/closed/bug_12623.v
@@ -0,0 +1,18 @@
+Set Universe Polymorphism.
+
+Axiom M : Type -> Prop.
+Axiom raise : forall {T}, M T.
+
+Inductive goal : Type :=
+| AHyp : forall {A : Type}, goal.
+
+Definition gtactic@{u u0} := goal@{u} -> M@{u0} (False).
+
+Class Seq (C : Type) :=
+ seq : C -> gtactic.
+Arguments seq {C _} _.
+
+Instance seq_one : Seq@{Set _ _} (gtactic) := fun t2 => fun g => raise.
+
+Definition x1 : gtactic := @seq@{_ _ _} _ _ (fun g : goal => raise).
+Definition x2 : gtactic := @seq@{_ _ _} _ seq_one (fun g : goal => raise).
diff --git a/test-suite/bugs/closed/bug_12895.v b/test-suite/bugs/closed/bug_12895.v
new file mode 100644
index 0000000000..53adc2981c
--- /dev/null
+++ b/test-suite/bugs/closed/bug_12895.v
@@ -0,0 +1,20 @@
+Fixpoint bug_1 (e1 : nat) {struct e1}
+ : nat
+with bug_2 {H_imp : nat} (e2 : nat) {struct e2}
+ : nat.
+Proof.
+ - exact e1.
+ - exact e2.
+Admitted.
+
+Fixpoint hbug_1 (a:bool) (e1 : nat) {struct e1}
+ : nat
+with hbug_2 (a:nat) (e2 : nat) {struct e2}
+ : nat.
+Proof.
+ - exact e1.
+ - exact e2.
+Admitted.
+
+Check (hbug_1 : bool -> nat -> nat).
+Check (hbug_2 : nat -> nat -> nat).
diff --git a/test-suite/bugs/closed/bug_12970.v b/test-suite/bugs/closed/bug_12970.v
new file mode 100644
index 0000000000..69ce7ec2c2
--- /dev/null
+++ b/test-suite/bugs/closed/bug_12970.v
@@ -0,0 +1,4 @@
+Arguments existT _ & _ _.
+
+Definition f := fun X (A : X -> Type) (P : forall x, A x -> Type) x y =>
+ existT (fun f => forall x, P x (f x)) x y : sigT (fun f => forall x, P x (f x)).
diff --git a/test-suite/bugs/closed/bug_13086.v b/test-suite/bugs/closed/bug_13086.v
new file mode 100644
index 0000000000..75f842b1cf
--- /dev/null
+++ b/test-suite/bugs/closed/bug_13086.v
@@ -0,0 +1,11 @@
+Unset Universe Checking.
+
+Definition bad1@{|Set < Set} := Prop.
+
+Set Universe Polymorphism.
+Axiom ax : Type.
+Inductive I@{u} : Prop := foo : ax@{u} -> I.
+
+Definition bad2@{v} (x:I@{v}) : I@{Set} := x.
+
+Definition vsdvds (f : (Prop -> Prop) -> Prop) (x : Set -> Prop) := f x.
diff --git a/test-suite/bugs/closed/bug_13169.v b/test-suite/bugs/closed/bug_13169.v
new file mode 100644
index 0000000000..a0b564c725
--- /dev/null
+++ b/test-suite/bugs/closed/bug_13169.v
@@ -0,0 +1,14 @@
+Goal False.
+Proof.
+ set (H1:=I).
+ set (x:=true).
+ assert (H2: x = true) by reflexivity.
+ set (y:=false).
+ assert (H3: y = false) by reflexivity.
+ clearbody H1 x y.
+ eenough (H4: _ = false).
+ vm_compute in H4.
+ (* H4 now has "x:=y" in the evar context. *)
+ 2: exact H3.
+ match type of H4 with y = false => idtac end.
+Abort.
diff --git a/test-suite/bugs/closed/bug_13171.v b/test-suite/bugs/closed/bug_13171.v
new file mode 100644
index 0000000000..0564722729
--- /dev/null
+++ b/test-suite/bugs/closed/bug_13171.v
@@ -0,0 +1,10 @@
+Primitive array := #array_type.
+
+Goal False.
+Proof.
+ unshelve epose (_:nat). exact_no_check true.
+ Fail let c := open_constr:([| n | 0 |]) in
+ let c := eval cbv in c in
+ let c := type of c in
+ idtac c.
+Abort.
diff --git a/test-suite/bugs/closed/bug_5197.v b/test-suite/bugs/closed/bug_5197.v
index 0c236e12ad..00b9e9bd9d 100644
--- a/test-suite/bugs/closed/bug_5197.v
+++ b/test-suite/bugs/closed/bug_5197.v
@@ -20,11 +20,11 @@ Definition Typeᶠ : TYPE := {|
rel := fun _ A => (forall ω : Ω, A ω) -> Type;
|}.
Set Printing Universes.
-Fail Definition Typeᵇ : El Typeᶠ :=
+Definition Typeᵇ : El Typeᶠ :=
mkPack _ _ (fun w => Type) (fun w A => (forall ω, A ω) -> Type).
-Definition Typeᵇ : El Typeᶠ :=
- mkPack _ (fun _ (A : Ω -> Type) => (forall ω : Ω, A ω) -> _) (fun w => Type) (fun w A => (forall ω, A ω) -> Type).
+(* Definition Typeᵇ : El Typeᶠ := *)
+(* mkPack _ (fun _ (A : Ω -> Type) => (forall ω : Ω, A ω) -> _) (fun w => Type) (fun w A => (forall ω, A ω) -> Type). *)
(** Bidirectional typechecking helps here *)
Require Import Program.Tactics.
diff --git a/test-suite/ide/proof-diffs.fake b/test-suite/ide/proof-diffs.fake
new file mode 100644
index 0000000000..594ebced23
--- /dev/null
+++ b/test-suite/ide/proof-diffs.fake
@@ -0,0 +1,10 @@
+ADD { Goal True /\ False /\ True = False. }
+ADD { split. }
+GOALS
+ADD here { split. }
+GOALS
+PDIFF here
+ADD there { auto. }
+GOALS
+PDIFF there
+ADD { Admitted. }
diff --git a/test-suite/micromega/int63.v b/test-suite/micromega/int63.v
new file mode 100644
index 0000000000..20dfa2631e
--- /dev/null
+++ b/test-suite/micromega/int63.v
@@ -0,0 +1,24 @@
+Require Import ZArith ZifyInt63 Lia.
+Require Import Int63.
+
+Open Scope int63_scope.
+
+Goal forall (x:int), 0 <= x = true.
+Proof. lia. Qed.
+
+Goal max_int = 9223372036854775807.
+Proof. lia. Qed.
+
+Goal digits = 63.
+Proof. lia. Qed.
+
+Goal wB = (2^63)%Z.
+Proof. lia. Qed.
+
+Goal forall x y, x + y <= max_int = true.
+Proof. lia. Qed.
+
+Goal forall x, x <> 0 -> x / x = 1.
+Proof.
+ nia.
+Qed.
diff --git a/test-suite/output/Notations3.out b/test-suite/output/Notations3.out
index abada44da7..bd22d45059 100644
--- a/test-suite/output/Notations3.out
+++ b/test-suite/output/Notations3.out
@@ -231,16 +231,13 @@ fun l : list nat => match l with
: list nat -> list nat
Arguments foo _%list_scope
-Notation
-"'exists' x .. y , p" := ex (fun x => .. (ex (fun y => p)) ..) : type_scope
-(default interpretation)
-"'exists' ! x .. y , p" := ex
- (unique
- (fun x => .. (ex (unique (fun y => p))) ..))
-: type_scope (default interpretation)
-Notation
-"( x , y , .. , z )" := pair .. (pair x y) .. z : core_scope
-(default interpretation)
+Notation "'exists' x .. y , p" := (ex (fun x => .. (ex (fun y => p)) ..))
+ : type_scope (default interpretation)
+Notation "'exists' ! x .. y , p" :=
+ (ex (unique (fun x => .. (ex (unique (fun y => p))) ..))) : type_scope
+ (default interpretation)
+Notation "( x , y , .. , z )" := (pair .. (pair x y) .. z) : core_scope
+ (default interpretation)
1 subgoal
============================
diff --git a/test-suite/output/Record.out b/test-suite/output/Record.out
index d45343fe60..7de1e7d559 100644
--- a/test-suite/output/Record.out
+++ b/test-suite/output/Record.out
@@ -30,3 +30,43 @@ fun '{| U := T; a := a; q := p |} => (T, p, a)
: M -> Type * True * nat
fun '{| U := T; a := a; q := p |} => (T, p, a)
: M -> Type * True * nat
+{| a := 0; b := 0 |}
+ : T
+fun '{| |} => 0
+ : LongModuleName.test -> nat
+ = {|
+ a :=
+ {|
+ LongModuleName.long_field_name0 := 0;
+ LongModuleName.long_field_name1 := 1;
+ LongModuleName.long_field_name2 := 2;
+ LongModuleName.long_field_name3 := 3
+ |};
+ b :=
+ fun
+ '{|
+ LongModuleName.long_field_name0 := a;
+ LongModuleName.long_field_name1 := b;
+ LongModuleName.long_field_name2 := c;
+ LongModuleName.long_field_name3 := d
+ |} => (a, b, c, d)
+ |}
+ : T
+ = {|
+ a :=
+ {|
+ long_field_name0 := 0;
+ long_field_name1 := 1;
+ long_field_name2 := 2;
+ long_field_name3 := 3
+ |};
+ b :=
+ fun
+ '{|
+ long_field_name0 := a;
+ long_field_name1 := b;
+ long_field_name2 := c;
+ long_field_name3 := d
+ |} => (a, b, c, d)
+ |}
+ : T
diff --git a/test-suite/output/Record.v b/test-suite/output/Record.v
index 71a8afa131..13ea37b11e 100644
--- a/test-suite/output/Record.v
+++ b/test-suite/output/Record.v
@@ -33,3 +33,34 @@ Check fun x:M => let 'D T _ p := x in T.
Check fun x:M => let 'D T p := x in (T,p).
Check fun x:M => let 'D T a p := x in (T,p,a).
Check fun x:M => let '{|U:=T;a:=a;q:=p|} := x in (T,p,a).
+
+Module FormattingIssue13142.
+
+Record T {A B} := {a:A;b:B}.
+
+Module LongModuleName.
+ Record test := { long_field_name0 : nat;
+ long_field_name1 : nat;
+ long_field_name2 : nat;
+ long_field_name3 : nat }.
+End LongModuleName.
+
+Definition c :=
+ {| LongModuleName.long_field_name0 := 0;
+ LongModuleName.long_field_name1 := 1;
+ LongModuleName.long_field_name2 := 2;
+ LongModuleName.long_field_name3 := 3 |}.
+
+Definition d :=
+ fun '{| LongModuleName.long_field_name0 := a;
+ LongModuleName.long_field_name1 := b;
+ LongModuleName.long_field_name2 := c;
+ LongModuleName.long_field_name3 := d |} => (a,b,c,d).
+
+Check {|a:=0;b:=0|}.
+Check fun '{| LongModuleName.long_field_name0:=_ |} => 0.
+Eval compute in {|a:=c;b:=d|}.
+Import LongModuleName.
+Eval compute in {|a:=c;b:=d|}.
+
+End FormattingIssue13142.
diff --git a/test-suite/output/bug_12908.out b/test-suite/output/bug_12908.out
index fca6dde704..54c4f98422 100644
--- a/test-suite/output/bug_12908.out
+++ b/test-suite/output/bug_12908.out
@@ -1,2 +1,7 @@
forall m n : nat, m * n = (2 * m * n)%nat
: Prop
+File "stdin", line 11, characters 0-31:
+Warning: Notation "_ * _" was already used in scope nat_scope.
+[notation-overridden,parsing]
+forall m n : nat, m * n = Nat.mul (Nat.mul 2 m) n
+ : Prop
diff --git a/test-suite/output/bug_12908.v b/test-suite/output/bug_12908.v
index 558c9f9f6a..6f7be22fa0 100644
--- a/test-suite/output/bug_12908.v
+++ b/test-suite/output/bug_12908.v
@@ -1,6 +1,13 @@
Definition mult' m n := 2 * m * n.
+
Module A.
(* Test hiding of a scoped notation by a lonely notation *)
Infix "*" := mult'.
Check forall m n, mult' m n = Nat.mul (Nat.mul 2 m) n.
End A.
+
+Module B.
+(* Test that an overriden scoped notation is deactivated *)
+Infix "*" := mult' : nat_scope.
+Check forall m n, mult' m n = Nat.mul (Nat.mul 2 m) n.
+End B.
diff --git a/test-suite/output/bug_13112.out b/test-suite/output/bug_13112.out
new file mode 100644
index 0000000000..a8a98d6b68
--- /dev/null
+++ b/test-suite/output/bug_13112.out
@@ -0,0 +1,4 @@
+0 + 0
+ : nat
+HI
+ : nat
diff --git a/test-suite/output/bug_13112.v b/test-suite/output/bug_13112.v
new file mode 100644
index 0000000000..9fee5e09d8
--- /dev/null
+++ b/test-suite/output/bug_13112.v
@@ -0,0 +1,5 @@
+Reserved Notation "'HI'".
+Notation "'HI'" := (O + O) (only parsing).
+Check HI. (* 0 + 0 : nat *)
+Notation "'HI'" := (O + O) (only printing).
+Check HI. (* 0 + 0 : nat *)
diff --git a/test-suite/output/bug_9180.out b/test-suite/output/bug_9180.out
index ed4892b389..f035d0252a 100644
--- a/test-suite/output/bug_9180.out
+++ b/test-suite/output/bug_9180.out
@@ -1,4 +1,3 @@
-Notation
-"n .+1" := S n : nat_scope (default interpretation)
+Notation "n .+1" := (S n) : nat_scope (default interpretation)
forall x : nat, x.+1 = x.+1
: Prop
diff --git a/test-suite/output/bug_9682.out b/test-suite/output/bug_9682.out
new file mode 100644
index 0000000000..45d9e4cad1
--- /dev/null
+++ b/test-suite/output/bug_9682.out
@@ -0,0 +1,9 @@
+mmatch 1 + 2 + 3 + 4 + 5 + 6 in nat as x
+return M (x = x) with
+| 1
+end
+ : unit
+#
+ : True
+##
+ : True
diff --git a/test-suite/output/bug_9682.v b/test-suite/output/bug_9682.v
new file mode 100644
index 0000000000..fa30d323ef
--- /dev/null
+++ b/test-suite/output/bug_9682.v
@@ -0,0 +1,28 @@
+Declare Scope blafu.
+Delimit Scope blafu with B.
+Axiom DoesNotMatch : Type.
+Axiom consumer : forall {A} (B : A -> Type) (E:Type) (x : A) (ls : list nat), unit.
+
+Notation "| p1 | .. | pn" := (@cons _ p1 .. (@cons _ pn nil) ..) (at level 91) : blafu.
+Notation "'mmatch_do_not_write' x 'in' T 'as' y 'return' 'M' p 'with_do_not_write' ls" :=
+ (@consumer _ (fun y : T => p%type) DoesNotMatch x ls%B)
+ (at level 200, ls at level 91, only parsing).
+Notation "'mmatch' x 'in' T 'as' y 'return' 'M' p 'with' ls 'end'" :=
+ (mmatch_do_not_write x in T as y return M p with_do_not_write ls)
+ (at level 200, ls at level 91, p at level 10, only parsing).
+(* This should not gives a warning *)
+Notation "'mmatch' x 'in' T 'as' y 'return' 'M' p 'with' ls 'end'" :=
+ (@consumer _ (fun y : T => p%type) DoesNotMatch x ls%B)
+ (at level 200, ls at level 91, p at level 10, only printing,
+ format "'[ ' mmatch '/' x ']' '/' '[ ' in '/' T ']' '/' '[ ' as '/' y ']' '/' '[ ' return M p ']' with '//' '[' ls ']' '//' end"
+ ).
+(* Check use of "mmatch" *)
+Check (mmatch 1 + 2 + 3 + 4 + 5 + 6 in nat as x return M (x = x) with | 1 end).
+
+(* 2nd example *)
+Notation "#" := I (at level 0, only parsing).
+Notation "#" := I (at level 0, only printing).
+Check #.
+Notation "##" := I (at level 0, only printing).
+Notation "##" := I (at level 0, only parsing).
+Check ##.
diff --git a/test-suite/output/goal_output.out b/test-suite/output/goal_output.out
index 773533a8d3..17c1aaa55b 100644
--- a/test-suite/output/goal_output.out
+++ b/test-suite/output/goal_output.out
@@ -2,7 +2,79 @@ Nat.t = nat
: Set
Nat.t = nat
: Set
+2 subgoals
+
+ ============================
+ True
+
+subgoal 2 is:
+ True
+2 subgoals, subgoal 1 (?Goal)
+
+ ============================
+ True
+
+subgoal 2 (?Goal0) is:
+ True
1 subgoal
============================
- False
+ True
+1 subgoal (?Goal0)
+
+ ============================
+ True
+1 subgoal (?Goal0)
+
+ ============================
+ True
+
+*** Unfocused goals:
+
+subgoal 2 (?Goal1) is:
+ True
+subgoal 3 (?Goal) is:
+ True
+1 subgoal
+
+ ============================
+ True
+
+*** Unfocused goals:
+
+subgoal 2 is:
+ True
+subgoal 3 is:
+ True
+This subproof is complete, but there are some unfocused goals.
+Focus next goal with bullet -.
+
+2 subgoals
+
+subgoal 1 is:
+ True
+subgoal 2 is:
+ True
+This subproof is complete, but there are some unfocused goals.
+Focus next goal with bullet -.
+
+2 subgoals
+
+subgoal 1 (?Goal0) is:
+ True
+subgoal 2 (?Goal) is:
+ True
+This subproof is complete, but there are some unfocused goals.
+Focus next goal with bullet -.
+
+1 subgoal
+
+subgoal 1 is:
+ True
+This subproof is complete, but there are some unfocused goals.
+Focus next goal with bullet -.
+
+1 subgoal
+
+subgoal 1 (?Goal) is:
+ True
diff --git a/test-suite/output/goal_output.v b/test-suite/output/goal_output.v
index 327b80b0aa..b1ced94054 100644
--- a/test-suite/output/goal_output.v
+++ b/test-suite/output/goal_output.v
@@ -6,8 +6,32 @@
Print Nat.t.
Timeout 1 Print Nat.t.
-Lemma toto: False.
Set Printing All.
+Lemma toto: True/\True.
+Proof.
+split.
Show.
+Set Printing Goal Names.
+Show.
+Unset Printing Goal Names.
+assert True.
+- idtac.
+Show.
+Set Printing Goal Names.
+Show.
+Set Printing Unfocused.
+Show.
+Unset Printing Goal Names.
+Show.
+Unset Printing Unfocused.
+ auto.
+Show.
+Set Printing Goal Names.
+Show.
+Unset Printing Goal Names.
+- auto.
+Show.
+Set Printing Goal Names.
+Show.
+Unset Printing Goal Names.
Abort.
-
diff --git a/test-suite/output/locate.out b/test-suite/output/locate.out
index 473db2d312..93d9d6cf7b 100644
--- a/test-suite/output/locate.out
+++ b/test-suite/output/locate.out
@@ -1,3 +1,2 @@
-Notation
-"b1 && b2" := if b1 then b2 else false (default interpretation)
-"x && y" := andb x y : bool_scope
+Notation "b1 && b2" := (if b1 then b2 else false) (default interpretation)
+Notation "x && y" := (andb x y) : bool_scope
diff --git a/test-suite/success/Nsatz.v b/test-suite/success/Nsatz.v
index 998f3f7dd1..73e98ea920 100644
--- a/test-suite/success/Nsatz.v
+++ b/test-suite/success/Nsatz.v
@@ -1,6 +1,8 @@
Require Import TestSuite.admit.
(* compile en user 3m39.915s sur cachalot *)
Require Import Nsatz.
+Require List.
+Import List.ListNotations.
(* Example with a generic domain *)
@@ -294,7 +296,7 @@ Lemma minh: forall A B C D O E H I:point,
Proof. geo_begin.
idtac "minh".
Time nsatz with radicalmax :=1%N strategy:=1%Z
- parameters:=(X O::X B::X C::nil)
+ parameters:=[X O; X B; X C]
variables:= (@nil R).
(*Finished transaction in 13. secs (10.102464u,0.s)
*)
@@ -314,15 +316,15 @@ Proof.
geo_begin.
idtac "Pappus".
Time nsatz with radicalmax :=1%N strategy:=0%Z
- parameters:=(X B::X A1::Y A1::X B1::Y B1::X C::Y C1::nil)
- variables:= (X B
- :: X A1
- :: Y A1
- :: X B1
- :: Y B1
- :: X C
- :: Y C1
- :: X C1 :: Y P :: X P :: Y Q :: X Q :: Y S :: X S :: nil).
+ parameters:=[X B; X A1; Y A1; X B1; Y B1; X C; Y C1]
+ variables:= [X B;
+ X A1;
+ Y A1;
+ X B1;
+ Y B1;
+ X C;
+ Y C1;
+ X C1; Y P; X P; Y Q; X Q; Y S; X S].
(*Finished transaction in 8. secs (7.795815u,0.000999999999999s)
*)
Qed.
@@ -347,7 +349,7 @@ Proof.
geo_begin.
idtac "Simson".
Time nsatz with radicalmax :=1%N strategy:=0%Z
- parameters:=(X B::Y B::X C::Y C::Y D::nil)
+ parameters:=[X B; Y B; X C; Y C; Y D]
variables:= (@nil R). (* compute -[X Y]. *)
(*Finished transaction in 8. secs (7.550852u,0.s)
*)
@@ -432,20 +434,20 @@ Proof.
geo_begin.
idtac "Desargues".
Time
-let lv := rev (X A
- :: X B
- :: Y B
- :: X C
- :: Y C
- :: Y A1 :: X A1
- :: Y B1
- :: Y C1
- :: X T
- :: Y T
- :: X Q
- :: Y Q :: X P :: Y P :: X C1 :: X B1 :: nil) in
+let lv := rev [X A;
+ X B;
+ Y B;
+ X C;
+ Y C;
+ Y A1; X A1;
+ Y B1;
+ Y C1;
+ X T;
+ Y T;
+ X Q;
+ Y Q; X P; Y P; X C1; X B1] in
nsatz with radicalmax :=1%N strategy:=0%Z
- parameters:=(X A::X B::Y B::X C::Y C::X A1::Y B1::Y C1::nil)
+ parameters:=[X A; X B; Y B; X C; Y C; X A1; Y B1; Y C1]
variables:= lv. (*Finished transaction in 8. secs (8.02578u,0.001s)*)
Qed.
@@ -522,9 +524,9 @@ Lemma hauteurs:forall A B C A1 B1 C1 H:point,
geo_begin.
idtac "hauteurs".
Time
- let lv := constr:(Y A1
- :: X A1 :: Y B1 :: X B1 :: Y A :: Y B :: X B :: X A :: X H :: Y C
- :: Y C1 :: Y H :: X C1 :: X C :: (@Datatypes.nil R)) in
+ let lv := constr:([Y A1;
+ X A1; Y B1; X B1; Y A; Y B; X B; X A; X H; Y C;
+ Y C1; Y H; X C1; X C]) in
nsatz with radicalmax := 2%N strategy := 1%Z parameters := (@Datatypes.nil R)
variables := lv.
(*Finished transaction in 5. secs (4.360337u,0.008999s)*)
diff --git a/test-suite/success/Record.v b/test-suite/success/Record.v
index ce07512a1e..beb424dd40 100644
--- a/test-suite/success/Record.v
+++ b/test-suite/success/Record.v
@@ -93,3 +93,18 @@ Record R : Type := {
(* This is used in a couple of development such as UniMatch *)
Record S {A:Type} := { a : A; b : forall A:Type, A }.
+
+(* Bug #13165 on implicit arguments in defined fields *)
+Record T := {
+ f {n:nat} (p:n=n) := nat;
+ g := f (eq_refl 0)
+}.
+
+(* Slight improvement in when SProp relevance is detected *)
+Inductive True : SProp := I.
+Inductive eqI : True -> SProp := reflI : eqI I.
+
+Record U (c:True) := {
+ u := c;
+ v := reflI : eqI u;
+ }.
diff --git a/test-suite/success/polymorphism.v b/test-suite/success/polymorphism.v
index 9ab8ace39e..0796b507a1 100644
--- a/test-suite/success/polymorphism.v
+++ b/test-suite/success/polymorphism.v
@@ -457,5 +457,10 @@ Module ObligationRegression.
(** Test for a regression encountered when fixing obligations for
stronger restriction of universe context. *)
Require Import CMorphisms.
- Check trans_co_eq_inv_arrow_morphism@{_ _ _ _ _ _ _ _}.
+ Check trans_co_eq_inv_arrow_morphism@{_ _ _ _ _ _ _}.
End ObligationRegression.
+
+Axiom poly@{i} : forall(A : Type@{i}) (a : A), unit.
+
+Definition nonpoly := @poly True Logic.I.
+Definition check := nonpoly@{}.
diff --git a/theories/Reals/RIneq.v b/theories/Reals/RIneq.v
index 4fa8b3216a..993b7b3ec4 100644
--- a/theories/Reals/RIneq.v
+++ b/theories/Reals/RIneq.v
@@ -459,12 +459,12 @@ Lemma Rplus_eq_0_l :
forall r1 r2, 0 <= r1 -> 0 <= r2 -> r1 + r2 = 0 -> r1 = 0.
Proof.
intros a b H [H0| H0] H1; auto with real.
- absurd (0 < a + b).
- rewrite H1; auto with real.
- apply Rle_lt_trans with (a + 0).
- rewrite Rplus_0_r; assumption.
- auto using Rplus_lt_compat_l with real.
- rewrite <- H0, Rplus_0_r in H1; assumption.
+ - absurd (0 < a + b).
+ + rewrite H1; auto with real.
+ + apply Rle_lt_trans with (a + 0).
+ * rewrite Rplus_0_r; assumption.
+ * auto using Rplus_lt_compat_l with real.
+ - rewrite <- H0, Rplus_0_r in H1; assumption.
Qed.
Lemma Rplus_eq_R0 :
@@ -1529,7 +1529,7 @@ Qed.
Lemma Rinv_1_lt_contravar : forall r1 r2, 1 <= r1 -> r1 < r2 -> / r2 < / r1.
Proof.
- intros x y H' H'0.
+ intros x y H' H'0.
cut (0 < x); [ intros Lt0 | apply Rlt_le_trans with (r2 := 1) ];
auto with real.
apply Rmult_lt_reg_l with (r := x); auto with real.
@@ -1753,11 +1753,11 @@ 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.
+ { 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.
+ apply Rmult_1_r. }
intros [p|p|] ; unfold IPR.
rewrite Pos2Nat.inj_xI, S_INR, mult_INR, <- H.
apply Rplus_comm.
@@ -1830,12 +1830,12 @@ Qed.
Lemma pow_IZR : forall z n, pow (IZR z) n = IZR (Z.pow z (Z.of_nat n)).
Proof.
- intros z [|n];simpl;trivial.
- rewrite Zpower_pos_nat.
- rewrite SuccNat2Pos.id_succ. unfold Zpower_nat;simpl.
- rewrite mult_IZR.
- induction n;simpl;trivial.
- rewrite mult_IZR;ring[IHn].
+ intros z [|n];simpl;trivial.
+ rewrite Zpower_pos_nat.
+ rewrite SuccNat2Pos.id_succ. unfold Zpower_nat;simpl.
+ rewrite mult_IZR.
+ induction n;simpl;trivial.
+ rewrite mult_IZR;ring[IHn].
Qed.
(**********)
@@ -2043,7 +2043,7 @@ Proof.
Qed.
Lemma Ropp_div : forall x y, -x/y = - (x / y).
-intros x y; unfold Rdiv; ring.
+ intros x y; unfold Rdiv; ring.
Qed.
Lemma Ropp_div_den : forall x y : R, y<>0 -> x / - y = - (x / y).
@@ -2068,22 +2068,22 @@ Lemma R_rm : ring_morph
0%R 1%R Rplus Rmult Rminus Ropp eq
0%Z 1%Z Zplus Zmult Zminus Z.opp 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.
+ 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.
+ intros H.
+ apply Zeq_is_eq_bool.
+ now apply eq_IZR.
Qed.
Add Field RField : Rfield
@@ -2127,15 +2127,15 @@ Qed.
Lemma Rdiv_lt_0_compat : forall a b, 0 < a -> 0 < b -> 0 < a/b.
Proof.
-intros; apply Rmult_lt_0_compat;[|apply Rinv_0_lt_compat]; assumption.
+ intros; apply Rmult_lt_0_compat;[|apply Rinv_0_lt_compat]; assumption.
Qed.
Lemma Rdiv_plus_distr : forall a b c, (a + b)/c = a/c + b/c.
-intros a b c; apply Rmult_plus_distr_r.
+ intros a b c; apply Rmult_plus_distr_r.
Qed.
Lemma Rdiv_minus_distr : forall a b c, (a - b)/c = a/c - b/c.
-intros a b c; unfold Rminus, Rdiv; rewrite Rmult_plus_distr_r; ring.
+ intros a b c; unfold Rminus, Rdiv; rewrite Rmult_plus_distr_r; ring.
Qed.
(* A test for equality function. *)
diff --git a/theories/micromega/Zify.v b/theories/micromega/Zify.v
index 183fd6a914..01cc9ad810 100644
--- a/theories/micromega/Zify.v
+++ b/theories/micromega/Zify.v
@@ -16,11 +16,22 @@ Ltac zify_pre_hook := idtac.
Ltac zify_post_hook := idtac.
-Ltac iter_specs := zify_iter_specs.
+Ltac zify_convert_to_euclidean_division_equations_flag := constr:(false).
+
+(** [zify_internal_to_euclidean_division_equations] is bound in [PreOmega] *)
+Ltac zify_internal_to_euclidean_division_equations := idtac.
+
+Ltac zify_to_euclidean_division_equations :=
+ lazymatch zify_convert_to_euclidean_division_equations_flag with
+ | true => zify_internal_to_euclidean_division_equations
+ | false => idtac
+ end.
+
Ltac zify := intros;
zify_pre_hook ;
zify_elim_let ;
zify_op ;
(zify_iter_specs) ;
- zify_saturate ; zify_post_hook.
+ zify_saturate ;
+ zify_to_euclidean_division_equations ; zify_post_hook.
diff --git a/theories/micromega/ZifyInt63.v b/theories/micromega/ZifyInt63.v
new file mode 100644
index 0000000000..27845898aa
--- /dev/null
+++ b/theories/micromega/ZifyInt63.v
@@ -0,0 +1,178 @@
+Require Import ZArith.
+Require Import Int63.
+Require Import ZifyBool.
+Import ZifyClasses.
+
+Lemma to_Z_bounded : forall x, (0 <= to_Z x < 9223372036854775808)%Z.
+Proof. apply to_Z_bounded. Qed.
+
+Instance Inj_int_Z : InjTyp int Z :=
+ mkinj _ _ to_Z (fun x => 0 <= x < 9223372036854775808)%Z to_Z_bounded.
+Add Zify InjTyp Inj_int_Z.
+
+Instance Op_max_int : CstOp max_int :=
+ { TCst := 9223372036854775807 ; TCstInj := eq_refl }.
+Add Zify CstOp Op_max_int.
+
+Instance Op_digits : CstOp digits :=
+ { TCst := 63 ; TCstInj := eq_refl }.
+Add Zify CstOp Op_digits.
+
+Instance Op_size : CstOp size :=
+ { TCst := 63 ; TCstInj := eq_refl }.
+Add Zify CstOp Op_size.
+
+Instance Op_wB : CstOp wB :=
+ { TCst := 2^63 ; TCstInj := eq_refl }.
+Add Zify CstOp Op_wB.
+
+Lemma ltb_lt : forall n m,
+ (n <? m)%int63 = (φ (n)%int63 <? φ (m)%int63)%Z.
+Proof.
+ intros. apply Bool.eq_true_iff_eq.
+ rewrite ltb_spec. rewrite <- Z.ltb_lt.
+ apply iff_refl.
+Qed.
+
+Instance Op_ltb : BinOp ltb :=
+ {| TBOp := Z.ltb; TBOpInj := ltb_lt |}.
+Add Zify BinOp Op_ltb.
+
+Lemma leb_le : forall n m,
+ (n <=? m)%int63 = (φ (n)%int63 <=? φ (m)%int63)%Z.
+Proof.
+ intros. apply Bool.eq_true_iff_eq.
+ rewrite leb_spec. rewrite <- Z.leb_le.
+ apply iff_refl.
+Qed.
+
+Instance Op_leb : BinOp leb :=
+ {| TBOp := Z.leb; TBOpInj := leb_le |}.
+Add Zify BinOp Op_leb.
+
+Lemma eqb_eq : forall n m,
+ (n =? m)%int63 = (φ (n)%int63 =? φ (m)%int63)%Z.
+Proof.
+ intros. apply Bool.eq_true_iff_eq.
+ rewrite eqb_spec. rewrite Z.eqb_eq.
+ split ; intro H.
+ now subst; reflexivity.
+ now apply to_Z_inj in H.
+Qed.
+
+Instance Op_eqb : BinOp eqb :=
+ {| TBOp := Z.eqb; TBOpInj := eqb_eq |}.
+Add Zify BinOp Op_eqb.
+
+Lemma eq_int_inj : forall n m : int, n = m <-> (φ n = φ m)%int63.
+Proof.
+ split; intro H.
+ rewrite H ; reflexivity.
+ apply to_Z_inj; auto.
+Qed.
+
+Instance Op_eq : BinRel (@eq int) :=
+ {| TR := @eq Z; TRInj := eq_int_inj |}.
+Add Zify BinRel Op_eq.
+
+Instance Op_add : BinOp add :=
+ {| TBOp := fun x y => (x + y) mod 9223372036854775808%Z; TBOpInj := add_spec |}%Z.
+Add Zify BinOp Op_add.
+
+Instance Op_sub : BinOp sub :=
+ {| TBOp := fun x y => (x - y) mod 9223372036854775808%Z; TBOpInj := sub_spec |}%Z.
+Add Zify BinOp Op_sub.
+
+Instance Op_opp : UnOp Int63.opp :=
+ {| TUOp := (fun x => (- x) mod 9223372036854775808)%Z; TUOpInj := (sub_spec 0) |}%Z.
+Add Zify UnOp Op_opp.
+
+Instance Op_oppcarry : UnOp oppcarry :=
+ {| TUOp := (fun x => 2^63 - x - 1)%Z; TUOpInj := oppcarry_spec |}%Z.
+Add Zify UnOp Op_oppcarry.
+
+Instance Op_succ : UnOp succ :=
+ {| TUOp := (fun x => (x + 1) mod 2^63)%Z; TUOpInj := succ_spec |}%Z.
+Add Zify UnOp Op_succ.
+
+Instance Op_pred : UnOp Int63.pred :=
+ {| TUOp := (fun x => (x - 1) mod 2^63)%Z; TUOpInj := pred_spec |}%Z.
+Add Zify UnOp Op_pred.
+
+Instance Op_mul : BinOp mul :=
+ {| TBOp := fun x y => (x * y) mod 9223372036854775808%Z; TBOpInj := mul_spec |}%Z.
+Add Zify BinOp Op_mul.
+
+Instance Op_gcd : BinOp gcd:=
+ {| TBOp := (fun x y => Zgcd_alt.Zgcdn (2 * 63)%nat y x) ; TBOpInj := to_Z_gcd |}.
+Add Zify BinOp Op_gcd.
+
+Instance Op_mod : BinOp Int63.mod :=
+ {| TBOp := Z.modulo ; TBOpInj := mod_spec |}.
+Add Zify BinOp Op_mod.
+
+Instance Op_subcarry : BinOp subcarry :=
+ {| TBOp := (fun x y => (x - y - 1) mod 2^63)%Z ; TBOpInj := subcarry_spec |}.
+Add Zify BinOp Op_subcarry.
+
+Instance Op_addcarry : BinOp addcarry :=
+ {| TBOp := (fun x y => (x + y + 1) mod 2^63)%Z ; TBOpInj := addcarry_spec |}.
+Add Zify BinOp Op_addcarry.
+
+Instance Op_lsr : BinOp lsr :=
+ {| TBOp := (fun x y => x / 2^ y)%Z ; TBOpInj := lsr_spec |}.
+Add Zify BinOp Op_lsr.
+
+Instance Op_lsl : BinOp lsl :=
+ {| TBOp := (fun x y => (x * 2^ y) mod 2^ 63)%Z ; TBOpInj := lsl_spec |}.
+Add Zify BinOp Op_lsl.
+
+Instance Op_lor : BinOp Int63.lor :=
+ {| TBOp := Z.lor ; TBOpInj := lor_spec' |}.
+Add Zify BinOp Op_lor.
+
+Instance Op_land : BinOp Int63.land :=
+ {| TBOp := Z.land ; TBOpInj := land_spec' |}.
+Add Zify BinOp Op_land.
+
+Instance Op_lxor : BinOp Int63.lxor :=
+ {| TBOp := Z.lxor ; TBOpInj := lxor_spec' |}.
+Add Zify BinOp Op_lxor.
+
+Instance Op_div : BinOp div :=
+ {| TBOp := Z.div ; TBOpInj := div_spec |}.
+Add Zify BinOp Op_div.
+
+Instance Op_bit : BinOp bit :=
+ {| TBOp := Z.testbit ; TBOpInj := bitE |}.
+Add Zify BinOp Op_bit.
+
+Instance Op_of_Z : UnOp of_Z :=
+ { TUOp := (fun x => x mod 9223372036854775808)%Z; TUOpInj := of_Z_spec }.
+Add Zify UnOp Op_of_Z.
+
+Instance Op_to_Z : UnOp to_Z :=
+ { TUOp := fun x => x ; TUOpInj := fun x : int => eq_refl }.
+Add Zify UnOp Op_to_Z.
+
+Instance Op_is_zero : UnOp is_zero :=
+ { TUOp := (Z.eqb 0) ; TUOpInj := is_zeroE }.
+Add Zify UnOp Op_is_zero.
+
+Lemma is_evenE : forall x,
+ is_even x = Z.even φ (x)%int63.
+Proof.
+ intros.
+ generalize (is_even_spec x).
+ rewrite Z_evenE.
+ destruct (is_even x).
+ symmetry. apply Z.eqb_eq. auto.
+ symmetry. apply Z.eqb_neq. congruence.
+Qed.
+
+Instance Op_is_even : UnOp is_even :=
+ { TUOp := Z.even ; TUOpInj := is_evenE }.
+Add Zify UnOp Op_is_even.
+
+
+Ltac Zify.zify_convert_to_euclidean_division_equations_flag ::= constr:(true).
diff --git a/theories/omega/PreOmega.v b/theories/omega/PreOmega.v
index 506a4108ee..70f25e7243 100644
--- a/theories/omega/PreOmega.v
+++ b/theories/omega/PreOmega.v
@@ -573,4 +573,6 @@ Ltac zify_N := repeat zify_N_rel; repeat zify_N_op; unfold Z_of_N' in *.
Require Import ZifyClasses ZifyInst.
Require Zify.
+Ltac Zify.zify_internal_to_euclidean_division_equations ::= Z.to_euclidean_division_equations.
+
Ltac zify := Zify.zify.
diff --git a/theories/ssr/ssrbool.v b/theories/ssr/ssrbool.v
index f35da63fd6..e8a036bbb0 100644
--- a/theories/ssr/ssrbool.v
+++ b/theories/ssr/ssrbool.v
@@ -1401,8 +1401,8 @@ Definition mem T (pT : predType T) : pT -> mem_pred T :=
let: PredType toP := pT in fun A => Mem [eta toP A].
Arguments mem {T pT} A : rename, simpl never.
-Notation "x \in A" := (in_mem x (mem A)) : bool_scope.
-Notation "x \in A" := (in_mem x (mem A)) : bool_scope.
+Notation "x \in A" := (in_mem x (mem A)) (only parsing) : bool_scope.
+Notation "x \in A" := (in_mem x (mem A)) (only printing) : bool_scope.
Notation "x \notin A" := (~~ (x \in A)) : bool_scope.
Notation "A =i B" := (eq_mem (mem A) (mem B)) : type_scope.
Notation "{ 'subset' A <= B }" := (sub_mem (mem A) (mem B)) : type_scope.
@@ -1573,9 +1573,12 @@ Arguments has_quality n {T}.
Lemma qualifE n T p x : (x \in @Qualifier n T p) = p x. Proof. by []. Qed.
-Notation "x \is A" := (x \in has_quality 0 A) : bool_scope.
-Notation "x \is 'a' A" := (x \in has_quality 1 A) : bool_scope.
-Notation "x \is 'an' A" := (x \in has_quality 2 A) : bool_scope.
+Notation "x \is A" := (x \in has_quality 0 A) (only parsing) : bool_scope.
+Notation "x \is A" := (x \in has_quality 0 A) (only printing) : bool_scope.
+Notation "x \is 'a' A" := (x \in has_quality 1 A) (only parsing) : bool_scope.
+Notation "x \is 'a' A" := (x \in has_quality 1 A) (only printing) : bool_scope.
+Notation "x \is 'an' A" := (x \in has_quality 2 A) (only parsing) : bool_scope.
+Notation "x \is 'an' A" := (x \in has_quality 2 A) (only printing) : bool_scope.
Notation "x \isn't A" := (x \notin has_quality 0 A) : bool_scope.
Notation "x \isn't 'a' A" := (x \notin has_quality 1 A) : bool_scope.
Notation "x \isn't 'an' A" := (x \notin has_quality 2 A) : bool_scope.
diff --git a/topbin/coqtacticworker_bin.ml b/topbin/coqtacticworker_bin.ml
index 252c8faa05..706554e025 100644
--- a/topbin/coqtacticworker_bin.ml
+++ b/topbin/coqtacticworker_bin.ml
@@ -8,6 +8,6 @@
(* * (see LICENSE file for the text of the license) *)
(************************************************************************)
-module W = AsyncTaskQueue.MakeWorker(Stm.TacTask) ()
+module W = AsyncTaskQueue.MakeWorker(Partac.TacTask) ()
let () = WorkerLoop.start ~init:W.init_stdout ~loop:W.main_loop "coqtacticworker"
diff --git a/toplevel/coqargs.ml b/toplevel/coqargs.ml
index eb386ea3e8..d587e57fd8 100644
--- a/toplevel/coqargs.ml
+++ b/toplevel/coqargs.ml
@@ -508,6 +508,7 @@ let parse_args ~help ~init arglist : t * string list =
|"-color" -> set_color oval (next ())
|"-config"|"--config" -> set_query oval PrintConfig
|"-debug" -> Coqinit.set_debug (); oval
+ |"-xml-debug" -> Flags.xml_debug := true; Coqinit.set_debug (); oval
|"-diffs" ->
add_set_option oval Proof_diffs.opt_name @@ Stm.OptionSet (Some (next ()))
|"-stm-debug" -> Stm.stm_debug := true; oval
diff --git a/toplevel/coqloop.ml b/toplevel/coqloop.ml
index 88924160ff..6460378edc 100644
--- a/toplevel/coqloop.ml
+++ b/toplevel/coqloop.ml
@@ -371,41 +371,13 @@ let exit_on_error =
declare_bool_option_and_ref ~depr:false ~key:["Coqtop";"Exit";"On";"Error"]
~value:false
-(* XXX: This is duplicated with Vernacentries.show_proof , at some
- point we should consolidate the code *)
-let show_proof_diff_to_pp pstate =
- let p = Option.get pstate in
- let sigma, env = Proof.get_proof_context p in
- let pprf = Proof.partial_proof p in
- Pp.prlist_with_sep Pp.fnl (Printer.pr_econstr_env env sigma) pprf
-
-let show_proof_diff_cmd ~state removed =
+let show_proof_diff_cmd ~state diff_opt =
let open Vernac.State in
- try
- let n_pp = show_proof_diff_to_pp state.proof in
- if true (*Proof_diffs.show_diffs ()*) then
- let doc = state.doc in
- let oproof = Stm.get_prev_proof ~doc (Stm.get_current_state ~doc) in
- try
- let o_pp = show_proof_diff_to_pp oproof in
- let tokenize_string = Proof_diffs.tokenize_string in
- let show_removed = Some removed in
- Pp_diff.diff_pp_combined ~tokenize_string ?show_removed o_pp n_pp
- with
- | Proof.NoSuchGoal _
- | Option.IsNone -> n_pp
- | Pp_diff.Diff_Failure msg -> begin
- (* todo: print the unparsable string (if we know it) *)
- Feedback.msg_warning Pp.(str ("Diff failure: " ^ msg) ++ cut()
- ++ str "Showing results without diff highlighting" );
- n_pp
- end
- else
- n_pp
- with
- | Proof.NoSuchGoal _
- | Option.IsNone ->
- CErrors.user_err (str "No goals to show.")
+ match state.proof with
+ | None -> CErrors.user_err (str "No proofs to diff.")
+ | Some proof ->
+ let old = Stm.get_prev_proof ~doc:state.doc state.sid in
+ Proof_diffs.diff_proofs ~diff_opt ?old proof
let process_toplevel_command ~state stm =
let open Vernac.State in
@@ -444,12 +416,12 @@ let process_toplevel_command ~state stm =
Feedback.msg_notice (v 0 (goal ++ evars));
state
- | VernacShowProofDiffs removed ->
+ | VernacShowProofDiffs diff_opt ->
(* We print nothing if there are no goals left *)
if not (Proof_diffs.color_enabled ()) then
CErrors.user_err Pp.(str "Show Proof Diffs requires setting the \"-color\" command line argument to \"on\" or \"auto\".")
else
- let out = show_proof_diff_cmd ~state removed in
+ let out = show_proof_diff_cmd ~state diff_opt in
Feedback.msg_notice out;
state
diff --git a/toplevel/g_toplevel.mlg b/toplevel/g_toplevel.mlg
index 1902103a3e..ef79f4562e 100644
--- a/toplevel/g_toplevel.mlg
+++ b/toplevel/g_toplevel.mlg
@@ -20,7 +20,7 @@ type vernac_toplevel =
| VernacQuit
| VernacControl of vernac_control
| VernacShowGoal of { gid : int; sid: int }
- | VernacShowProofDiffs of bool
+ | VernacShowProofDiffs of Proof_diffs.diffOpt
module Toplevel_ : sig
val vernac_toplevel : vernac_toplevel option Entry.t
@@ -52,7 +52,8 @@ GRAMMAR EXTEND Gram
| test_show_goal; IDENT "Show"; IDENT "Goal"; gid = natural; IDENT "at"; sid = natural; "." ->
{ Some (VernacShowGoal {gid; sid}) }
| IDENT "Show"; IDENT "Proof"; IDENT "Diffs"; removed = OPT [ IDENT "removed" -> { () } ]; "." ->
- { Some (VernacShowProofDiffs (removed <> None)) }
+ { Some (VernacShowProofDiffs
+ (if removed = None then Proof_diffs.DiffOn else Proof_diffs.DiffRemoved)) }
| cmd = Pvernac.Vernac_.main_entry ->
{ match cmd with
| None -> None
diff --git a/toplevel/usage.ml b/toplevel/usage.ml
index 732ad05b26..6fb5f821ee 100644
--- a/toplevel/usage.ml
+++ b/toplevel/usage.ml
@@ -72,6 +72,7 @@ let print_usage_common co command =
\n -init-file f set the rcfile to f\
\n -bt print backtraces (requires configure debug flag)\
\n -debug debug mode (implies -bt)\
+\n -xml-debug debug mode and print XML messages to/from coqide\
\n -diffs (on|off|removed) highlight differences between proof steps\
\n -stm-debug STM debug mode (will trace every transaction)\
\n -noglob do not dump globalizations\
diff --git a/user-contrib/Ltac2/tac2quote.ml b/user-contrib/Ltac2/tac2quote.ml
index b346b3ee5c..90f8008dc2 100644
--- a/user-contrib/Ltac2/tac2quote.ml
+++ b/user-contrib/Ltac2/tac2quote.ml
@@ -229,7 +229,7 @@ let check_pattern_id ?loc id =
let pattern_vars pat =
let rec aux () accu pat = match pat.CAst.v with
| Constrexpr.CPatVar id
- | Constrexpr.CEvar (id, []) ->
+ | Constrexpr.CEvar ({CAst.v=id}, []) ->
let loc = pat.CAst.loc in
let () = check_pattern_id ?loc id in
Id.Map.add id loc accu
diff --git a/vernac/comAssumption.ml b/vernac/comAssumption.ml
index 401ba0fba4..12194ea20c 100644
--- a/vernac/comAssumption.ml
+++ b/vernac/comAssumption.ml
@@ -68,10 +68,12 @@ let declare_axiom is_coe ~poly ~local ~kind typ (univs, pl) imps nl {CAst.v=name
let inst = instance_of_univ_entry univs in
(gr,inst)
-let interp_assumption ~program_mode sigma env impls c =
+let interp_assumption ~program_mode env sigma impl_env bl c =
let flags = { Pretyping.all_no_fail_flags with program_mode } in
- let sigma, (ty, impls) = interp_type_evars_impls ~flags env sigma ~impls c in
- sigma, (ty, impls)
+ let sigma, (impls, ((env_bl, ctx), impls1)) = interp_context_evars ~program_mode ~impl_env env sigma bl in
+ let sigma, (ty, impls2) = interp_type_evars_impls ~flags env_bl sigma ~impls c in
+ let ty = EConstr.it_mkProd_or_LetIn ty ctx in
+ sigma, ty, impls1@impls2
(* When monomorphic the universe constraints and universe names are
declared with the first declaration only. *)
@@ -153,7 +155,7 @@ let do_assumptions ~program_mode ~poly ~scope ~kind nl l =
in
(* We interpret all declarations in the same evar_map, i.e. as a telescope. *)
let (sigma,_,_),l = List.fold_left_map (fun (sigma,env,ienv) (is_coe,(idl,c)) ->
- let sigma,(t,imps) = interp_assumption ~program_mode sigma env ienv c in
+ let sigma,t,imps = interp_assumption ~program_mode env sigma ienv [] c in
let r = Retyping.relevance_of_type env sigma t in
let env =
EConstr.push_named_context (List.map (fun {CAst.v=id} -> LocalAssum (make_annot id r,t)) idl) env in
diff --git a/vernac/comAssumption.mli b/vernac/comAssumption.mli
index 3d425ad768..64b8212b90 100644
--- a/vernac/comAssumption.mli
+++ b/vernac/comAssumption.mli
@@ -14,6 +14,15 @@ open Constrexpr
(** {6 Parameters/Assumptions} *)
+val interp_assumption
+ : program_mode:bool
+ -> Environ.env
+ -> Evd.evar_map
+ -> Constrintern.internalization_env
+ -> Constrexpr.local_binder_expr list
+ -> constr_expr
+ -> Evd.evar_map * EConstr.t * Impargs.manual_implicits
+
val do_assumptions
: program_mode:bool
-> poly:bool
diff --git a/vernac/comDefinition.ml b/vernac/comDefinition.ml
index 37b7106856..c1dbf0a1ea 100644
--- a/vernac/comDefinition.ml
+++ b/vernac/comDefinition.ml
@@ -81,14 +81,11 @@ let protect_pattern_in_binder bl c ctypopt =
else
(bl, c, ctypopt, fun f env evd c -> f env evd c)
-let interp_definition ~program_mode pl bl ~poly red_option c ctypopt =
+let interp_definition ~program_mode env evd impl_env bl red_option c ctypopt =
let flags = Pretyping.{ all_no_fail_flags with program_mode } in
- let env = Global.env() in
- (* Explicitly bound universes and constraints *)
- let evd, udecl = Constrexpr_ops.interp_univ_decl_opt env pl in
let (bl, c, ctypopt, apply_under_binders) = protect_pattern_in_binder bl c ctypopt in
(* Build the parameters *)
- let evd, (impls, ((env_bl, ctx), imps1)) = interp_context_evars ~program_mode env evd bl in
+ let evd, (impls, ((env_bl, ctx), imps1)) = interp_context_evars ~program_mode ~impl_env env evd bl in
(* Build the type *)
let evd, tyopt = Option.fold_left_map
(interp_type_evars_impls ~flags ~impls env_bl)
@@ -111,12 +108,15 @@ let interp_definition ~program_mode pl bl ~poly red_option c ctypopt =
(* Declare the definition *)
let c = EConstr.it_mkLambda_or_LetIn c ctx in
let tyopt = Option.map (fun ty -> EConstr.it_mkProd_or_LetIn ty ctx) tyopt in
- (c, tyopt), evd, udecl, imps
+ evd, (c, tyopt), imps
let do_definition ?hook ~name ~scope ~poly ~kind udecl bl red_option c ctypopt =
let program_mode = false in
- let (body, types), evd, udecl, impargs =
- interp_definition ~program_mode udecl bl ~poly red_option c ctypopt
+ let env = Global.env() in
+ (* Explicitly bound universes and constraints *)
+ let evd, udecl = Constrexpr_ops.interp_univ_decl_opt env udecl in
+ let evd, (body, types), impargs =
+ interp_definition ~program_mode env evd empty_internalization_env bl red_option c ctypopt
in
let kind = Decls.IsDefinition kind in
let cinfo = Declare.CInfo.make ~name ~impargs ~typ:types () in
@@ -127,8 +127,11 @@ let do_definition ?hook ~name ~scope ~poly ~kind udecl bl red_option c ctypopt =
let do_definition_program ?hook ~pm ~name ~scope ~poly ~kind udecl bl red_option c ctypopt =
let program_mode = true in
- let (body, types), evd, udecl, impargs =
- interp_definition ~program_mode udecl bl ~poly red_option c ctypopt
+ let env = Global.env() in
+ (* Explicitly bound universes and constraints *)
+ let evd, udecl = Constrexpr_ops.interp_univ_decl_opt env udecl in
+ let evd, (body, types), impargs =
+ interp_definition ~program_mode env evd empty_internalization_env bl red_option c ctypopt
in
let term, typ, uctx, obls = Declare.Obls.prepare_obligation ~name ~body ~types evd in
let pm, _ =
diff --git a/vernac/comDefinition.mli b/vernac/comDefinition.mli
index d95e64a85f..7420235449 100644
--- a/vernac/comDefinition.mli
+++ b/vernac/comDefinition.mli
@@ -14,6 +14,17 @@ open Constrexpr
(** {6 Definitions/Let} *)
+val interp_definition
+ : program_mode:bool
+ -> Environ.env
+ -> Evd.evar_map
+ -> Constrintern.internalization_env
+ -> Constrexpr.local_binder_expr list
+ -> red_expr option
+ -> constr_expr
+ -> constr_expr option
+ -> Evd.evar_map * (EConstr.t * EConstr.t option) * Impargs.manual_implicits
+
val do_definition
: ?hook:Declare.Hook.t
-> name:Id.t
diff --git a/vernac/comTactic.ml b/vernac/comTactic.ml
new file mode 100644
index 0000000000..8a9a412362
--- /dev/null
+++ b/vernac/comTactic.ml
@@ -0,0 +1,82 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * Copyright INRIA, CNRS and contributors *)
+(* <O___,, * (see version control and CREDITS file for authors & dates) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+open Goptions
+
+module Dyn = Dyn.Make()
+
+module DMap = Dyn.Map(struct type 'a t = 'a -> unit Proofview.tactic end)
+
+let interp_map = ref DMap.empty
+
+type 'a tactic_interpreter = 'a Dyn.tag
+type interpretable = I : 'a tactic_interpreter * 'a -> interpretable
+
+let register_tactic_interpreter na f =
+ let t = Dyn.create na in
+ interp_map := DMap.add t f !interp_map;
+ t
+
+let interp_tac (I (tag,t)) =
+ let f = DMap.find tag !interp_map in
+ f t
+
+type parallel_solver =
+ pstate:Declare.Proof.t ->
+ info:int option ->
+ interpretable ->
+ abstract:bool ->
+ with_end_tac:bool ->
+ Declare.Proof.t
+
+let print_info_trace =
+ declare_intopt_option_and_ref ~depr:false ~key:["Info" ; "Level"]
+
+let solve_core ~pstate n ~info t ~with_end_tac:b =
+ let pstate, status = Declare.Proof.map_fold_endline ~f:(fun etac p ->
+ let with_end_tac = if b then Some etac else None in
+ let info = Option.append info (print_info_trace ()) in
+ let (p,status) = Proof.solve n info t ?with_end_tac p in
+ (* in case a strict subtree was completed,
+ go back to the top of the prooftree *)
+ let p = Proof.maximal_unfocus Vernacentries.command_focus p in
+ p,status) pstate in
+ if not status then Feedback.feedback Feedback.AddedAxiom;
+ pstate
+
+let solve ~pstate n ~info t ~with_end_tac =
+ let t = interp_tac t in
+ solve_core ~pstate n ~info t ~with_end_tac
+
+let check_par_applicable pstate =
+ Declare.Proof.fold pstate ~f:(fun p ->
+ (Proof.data p).Proof.goals |> List.iter (fun goal ->
+ let is_ground =
+ let { Proof.sigma = sigma0 } = Declare.Proof.fold pstate ~f:Proof.data in
+ let g = Evd.find sigma0 goal in
+ let concl, hyps = Evd.evar_concl g, Evd.evar_context g in
+ Evarutil.is_ground_term sigma0 concl &&
+ List.for_all (Context.Named.Declaration.for_all (Evarutil.is_ground_term sigma0)) hyps in
+ if not is_ground then
+ CErrors.user_err
+ Pp.(strbrk("The par: goal selector does not support goals with existential variables"))))
+
+let par_implementation = ref (fun ~pstate ~info t ~abstract ~with_end_tac ->
+ let t = interp_tac t in
+ let t = Proofview.Goal.enter (fun _ ->
+ if abstract then Abstract.tclABSTRACT None ~opaque:true t else t)
+ in
+ solve_core ~pstate Goal_select.SelectAll ~info t ~with_end_tac)
+
+let set_par_implementation f = par_implementation := f
+
+let solve_parallel ~pstate ~info t ~abstract ~with_end_tac =
+ check_par_applicable pstate;
+ !par_implementation ~pstate ~info t ~abstract ~with_end_tac
diff --git a/vernac/comTactic.mli b/vernac/comTactic.mli
new file mode 100644
index 0000000000..f1a75e1b6a
--- /dev/null
+++ b/vernac/comTactic.mli
@@ -0,0 +1,47 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * Copyright INRIA, CNRS and contributors *)
+(* <O___,, * (see version control and CREDITS file for authors & dates) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+(** Tactic interpreters have to register their interpretation function *)
+type 'a tactic_interpreter
+type interpretable = I : 'a tactic_interpreter * 'a -> interpretable
+
+(** ['a] should be marshallable if ever used with [par:] *)
+val register_tactic_interpreter :
+ string -> ('a -> unit Proofview.tactic) -> 'a tactic_interpreter
+
+(** Entry point for toplevel tactic expression execution. It calls Proof.solve
+ after having interpreted the tactic, and after the tactic runs it
+ unfocus as much as needed to put a goal under focus. *)
+val solve :
+ pstate:Declare.Proof.t ->
+ Goal_select.t ->
+ info:int option ->
+ interpretable ->
+ with_end_tac:bool ->
+ Declare.Proof.t
+
+(** [par: tac] runs tac on all goals, possibly in parallel using a worker pool.
+ If tac is [abstract tac1], then [abstract] is passed
+ explicitly to the solver and [tac1] passed to worker since it is up to
+ master to opacify the sub proofs produced by the workers. *)
+type parallel_solver =
+ pstate:Declare.Proof.t ->
+ info:int option ->
+ interpretable ->
+ abstract:bool -> (* the tactic result has to be opacified as per abstract *)
+ with_end_tac:bool ->
+ Declare.Proof.t
+
+(** Entry point when the goal selector is par: *)
+val solve_parallel : parallel_solver
+
+(** By default par: is implemented with all: (sequential).
+ The STM and LSP document manager provide "more parallel" implementations *)
+val set_par_implementation : parallel_solver -> unit
diff --git a/vernac/declare.ml b/vernac/declare.ml
index ae7878b615..5274a6da3b 100644
--- a/vernac/declare.ml
+++ b/vernac/declare.ml
@@ -1854,7 +1854,8 @@ module MutualEntry : sig
val declare_variable
: pinfo:Proof_info.t
-> uctx:UState.t
- -> Entries.parameter_entry
+ -> sec_vars:Id.Set.t option
+ -> univs:Entries.universes_entry
-> Names.GlobRef.t list
val declare_mutdef
@@ -1920,10 +1921,11 @@ end = struct
in
List.map_i (declare_mutdef ~pinfo ~uctx pe) 0 pinfo.Proof_info.cinfo
- let declare_variable ~pinfo ~uctx pe =
+ let declare_variable ~pinfo ~uctx ~sec_vars ~univs =
let { Info.scope; hook } = pinfo.Proof_info.info in
List.map_i (
fun i { CInfo.name; typ; impargs } ->
+ let pe = (sec_vars, (typ, univs), None) in
declare_assumption ~name ~scope ~hook ~impargs ~uctx pe
) 0 pinfo.Proof_info.cinfo
@@ -1953,8 +1955,8 @@ let compute_proof_using_for_admitted proof typ pproofs =
Some (Environ.really_needed env (Id.Set.union ids_typ ids_def))
| _ -> None
-let finish_admitted ~pm ~pinfo ~uctx pe =
- let cst = MutualEntry.declare_variable ~pinfo ~uctx pe in
+let finish_admitted ~pm ~pinfo ~uctx ~sec_vars ~univs =
+ let cst = MutualEntry.declare_variable ~pinfo ~uctx ~sec_vars ~univs in
(* If the constant was an obligation we need to update the program map *)
match CEphemeron.get pinfo.Proof_info.proof_ending with
| Proof_ending.End_obligation oinfo ->
@@ -1974,7 +1976,7 @@ let save_admitted ~pm ~proof =
let sec_vars = compute_proof_using_for_admitted proof typ pproofs in
let uctx = get_initial_euctx proof in
let univs = UState.check_univ_decl ~poly uctx udecl in
- finish_admitted ~pm ~pinfo:proof.pinfo ~uctx (sec_vars, (typ, univs), None)
+ finish_admitted ~pm ~pinfo:proof.pinfo ~uctx ~sec_vars ~univs
(************************************************************************)
(* Saving a lemma-like constant *)
@@ -2097,12 +2099,9 @@ let save_lemma_admitted_delayed ~pm ~proof ~pinfo =
let poly = match proof_entry_universes with
| Entries.Monomorphic_entry _ -> false
| Entries.Polymorphic_entry (_, _) -> true in
- let typ = match proof_entry_type with
- | None -> CErrors.user_err Pp.(str "Admitted requires an explicit statement");
- | Some typ -> typ in
- let ctx = UState.univ_entry ~poly uctx in
+ let univs = UState.univ_entry ~poly uctx in
let sec_vars = if get_keep_admitted_vars () then proof_entry_secctx else None in
- finish_admitted ~pm ~uctx ~pinfo (sec_vars, (typ, ctx), None)
+ finish_admitted ~pm ~uctx ~pinfo ~sec_vars ~univs
let save_lemma_proved_delayed ~pm ~proof ~pinfo ~idopt =
(* vio2vo calls this but with invalid info, we have to workaround
diff --git a/vernac/g_vernac.mlg b/vernac/g_vernac.mlg
index 831aeff6a0..dfc7b05b51 100644
--- a/vernac/g_vernac.mlg
+++ b/vernac/g_vernac.mlg
@@ -429,19 +429,19 @@ GRAMMAR EXTEND Gram
;
record_binder_body:
[ [ l = binders; oc = of_type_with_opt_coercion;
- t = lconstr -> { fun id -> (oc,AssumExpr (id,mkProdCN ~loc l t)) }
+ t = lconstr -> { fun id -> (oc,AssumExpr (id,l,t)) }
| l = binders; oc = of_type_with_opt_coercion;
t = lconstr; ":="; b = lconstr -> { fun id ->
- (oc,DefExpr (id,mkLambdaCN ~loc l b,Some (mkProdCN ~loc l t))) }
+ (oc,DefExpr (id,l,b,Some t)) }
| l = binders; ":="; b = lconstr -> { fun id ->
match b.CAst.v with
| CCast(b', (CastConv t|CastVM t|CastNative t)) ->
- (None,DefExpr(id,mkLambdaCN ~loc l b',Some (mkProdCN ~loc l t)))
+ (NoInstance,DefExpr(id,l,b',Some t))
| _ ->
- (None,DefExpr(id,mkLambdaCN ~loc l b,None)) } ] ]
+ (NoInstance,DefExpr(id,l,b,None)) } ] ]
;
record_binder:
- [ [ id = name -> { (None,AssumExpr(id, CAst.make ~loc @@ CHole (None, IntroAnonymous, None))) }
+ [ [ id = name -> { (NoInstance,AssumExpr(id, [], CAst.make ~loc @@ CHole (None, IntroAnonymous, None))) }
| id = name; f = record_binder_body -> { f id } ] ]
;
assum_list:
@@ -452,13 +452,13 @@ GRAMMAR EXTEND Gram
;
simple_assum_coe:
[ [ idl = LIST1 ident_decl; oc = of_type_with_opt_coercion; c = lconstr ->
- { (not (Option.is_empty oc),(idl,c)) } ] ]
+ { (oc <> NoInstance,(idl,c)) } ] ]
;
constructor_type:
[[ l = binders;
t= [ coe = of_type_with_opt_coercion; c = lconstr ->
- { fun l id -> (not (Option.is_empty coe),(id,mkProdCN ~loc l c)) }
+ { fun l id -> (coe <> NoInstance,(id,mkProdCN ~loc l c)) }
| ->
{ fun l id -> (false,(id,mkProdCN ~loc l (CAst.make ~loc @@ CHole (None, IntroAnonymous, None)))) } ]
-> { t l }
@@ -469,9 +469,9 @@ GRAMMAR EXTEND Gram
[ [ id = identref; c=constructor_type -> { c id } ] ]
;
of_type_with_opt_coercion:
- [ [ ":>" -> { Some () }
- | ":"; ">" -> { Some () }
- | ":" -> { None } ] ]
+ [ [ ":>" -> { BackInstance }
+ | ":"; ">" -> { BackInstance }
+ | ":" -> { NoInstance } ] ]
;
END
diff --git a/vernac/himsg.ml b/vernac/himsg.ml
index c16eaac516..5f7eb78a40 100644
--- a/vernac/himsg.ml
+++ b/vernac/himsg.ml
@@ -831,7 +831,7 @@ let pr_constraints printenv env sigma evars cstrs =
(fun (ev, evi) -> fnl () ++ pr_existential_key sigma ev ++
str " : " ++ pr_leconstr_env env' sigma evi.evar_concl ++ fnl ()) l
in
- h 0 (pe ++ evs ++ pr_evar_constraints sigma cstrs)
+ h (pe ++ evs ++ pr_evar_constraints sigma cstrs)
else
let filter evk _ = Evar.Map.mem evk evars in
pr_evar_map_filter ~with_univs:false filter env sigma
@@ -866,7 +866,7 @@ let explain_unsatisfiable_constraints env sigma constr comp =
let info = Evar.Map.find ev undef in
explain_typeclass_resolution env sigma info k ++ fnl () ++ cstr
-let explain_pretype_error env sigma err =
+let rec explain_pretype_error env sigma err =
let env = Evardefine.env_nf_betaiotaevar sigma env in
let env = make_all_name_different env sigma in
match err with
@@ -893,7 +893,7 @@ let explain_pretype_error env sigma err =
| CannotUnifyBindingType (m,n) -> explain_cannot_unify_binding_type env sigma m n
| CannotFindWellTypedAbstraction (p,l,e) ->
explain_cannot_find_well_typed_abstraction env sigma p l
- (Option.map (fun (env',e) -> explain_type_error env' sigma e) e)
+ (Option.map (fun (env',e) -> explain_pretype_error env' sigma e) e)
| WrongAbstractionType (n,a,t,u) ->
explain_wrong_abstraction_type env sigma n a t u
| AbstractionOverMeta (m,n) -> explain_abstraction_over_meta env m n
@@ -973,8 +973,8 @@ let explain_not_match_error = function
(UContext.instance uctx)
(UContext.constraints uctx)
in
- str "incompatible polymorphic binders: got" ++ spc () ++ h 0 (pr_auctx got) ++ spc() ++
- str "but expected" ++ spc() ++ h 0 (pr_auctx expect) ++
+ str "incompatible polymorphic binders: got" ++ spc () ++ h (pr_auctx got) ++ spc() ++
+ str "but expected" ++ spc() ++ h (pr_auctx expect) ++
(if not (Int.equal (AUContext.size got) (AUContext.size expect)) then mt() else
fnl() ++ str "(incompatible constraints)")
| IncompatibleVariance ->
diff --git a/vernac/metasyntax.ml b/vernac/metasyntax.ml
index 898a262266..8ce59c40c3 100644
--- a/vernac/metasyntax.ml
+++ b/vernac/metasyntax.ml
@@ -1165,11 +1165,6 @@ let warn_non_reversible_notation =
str " not occur in the right-hand side." ++ spc() ++
strbrk "The notation will not be used for printing as it is not reversible.")
-type entry_coercion_kind =
- | IsEntryCoercion of notation_entry_level
- | IsEntryGlobal of string * int
- | IsEntryIdent of string * int
-
let is_coercion level typs =
match level, typs with
| Some (custom,n,_), [e] ->
@@ -1417,8 +1412,7 @@ type notation_obj = {
notobj_scope : scope_name option;
notobj_interp : interpretation;
notobj_coercion : entry_coercion_kind option;
- notobj_onlyparse : bool;
- notobj_onlyprint : bool;
+ notobj_use : notation_use option;
notobj_deprecation : Deprecation.t option;
notobj_notation : notation * notation_location;
notobj_specific_pp_rules : syntax_printing_extension option;
@@ -1442,37 +1436,19 @@ let open_notation i (_, nobj) =
let scope = nobj.notobj_scope in
let (ntn, df) = nobj.notobj_notation in
let pat = nobj.notobj_interp in
- let onlyprint = nobj.notobj_onlyprint in
let deprecation = nobj.notobj_deprecation in
- let specific = match scope with None -> LastLonelyNotation | Some sc -> NotationInScope sc in
- let specific_ntn = (specific,ntn) in
- let fresh = not (Notation.exists_notation_in_scope scope ntn onlyprint pat) in
- if fresh then begin
- (* Declare the interpretation *)
- let () = Notation.declare_notation_interpretation ntn scope pat df ~onlyprint deprecation in
- (* Declare the uninterpretation *)
- if not nobj.notobj_onlyparse then
- Notation.declare_uninterpretation (NotationRule specific_ntn) pat;
- (* Declare a possible coercion *)
- (match nobj.notobj_coercion with
- | Some (IsEntryCoercion entry) ->
- let (_,level,_) = Notation.level_of_notation ntn in
- let level = match fst ntn with
- | InConstrEntry -> None
- | InCustomEntry _ -> Some level
- in
- Notation.declare_entry_coercion specific_ntn level entry
- | Some (IsEntryGlobal (entry,n)) -> Notation.declare_custom_entry_has_global entry n
- | Some (IsEntryIdent (entry,n)) -> Notation.declare_custom_entry_has_ident entry n
- | None -> ())
- end;
+ let scope = match scope with None -> LastLonelyNotation | Some sc -> NotationInScope sc in
+ (* Declare the notation *)
+ (match nobj.notobj_use with
+ | Some use -> Notation.declare_notation (scope,ntn) pat df ~use nobj.notobj_coercion deprecation
+ | None -> ());
(* Declare specific format if any *)
- match nobj.notobj_specific_pp_rules with
+ (match nobj.notobj_specific_pp_rules with
| Some pp_sy ->
- if specific_format_to_declare specific_ntn pp_sy then
+ if specific_format_to_declare (scope,ntn) pp_sy then
Ppextend.declare_specific_notation_printing_rules
- specific_ntn ~extra:pp_sy.synext_extra pp_sy.synext_unparsing
- | None -> ()
+ (scope,ntn) ~extra:pp_sy.synext_extra pp_sy.synext_unparsing
+ | None -> ())
end
let cache_notation o =
@@ -1602,6 +1578,20 @@ let make_printing_rules reserved (sd : SynData.syn_data) = let open SynData in
synext_extra = sd.extra;
}
+let warn_unused_interpretation =
+ CWarnings.create ~name:"unused-notation" ~category:"parsing"
+ (fun b ->
+ strbrk "interpretation is used neither for printing nor for parsing, " ++
+ (if b then strbrk "the declaration could be replaced by \"Reserved Notation\"."
+ else strbrk "the declaration could be removed."))
+
+let make_use reserved onlyparse onlyprint =
+ match onlyparse, onlyprint with
+ | false, false -> Some ParsingAndPrinting
+ | true, false -> Some OnlyParsing
+ | false, true -> Some OnlyPrinting
+ | true, true -> warn_unused_interpretation reserved; None
+
(**********************************************************************)
(* Main functions about notations *)
@@ -1614,7 +1604,14 @@ let add_notation_in_scope ~local deprecation df env c mods scope =
let sd = compute_syntax_data ~local deprecation df mods in
(* Prepare the parsing and printing rules *)
let sy_pa_rules = make_parsing_rules sd in
- let sy_pp_rules = make_printing_rules false sd in
+ let sy_pp_rules, gen_sy_pp_rules =
+ match sd.only_parsing, Ppextend.has_generic_notation_printing_rule (fst sd.info) with
+ | true, true -> None, None
+ | onlyparse, has_generic ->
+ let rules = make_printing_rules false sd in
+ let _ = check_reserved_format (fst sd.info) rules in
+ (if onlyparse then None else rules),
+ (if has_generic then None else (* We use the format of this notation as the default *) rules) in
(* Prepare the interpretation *)
let i_vars = make_internalization_vars sd.recvars sd.mainvars sd.intern_typs in
let nenv = {
@@ -1626,22 +1623,18 @@ let add_notation_in_scope ~local deprecation df env c mods scope =
let map (x, _) = try Some (x, Id.Map.find x interp) with Not_found -> None in
let onlyparse,coe = printability (Some sd.level) sd.subentries sd.only_parsing reversibility ac in
let notation, location = sd.info in
+ let use = make_use true onlyparse sd.only_printing in
let notation = {
notobj_local = local;
notobj_scope = scope;
notobj_interp = (List.map_filter map i_vars, ac);
(* Order is important here! *)
- notobj_onlyparse = onlyparse;
+ notobj_use = use;
notobj_coercion = coe;
- notobj_onlyprint = sd.only_printing;
notobj_deprecation = sd.deprecation;
notobj_notation = (notation, location);
notobj_specific_pp_rules = sy_pp_rules;
} in
- let gen_sy_pp_rules =
- if Ppextend.has_generic_notation_printing_rule (fst sd.info) then None
- else sy_pp_rules (* We use the format of this notation as the default *) in
- let _ = check_reserved_format (fst sd.info) sy_pp_rules in
(* Ready to change the global state *)
List.iter (fun f -> f ()) sd.msgs;
Lib.add_anonymous_leaf (inSyntaxExtension (local, (sy_pa_rules,gen_sy_pp_rules)));
@@ -1673,14 +1666,14 @@ let add_notation_interpretation_core ~local df env ?(impls=empty_internalization
let interp = make_interpretation_vars recvars plevel acvars (List.combine mainvars i_typs) in
let map (x, _) = try Some (x, Id.Map.find x interp) with Not_found -> None in
let onlyparse,coe = printability level i_typs onlyparse reversibility ac in
+ let use = make_use false onlyparse onlyprint in
let notation = {
notobj_local = local;
notobj_scope = scope;
notobj_interp = (List.map_filter map i_vars, ac);
(* Order is important here! *)
- notobj_onlyparse = onlyparse;
+ notobj_use = use;
notobj_coercion = coe;
- notobj_onlyprint = onlyprint;
notobj_deprecation = deprecation;
notobj_notation = df';
notobj_specific_pp_rules = pp_sy;
diff --git a/vernac/ppvernac.ml b/vernac/ppvernac.ml
index 8a98a43ba0..0e660bf20c 100644
--- a/vernac/ppvernac.ml
+++ b/vernac/ppvernac.ml
@@ -503,18 +503,20 @@ let pr_lconstrarg c =
let pr_intarg n = spc () ++ int n
let pr_oc = function
- | None -> str" :"
- | Some () -> str" :>"
+ | NoInstance -> str" :"
+ | BackInstance -> str" :>"
let pr_record_field (x, { rf_subclass = oc ; rf_priority = pri ; rf_notation = ntn }) =
let prx = match x with
- | AssumExpr (id,t) ->
+ | AssumExpr (id,binders,t) ->
hov 1 (pr_lname id ++
+ pr_binders_arg binders ++ spc() ++
pr_oc oc ++ spc() ++
pr_lconstr_expr t)
- | DefExpr(id,b,opt) -> (match opt with
+ | DefExpr(id,binders,b,opt) -> (match opt with
| Some t ->
hov 1 (pr_lname id ++
+ pr_binders_arg binders ++ spc() ++
pr_oc oc ++ spc() ++
pr_lconstr_expr t ++ str" :=" ++ pr_lconstr b)
| None ->
@@ -524,8 +526,7 @@ let pr_record_field (x, { rf_subclass = oc ; rf_priority = pri ; rf_notation = n
prx ++ prpri ++ prlist (pr_decl_notation @@ pr_constr) ntn
let pr_record_decl c fs =
- pr_opt pr_lident c ++ (if c = None then str"{" else str" {") ++
- hv 0 (prlist_with_sep pr_semicolon pr_record_field fs ++ str"}")
+ pr_opt pr_lident c ++ pr_record "{" "}" pr_record_field fs
let pr_printable = function
| PrintFullContext ->
@@ -966,7 +967,7 @@ let pr_vernac_expr v =
str":" ++ spc () ++
pr_constr cl ++ pr_hint_info pr_constr_pattern_expr info ++
(match props with
- | Some (true, { v = CRecord l}) -> spc () ++ str":=" ++ spc () ++ str"{" ++ pr_record_body l ++ str "}"
+ | Some (true, { v = CRecord l}) -> spc () ++ str":=" ++ spc () ++ pr_record_body "{" "}" pr_lconstr l
| Some (true,_) -> assert false
| Some (false,p) -> spc () ++ str":=" ++ spc () ++ pr_constr p
| None -> mt()))
diff --git a/vernac/prettyp.ml b/vernac/prettyp.ml
index 8b00484b4a..06f7c32cdc 100644
--- a/vernac/prettyp.ml
+++ b/vernac/prettyp.ml
@@ -216,7 +216,7 @@ let print_polymorphism ref =
(if poly then str "universe polymorphic"
else if template_poly then
str "template universe polymorphic "
- ++ h 0 (pr_template_variables template_variables)
+ ++ h (pr_template_variables template_variables)
else str "not universe polymorphic") ]
let print_type_in_type ref =
diff --git a/vernac/record.ml b/vernac/record.ml
index 89acd79dda..a4bf9893d9 100644
--- a/vernac/record.ml
+++ b/vernac/record.ml
@@ -62,23 +62,33 @@ let () =
let interp_fields_evars env sigma ~ninds ~nparams impls_env nots l =
let _, sigma, impls, newfs, _ =
List.fold_left2
- (fun (env, sigma, uimpls, params, impls) no ({CAst.loc;v=i}, b, t) ->
- let sigma, (t', impl) = interp_type_evars_impls env sigma ~impls t in
- let r = Retyping.relevance_of_type env sigma t' in
- let sigma, b' =
- Option.cata (fun x -> on_snd (fun x -> Some (fst x)) @@
- interp_casted_constr_evars_impls ~program_mode:false env sigma ~impls x t') (sigma,None) b in
- let impls =
+ (fun (env, sigma, uimpls, params, impls_env) no d ->
+ let sigma, (i, b, t), impl = match d with
+ | Vernacexpr.AssumExpr({CAst.loc;v=id},bl,t) ->
+ (* Temporary compatibility with the type-classes heuristics *)
+ (* which are applied after the interpretation of bl and *)
+ (* before the one of t otherwise (see #13166) *)
+ let t = if bl = [] then t else mkCProdN bl t in
+ let sigma, t, impl =
+ ComAssumption.interp_assumption ~program_mode:false env sigma impls_env [] t in
+ sigma, (id, None, t), impl
+ | Vernacexpr.DefExpr({CAst.loc;v=id},bl,b,t) ->
+ let sigma, (b, t), impl =
+ ComDefinition.interp_definition ~program_mode:false env sigma impls_env bl None b t in
+ let t = match t with Some t -> t | None -> Retyping.get_type_of env sigma b in
+ sigma, (id, Some b, t), impl in
+ let r = Retyping.relevance_of_type env sigma t in
+ let impls_env =
match i with
- | Anonymous -> impls
- | Name id -> Id.Map.add id (compute_internalization_data env sigma id Constrintern.Method t' impl) impls
+ | Anonymous -> impls_env
+ | Name id -> Id.Map.add id (compute_internalization_data env sigma id Constrintern.Method t impl) impls_env
in
- let d = match b' with
- | None -> LocalAssum (make_annot i r,t')
- | Some b' -> LocalDef (make_annot i r,b',t')
+ let d = match b with
+ | None -> LocalAssum (make_annot i r,t)
+ | Some b -> LocalDef (make_annot i r,b,t)
in
- List.iter (Metasyntax.set_notation_for_interpretation env impls) no;
- (EConstr.push_rel d env, sigma, impl :: uimpls, d::params, impls))
+ List.iter (Metasyntax.set_notation_for_interpretation env impls_env) no;
+ (EConstr.push_rel d env, sigma, impl :: uimpls, d::params, impls_env))
(env, sigma, [], [], impls_env) nots l
in
let _, _, sigma = Context.Rel.fold_outside ~init:(env,0,sigma) (fun f (env,k,sigma) ->
@@ -101,14 +111,6 @@ let compute_constructor_level evars env l =
in (EConstr.push_rel d env, univ))
l (env, Univ.Universe.sprop)
-let binder_of_decl = function
- | Vernacexpr.AssumExpr(n,t) -> (n,None,t)
- | Vernacexpr.DefExpr(n,c,t) ->
- (n,Some c, match t with Some c -> c
- | None -> CAst.make ?loc:n.CAst.loc @@ CHole (None, Namegen.IntroAnonymous, None))
-
-let binders_of_decls = List.map binder_of_decl
-
let check_anonymous_type ind =
match ind with
| { CAst.v = CSort (Glob_term.UAnonymous {rigid=true}) } -> true
@@ -176,7 +178,7 @@ let typecheck_params_and_fields def poly pl ps records =
let ninds = List.length arities in
let nparams = List.length newps in
let fold sigma (_, _, nots, fs) arity =
- interp_fields_evars env_ar sigma ~ninds ~nparams impls_env nots (binders_of_decls fs)
+ interp_fields_evars env_ar sigma ~ninds ~nparams impls_env nots fs
in
let (sigma, data) = List.fold_left2_map fold sigma records arities in
let sigma =
@@ -518,7 +520,7 @@ let implicits_of_context ctx =
(List.rev (Anonymous :: (List.map RelDecl.get_name ctx)))
let declare_class def cumulative ubinders univs id idbuild paramimpls params univ arity
- template fieldimpls fields ?(kind=Decls.StructureComponent) coers priorities =
+ template fieldimpls fields ?(kind=Decls.StructureComponent) coers =
let fieldimpls =
(* Make the class implicit in the projections, and the params if applicable. *)
let impls = implicits_of_context params in
@@ -556,10 +558,7 @@ let declare_class def cumulative ubinders univs id idbuild paramimpls params uni
Impargs.declare_manual_implicits false cref paramimpls;
Impargs.declare_manual_implicits false (GlobRef.ConstRef proj_cst) (List.hd fieldimpls);
Classes.set_typeclass_transparency (EvalConstRef cst) false false;
- let sub = match List.hd coers with
- | Some () -> Some (List.hd priorities)
- | None -> None
- in
+ let sub = List.hd coers in
let m = {
meth_name = Name proj_name;
meth_info = sub;
@@ -572,10 +571,6 @@ let declare_class def cumulative ubinders univs id idbuild paramimpls params uni
let inds = declare_structure ~cumulative Declarations.BiFinite ubinders univs paramimpls
params template ~kind:Decls.Method ~name:[|binder_name|] record_data
in
- let coers = List.map2 (fun coe pri ->
- Option.map (fun () -> pri) coe)
- coers priorities
- in
let map ind =
let map decl b y = {
meth_name = RelDecl.get_name decl;
@@ -683,8 +678,8 @@ open Vernacexpr
let check_unique_names records =
let extract_name acc (rf_decl, _) = match rf_decl with
- Vernacexpr.AssumExpr({CAst.v=Name id},_) -> id::acc
- | Vernacexpr.DefExpr ({CAst.v=Name id},_,_) -> id::acc
+ Vernacexpr.AssumExpr({CAst.v=Name id},_,_) -> id::acc
+ | Vernacexpr.DefExpr ({CAst.v=Name id},_,_,_) -> id::acc
| _ -> acc in
let allnames =
List.fold_left (fun acc (_, id, _, cfs, _, _) ->
@@ -739,16 +734,21 @@ let definition_structure udecl kind ~template ~cumulative ~poly finite records =
| [r], [d] -> r, d
| _, _ -> CErrors.user_err (str "Mutual definitional classes are not handled")
in
- let priorities = List.map (fun (_, { rf_priority }) -> {hint_priority = rf_priority ; hint_pattern = None}) cfs in
- let coers = List.map (fun (_, { rf_subclass }) -> rf_subclass) cfs in
+ let coers = List.map (fun (_, { rf_subclass=coe; rf_priority=pri }) ->
+ match coe with
+ | Vernacexpr.BackInstance -> Some {hint_priority = pri ; hint_pattern = None}
+ | Vernacexpr.NoInstance -> None)
+ cfs
+ in
declare_class def cumulative ubinders univs id.CAst.v idbuild
- implpars params univ arity template implfs fields coers priorities
+ implpars params univ arity template implfs fields coers
| _ ->
let map impls = implpars @ [CAst.make None] @ impls in
let data = List.map (fun (univ, arity, implfs, fields) -> (univ, arity, List.map map implfs, fields)) data in
let map (univ, arity, implfs, fields) (is_coe, id, _, cfs, idbuild, _) =
let coe = List.map (fun (_, { rf_subclass ; rf_canonical }) ->
- { pf_subclass = not (Option.is_empty rf_subclass);
+ { pf_subclass =
+ (match rf_subclass with Vernacexpr.BackInstance -> true | Vernacexpr.NoInstance -> false);
pf_canonical = rf_canonical })
cfs
in
diff --git a/vernac/vernac.mllib b/vernac/vernac.mllib
index 994592a88a..cd0dd5e9a6 100644
--- a/vernac/vernac.mllib
+++ b/vernac/vernac.mllib
@@ -43,4 +43,5 @@ Topfmt
Loadpath
ComArguments
Vernacentries
+ComTactic
Vernacinterp
diff --git a/vernac/vernacentries.ml b/vernac/vernacentries.ml
index 60c6d2ec0b..3ced38d6ea 100644
--- a/vernac/vernacentries.ml
+++ b/vernac/vernacentries.ml
@@ -700,7 +700,7 @@ let vernac_record ~template udecl ~cumulative k ~poly finite records =
if Dumpglob.dump () then
let () = Dumpglob.dump_definition id false "rec" in
let iter (x, _) = match x with
- | Vernacexpr.AssumExpr ({loc;v=Name id}, _) ->
+ | Vernacexpr.(AssumExpr ({loc;v=Name id}, _, _) | DefExpr ({loc;v=Name id}, _, _, _)) ->
Dumpglob.dump_definition (make ?loc id) false "proj"
| _ -> ()
in
@@ -776,8 +776,8 @@ let vernac_inductive ~atts kind indl =
| _ -> CErrors.user_err Pp.(str "Definitional classes do not support the \"|\" syntax.")
in
let (coe, (lid, ce)) = l in
- let coe' = if coe then Some () else None in
- let f = AssumExpr ((make ?loc:lid.loc @@ Name lid.v), ce),
+ let coe' = if coe then BackInstance else NoInstance in
+ let f = AssumExpr ((make ?loc:lid.loc @@ Name lid.v), [], ce),
{ rf_subclass = coe' ; rf_priority = None ; rf_notation = [] ; rf_canonical = true } in
vernac_record ~template udecl ~cumulative (Class true) ~poly finite [id, bl, c, None, [f]]
else if List.for_all is_record indl then
@@ -1790,11 +1790,11 @@ let vernac_print ~pstate =
| PrintHintDbName s -> Hints.pr_hint_db_by_name env sigma s
| PrintHintDb -> Hints.pr_searchtable env sigma
| PrintScopes ->
- Notation.pr_scopes (Constrextern.without_symbols (pr_lglob_constr_env env))
+ Notation.pr_scopes (Constrextern.without_symbols (pr_glob_constr_env env))
| PrintScope s ->
- Notation.pr_scope (Constrextern.without_symbols (pr_lglob_constr_env env)) s
+ Notation.pr_scope (Constrextern.without_symbols (pr_glob_constr_env env)) s
| PrintVisibility s ->
- Notation.pr_visibility (Constrextern.without_symbols (pr_lglob_constr_env env)) s
+ Notation.pr_visibility (Constrextern.without_symbols (pr_glob_constr_env env)) s
| PrintAbout (ref_or_by_not,udecl,glnumopt) ->
print_about_hyp_globs ~pstate ref_or_by_not udecl glnumopt
| PrintImplicit qid ->
@@ -1830,7 +1830,7 @@ let vernac_locate ~pstate = let open Constrexpr in function
| LocateTerm {v=ByNotation (ntn, sc)} ->
let _, env = get_current_or_global_context ~pstate in
Notation.locate_notation
- (Constrextern.without_symbols (pr_lglob_constr_env env)) ntn sc
+ (Constrextern.without_symbols (pr_glob_constr_env env)) ntn sc
| LocateLibrary qid -> print_located_library qid
| LocateModule qid -> Prettyp.print_located_module qid
| LocateOther (s, qid) -> Prettyp.print_located_other s qid
diff --git a/vernac/vernacexpr.ml b/vernac/vernacexpr.ml
index 721e710e1d..6a9a74144f 100644
--- a/vernac/vernacexpr.ml
+++ b/vernac/vernacexpr.ml
@@ -106,8 +106,7 @@ type search_restriction =
type verbose_flag = bool (* true = Verbose; false = Silent *)
type coercion_flag = bool (* true = AddCoercion false = NoCoercion *)
-type instance_flag = unit option
- (* Some () = Backward instance, None = NoInstance *)
+type instance_flag = BackInstance | NoInstance
type export_flag = bool (* true = Export; false = Import *)
@@ -168,8 +167,8 @@ type fixpoint_expr = recursion_order_expr option fix_expr_gen
type cofixpoint_expr = unit fix_expr_gen
type local_decl_expr =
- | AssumExpr of lname * constr_expr
- | DefExpr of lname * constr_expr * constr_expr option
+ | AssumExpr of lname * local_binder_expr list * constr_expr
+ | DefExpr of lname * local_binder_expr list * constr_expr * constr_expr option
type inductive_kind = Inductive_kw | CoInductive | Variant | Record | Structure | Class of bool (* true = definitional, false = inductive *)
type simple_binder = lident list * constr_expr
diff --git a/vernac/vernacextend.ml b/vernac/vernacextend.ml
index eacb7fe6cb..ed63332861 100644
--- a/vernac/vernacextend.ml
+++ b/vernac/vernacextend.ml
@@ -30,7 +30,6 @@ type vernac_classification =
| VtQed of vernac_qed_type
(* A proof step *)
| VtProofStep of {
- parallel : [ `Yes of solving_tac * anon_abstracting_tac | `No ];
proof_block_detection : proof_block_name option
}
(* Queries are commands assumed to be "pure", that is to say, they
@@ -124,7 +123,7 @@ let declare_vernac_classifier name f =
let classify_as_query = VtQuery
let classify_as_sideeff = VtSideff ([], VtLater)
-let classify_as_proofstep = VtProofStep { parallel = `No; proof_block_detection = None}
+let classify_as_proofstep = VtProofStep { proof_block_detection = None}
type (_, _) ty_sig =
| TyNil : (vernac_command, vernac_classification) ty_sig
diff --git a/vernac/vernacextend.mli b/vernac/vernacextend.mli
index 5ef137cfc0..e1e3b4cfe5 100644
--- a/vernac/vernacextend.mli
+++ b/vernac/vernacextend.mli
@@ -46,7 +46,6 @@ type vernac_classification =
| VtQed of vernac_qed_type
(* A proof step *)
| VtProofStep of {
- parallel : [ `Yes of solving_tac * anon_abstracting_tac | `No ];
proof_block_detection : proof_block_name option
}
(* Queries are commands assumed to be "pure", that is to say, they