aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/CODEOWNERS3
-rw-r--r--.gitignore2
-rw-r--r--.gitlab-ci.yml87
-rw-r--r--INSTALL2
-rw-r--r--META.coq.in80
-rw-r--r--Makefile13
-rw-r--r--Makefile.build8
-rw-r--r--Makefile.ci1
-rw-r--r--Makefile.dune8
-rw-r--r--Makefile.ide8
-rw-r--r--Makefile.install4
-rw-r--r--azure-pipelines.yml8
-rw-r--r--checker/check.ml2
-rw-r--r--checker/values.ml40
-rw-r--r--checker/values.mli2
-rw-r--r--checker/votour.ml2
-rw-r--r--clib/hashset.ml4
-rw-r--r--configure.ml8
-rw-r--r--default.nix2
-rw-r--r--[-rwxr-xr-x]dev/build/windows/patches_coq/ocaml-4.07.1.patch0
-rw-r--r--[-rwxr-xr-x]dev/build/windows/patches_coq/pkg-config.c0
-rwxr-xr-xdev/ci/azure-opam.sh2
-rwxr-xr-xdev/ci/ci-basic-overlay.sh7
-rwxr-xr-xdev/ci/ci-perennial.sh12
-rw-r--r--dev/ci/docker/bionic_coq/Dockerfile12
-rw-r--r--dev/ci/user-overlays/10727-ejgallego-library+to_vernac_step2.sh6
-rw-r--r--dev/ci/user-overlays/10811-SkySkimmer-sprop-default-on.sh9
-rw-r--r--dev/doc/build-system.txt8
-rw-r--r--dev/doc/coq-src-description.txt2
-rw-r--r--dev/doc/critical-bugs12
-rw-r--r--dev/doc/release-process.md51
-rw-r--r--dev/dune-workspace.all6
-rwxr-xr-xdev/tools/make-changelog.sh25
-rw-r--r--dev/v8-syntax/syntax-v8.tex2
-rw-r--r--doc/changelog/01-kernel/10664-sections-stack-in-kernel.rst6
-rw-r--r--doc/changelog/01-kernel/10811-sprop-default-on.rst3
-rw-r--r--doc/changelog/02-specification-language/10758-fix-10757.rst5
-rw-r--r--doc/changelog/04-tactics/10765-micromega-caches.rst3
-rw-r--r--doc/changelog/04-tactics/10774-zify-Z_to_N.rst3
-rw-r--r--doc/changelog/07-commands-and-options/10489-print_dependent_evars.rst7
-rw-r--r--doc/changelog/10-standard-library/09772-ordered_type-hint-db.rst4
-rw-r--r--doc/changelog/README.md27
-rw-r--r--doc/sphinx/addendum/micromega.rst12
-rw-r--r--doc/sphinx/addendum/sprop.rst7
-rw-r--r--doc/sphinx/addendum/universe-polymorphism.rst61
-rw-r--r--doc/sphinx/changes.rst8
-rw-r--r--doc/sphinx/language/gallina-extensions.rst19
-rw-r--r--doc/sphinx/practical-tools/utilities.rst4
-rw-r--r--doc/sphinx/proof-engine/tactics.rst66
-rw-r--r--doc/sphinx/proof-engine/vernacular-commands.rst5
-rw-r--r--doc/stdlib/index-list.html.template3
-rw-r--r--dune4
-rw-r--r--engine/evarutil.ml12
-rw-r--r--engine/evd.ml13
-rw-r--r--engine/evd.mli4
-rw-r--r--engine/proofview.ml2
-rw-r--r--engine/uState.ml106
-rw-r--r--engine/uState.mli4
-rw-r--r--[-rwxr-xr-x]ide/coq2.icobin4710 -> 4710 bytes
-rw-r--r--ide/wg_ScriptView.ml4
-rw-r--r--interp/modintern.ml6
-rw-r--r--interp/modintern.mli4
-rw-r--r--kernel/cooking.ml10
-rw-r--r--kernel/cooking.mli2
-rw-r--r--kernel/entries.ml8
-rw-r--r--kernel/inferCumulativity.ml (renamed from pretyping/inferCumulativity.ml)13
-rw-r--r--kernel/inferCumulativity.mli (renamed from pretyping/inferCumulativity.mli)0
-rw-r--r--kernel/kernel.mllib2
-rw-r--r--kernel/nativevalues.ml4
-rw-r--r--kernel/opaqueproof.ml102
-rw-r--r--kernel/opaqueproof.mli19
-rw-r--r--kernel/safe_typing.ml201
-rw-r--r--kernel/safe_typing.mli32
-rw-r--r--kernel/section.ml216
-rw-r--r--kernel/section.mli85
-rw-r--r--kernel/term_typing.ml28
-rw-r--r--lib/flags.ml6
-rw-r--r--lib/flags.mli2
-rw-r--r--library/global.ml10
-rw-r--r--library/global.mli11
-rw-r--r--library/lib.ml168
-rw-r--r--library/lib.mli10
-rw-r--r--library/library.mllib1
-rw-r--r--parsing/pcoq.ml2
-rw-r--r--parsing/pcoq.mli2
-rw-r--r--plugins/cc/README2
-rw-r--r--plugins/cc/ccproof.ml2
-rw-r--r--plugins/funind/functional_principles_proofs.ml18
-rw-r--r--plugins/funind/gen_principle.ml16
-rw-r--r--plugins/funind/recdef.ml6
-rw-r--r--plugins/ltac/tacarg.ml2
-rw-r--r--plugins/ltac/taccoerce.ml7
-rw-r--r--plugins/micromega/ZifyInst.v4
-rw-r--r--plugins/micromega/coq_micromega.ml212
-rw-r--r--plugins/micromega/mutils.ml81
-rw-r--r--plugins/micromega/mutils.mli42
-rw-r--r--plugins/micromega/persistent_cache.ml4
-rw-r--r--plugins/setoid_ring/InitialRing.v16
-rw-r--r--plugins/ssr/ssrfun.v2
-rw-r--r--pretyping/pretyping.mllib1
-rw-r--r--printing/prettyp.ml63
-rw-r--r--printing/prettyp.mli37
-rw-r--r--printing/printer.ml75
-rw-r--r--printing/printer.mli1
-rw-r--r--printing/printmod.ml75
-rw-r--r--printing/printmod.mli10
-rw-r--r--stm/stm.ml12
-rw-r--r--stm/vernac_classifier.ml2
-rw-r--r--tactics/declare.ml177
-rw-r--r--tactics/declare.mli4
-rw-r--r--tactics/pfedit.ml5
-rw-r--r--tactics/proof_global.ml4
-rw-r--r--tactics/proof_global.mli2
-rw-r--r--test-suite/bugs/closed/bug_10669.v12
-rw-r--r--test-suite/bugs/closed/bug_10757.v38
-rw-r--r--test-suite/bugs/closed/bug_10778.v32
-rw-r--r--test-suite/bugs/closed/bug_10888.v11
-rw-r--r--test-suite/bugs/closed/bug_9512.v35
-rw-r--r--test-suite/bugs/opened/bug_1596.v7
-rw-r--r--test-suite/ltac2/constr.v12
-rw-r--r--test-suite/micromega/bug_9162.v8
-rw-r--r--test-suite/output-coqtop/DependentEvars.out91
-rw-r--r--test-suite/output-coqtop/DependentEvars.v24
-rw-r--r--test-suite/output-coqtop/DependentEvars2.out120
-rw-r--r--test-suite/output-coqtop/DependentEvars2.v27
-rw-r--r--test-suite/output/UnivBinders.out38
-rw-r--r--test-suite/prerequisite/ssr_mini_mathcomp.v8
-rw-r--r--test-suite/success/CompatCurrentFlag.v4
-rw-r--r--test-suite/success/CompatOldFlag.v4
-rw-r--r--test-suite/success/CompatOldOldFlag.v6
-rw-r--r--test-suite/success/CompatPreviousFlag.v4
-rw-r--r--test-suite/success/section_poly.v74
-rwxr-xr-xtest-suite/tools/update-compat/run.sh2
-rw-r--r--theories/Compat/Coq810.v2
-rw-r--r--theories/Compat/Coq811.v11
-rw-r--r--theories/FSets/FMapAVL.v54
-rw-r--r--theories/FSets/FMapFacts.v24
-rw-r--r--theories/FSets/FMapFullAVL.v2
-rw-r--r--theories/FSets/FMapList.v53
-rw-r--r--theories/FSets/FSetBridge.v10
-rw-r--r--theories/FSets/FSetProperties.v8
-rw-r--r--theories/Init/Logic.v16
-rw-r--r--theories/Reals/ConstructiveCauchyReals.v1979
-rw-r--r--theories/Reals/ConstructiveCauchyRealsMult.v1415
-rw-r--r--theories/Reals/ConstructiveRIneq.v97
-rw-r--r--theories/Reals/ConstructiveRcomplete.v369
-rw-r--r--theories/Reals/ConstructiveReals.v746
-rw-r--r--theories/Reals/ConstructiveRealsLUB.v90
-rw-r--r--theories/Reals/ConstructiveRealsMorphisms.v1158
-rw-r--r--theories/Reals/Raxioms.v7
-rw-r--r--theories/Structures/OrderedType.v135
-rw-r--r--theories/Structures/OrderedTypeEx.v10
-rw-r--r--tools/CoqMakefile.in2
-rw-r--r--tools/coq_dune.ml1
-rw-r--r--toplevel/coqargs.ml7
-rw-r--r--toplevel/coqc.ml5
-rw-r--r--toplevel/coqloop.ml12
-rw-r--r--toplevel/usage.ml1
-rw-r--r--[-rwxr-xr-x]user-contrib/Ltac2/Bool.v0
-rw-r--r--user-contrib/Ltac2/Constr.v14
-rw-r--r--[-rwxr-xr-x]user-contrib/Ltac2/Init.v0
-rw-r--r--vernac/classes.ml3
-rw-r--r--vernac/comAssumption.ml296
-rw-r--r--vernac/comAssumption.mli37
-rw-r--r--vernac/comPrimitive.ml37
-rw-r--r--vernac/comPrimitive.mli11
-rw-r--r--vernac/comProgramFixpoint.ml53
-rw-r--r--vernac/declaremods.ml (renamed from library/declaremods.ml)116
-rw-r--r--vernac/declaremods.mli (renamed from library/declaremods.mli)47
-rw-r--r--vernac/g_vernac.mlg3
-rw-r--r--vernac/himsg.ml4
-rw-r--r--vernac/lemmas.ml5
-rw-r--r--vernac/obligations.ml7
-rw-r--r--vernac/vernac.mllib7
-rw-r--r--vernac/vernacentries.ml320
-rw-r--r--vernac/vernacentries.mli29
-rw-r--r--vernac/vernacextend.ml1
-rw-r--r--vernac/vernacinterp.ml278
-rw-r--r--vernac/vernacinterp.mli33
179 files changed, 6771 insertions, 3957 deletions
diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
index 6c7b7a9a1c..4789d9b6fa 100644
--- a/.github/CODEOWNERS
+++ b/.github/CODEOWNERS
@@ -333,6 +333,9 @@ azure-pipelines.yml @coq/ci-maintainers
/dev/tools/github-check-prs.py @SkySkimmer
+/dev/tools/make-changelog.sh @SkySkimmer
+# Secondary maintainer @Zimmi48
+
/dev/tools/merge-pr.sh @maximedenes
# Secondary maintainer @gares
diff --git a/.gitignore b/.gitignore
index 587a6191ab..ad5204847c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -135,7 +135,7 @@ ide/protocol/xml_lexer.ml
coqpp/coqpp_parse.ml
coqpp/coqpp_parse.mli
-# .ml4 / .mlp files
+# .mlg / .mlp files
g_*.ml
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 64d930a735..0ebf69f50f 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -8,14 +8,17 @@ stages:
- stage-4 # Only dependencies in stage 1, 2 and 3
- deploy
-# When a job has no dependencies, it goes to stage 1.
-# Otherwise, we set "needs" and "dependencies" to the same value.
+# When a job has no dependencies, it goes to stage 1. Otherwise, we
+# set both "needs" and "dependencies". "needs" is a superset of
+# "dependencies" that should include all the transitive dependencies.
+# "dependencies" only list the previous jobs whose artifact we need to
+# keep.
# some default values
variables:
# Format: $IMAGE-V$DATE [Cache is not used as of today but kept here
# for reference]
- CACHEKEY: "bionic_coq-V2019-07-09-V01"
+ CACHEKEY: "bionic_coq-V2019-09-20-V01"
IMAGE: "$CI_REGISTRY_IMAGE:$CACHEKEY"
# By default, jobs run in the base switch; override to select another switch
OPAM_SWITCH: "base"
@@ -67,8 +70,6 @@ before_script:
- config/coq_config.py
- test-suite/misc/universes/all_stdlib.v
expire_in: 1 week
- variables:
- timeout: ""
script:
- set -e
@@ -81,8 +82,8 @@ before_script:
- echo 'end:coq.config'
- echo 'start:coq.build'
- - $timeout make -j "$NJOBS" byte
- - $timeout make -j "$NJOBS" world $EXTRA_TARGET
+ - make -j "$NJOBS" byte
+ - make -j "$NJOBS" world $EXTRA_TARGET
- make test-suite/misc/universes/all_stdlib.v
- echo 'end:coq:build'
@@ -161,7 +162,7 @@ before_script:
- BIN=$(readlink -f ../_install_ci/bin)/
- LIB=$(readlink -f ../_install_ci/lib/coq)/
- export OCAMLPATH=$(readlink -f ../_install_ci/lib/):"$OCAMLPATH"
- - $timeout make -j "$NJOBS" BIN="$BIN" COQLIB="$LIB" COQFLAGS="${COQFLAGS}" all
+ - make -j "$NJOBS" BIN="$BIN" COQLIB="$LIB" COQFLAGS="${COQFLAGS}" all
artifacts:
name: "$CI_JOB_NAME.logs"
when: on_failure
@@ -169,8 +170,6 @@ before_script:
- test-suite/logs
# Gitlab doesn't support yet "expire_in: never" so we use the instance default
# expire_in: never
- variables:
- timeout: ""
# set dependencies when using
.validate-template:
@@ -276,7 +275,7 @@ build:base+async:
variables:
COQ_EXTRA_CONF: "-native-compiler yes -coqide opt"
COQUSERFLAGS: "-async-proofs on"
- timeout: "timeout 100m"
+ timeout: 100m
allow_failure: true # See https://github.com/coq/coq/issues/9658
only:
variables:
@@ -287,7 +286,7 @@ build:quick:
variables:
COQ_EXTRA_CONF: "-native-compiler no"
QUICK: "1"
- timeout: "timeout 100m"
+ timeout: 100m
allow_failure: true # See https://github.com/coq/coq/issues/9637
only:
variables:
@@ -324,7 +323,7 @@ pkg:opam:
- opam pin add --kind=path coqide.$COQ_VERSION .
- set +e
variables:
- COQ_VERSION: "8.10"
+ COQ_VERSION: "8.11"
OPAM_SWITCH: "edge"
OPAM_VARIANT: "+flambda"
only: *full-ci
@@ -504,62 +503,6 @@ test-suite:egde:dune:dev:
# Gitlab doesn't support yet "expire_in: never" so we use the instance default
# expire_in: never
-test-suite:edge+trunk+make:
- stage: stage-1
- dependencies: []
- script:
- - opam switch create 4.09.0 --empty
- - eval $(opam env)
- - opam repo add ocaml-beta https://github.com/ocaml/ocaml-beta-repository.git
- - opam update
- - opam install ocaml-variants=4.09.0+trunk
- - opam pin add -n ocamlfind --dev
- - opam install num
- - eval $(opam env)
- # We avoid problems with warnings:
- - ./configure -profile devel -warn-error no
- - make -j "$NJOBS" world
- - make -j "$NJOBS" test-suite UNIT_TESTS=
- variables:
- OPAM_SWITCH: base
- artifacts:
- name: "$CI_JOB_NAME.logs"
- when: always
- paths:
- - test-suite/logs
- expire_in: 1 week
- allow_failure: true
- only: *full-ci
-
-test-suite:edge+trunk+dune:
- stage: stage-1
- dependencies: []
- script:
- - opam switch create 4.09.0 --empty
- - eval $(opam env)
- - opam repo add ocaml-beta https://github.com/ocaml/ocaml-beta-repository.git
- - opam update
- - opam install ocaml-variants=4.09.0+trunk
- - opam pin add -n ocamlfind --dev
- - opam pin add dune --dev # ounit lablgtk conf-gtksourceview
- - opam install dune num
- - eval $(opam env)
- # We use the release profile to avoid problems with warnings
- - make -f Makefile.dune trunk
- - export COQ_UNIT_TEST=noop
- - dune runtest --profile=ocaml409
- variables:
- OPAM_SWITCH: base
- artifacts:
- name: "$CI_JOB_NAME.logs"
- when: always
- paths:
- - _build/log
- - _build/default/test-suite/logs
- expire_in: 1 week
- allow_failure: true
- only: *full-ci
-
test-suite:base+async:
extends: .test-suite-template
dependencies:
@@ -568,7 +511,7 @@ test-suite:base+async:
- build:base
variables:
COQFLAGS: "-async-proofs on -async-proofs-cache force"
- timeout: "timeout 100m"
+ timeout: 100m
allow_failure: true
only:
variables:
@@ -657,6 +600,7 @@ library:ci-corn:
stage: stage-4
needs:
- build:edge+flambda
+ - plugin:ci-bignums
- library:ci-math-classes
dependencies:
- build:edge+flambda
@@ -737,6 +681,9 @@ plugin:ci-mtac2:
plugin:ci-paramcoq:
extends: .ci-template
+plugin:ci-perennial:
+ extends: .ci-template-flambda
+
plugin:plugin-tutorial:
stage: stage-1
dependencies: []
diff --git a/INSTALL b/INSTALL
index e82ecf68f8..e30706e005 100644
--- a/INSTALL
+++ b/INSTALL
@@ -9,7 +9,7 @@ WHAT DO YOU NEED ?
- OCaml (version >= 4.05.0)
(available at https://ocaml.org/)
- (This version of Coq has been tested up to OCaml 4.08.1)
+ (This version of Coq has been tested up to OCaml 4.09.0)
- The Num package, which used to be part of the OCaml standard library,
if you are using an OCaml version >= 4.06.0
diff --git a/META.coq.in b/META.coq.in
index f7922e0ac2..0baacbc82e 100644
--- a/META.coq.in
+++ b/META.coq.in
@@ -1,7 +1,7 @@
# TODO: Generate automatically with Dune
description = "The Coq Proof Assistant Plugin API"
-version = "8.10"
+version = "8.11"
directory = ""
requires = ""
@@ -9,7 +9,7 @@ requires = ""
package "config" (
description = "Coq Configuration Variables"
- version = "8.10"
+ version = "8.11"
directory = "config"
@@ -19,7 +19,7 @@ package "config" (
package "clib" (
description = "Base General Coq Library"
- version = "8.10"
+ version = "8.11"
directory = "clib"
requires = "str, unix, threads"
@@ -31,7 +31,7 @@ package "clib" (
package "lib" (
description = "Base Coq-Specific Library"
- version = "8.10"
+ version = "8.11"
directory = "lib"
@@ -45,7 +45,7 @@ package "lib" (
package "vm" (
description = "Coq VM"
- version = "8.10"
+ version = "8.11"
directory = "kernel/byterun"
@@ -64,7 +64,7 @@ package "vm" (
package "kernel" (
description = "Coq's Kernel"
- version = "8.10"
+ version = "8.11"
directory = "kernel"
@@ -78,7 +78,7 @@ package "kernel" (
package "library" (
description = "Coq Libraries (vo) support"
- version = "8.10"
+ version = "8.11"
requires = "coq.kernel"
@@ -92,7 +92,7 @@ package "library" (
package "engine" (
description = "Coq Tactic Engine"
- version = "8.10"
+ version = "8.11"
requires = "coq.library"
directory = "engine"
@@ -105,7 +105,7 @@ package "engine" (
package "pretyping" (
description = "Coq Pretyper"
- version = "8.10"
+ version = "8.11"
requires = "coq.engine"
directory = "pretyping"
@@ -118,7 +118,7 @@ package "pretyping" (
package "interp" (
description = "Coq Term Interpretation"
- version = "8.10"
+ version = "8.11"
requires = "coq.pretyping"
directory = "interp"
@@ -131,7 +131,7 @@ package "interp" (
package "proofs" (
description = "Coq Proof Engine"
- version = "8.10"
+ version = "8.11"
requires = "coq.interp"
directory = "proofs"
@@ -144,7 +144,7 @@ package "proofs" (
package "gramlib" (
description = "Coq Grammar Engine"
- version = "8.10"
+ version = "8.11"
requires = "coq.lib"
directory = "gramlib/.pack"
@@ -156,7 +156,7 @@ package "gramlib" (
package "parsing" (
description = "Coq Parsing Engine"
- version = "8.10"
+ version = "8.11"
requires = "coq.gramlib, coq.proofs"
directory = "parsing"
@@ -169,7 +169,7 @@ package "parsing" (
package "printing" (
description = "Coq Printing Engine"
- version = "8.10"
+ version = "8.11"
requires = "coq.parsing"
directory = "printing"
@@ -182,7 +182,7 @@ package "printing" (
package "tactics" (
description = "Coq Basic Tactics"
- version = "8.10"
+ version = "8.11"
requires = "coq.printing"
directory = "tactics"
@@ -195,7 +195,7 @@ package "tactics" (
package "vernac" (
description = "Coq Vernacular Interpreter"
- version = "8.10"
+ version = "8.11"
requires = "coq.tactics"
directory = "vernac"
@@ -208,7 +208,7 @@ package "vernac" (
package "stm" (
description = "Coq State Transactional Machine"
- version = "8.10"
+ version = "8.11"
requires = "coq.vernac"
directory = "stm"
@@ -221,7 +221,7 @@ package "stm" (
package "toplevel" (
description = "Coq Toplevel"
- version = "8.10"
+ version = "8.11"
requires = "num, coq.stm"
directory = "toplevel"
@@ -234,7 +234,7 @@ package "toplevel" (
package "idetop" (
description = "Coq IDE Libraries"
- version = "8.10"
+ version = "8.11"
requires = "coq.toplevel"
directory = "ide"
@@ -247,7 +247,7 @@ package "idetop" (
package "ide" (
description = "Coq IDE Libraries"
- version = "8.10"
+ version = "8.11"
requires = "coq.lib, coq.ideprotocol, lablgtk3, lablgtk3-sourceview3"
directory = "ide"
@@ -260,7 +260,7 @@ package "ide" (
package "ideprotocol" (
description = "Coq IDE protocol"
- version = "8.10"
+ version = "8.11"
requires = "coq.toplevel"
directory = "ide/protocol"
@@ -273,14 +273,14 @@ package "ideprotocol" (
package "plugins" (
description = "Coq built-in plugins"
- version = "8.10"
+ version = "8.11"
directory = "plugins"
package "ltac" (
description = "Coq LTAC Plugin"
- version = "8.10"
+ version = "8.11"
requires = "coq.stm"
directory = "ltac"
@@ -293,7 +293,7 @@ package "plugins" (
package "tauto" (
description = "Coq tauto plugin"
- version = "8.10"
+ version = "8.11"
requires = "coq.plugins.ltac"
directory = "ltac"
@@ -305,7 +305,7 @@ package "plugins" (
package "omega" (
description = "Coq omega plugin"
- version = "8.10"
+ version = "8.11"
requires = "coq.plugins.ltac"
directory = "omega"
@@ -317,7 +317,7 @@ package "plugins" (
package "micromega" (
description = "Coq micromega plugin"
- version = "8.10"
+ version = "8.11"
requires = "num,coq.plugins.ltac"
directory = "micromega"
@@ -329,7 +329,7 @@ package "plugins" (
package "setoid_ring" (
description = "Coq newring plugin"
- version = "8.10"
+ version = "8.11"
requires = ""
directory = "setoid_ring"
@@ -341,7 +341,7 @@ package "plugins" (
package "extraction" (
description = "Coq extraction plugin"
- version = "8.10"
+ version = "8.11"
requires = "coq.plugins.ltac"
directory = "extraction"
@@ -353,7 +353,7 @@ package "plugins" (
package "cc" (
description = "Coq cc plugin"
- version = "8.10"
+ version = "8.11"
requires = "coq.plugins.ltac"
directory = "cc"
@@ -365,7 +365,7 @@ package "plugins" (
package "firstorder" (
description = "Coq ground plugin"
- version = "8.10"
+ version = "8.11"
requires = "coq.plugins.ltac"
directory = "firstorder"
@@ -377,7 +377,7 @@ package "plugins" (
package "rtauto" (
description = "Coq rtauto plugin"
- version = "8.10"
+ version = "8.11"
requires = "coq.plugins.ltac"
directory = "rtauto"
@@ -389,7 +389,7 @@ package "plugins" (
package "btauto" (
description = "Coq btauto plugin"
- version = "8.10"
+ version = "8.11"
requires = "coq.plugins.ltac"
directory = "btauto"
@@ -401,7 +401,7 @@ package "plugins" (
package "funind" (
description = "Coq recdef plugin"
- version = "8.10"
+ version = "8.11"
requires = "coq.plugins.extraction"
directory = "funind"
@@ -413,7 +413,7 @@ package "plugins" (
package "nsatz" (
description = "Coq nsatz plugin"
- version = "8.10"
+ version = "8.11"
requires = "num,coq.plugins.ltac"
directory = "nsatz"
@@ -425,7 +425,7 @@ package "plugins" (
package "rsyntax" (
description = "Coq rsyntax plugin"
- version = "8.10"
+ version = "8.11"
requires = ""
directory = "syntax"
@@ -437,7 +437,7 @@ package "plugins" (
package "int63syntax" (
description = "Coq int63syntax plugin"
- version = "8.10"
+ version = "8.11"
requires = ""
directory = "syntax"
@@ -449,7 +449,7 @@ package "plugins" (
package "string_notation" (
description = "Coq string_notation plugin"
- version = "8.10"
+ version = "8.11"
requires = ""
directory = "syntax"
@@ -461,7 +461,7 @@ package "plugins" (
package "derive" (
description = "Coq derive plugin"
- version = "8.10"
+ version = "8.11"
requires = ""
directory = "derive"
@@ -473,7 +473,7 @@ package "plugins" (
package "ssrmatching" (
description = "Coq ssrmatching plugin"
- version = "8.10"
+ version = "8.11"
requires = "coq.plugins.ltac"
directory = "ssrmatching"
@@ -485,7 +485,7 @@ package "plugins" (
package "ssreflect" (
description = "Coq ssreflect plugin"
- version = "8.10"
+ version = "8.11"
requires = "coq.plugins.ssrmatching"
directory = "ssr"
diff --git a/Makefile b/Makefile
index 3ebff90f00..d9fd03ac5a 100644
--- a/Makefile
+++ b/Makefile
@@ -101,15 +101,18 @@ EXISTINGMLI := $(call find, '*.mli')
## Files that will be generated
-GENMLGFILES:= $(MLGFILES:.mlg=.ml)
# GRAMFILES must be in linking order
GRAMFILES=$(addprefix gramlib/.pack/gramlib__,Ploc Plexing Gramext Grammar)
-GRAMMLFILES := $(addsuffix .ml, $(GRAMFILES)) $(addsuffix .mli, $(GRAMFILES))
-GENGRAMFILES := $(GRAMMLFILES) gramlib/.pack/gramlib.ml
-GENMLFILES:=$(LEXFILES:.mll=.ml) $(YACCFILES:.mly=.ml) $(GENMLGFILES) ide/coqide_os_specific.ml kernel/copcodes.ml kernel/uint63.ml
+GRAMMLFILES := $(addsuffix .ml, $(GRAMFILES))
+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_os_specific.ml kernel/copcodes.ml kernel/uint63.ml
+GENMLIFILES:=$(GRAMMLIFILES)
GENHFILES:=kernel/byterun/coq_instruct.h kernel/byterun/coq_jumptbl.h
GENFILES:=$(GENMLFILES) $(GENMLIFILES) $(GENHFILES) kernel/genOpcodeFiles.exe
-COQ_EXPORTED += GRAMFILES GRAMMLFILES GENGRAMFILES GENMLFILES GENHFILES GENFILES
+COQ_EXPORTED += GRAMFILES GRAMMLFILES GRAMMLIFILES GENMLFILES GENHFILES GENFILES
## More complex file lists
diff --git a/Makefile.build b/Makefile.build
index 610af5fe40..35f5e26272 100644
--- a/Makefile.build
+++ b/Makefile.build
@@ -203,7 +203,7 @@ TIMER=$(if $(TIMED), $(STDTIME), $(TIMECMD))
# the output format of the unix command time. For instance:
# TIME="%C (%U user, %S sys, %e total, %M maxres)"
-COQOPTS=$(NATIVECOMPUTE) $(COQWARNERROR) $(COQUSERFLAGS) -allow-sprop
+COQOPTS=$(NATIVECOMPUTE) $(COQWARNERROR) $(COQUSERFLAGS)
# Beware this depends on the makefile being in a particular dir, we
# should pass an absolute path here but windows is tricky
# c.f. https://github.com/coq/coq/pull/9560
@@ -581,7 +581,7 @@ bin/votour.byte: $(VOTOURCMO)
###########################################################################
CSDPCERTCMO:=clib/clib.cma $(addprefix plugins/micromega/, \
- mutils.cmo micromega.cmo \
+ micromega.cmo mutils.cmo \
sos_types.cmo sos_lib.cmo sos.cmo csdpcert.cmo )
$(CSDPCERT): $(call bestobj, $(CSDPCERTCMO))
@@ -807,9 +807,9 @@ OCAMLDEP = $(OCAMLFIND) ocamldep -slash -ml-synonym .mlpack
MAINMLFILES := $(filter-out gramlib/.pack/% checker/% plugins/% user-contrib/%, $(MLFILES) $(MLIFILES))
MAINMLLIBFILES := $(filter-out gramlib/.pack/% checker/% plugins/% user-contrib/%, $(MLLIBFILES) $(MLPACKFILES))
-$(MLDFILE).d: $(D_DEPEND_BEFORE_SRC) $(MAINMLFILES) $(D_DEPEND_AFTER_SRC) $(GENFILES) $(GENGRAMFILES)
+$(MLDFILE).d: $(D_DEPEND_BEFORE_SRC) $(MAINMLFILES) $(D_DEPEND_AFTER_SRC) $(GENFILES)
$(SHOW)'OCAMLDEP MLFILES MLIFILES'
- $(HIDE)$(OCAMLDEP) $(DEPFLAGS) -passrest $(MAINMLFILES) -open Gramlib $(GRAMMLFILES) $(TOTARGET)
+ $(HIDE)$(OCAMLDEP) $(DEPFLAGS) -passrest $(MAINMLFILES) -open Gramlib $(GRAMMLFILES) $(GRAMMLIFILES) $(TOTARGET)
#NB: -passrest is needed to avoid ocamlfind reordering the -open Gramlib
$(MLLIBDFILE).d: $(D_DEPEND_BEFORE_SRC) $(MAINMLLIBFILES) $(D_DEPEND_AFTER_SRC) $(OCAMLLIBDEP) $(GENFILES)
diff --git a/Makefile.ci b/Makefile.ci
index de03ee8e84..60d4b68f53 100644
--- a/Makefile.ci
+++ b/Makefile.ci
@@ -35,6 +35,7 @@ CI_TARGETS= \
ci-math-comp \
ci-mtac2 \
ci-paramcoq \
+ ci-perennial \
ci-quickchick \
ci-relation_algebra \
ci-sf \
diff --git a/Makefile.dune b/Makefile.dune
index 88055d62dc..19e8a770bd 100644
--- a/Makefile.dune
+++ b/Makefile.dune
@@ -6,7 +6,7 @@
.PHONY: quickbyte quickopt quickide # Partial / quick developer targets
.PHONY: refman-html stdlib-html apidoc # Documentation targets
.PHONY: test-suite release # Accessory targets
-.PHONY: ocheck trunk ireport clean # Maintenance targets
+.PHONY: ocheck ireport clean # Maintenance targets
# use DUNEOPT=--display=short for a more verbose build
# DUNEOPT=--display=short
@@ -36,7 +36,6 @@ help:
@echo " - release: build Coq in release mode"
@echo ""
@echo " - ocheck: build for all supported OCaml versions [requires OPAM]"
- @echo " - trunk: build with a configuration compatible with OCaml trunk"
@echo " - ireport: build with optimized flambda settings and emit an inline report"
@echo " - clean: remove build directory and autogenerated files"
@echo " - help: show this message"
@@ -103,11 +102,6 @@ release: voboot
ocheck: voboot
dune build $(DUNEOPT) @install --workspace=dev/dune-workspace.all
-trunk:
- dune build $(DUNEOPT) --profile=ocaml409 @vodeps
- dune exec coq_dune $(BUILD_CONTEXT)/.vfiles.d
- dune build $(DUNEOPT) --profile=ocaml409 coq.install coqide-server.install
-
ireport:
dune clean
dune build $(DUNEOPT) @vodeps --profile=ireport
diff --git a/Makefile.ide b/Makefile.ide
index 081d15a1a2..39c6c8ad1e 100644
--- a/Makefile.ide
+++ b/Makefile.ide
@@ -264,7 +264,7 @@ $(COQIDEAPP)/Contents/Resources/loaders: $(COQIDEAPP)/Contents
$(COQIDEAPP)/Contents/Resources/immodules: $(COQIDEAPP)/Contents
$(MKDIR) $@
- $(INSTALLLIB) "$(GTKLIBS)/gtk-3.0/3.0.0/immodules/"*.so $@
+ $(INSTALLLIB) "$(GTKLIBS)/gtk-3.0/3.0.0/immodules/"*.dylib $@
$(COQIDEAPP)/Contents/Resources/etc: $(COQIDEAPP)/Contents/Resources/lib
@@ -273,8 +273,8 @@ $(COQIDEAPP)/Contents/Resources/etc: $(COQIDEAPP)/Contents/Resources/lib
{ "$(PIXBUFBIN)/gdk-pixbuf-query-loaders" $@/../loaders/*.so |\
sed -e "s!/.*\(/loaders/.*.so\)!@executable_path/../Resources/\1!"; } \
> $@/gtk-3.0/gdk-pixbuf.loaders
- { "$(GTKBIN)/gtk-query-immodules-3.0" $@/../immodules/*.so |\
- sed -e "s!/.*\(/immodules/.*.so\)!@executable_path/../Resources/\1!" |\
+ { "$(GTKBIN)/gtk-query-immodules-3.0" $@/../immodules/*.dylib |\
+ sed -e "s!/.*\(/immodules/.*.dylib\)!@executable_path/../Resources/\1!" |\
sed -e "s!/.*\(/share/locale\)!@executable_path/../Resources/\1!"; } \
> $@/gtk-3.0/gtk-immodules.loaders
$(MKDIR) $@/pango
@@ -283,7 +283,7 @@ $(COQIDEAPP)/Contents/Resources/etc: $(COQIDEAPP)/Contents/Resources/lib
$(COQIDEAPP)/Contents/Resources/lib: $(COQIDEAPP)/Contents/Resources/immodules $(COQIDEAPP)/Contents/Resources/loaders $(COQIDEAPP)/Contents $(COQIDEINAPP)
$(MKDIR) $@
macpack -d ../Resources/lib $(COQIDEINAPP)
- for i in $@/../loaders/*.so $@/../immodules/*.so; \
+ for i in $@/../loaders/*.so $@/../immodules/*.dylib; \
do \
macpack -d ../lib $$i; \
done
diff --git a/Makefile.install b/Makefile.install
index 608e8a3c8e..456c391fd9 100644
--- a/Makefile.install
+++ b/Makefile.install
@@ -92,13 +92,13 @@ install-tools:
INSTALLCMI = $(sort \
$(filter-out checker/% ide/% tools/%, $(MLIFILES:.mli=.cmi)) \
- $(filter %.cmi, $(GRAMMLFILES:.mli=.cmi)) gramlib/.pack/gramlib.cmi \
+ $(GRAMMLIFILES:.mli=.cmi) gramlib/.pack/gramlib.cmi \
$(foreach lib,$(CORECMA), $(addsuffix .cmi,$($(lib:.cma=_MLLIB_DEPENDENCIES))))) \
$(PLUGINS:.cmo=.cmi)
INSTALLCMX = $(sort $(filter-out checker/% ide/% tools/% dev/% \
configure.cmx toplevel/coqtop_byte_bin.cmx plugins/extraction/big.cmx, \
- $(filter %.cmx, $(GRAMMLFILES:.ml=.cmx)) $(MLFILES:.ml=.cmx)))
+ $(GRAMMLFILES:.ml=.cmx) $(MLFILES:.ml=.cmx)))
install-devfiles:
$(MKDIR) $(FULLBINDIR)
diff --git a/azure-pipelines.yml b/azure-pipelines.yml
index 84f080cc73..31dcae0f82 100644
--- a/azure-pipelines.yml
+++ b/azure-pipelines.yml
@@ -58,8 +58,8 @@ jobs:
displayName: 'Install system dependencies'
env:
HOMEBREW_NO_AUTO_UPDATE: "1"
- HBCORE_DATE: "2019-06-16"
- HBCORE_REF: "944a5b7d83e4b81c749d93831b514607bdd2b6a1"
+ HBCORE_DATE: "2019-09-03"
+ HBCORE_REF: "44ee64cf4b9f2d2bf000758d356db0c77425e42e"
- script: |
set -e
@@ -72,8 +72,8 @@ jobs:
opam list
displayName: 'Install OCaml dependencies'
env:
- COMPILER: "4.08.1"
- FINDLIB_VER: ".1.8.0"
+ COMPILER: "4.09.0"
+ FINDLIB_VER: ".1.8.1"
OPAMYES: "true"
- script: |
diff --git a/checker/check.ml b/checker/check.ml
index 69de2536c5..09ecd675f7 100644
--- a/checker/check.ml
+++ b/checker/check.ml
@@ -359,7 +359,7 @@ let intern_from_file ~intern_mode (dir, f) =
(* Verification of the unmarshalled values *)
validate !Flags.debug Values.v_libsum sd;
validate !Flags.debug Values.v_lib md;
- validate !Flags.debug Values.(Opt v_opaques) table;
+ validate !Flags.debug Values.(Opt v_opaquetable) table;
Flags.if_verbose chk_pp (str" done]" ++ fnl ());
let digest =
if opaque_csts <> None then Safe_typing.Dvivo (digest,udg)
diff --git a/checker/values.ml b/checker/values.ml
index 6b340635d7..9a2028a96b 100644
--- a/checker/values.ml
+++ b/checker/values.ml
@@ -187,10 +187,24 @@ let v_substituted v_a =
let v_cstr_subst = v_substituted v_constr
-(** NB: Second constructor [Direct] isn't supposed to appear in a .vo *)
-let v_lazy_constr =
- v_sum "lazy_constr" 0 [|[|List v_subst;v_dp;Int|]|]
+let v_ndecl = v_sum "named_declaration" 0
+ [| [|v_binder_annot v_id; v_constr|]; (* LocalAssum *)
+ [|v_binder_annot v_id; v_constr; v_constr|] |] (* LocalDef *)
+
+let v_nctxt = List v_ndecl
+
+let v_work_list =
+ let v_abstr = v_pair v_instance (Array v_id) in
+ Tuple ("work_list", [|v_hmap v_cst v_abstr; v_hmap v_cst v_abstr|])
+
+let v_abstract =
+ Tuple ("abstract", [| v_nctxt; v_instance; v_abs_context |])
+let v_cooking_info =
+ Tuple ("cooking_info", [|v_work_list; v_abstract|])
+
+let v_opaque =
+ v_sum "opaque" 0 [|[|List v_subst; List v_cooking_info; v_dp; Int|]|]
(** kernel/declarations *)
@@ -216,7 +230,7 @@ let v_primitive =
let v_cst_def =
v_sum "constant_def" 0
- [|[|Opt Int|]; [|v_cstr_subst|]; [|v_lazy_constr|]; [|v_primitive|]|]
+ [|[|Opt Int|]; [|v_cstr_subst|]; [|v_opaque|]; [|v_primitive|]|]
let v_typing_flags =
v_tuple "typing_flags" [|v_bool; v_bool; v_bool; v_oracle; v_bool; v_bool; v_bool; v_bool; v_bool|]
@@ -400,25 +414,9 @@ let v_libsum =
let v_lib =
Tuple ("library",[|v_compiled_lib;v_libraryobjs|])
-let v_ndecl = v_sum "named_declaration" 0
- [| [|v_binder_annot v_id; v_constr|]; (* LocalAssum *)
- [|v_binder_annot v_id; v_constr; v_constr|] |] (* LocalDef *)
-
-let v_nctxt = List v_ndecl
-
-let v_work_list =
- let v_abstr = v_pair v_instance (Array v_id) in
- Tuple ("work_list", [|v_hmap v_cst v_abstr; v_hmap v_cst v_abstr|])
-
-let v_abstract =
- Tuple ("abstract", [| v_nctxt; v_instance; v_abs_context |])
-
-let v_cooking_info =
- Tuple ("cooking_info", [|v_work_list; v_abstract|])
-
let v_delayed_universes =
Sum ("delayed_universes", 0, [| [| v_unit |]; [| Int; v_context_set |] |])
-let v_opaques = Array (Tuple ("opaque", [| List v_cooking_info; Opt (v_pair v_constr v_delayed_universes) |]))
+let v_opaquetable = Array (Opt (v_pair v_constr v_delayed_universes))
let v_univopaques =
Opt (Tuple ("univopaques",[|v_context_set;v_bool|]))
diff --git a/checker/values.mli b/checker/values.mli
index 93983eb700..db6b0be250 100644
--- a/checker/values.mli
+++ b/checker/values.mli
@@ -46,5 +46,5 @@ type value =
val v_univopaques : value
val v_libsum : value
val v_lib : value
-val v_opaques : value
+val v_opaquetable : value
val v_stm_seg : value
diff --git a/checker/votour.ml b/checker/votour.ml
index f0e0cf22ab..5a610e6938 100644
--- a/checker/votour.ml
+++ b/checker/votour.ml
@@ -366,7 +366,7 @@ let visit_vo f =
make_seg "univ constraints of opaque proofs" Values.v_univopaques;
make_seg "discharging info" (Opt Any);
make_seg "STM tasks" (Opt Values.v_stm_seg);
- make_seg "opaque proofs" Values.v_opaques;
+ make_seg "opaque proofs" Values.v_opaquetable;
|] in
let repr =
if Sys.word_size = 64 then (module ReprMem : S) else (module ReprObj : S)
diff --git a/clib/hashset.ml b/clib/hashset.ml
index debfc15c9a..b7a245aed1 100644
--- a/clib/hashset.ml
+++ b/clib/hashset.ml
@@ -118,8 +118,8 @@ module Make (E : EqType) =
t.table.(t.rover) <- emptybucket;
t.hashes.(t.rover) <- [| |];
end else begin
- Obj.truncate (Obj.repr bucket) (prev_len + 1);
- Obj.truncate (Obj.repr hbucket) prev_len;
+ Obj.truncate (Obj.repr bucket) (prev_len + 1) [@ocaml.alert "--deprecated"];
+ Obj.truncate (Obj.repr hbucket) prev_len [@ocaml.alert "--deprecated"];
end;
if len > t.limit && prev_len <= t.limit then t.oversize <- t.oversize - 1;
end;
diff --git a/configure.ml b/configure.ml
index d7370b28c1..e59a41a8d4 100644
--- a/configure.ml
+++ b/configure.ml
@@ -12,11 +12,11 @@
#load "str.cma"
open Printf
-let coq_version = "8.10+alpha"
-let coq_macos_version = "8.9.90" (** "[...] should be a string comprised of
+let coq_version = "8.11+alpha"
+let coq_macos_version = "8.10.90" (** "[...] should be a string comprised of
three non-negative, period-separated integers [...]" *)
-let vo_magic = 8991
-let state_magic = 58991
+let vo_magic = 81091
+let state_magic = 581091
let is_a_released_version = false
let distributed_exec =
["coqtop.opt"; "coqidetop.opt"; "coqqueryworker.opt"; "coqproofworker.opt"; "coqtacticworker.opt";
diff --git a/default.nix b/default.nix
index 2d101eed57..19afc2bd1b 100644
--- a/default.nix
+++ b/default.nix
@@ -29,7 +29,7 @@
, shell ? false
# We don't use lib.inNixShell because that would also apply
# when in a nix-shell of some package depending on this one.
-, coq-version ? "8.10-git"
+, coq-version ? "8.11-git"
}:
with pkgs;
diff --git a/dev/build/windows/patches_coq/ocaml-4.07.1.patch b/dev/build/windows/patches_coq/ocaml-4.07.1.patch
index 2d61b5b838..2d61b5b838 100755..100644
--- a/dev/build/windows/patches_coq/ocaml-4.07.1.patch
+++ b/dev/build/windows/patches_coq/ocaml-4.07.1.patch
diff --git a/dev/build/windows/patches_coq/pkg-config.c b/dev/build/windows/patches_coq/pkg-config.c
index c4c7ec2bff..c4c7ec2bff 100755..100644
--- a/dev/build/windows/patches_coq/pkg-config.c
+++ b/dev/build/windows/patches_coq/pkg-config.c
diff --git a/dev/ci/azure-opam.sh b/dev/ci/azure-opam.sh
index 03ce5a6b5d..ee6c62673b 100755
--- a/dev/ci/azure-opam.sh
+++ b/dev/ci/azure-opam.sh
@@ -2,7 +2,7 @@
set -e -x
-OPAM_VARIANT=ocaml-variants.4.08.1+mingw64c
+OPAM_VARIANT=ocaml-variants.4.09.0+mingw64c
wget https://github.com/fdopen/opam-repository-mingw/releases/download/0.0.0.2/opam64.tar.xz -O opam64.tar.xz
tar -xf opam64.tar.xz
diff --git a/dev/ci/ci-basic-overlay.sh b/dev/ci/ci-basic-overlay.sh
index 3923fea30e..8db0087e3c 100755
--- a/dev/ci/ci-basic-overlay.sh
+++ b/dev/ci/ci-basic-overlay.sh
@@ -311,3 +311,10 @@
: "${argosy_CI_REF:=master}"
: "${argosy_CI_GITURL:=https://github.com/mit-pdos/argosy}"
: "${argosy_CI_ARCHIVEURL:=${argosy_CI_GITURL}/archive}"
+
+########################################################################
+# perennial
+########################################################################
+: "${perennial_CI_REF:=master}"
+: "${perennial_CI_GITURL:=https://github.com/mit-pdos/perennial}"
+: "${perennial_CI_ARCHIVEURL:=${perennial_CI_GITURL}/archive}"
diff --git a/dev/ci/ci-perennial.sh b/dev/ci/ci-perennial.sh
new file mode 100755
index 0000000000..f3be66e814
--- /dev/null
+++ b/dev/ci/ci-perennial.sh
@@ -0,0 +1,12 @@
+#!/usr/bin/env bash
+
+ci_dir="$(dirname "$0")"
+. "${ci_dir}/ci-common.sh"
+
+FORCE_GIT=1
+git_download perennial
+
+# required by Perennial's coqc.py build wrapper
+export LC_ALL=C.UTF-8
+
+( cd "${CI_BUILD_DIR}/perennial" && git submodule update --init --recursive && make TIMED=false )
diff --git a/dev/ci/docker/bionic_coq/Dockerfile b/dev/ci/docker/bionic_coq/Dockerfile
index 567f0539ab..edca83c6ef 100644
--- a/dev/ci/docker/bionic_coq/Dockerfile
+++ b/dev/ci/docker/bionic_coq/Dockerfile
@@ -1,4 +1,4 @@
-# CACHEKEY: "bionic_coq-V2019-07-09-V01"
+# CACHEKEY: "bionic_coq-V2019-09-20-V01"
# ^^ Update when modifying this file.
FROM ubuntu:bionic
@@ -37,12 +37,12 @@ ENV COMPILER="4.05.0"
# Common OPAM packages.
# `num` does not have a version number as the right version to install varies
# with the compiler version.
-ENV BASE_OPAM="num ocamlfind.1.8.0 dune.1.10.0 ounit.2.0.8 odoc.1.4.0" \
+ENV BASE_OPAM="num ocamlfind.1.8.1 dune.1.11.3 ounit.2.0.8 odoc.1.4.2" \
CI_OPAM="menhir.20190626 ocamlgraph.1.8.8" \
BASE_ONLY_OPAM="elpi.1.7.0"
# BASE switch; CI_OPAM contains Coq's CI dependencies.
-ENV COQIDE_OPAM="cairo2.0.6 lablgtk3-sourceview3.3.0.beta5"
+ENV COQIDE_OPAM="cairo2.0.6.1 lablgtk3-sourceview3.3.0.beta6"
# Must add this to COQIDE_OPAM{,_EDGE} when we update the opam
# packages "lablgtk3-gtksourceview3"
@@ -56,9 +56,9 @@ RUN opam switch create "${COMPILER}+32bit" && eval $(opam env) && \
opam install $BASE_OPAM
# EDGE switch
-ENV COMPILER_EDGE="4.08.1" \
- COQIDE_OPAM_EDGE="cairo2.0.6 lablgtk3-sourceview3.3.0.beta6" \
- BASE_OPAM_EDGE="dune-release.1.3.1"
+ENV COMPILER_EDGE="4.09.0" \
+ COQIDE_OPAM_EDGE="cairo2.0.6.1 lablgtk3-sourceview3.3.0.beta6" \
+ BASE_OPAM_EDGE="dune-release.1.3.2"
# EDGE+flambda switch, we install CI_OPAM as to be able to use
# `ci-template-flambda` with everything.
diff --git a/dev/ci/user-overlays/10727-ejgallego-library+to_vernac_step2.sh b/dev/ci/user-overlays/10727-ejgallego-library+to_vernac_step2.sh
new file mode 100644
index 0000000000..a5f6551474
--- /dev/null
+++ b/dev/ci/user-overlays/10727-ejgallego-library+to_vernac_step2.sh
@@ -0,0 +1,6 @@
+if [ "$CI_PULL_REQUEST" = "10727" ] || [ "$CI_BRANCH" = "library+to_vernac_step2" ]; then
+
+ elpi_CI_REF=library+to_vernac_step2
+ elpi_CI_GITURL=https://github.com/ejgallego/coq-elpi
+
+fi
diff --git a/dev/ci/user-overlays/10811-SkySkimmer-sprop-default-on.sh b/dev/ci/user-overlays/10811-SkySkimmer-sprop-default-on.sh
new file mode 100644
index 0000000000..d7af6b7a36
--- /dev/null
+++ b/dev/ci/user-overlays/10811-SkySkimmer-sprop-default-on.sh
@@ -0,0 +1,9 @@
+if [ "$CI_PULL_REQUEST" = "10811" ] || [ "$CI_BRANCH" = "sprop-default-on" ]; then
+
+ elpi_CI_REF=sprop-default-on
+ elpi_CI_GITURL=https://github.com/SkySkimmer/coq-elpi
+
+ coq_dpdgraph_CI_REF=sprop-default-on
+ coq_dpdgraph_CI_GITURL=https://github.com/SkySkimmer/coq-dpdgraph
+
+fi
diff --git a/dev/doc/build-system.txt b/dev/doc/build-system.txt
index a14781a058..b8987b7086 100644
--- a/dev/doc/build-system.txt
+++ b/dev/doc/build-system.txt
@@ -89,7 +89,7 @@ enables partial recalculation of dependencies (only the dependencies
of changed files are recomputed).
If you add a dependency to a Coq camlp5 extension (grammar.cma or
-q_constr.cmo), then see sections ".ml4 files" and "new files".
+q_constr.cmo), then see sections ".mlg files" and "new files".
Cleaning Targets
----------------
@@ -113,13 +113,13 @@ Targets for cleaning various parts:
- docclean: clean documentation
-.ml4/.mlp files
+.mlg/.mlp files
---------------
There is now two kinds of preprocessed files :
- a .mlp do not need grammar.cma (they are in grammar/)
- - a .ml4 is now always preprocessed with grammar.cma (and q_constr.cmo),
- except coqide_main.ml4 and its specific rule
+ - a .mlg is now always preprocessed with grammar.cma (and q_constr.cmo),
+ except coqide_main.mlg and its specific rule
This classification replaces the old mechanism of declaring the use
of a grammar extension via a line of the form:
diff --git a/dev/doc/coq-src-description.txt b/dev/doc/coq-src-description.txt
index e5e4f740bd..096ffe6a1c 100644
--- a/dev/doc/coq-src-description.txt
+++ b/dev/doc/coq-src-description.txt
@@ -20,7 +20,7 @@ Special components
grammar :
Camlp5 syntax extensions. The file grammar/grammar.cma is used
- to pre-process .ml4 files containing EXTEND constructions,
+ to pre-process .mlg files containing EXTEND constructions,
either TACTIC EXTEND, ARGUMENTS EXTEND or VERNAC ... EXTEND.
This grammar.cma incorporates many files from other directories
(mainly parsing/), plus some specific files in grammar/.
diff --git a/dev/doc/critical-bugs b/dev/doc/critical-bugs
index d00c8cb11a..78d7061259 100644
--- a/dev/doc/critical-bugs
+++ b/dev/doc/critical-bugs
@@ -129,6 +129,18 @@ Universes
GH issue number: #9294
risk: moderate risk to be activated by chance
+ component: universe polymorphism, asynchronous proofs
+ summary: universe constraints erroneously discarded when forcing an asynchronous proof containing delayed monomorphic constraints inside a universe polymorphic section
+ introduced: between 8.4 and 8.5 by merging the asynchronous proofs feature branch and universe polymorphism one
+ impacted released: V8.5-V8.10
+ impacted development branches: none
+ impacted coqchk versions: immune
+ fixed in: PR#10664
+ found by: Pédrot
+ exploit: no test
+ GH issue number: none
+ risk: unlikely to be triggered in interactive mode, not present in batch mode (i.e. coqc)
+
Primitive projections
component: primitive projections, guard condition
diff --git a/dev/doc/release-process.md b/dev/doc/release-process.md
index 452160ea5a..1c486b024d 100644
--- a/dev/doc/release-process.md
+++ b/dev/doc/release-process.md
@@ -2,6 +2,11 @@
## As soon as the previous version branched off master ##
+In principle, these steps should be undertaken by the RM of the next
+release. Unfortunately, we have not yet been able to nominate RMs
+early enough in the process for this person to be known at that point
+in time.
+
- [ ] Create a new issue to track the release process where you can copy-paste
the present checklist.
- [ ] Change the version name to the next major version and the magic
@@ -54,25 +59,39 @@
- [ ] Ping the development coordinator (**@mattam82**) to get him started on
the update to the Credits chapter of the reference manual.
See also [#7058](https://github.com/coq/coq/issues/7058).
- The command to get the list of contributors for this version is
- `git shortlog -s -n VX.X+alpha..master | cut -f2 | sort -k 2`
- (the ordering is approximative as it will misplace people with middle names).
+
+ The command that was used in the previous versions to get the list
+ of contributors for this version is `git shortlog -s -n
+ VX.X+alpha..master | cut -f2 | sort -k 2`. Note that the ordering is
+ approximative as it will misplace people with middle names. It is
+ also probably not correctly handling `Co-authored-by` info that we
+ have been using more lately, so should probably be updated to
+ account for this.
## On the date of the feature freeze ##
- [ ] Create the new version branch `vX.X` (using this name will ensure that
the branch will be automatically protected).
+- [ ] Pin the versions of libraries and plugins in
+ `dev/ci/ci-basic-overlays.sh` to use commit hashes or tag (or, if it
+ exists, a branch dedicated to compatibility with the corresponding
+ Coq branch).
- [ ] Remove all remaining unmerged feature PRs from the beta milestone.
-- [ ] Start a new project to track PR backporting. The proposed model is to
- have a "X.X-only PRs" column for the rare PRs on the stable branch, a
- "Request X.X inclusion" column for the PRs that were merged in `master` that
- are to be considered for backporting, a "Waiting for CI" column to put the
- PRs in the process of being backported, and "Shipped in ..." columns to put
- what was backported. (The release manager is the person responsible for
- merging PRs that target the version branch and backporting appropriate PRs
- that are merged into `master`).
- A message to **@coqbot** in the milestone description tells it to
- automatically add merged PRs to the "Request X.X inclusion" column.
+- [ ] Start a new project to track PR backporting. The project should
+ have a "Request X.X+beta1 inclusion" column for the PRs that were
+ merged in `master` that are to be considered for backporting, and a
+ "Shipped in X.X+beta1" columns to put what was backported. A message
+ to **@coqbot** in the milestone description tells it to
+ automatically add merged PRs to the "Request ... inclusion" column
+ and backported PRs to the "Shipped in ..." column. See previous
+ milestones for examples. When moving to the next milestone
+ (e.g. X.X.0), you can clear and remove the "Request X.X+beta1
+ inclusion" column and create new "Request X.X.0 inclusion" and
+ "Shipped in X.X.0" columns.
+
+ The release manager is the person responsible for merging PRs that
+ target the version branch and backporting appropriate PRs that are
+ merged into `master`.
- [ ] Delay non-blocking issues to the appropriate milestone and ensure
blocking issues are solved. If required to solve some blocking issues,
it is possible to revert some feature PRs in the version branch only.
@@ -80,6 +99,11 @@
## Before the beta release date ##
- [ ] Ensure the Credits chapter has been updated.
+- [ ] Prepare the release notes (see e.g.,
+ [#10833](https://github.com/coq/coq/pull/10833)): in a PR against the `master`
+ branch, move the contents from all files of `doc/changelog/` that appear in
+ the release branch into the manual `doc/sphinx/changes.rst`. Merge that PR
+ into the `master` branch and backport it to the version branch.
- [ ] Ensure that an appropriate version of the plugins we will distribute with
Coq has been tagged.
- [ ] Have some people test the recently auto-generated Windows and MacOS
@@ -120,6 +144,7 @@
## At the final release time ##
+- [ ] Prepare the release notes (see above)
- [ ] In a PR:
- Change the version name from X.X.0 and the magic numbers (see
[#7271](https://github.com/coq/coq/pull/7271/files)).
diff --git a/dev/dune-workspace.all b/dev/dune-workspace.all
index 7e53f13e45..28e8773e25 100644
--- a/dev/dune-workspace.all
+++ b/dev/dune-workspace.all
@@ -1,7 +1,7 @@
-(lang dune 1.4)
+(lang dune 1.10)
; Add custom flags here. Default developer profile is `dev`
(context (opam (switch 4.05.0)))
(context (opam (switch 4.05.0+32bit)))
-(context (opam (switch 4.08.1)))
-(context (opam (switch 4.08.1+flambda)))
+(context (opam (switch 4.09.0)))
+(context (opam (switch 4.09.0+flambda)))
diff --git a/dev/tools/make-changelog.sh b/dev/tools/make-changelog.sh
new file mode 100755
index 0000000000..ea96de970a
--- /dev/null
+++ b/dev/tools/make-changelog.sh
@@ -0,0 +1,25 @@
+#!/bin/sh
+
+echo "PR number"
+read -r PR
+
+echo "Where? (type a prefix)"
+(cd doc/changelog && ls -d */)
+read -r where
+
+where=$(echo doc/changelog/"$where"*)
+where="$where/$PR-$(git rev-parse --abbrev-ref HEAD).rst"
+
+# shellcheck disable=SC2016
+# the ` are regular strings, this is intended
+# use %s for the leading - to avoid looking like an option (not sure
+# if necessary but doesn't hurt)
+printf '%s bla bla (`#%s <https://github.com/coq/coq/pull/%s>`_, by %s).' - "$PR" "$PR" "$(git config user.name)" > "$where"
+
+giteditor=$(git config core.editor)
+if [ "$giteditor" ]; then
+ $giteditor "$where"
+elif [ "$EDITOR" ]; then
+ $EDITOR "$where"
+else echo "$where"
+fi
diff --git a/dev/v8-syntax/syntax-v8.tex b/dev/v8-syntax/syntax-v8.tex
index 601d52ddda..2f5c7128e2 100644
--- a/dev/v8-syntax/syntax-v8.tex
+++ b/dev/v8-syntax/syntax-v8.tex
@@ -727,7 +727,7 @@ Conflicts exists between integers and constrs.
\nlsep \TERM{setoid_replace} ~\tacconstr ~\KWD{with} ~\tacconstr
\nlsep \TERM{setoid_rewrite} ~\NT{orient} ~\tacconstr
\nlsep \TERM{subst} ~\STAR{\NT{ident}}
-%% eqdecide.ml4
+%% eqdecide.mlg
\nlsep \TERM{decide}~\TERM{equality} ~\OPTGR{\tacconstr~\tacconstr}
\nlsep \TERM{compare}~\tacconstr~\tacconstr
%% eauto
diff --git a/doc/changelog/01-kernel/10664-sections-stack-in-kernel.rst b/doc/changelog/01-kernel/10664-sections-stack-in-kernel.rst
new file mode 100644
index 0000000000..bac08d12ea
--- /dev/null
+++ b/doc/changelog/01-kernel/10664-sections-stack-in-kernel.rst
@@ -0,0 +1,6 @@
+- Section data is now part of the kernel. Solves a soundness issue
+ in interactive mode where global monomorphic universe constraints would be
+ dropped when forcing a delayed opaque proof inside a polymorphic section. Also
+ relaxes the nesting criterion for sections, as polymorphic sections can now
+ appear inside a monomorphic one
+ (#10664, <https://github.com/coq/coq/pull/10664> by Pierre-Marie Pédrot).
diff --git a/doc/changelog/01-kernel/10811-sprop-default-on.rst b/doc/changelog/01-kernel/10811-sprop-default-on.rst
new file mode 100644
index 0000000000..349c44c205
--- /dev/null
+++ b/doc/changelog/01-kernel/10811-sprop-default-on.rst
@@ -0,0 +1,3 @@
+- Using ``SProp`` is now allowed by default, without needing to pass
+ ``-allow-sprop`` or use :flag:`Allow StrictProp` (`#10811
+ <https://github.com/coq/coq/pull/10811>`_, by Gaëtan Gilbert).
diff --git a/doc/changelog/02-specification-language/10758-fix-10757.rst b/doc/changelog/02-specification-language/10758-fix-10757.rst
new file mode 100644
index 0000000000..4cce26aedc
--- /dev/null
+++ b/doc/changelog/02-specification-language/10758-fix-10757.rst
@@ -0,0 +1,5 @@
+- ``Program Fixpoint`` now uses ``ex`` and ``sig`` to make telescopes
+ involving ``Prop`` types (`#10758
+ <https://github.com/coq/coq/pull/10758>`_, by Gaëtan Gilbert, fixing
+ `#10757 <https://github.com/coq/coq/issues/10757>`_ reported by
+ Xavier Leroy).
diff --git a/doc/changelog/04-tactics/10765-micromega-caches.rst b/doc/changelog/04-tactics/10765-micromega-caches.rst
new file mode 100644
index 0000000000..12d8f68e63
--- /dev/null
+++ b/doc/changelog/04-tactics/10765-micromega-caches.rst
@@ -0,0 +1,3 @@
+- Introduction of flags :flag:`Lia Cache`, :flag:`Nia Cache` and :flag:`Nra Cache`.
+ (see `#10772 <https://github.com/coq/coq/issues/10772>`_ for use case)
+ (`#10765 <https://github.com/coq/coq/pull/10765>`_ fixes `#10772 <https://github.com/coq/coq/issues/10772>`_ , by Frédéric Besson).
diff --git a/doc/changelog/04-tactics/10774-zify-Z_to_N.rst b/doc/changelog/04-tactics/10774-zify-Z_to_N.rst
new file mode 100644
index 0000000000..ed46cb101e
--- /dev/null
+++ b/doc/changelog/04-tactics/10774-zify-Z_to_N.rst
@@ -0,0 +1,3 @@
+- The :tacn:`zify` tactic is now aware of `Z.to_N`.
+ (`#10774 <https://github.com/coq/coq/pull/10774>`_ fixes
+ `#9162 <https://github.com/coq/coq/issues/9162>`_, by Kazuhiko Sakaguchi).
diff --git a/doc/changelog/07-commands-and-options/10489-print_dependent_evars.rst b/doc/changelog/07-commands-and-options/10489-print_dependent_evars.rst
new file mode 100644
index 0000000000..580e808baa
--- /dev/null
+++ b/doc/changelog/07-commands-and-options/10489-print_dependent_evars.rst
@@ -0,0 +1,7 @@
+- Update output generated by :flag:`Printing Dependent Evars Line` flag
+ used by the Prooftree tool in Proof General.
+ (`#10489 <https://github.com/coq/coq/pull/10489>`_,
+ closes `#4504 <https://github.com/coq/coq/issues/4504>`_,
+ `#10399 <https://github.com/coq/coq/issues/10399>`_ and
+ `#10400 <https://github.com/coq/coq/issues/10400>`_,
+ by Jim Fehrle).
diff --git a/doc/changelog/10-standard-library/09772-ordered_type-hint-db.rst b/doc/changelog/10-standard-library/09772-ordered_type-hint-db.rst
new file mode 100644
index 0000000000..7babcdb6f1
--- /dev/null
+++ b/doc/changelog/10-standard-library/09772-ordered_type-hint-db.rst
@@ -0,0 +1,4 @@
+- Moved the `auto` hints of the `OrderedType` module into a new `ordered_type`
+ database
+ (`#9772 <https://github.com/coq/coq/pull/9772>`_,
+ by Vincent Laporte).
diff --git a/doc/changelog/README.md b/doc/changelog/README.md
index 2891eb207e..3e0970a656 100644
--- a/doc/changelog/README.md
+++ b/doc/changelog/README.md
@@ -7,25 +7,28 @@ otherwise important infrastructure changes, and important bug fixes
should get a changelog entry.
Compatibility-breaking changes should always get a changelog entry,
-which should explain what compatibility-breakage is to expect.
+which should explain what compatibility breakage is to expect.
Pull requests changing the ML API in significant ways should add an
entry in [`dev/doc/changes.md`](../../dev/doc/changes.md).
## How to add an entry? ##
-You should create a file in one of the sub-directories. The name of
-the file should be `NNNNN-identifier.rst` where `NNNNN` is the number
-of the pull request on five digits and `identifier` is whatever you
-want.
-
-This file should use the same format as the reference manual (as it
-will be copied in there). You may reference the documentation you just
-added with `:ref:`, `:tacn:`, `:cmd:`, `:opt:`, `:token:`, etc. See
+Run `./dev/tools/make-changelog.sh`: it will ask you for your PR
+number, and to choose among the predefined categories. Afterward,
+fill in the automatically generated entry with a short description of
+your change (which should describe any compatibility issues in
+particular). You may also add a reference to the relevant fixed
+issue, and credit reviewers, co-authors, and anyone who helped advance
+the PR.
+
+The format for changelog entries is the same as in the reference
+manual. In particular, you may reference the documentation you just
+added with `:ref:`, `:tacn:`, `:cmd:`, `:opt:`, `:token:`, etc. See
the [documentation of the Sphinx format](../sphinx/README.rst) of the
manual for details.
-The entry should be written using the following structure:
+Here is a summary of the structure of a changelog entry:
``` rst
- Description of the changes, with possible link to
@@ -35,7 +38,3 @@ The entry should be written using the following structure:
[ and `#ISSUE2 <https://github.com/coq/coq/issues/ISSUE2>`_],]
by Full Name[, with help / review of Full Name]).
```
-
-The description should be kept rather short and the only additional
-required meta-information are the link to the pull request and the
-full name of the author.
diff --git a/doc/sphinx/addendum/micromega.rst b/doc/sphinx/addendum/micromega.rst
index 238106b2e7..4a691bde3a 100644
--- a/doc/sphinx/addendum/micromega.rst
+++ b/doc/sphinx/addendum/micromega.rst
@@ -35,6 +35,18 @@ tactics for solving arithmetic goals over :math:`\mathbb{Q}`,
use the Simplex method for solving linear goals. If it is not set,
the decision procedures are using Fourier elimination.
+.. flag:: Lia Cache
+
+ This option (set by default) instructs :tacn:`lia` to cache its results in the file `.lia.cache`
+
+.. flag:: Nia Cache
+
+ This option (set by default) instructs :tacn:`nia` to cache its results in the file `.nia.cache`
+
+.. flag:: Nra Cache
+
+ This option (set by default) instructs :tacn:`nra` to cache its results in the file `.nra.cache`
+
The tactics solve propositional formulas parameterized by atomic
arithmetic expressions interpreted over a domain :math:`D \in \{\mathbb{Z},\mathbb{Q},\mathbb{R}\}`.
diff --git a/doc/sphinx/addendum/sprop.rst b/doc/sphinx/addendum/sprop.rst
index 8935ba27e3..9a9ec78edc 100644
--- a/doc/sphinx/addendum/sprop.rst
+++ b/doc/sphinx/addendum/sprop.rst
@@ -9,15 +9,16 @@ SProp (proof irrelevant propositions)
This section describes the extension of |Coq| with definitionally
proof irrelevant propositions (types in the sort :math:`\SProp`, also
-known as strict propositions). To use :math:`\SProp` you must pass
-``-allow-sprop`` to the |Coq| program or use :flag:`Allow StrictProp`.
+known as strict propositions). Using :math:`\SProp` may be prevented
+by passing ``-disallow-sprop`` to the |Coq| program or using
+:flag:`Allow StrictProp`.
.. flag:: Allow StrictProp
:name: Allow StrictProp
Allows using :math:`\SProp` when set and forbids it when unset. The
initial value depends on whether you used the command line
- ``-allow-sprop``.
+ ``-disallow-sprop`` and ``-allow-sprop``.
.. exn:: SProp not allowed, you need to Set Allow StrictProp or to use the -allow-sprop command-line-flag.
:undocumented:
diff --git a/doc/sphinx/addendum/universe-polymorphism.rst b/doc/sphinx/addendum/universe-polymorphism.rst
index 7e698bfb66..905068e316 100644
--- a/doc/sphinx/addendum/universe-polymorphism.rst
+++ b/doc/sphinx/addendum/universe-polymorphism.rst
@@ -147,14 +147,7 @@ Many other commands support the ``Polymorphic`` flag, including:
- :cmd:`Section` will locally set the polymorphism flag inside the section.
- ``Variables``, ``Context``, ``Universe`` and ``Constraint`` in a section support
- polymorphism. This means that the universe variables (and associated
- constraints) are discharged polymorphically over definitions that use
- them. In other words, two definitions in the section sharing a common
- variable will both get parameterized by the universes produced by the
- variable declaration. This is in contrast to a “mononorphic” variable
- which introduces global universes and constraints, making the two
- definitions depend on the *same* global universes associated to the
- variable.
+ polymorphism. See :ref:`universe-polymorphism-in-sections` for more details.
- :cmd:`Hint Resolve` and :cmd:`Hint Rewrite` will use the auto/rewrite hint
polymorphically, not at a single instance.
@@ -375,9 +368,7 @@ to universes and explicitly instantiate polymorphic definitions.
as well. Global universe names live in a separate namespace. The
command supports the ``Polymorphic`` flag only in sections, meaning the
universe quantification will be discharged on each section definition
- independently. One cannot mix polymorphic and monomorphic
- declarations in the same section.
-
+ independently.
.. cmd:: Constraint @universe_constraint
Polymorphic Constraint @universe_constraint
@@ -510,3 +501,51 @@ underscore or by omitting the annotation to a polymorphic definition.
Lemma baz : Type@{outer}. Proof. exact Type@{inner}. Qed.
About baz.
+
+.. _universe-polymorphism-in-sections:
+
+Universe polymorphism and sections
+----------------------------------
+
+:cmd:`Variables`, :cmd:`Context`, :cmd:`Universe` and
+:cmd:`Constraint` in a section support polymorphism. This means that
+the universe variables and their associated constraints are discharged
+polymorphically over definitions that use them. In other words, two
+definitions in the section sharing a common variable will both get
+parameterized by the universes produced by the variable declaration.
+This is in contrast to a “mononorphic” variable which introduces
+global universes and constraints, making the two definitions depend on
+the *same* global universes associated to the variable.
+
+It is possible to mix universe polymorphism and monomorphism in
+sections, except in the following ways:
+
+- no monomorphic constraint may refer to a polymorphic universe:
+
+ .. coqtop:: all reset
+
+ Section Foo.
+
+ Polymorphic Universe i.
+ Fail Constraint i = i.
+
+ This includes constraints implictly declared by commands such as
+ :cmd:`Variable`, which may as a such need to be used with universe
+ polymorphism activated (locally by attribute or globally by option):
+
+ .. coqtop:: all
+
+ Fail Variable A : (Type@{i} : Type).
+ Polymorphic Variable A : (Type@{i} : Type).
+
+ (in the above example the anonymous :g:`Type` constrains polymorphic
+ universe :g:`i` to be strictly smaller.)
+
+- no monomorphic constant or inductive may be declared if polymorphic
+ universes or universe constraints are present.
+
+These restrictions are required in order to produce a sensible result
+when closing the section (the requirement on constants and inductives
+is stricter than the one on constraints, because constants and
+inductives are abstracted by *all* the section's polymorphic universes
+and constraints).
diff --git a/doc/sphinx/changes.rst b/doc/sphinx/changes.rst
index 3c87fe93a3..b6fcf9da22 100644
--- a/doc/sphinx/changes.rst
+++ b/doc/sphinx/changes.rst
@@ -718,6 +718,14 @@ Changes in 8.10+beta3
follow-up of `#8365 <https://github.com/coq/coq/pull/8365>`_,
which added ``uncons`` in 8.10+beta1).
+Changes in 8.10.0
+~~~~~~~~~~~~~~~~~
+
+- Micromega tactics (:tacn:`lia`, :tacn:`nia`, etc) are no longer confused by
+ primitive projections (`#10806 <https://github.com/coq/coq/pull/10806>`_,
+ fixes `#9512 <https://github.com/coq/coq/issues/9512>`_
+ by Vincent Laporte).
+
Version 8.9
-----------
diff --git a/doc/sphinx/language/gallina-extensions.rst b/doc/sphinx/language/gallina-extensions.rst
index dc4f91e66b..2d047a1058 100644
--- a/doc/sphinx/language/gallina-extensions.rst
+++ b/doc/sphinx/language/gallina-extensions.rst
@@ -638,7 +638,11 @@ the induction principle to easily reason about the function.
than like this:
- .. coqtop:: reset all
+ .. coqtop:: reset none
+
+ Require Import FunInd.
+
+ .. coqtop:: all
Function plus (n m : nat) {struct n} : nat :=
match n with
@@ -649,17 +653,22 @@ the induction principle to easily reason about the function.
*Limitations*
-|term_0| must be built as a *pure pattern matching tree* (:g:`match … with`)
+:token:`term` must be built as a *pure pattern matching tree* (:g:`match … with`)
with applications only *at the end* of each branch.
Function does not support partial application of the function being
defined. Thus, the following example cannot be accepted due to the
presence of partial application of :g:`wrong` in the body of :g:`wrong`:
-.. coqtop:: all
+.. coqtop:: none
+
+ Require List.
+ Import List.ListNotations.
+
+.. coqtop:: all fail
- Fail Function wrong (C:nat) : nat :=
- List.hd 0 (List.map wrong (C::nil)).
+ Function wrong (C:nat) : nat :=
+ List.hd 0 (List.map wrong (C::nil)).
For now, dependent cases are not treated for non structurally
terminating functions.
diff --git a/doc/sphinx/practical-tools/utilities.rst b/doc/sphinx/practical-tools/utilities.rst
index 47ecfb9db0..9e219bd503 100644
--- a/doc/sphinx/practical-tools/utilities.rst
+++ b/doc/sphinx/practical-tools/utilities.rst
@@ -62,7 +62,7 @@ A simple example of a ``_CoqProject`` file follows:
theories/foo.v
theories/bar.v
-I src/
- src/baz.ml4
+ src/baz.mlg
src/bazaux.ml
src/qux_plugin.mlpack
@@ -111,7 +111,7 @@ decide how to build them. In particular:
+ |Coq| files must use the ``.v`` extension
+ |OCaml| files must use the ``.ml`` or ``.mli`` extension
+ |OCaml| files that require pre processing for syntax
- extensions (like ``VERNAC EXTEND``) must use the ``.ml4`` extension
+ extensions (like ``VERNAC EXTEND``) must use the ``.mlg`` extension
+ In order to generate a plugin one has to list all |OCaml|
modules (i.e. ``Baz`` for ``baz.ml``) in a ``.mlpack`` file (or ``.mllib``
file).
diff --git a/doc/sphinx/proof-engine/tactics.rst b/doc/sphinx/proof-engine/tactics.rst
index fa6d62ffa2..c910136406 100644
--- a/doc/sphinx/proof-engine/tactics.rst
+++ b/doc/sphinx/proof-engine/tactics.rst
@@ -3005,7 +3005,7 @@ the conversion in hypotheses :n:`{+ @ident}`.
flags are either ``beta``, ``delta``, ``match``, ``fix``, ``cofix``,
``iota`` or ``zeta``. The ``iota`` flag is a shorthand for ``match``, ``fix``
and ``cofix``. The ``delta`` flag itself can be refined into
- :n:`delta {+ @qualid}` or :n:`delta -{+ @qualid}`, restricting in the first
+ :n:`delta [ {+ @qualid} ]` or :n:`delta - [ {+ @qualid} ]`, restricting in the first
case the constants to unfold to the constants listed, and restricting in the
second case the constant to unfold to all but the ones explicitly mentioned.
Notice that the ``delta`` flag does not apply to variables bound by a let-in
@@ -3049,18 +3049,18 @@ the conversion in hypotheses :n:`{+ @ident}`.
This is a synonym for ``lazy beta delta iota zeta``.
-.. tacv:: compute {+ @qualid}
- cbv {+ @qualid}
+.. tacv:: compute [ {+ @qualid} ]
+ cbv [ {+ @qualid} ]
These are synonyms of :n:`cbv beta delta {+ @qualid} iota zeta`.
-.. tacv:: compute -{+ @qualid}
- cbv -{+ @qualid}
+.. tacv:: compute - [ {+ @qualid} ]
+ cbv - [ {+ @qualid} ]
These are synonyms of :n:`cbv beta delta -{+ @qualid} iota zeta`.
-.. tacv:: lazy {+ @qualid}
- lazy -{+ @qualid}
+.. tacv:: lazy [ {+ @qualid} ]
+ lazy - [ {+ @qualid} ]
These are respectively synonyms of :n:`lazy beta delta {+ @qualid} iota zeta`
and :n:`lazy beta delta -{+ @qualid} iota zeta`.
@@ -3071,7 +3071,7 @@ the conversion in hypotheses :n:`{+ @ident}`.
This tactic evaluates the goal using the optimized call-by-value evaluation
bytecode-based virtual machine described in :cite:`CompiledStrongReduction`.
This algorithm is dramatically more efficient than the algorithm used for the
- ``cbv`` tactic, but it cannot be fine-tuned. It is specially interesting for
+ :tacn:`cbv` tactic, but it cannot be fine-tuned. It is especially interesting for
full evaluation of algebraic objects. This includes the case of
reflection-based tactics.
@@ -3080,14 +3080,14 @@ the conversion in hypotheses :n:`{+ @ident}`.
This tactic evaluates the goal by compilation to OCaml as described
in :cite:`FullReduction`. If Coq is running in native code, it can be
- typically two to five times faster than ``vm_compute``. Note however that the
+ typically two to five times faster than :tacn:`vm_compute`. Note however that the
compilation cost is higher, so it is worth using only for intensive
computations.
.. flag:: NativeCompute Profiling
On Linux, if you have the ``perf`` profiler installed, this option makes
- it possible to profile ``native_compute`` evaluations.
+ it possible to profile :tacn:`native_compute` evaluations.
.. opt:: NativeCompute Profile Filename @string
:name: NativeCompute Profile Filename
@@ -3097,7 +3097,7 @@ the conversion in hypotheses :n:`{+ @ident}`.
will contain extra characters to avoid overwriting an existing file; that
filename is reported to the user.
That means you can individually profile multiple uses of
- ``native_compute`` in a script. From the Linux command line, run ``perf report``
+ :tacn:`native_compute` in a script. From the Linux command line, run ``perf report``
on the profile file to see the results. Consult the ``perf`` documentation
for more details.
@@ -3153,14 +3153,15 @@ the conversion in hypotheses :n:`{+ @ident}`.
use the name of the constant the (co)fixpoint comes from instead of
the (co)fixpoint definition in recursive calls.
- The ``cbn`` tactic is claimed to be a more principled, faster and more
- predictable replacement for ``simpl``.
+ The :tacn:`cbn` tactic is claimed to be a more principled, faster and more
+ predictable replacement for :tacn:`simpl`.
- The ``cbn`` tactic accepts the same flags as ``cbv`` and ``lazy``. The
- behavior of both ``simpl`` and ``cbn`` can be tuned using the
- Arguments vernacular command as follows:
+ The :tacn:`cbn` tactic accepts the same flags as :tacn:`cbv` and
+ :tacn:`lazy`. The behavior of both :tacn:`simpl` and :tacn:`cbn`
+ can be tuned using the Arguments vernacular command as follows:
- + A constant can be marked to be never unfolded by ``cbn`` or ``simpl``:
+ + A constant can be marked to be never unfolded by :tacn:`cbn` or
+ :tacn:`simpl`:
.. example::
@@ -3169,7 +3170,7 @@ the conversion in hypotheses :n:`{+ @ident}`.
Arguments minus n m : simpl never.
After that command an expression like :g:`(minus (S x) y)` is left
- untouched by the tactics ``cbn`` and ``simpl``.
+ untouched by the tactics :tacn:`cbn` and :tacn:`simpl`.
+ A constant can be marked to be unfolded only if applied to enough
arguments. The number of arguments required can be specified using the
@@ -3184,7 +3185,7 @@ the conversion in hypotheses :n:`{+ @ident}`.
Notation "f \o g" := (fcomp f g) (at level 50).
After that command the expression :g:`(f \o g)` is left untouched by
- ``simpl`` while :g:`((f \o g) t)` is reduced to :g:`(f (g t))`.
+ :tacn:`simpl` while :g:`((f \o g) t)` is reduced to :g:`(f (g t))`.
The same mechanism can be used to make a constant volatile, i.e.
always unfolded.
@@ -3206,7 +3207,7 @@ the conversion in hypotheses :n:`{+ @ident}`.
Arguments minus !n !m.
After that command, the expression :g:`(minus (S x) y)` is left untouched
- by ``simpl``, while :g:`(minus (S x) (S y))` is reduced to :g:`(minus x y)`.
+ by :tacn:`simpl`, while :g:`(minus (S x) (S y))` is reduced to :g:`(minus x y)`.
+ A special heuristic to determine if a constant has to be unfolded
can be activated with the following command:
@@ -3222,25 +3223,25 @@ the conversion in hypotheses :n:`{+ @ident}`.
:g:`(minus (S (S x)) (S y))` is simplified to :g:`(minus (S x) y)`
even if an extra simplification is possible.
- In detail, the tactic ``simpl`` first applies :math:`\beta`:math:`\iota`-reduction. Then, it
+ In detail, the tactic :tacn:`simpl` first applies :math:`\beta`:math:`\iota`-reduction. Then, it
expands transparent constants and tries to reduce further using :math:`\beta`:math:`\iota`-
reduction. But, when no :math:`\iota` rule is applied after unfolding then
- :math:`\delta`-reductions are not applied. For instance trying to use ``simpl`` on
+ :math:`\delta`-reductions are not applied. For instance trying to use :tacn:`simpl` on
:g:`(plus n O) = n` changes nothing.
Notice that only transparent constants whose name can be reused in the
- recursive calls are possibly unfolded by ``simpl``. For instance a
+ recursive calls are possibly unfolded by :tacn:`simpl`. For instance a
constant defined by :g:`plus' := plus` is possibly unfolded and reused in
the recursive calls, but a constant such as :g:`succ := plus (S O)` is
- never unfolded. This is the main difference between ``simpl`` and ``cbn``.
- The tactic ``cbn`` reduces whenever it will be able to reuse it or not:
+ never unfolded. This is the main difference between :tacn:`simpl` and :tacn:`cbn`.
+ The tactic :tacn:`cbn` reduces whenever it will be able to reuse it or not:
:g:`succ t` is reduced to :g:`S t`.
-.. tacv:: cbn {+ @qualid}
- cbn -{+ @qualid}
+.. tacv:: cbn [ {+ @qualid} ]
+ cbn - [ {+ @qualid} ]
- These are respectively synonyms of :n:`cbn beta delta {+ @qualid} iota zeta`
- and :n:`cbn beta delta -{+ @qualid} iota zeta` (see :tacn:`cbn`).
+ These are respectively synonyms of :n:`cbn beta delta [ {+ @qualid} ] iota zeta`
+ and :n:`cbn beta delta - [ {+ @qualid} ] iota zeta` (see :tacn:`cbn`).
.. tacv:: simpl @pattern
@@ -3249,7 +3250,7 @@ the conversion in hypotheses :n:`{+ @ident}`.
.. tacv:: simpl @pattern at {+ @num}
- This applies ``simpl`` only to the :n:`{+ @num}` occurrences of the subterms
+ This applies :tacn:`simpl` only to the :n:`{+ @num}` occurrences of the subterms
matching :n:`@pattern` in the current goal.
.. exn:: Too few occurrences.
@@ -3265,7 +3266,7 @@ the conversion in hypotheses :n:`{+ @ident}`.
.. tacv:: simpl @qualid at {+ @num}
simpl @string at {+ @num}
- This applies ``simpl`` only to the :n:`{+ @num}` applicative subterms whose
+ This applies :tacn:`simpl` only to the :n:`{+ @num}` applicative subterms whose
head occurrence is :n:`@qualid` (or :n:`@string`).
.. flag:: Debug RAKAM
@@ -3960,6 +3961,9 @@ At Coq startup, only the core database is nonempty and can be used.
:fset: internal database for the implementation of the ``FSets`` library.
+:ordered_type: lemmas about ordered types (as defined in the legacy ``OrderedType`` module),
+ mainly used in the ``FSets`` and ``FMaps`` libraries.
+
You are advised not to put your own hints in the core database, but
use one or several databases specific to your development.
diff --git a/doc/sphinx/proof-engine/vernacular-commands.rst b/doc/sphinx/proof-engine/vernacular-commands.rst
index 2885d6dc33..843459b723 100644
--- a/doc/sphinx/proof-engine/vernacular-commands.rst
+++ b/doc/sphinx/proof-engine/vernacular-commands.rst
@@ -1012,8 +1012,9 @@ Controlling display
.. flag:: Printing Dependent Evars Line
- This option controls the printing of the “(dependent evars: …)” line when
- ``-emacs`` is passed.
+ This option controls the printing of the “(dependent evars: …)” information
+ after each tactic. The information is used by the Prooftree tool in Proof
+ General. (https://askra.de/software/prooftree)
.. _vernac-controlling-the-reduction-strategies:
diff --git a/doc/stdlib/index-list.html.template b/doc/stdlib/index-list.html.template
index cc91776a4d..75c8c6c1ea 100644
--- a/doc/stdlib/index-list.html.template
+++ b/doc/stdlib/index-list.html.template
@@ -515,7 +515,9 @@ through the <tt>Require Import</tt> command.</p>
<dd>
theories/Reals/Rdefinitions.v
theories/Reals/ConstructiveReals.v
+ theories/Reals/ConstructiveRealsMorphisms.v
theories/Reals/ConstructiveCauchyReals.v
+ theories/Reals/ConstructiveCauchyRealsMult.v
theories/Reals/Raxioms.v
theories/Reals/ConstructiveRIneq.v
theories/Reals/ConstructiveRealsLUB.v
@@ -625,5 +627,6 @@ through the <tt>Require Import</tt> command.</p>
theories/Compat/Coq88.v
theories/Compat/Coq89.v
theories/Compat/Coq810.v
+ theories/Compat/Coq811.v
</dd>
</dl>
diff --git a/dune b/dune
index 6fb0612e4e..832c864fc3 100644
--- a/dune
+++ b/dune
@@ -4,9 +4,7 @@
(release (flags :standard -rectypes)
(ocamlopt_flags -O3 -unbox-closures))
(ireport (flags :standard -rectypes -w -9-27-40+60)
- (ocamlopt_flags :standard -O3 -unbox-closures -inlining-report))
- (ocaml409
- (flags :standard -strict-sequence -strict-formats -keep-locs -rectypes -w -9-27+40+60 -warn-error -5 -alert --deprecated)))
+ (ocamlopt_flags :standard -O3 -unbox-closures -inlining-report)))
; Information about flags for release mode:
;
diff --git a/engine/evarutil.ml b/engine/evarutil.ml
index c946125d3f..5444d88e47 100644
--- a/engine/evarutil.ml
+++ b/engine/evarutil.ml
@@ -661,26 +661,26 @@ let clear_hyps2_in_evi env sigma hyps t concl ids =
(* spiwack: a few functions to gather evars on which goals depend. *)
let queue_set q is_dependent set =
Evar.Set.iter (fun a -> Queue.push (is_dependent,a) q) set
-let queue_term evm q is_dependent c =
- queue_set q is_dependent (evars_of_term evm c)
+let queue_term q is_dependent c =
+ queue_set q is_dependent (evar_nodes_of_term c)
let process_dependent_evar q acc evm is_dependent e =
let evi = Evd.find evm e in
(* Queues evars appearing in the types of the goal (conclusion, then
hypotheses), they are all dependent. *)
- queue_term evm q true evi.evar_concl;
+ queue_term q true evi.evar_concl;
List.iter begin fun decl ->
let open NamedDecl in
- queue_term evm q true (NamedDecl.get_type decl);
+ queue_term q true (NamedDecl.get_type decl);
match decl with
| LocalAssum _ -> ()
- | LocalDef (_,b,_) -> queue_term evm q true b
+ | LocalDef (_,b,_) -> queue_term q true b
end (EConstr.named_context_of_val evi.evar_hyps);
match evi.evar_body with
| Evar_empty ->
if is_dependent then Evar.Map.add e None acc else acc
| Evar_defined b ->
- let subevars = evars_of_term evm b in
+ let subevars = evar_nodes_of_term b in
(* evars appearing in the definition of an evar [e] are marked
as dependent when [e] is dependent itself: if [e] is a
non-dependent goal, then, unless they are reach from another
diff --git a/engine/evd.ml b/engine/evd.ml
index 6a721a1a8a..f051334f69 100644
--- a/engine/evd.ml
+++ b/engine/evd.ml
@@ -864,7 +864,7 @@ let universe_subst evd =
UState.subst evd.universes
let merge_context_set ?loc ?(sideff=false) rigid evd ctx' =
- {evd with universes = UState.merge ?loc ~sideff ~extend:true rigid evd.universes ctx'}
+ {evd with universes = UState.merge ?loc ~sideff rigid evd.universes ctx'}
let merge_universe_subst evd subst =
{evd with universes = UState.merge_subst evd.universes subst }
@@ -1403,7 +1403,16 @@ end
let evars_of_term evd c =
let rec evrec acc c =
- match MiniEConstr.kind evd c with
+ let c = MiniEConstr.whd_evar evd c in
+ match kind c with
+ | Evar (n, l) -> Evar.Set.add n (Array.fold_left evrec acc l)
+ | _ -> Constr.fold evrec acc c
+ in
+ evrec Evar.Set.empty c
+
+let evar_nodes_of_term c =
+ let rec evrec acc c =
+ match kind c with
| Evar (n, l) -> Evar.Set.add n (Array.fold_left evrec acc l)
| _ -> Constr.fold evrec acc c
in
diff --git a/engine/evd.mli b/engine/evd.mli
index 132f7bc745..5ab53947f7 100644
--- a/engine/evd.mli
+++ b/engine/evd.mli
@@ -509,6 +509,10 @@ val loc_of_conv_pb : evar_map -> evar_constraint -> Loc.t option
val evars_of_term : evar_map -> econstr -> Evar.Set.t
(** including evars in instances of evars *)
+val evar_nodes_of_term : econstr -> Evar.Set.t
+ (** same as evars_of_term but also including defined evars.
+ For use in printing dependent evars *)
+
val evars_of_named_context : evar_map -> (econstr, etypes) Context.Named.pt -> Evar.Set.t
val evars_of_filtered_evar_info : evar_map -> evar_info -> Evar.Set.t
diff --git a/engine/proofview.ml b/engine/proofview.ml
index 1f076470c1..d6f5aab1d1 100644
--- a/engine/proofview.ml
+++ b/engine/proofview.ml
@@ -1247,7 +1247,7 @@ module V82 = struct
let top_evars initial { solution=sigma; } =
let evars_of_initial (c,_) =
- Evar.Set.elements (Evd.evars_of_term sigma c)
+ Evar.Set.elements (Evd.evar_nodes_of_term c)
in
CList.flatten (CList.map evars_of_initial initial)
diff --git a/engine/uState.ml b/engine/uState.ml
index cb40e6eadd..af714f6282 100644
--- a/engine/uState.ml
+++ b/engine/uState.ml
@@ -178,6 +178,7 @@ exception UniversesDiffer
let drop_weak_constraints = ref false
+
let process_universe_constraints ctx cstrs =
let open UnivSubst in
let open UnivProblem in
@@ -236,22 +237,21 @@ let process_universe_constraints ctx cstrs =
else
match cst with
| ULe (l, r) ->
- if UGraph.check_leq univs l r then
- (* Keep Prop/Set <= var around if var might be instantiated by prop or set
- later. *)
- match Universe.level l, Universe.level r with
- | Some l, Some r ->
- Constraint.add (l, Le, r) local
- | _ -> local
- else
- begin match Universe.level r with
- | None -> user_err Pp.(str "Algebraic universe on the right")
- | Some r' ->
- if Level.is_small r' then
+ begin match Univ.Universe.level r with
+ | None ->
+ if UGraph.check_leq univs l r then local
+ else user_err Pp.(str "Algebraic universe on the right")
+ | Some r' ->
+ if Level.is_small r' then
if not (Universe.is_levels l)
- then
+ then (* l contains a +1 and r=r' small so l <= r impossible *)
raise (UniverseInconsistency (Le, l, r, None))
else
+ if UGraph.check_leq univs l r then match Univ.Universe.level l with
+ | Some l ->
+ Univ.Constraint.add (l, Le, r') local
+ | None -> local
+ else
let levels = Universe.levels l in
let fold l' local =
let l = Universe.make l' in
@@ -260,8 +260,12 @@ let process_universe_constraints ctx cstrs =
else raise (UniverseInconsistency (Le, l, r, None))
in
LSet.fold fold levels local
- else
- enforce_leq l r local
+ else
+ match Univ.Universe.level l with
+ | Some l ->
+ Univ.Constraint.add (l, Le, r') local
+ | None ->
+ if UGraph.check_leq univs l r then local else enforce_leq l r local
end
| ULub (l, r) ->
equalize_variables true (Universe.make l) l (Universe.make r) r local
@@ -459,14 +463,6 @@ let restrict ctx vars =
let uctx' = restrict_universe_context ~lbound:ctx.uctx_universes_lbound ctx.uctx_local vars in
{ ctx with uctx_local = uctx' }
-let demote_seff_univs universes uctx =
- let open Entries in
- match universes with
- | Polymorphic_entry _ -> uctx
- | Monomorphic_entry (univs, _) ->
- let seff = LSet.union uctx.uctx_seff_univs univs in
- { uctx with uctx_seff_univs = seff }
-
type rigid =
| UnivRigid
| UnivFlexible of bool (** Is substitution by an algebraic ok? *)
@@ -481,10 +477,9 @@ let univ_flexible_alg = UnivFlexible true
context we merge comes from a side effect that is already inlined
or defined separately. In the later case, there is no extension,
see [emit_side_effects] for example. *)
-let merge ?loc ~sideff ~extend rigid uctx ctx' =
+let merge ?loc ~sideff rigid uctx ctx' =
let levels = ContextSet.levels ctx' in
let uctx =
- if not extend then uctx else
match rigid with
| UnivRigid -> uctx
| UnivFlexible b ->
@@ -493,25 +488,23 @@ let merge ?loc ~sideff ~extend rigid uctx ctx' =
else LMap.add u None accu
in
let uvars' = LSet.fold fold levels uctx.uctx_univ_variables in
- if b then
- { uctx with uctx_univ_variables = uvars';
- uctx_univ_algebraic = LSet.union uctx.uctx_univ_algebraic levels }
- else { uctx with uctx_univ_variables = uvars' }
+ if b then
+ { uctx with uctx_univ_variables = uvars';
+ uctx_univ_algebraic = LSet.union uctx.uctx_univ_algebraic levels }
+ else { uctx with uctx_univ_variables = uvars' }
in
- let uctx_local =
- if not extend then uctx.uctx_local
- else ContextSet.append ctx' uctx.uctx_local in
+ let uctx_local = ContextSet.append ctx' uctx.uctx_local in
let declare g =
LSet.fold (fun u g ->
- try UGraph.add_universe ~lbound:uctx.uctx_universes_lbound ~strict:false u g
- with UGraph.AlreadyDeclared when sideff -> g)
- levels g
+ try UGraph.add_universe ~lbound:uctx.uctx_universes_lbound ~strict:false u g
+ with UGraph.AlreadyDeclared when sideff -> g)
+ levels g
in
let uctx_names =
let fold u accu =
let modify _ info = match info.uloc with
- | None -> { info with uloc = loc }
- | Some _ -> info
+ | None -> { info with uloc = loc }
+ | Some _ -> info
in
try LMap.modify u modify accu
with Not_found -> LMap.add u { uname = None; uloc = loc } accu
@@ -527,9 +520,38 @@ let merge ?loc ~sideff ~extend rigid uctx ctx' =
let merge_subst uctx s =
{ uctx with uctx_univ_variables = LMap.subst_union uctx.uctx_univ_variables s }
+let demote_seff_univs (univs,_) uctx =
+ let seff = LSet.union uctx.uctx_seff_univs univs in
+ { uctx with uctx_seff_univs = seff }
+
+let merge_seff uctx ctx' =
+ let levels = ContextSet.levels ctx' in
+ let declare g =
+ LSet.fold (fun u g ->
+ try UGraph.add_universe ~lbound:uctx.uctx_universes_lbound ~strict:false u g
+ with UGraph.AlreadyDeclared -> g)
+ levels g
+ in
+ let initial = declare uctx.uctx_initial_universes in
+ let univs = declare uctx.uctx_universes in
+ let uctx_universes = UGraph.merge_constraints (ContextSet.constraints ctx') univs in
+ { uctx with uctx_universes;
+ uctx_initial_universes = initial }
+
let emit_side_effects eff u =
let uctxs = Safe_typing.universes_of_private eff in
- List.fold_left (merge ~sideff:true ~extend:false univ_rigid) u uctxs
+ List.fold_left (fun u uctx ->
+ let u = demote_seff_univs uctx u in
+ merge_seff u uctx)
+ u uctxs
+
+let update_sigma_env uctx env =
+ let univs = UGraph.make_sprop_cumulative (Environ.universes env) in
+ let eunivs =
+ { uctx with uctx_initial_universes = univs;
+ uctx_universes = univs }
+ in
+ merge_seff eunivs eunivs.uctx_local
let new_univ_variable ?loc rigid name
({ uctx_local = ctx; uctx_univ_variables = uvars; uctx_univ_algebraic = avars} as uctx) =
@@ -726,14 +748,6 @@ let minimize uctx =
let universe_of_name uctx s =
UNameMap.find s (fst uctx.uctx_names)
-let update_sigma_env uctx env =
- let univs = UGraph.make_sprop_cumulative (Environ.universes env) in
- let eunivs =
- { uctx with uctx_initial_universes = univs;
- uctx_universes = univs }
- in
- merge ~sideff:true ~extend:false univ_rigid eunivs eunivs.uctx_local
-
let pr_weak prl {uctx_weak_constraints=weak} =
let open Pp in
prlist_with_sep fnl (fun (u,v) -> prl u ++ str " ~ " ++ prl v) (UPairSet.elements weak)
diff --git a/engine/uState.mli b/engine/uState.mli
index 52e48c4eeb..7cb2f49780 100644
--- a/engine/uState.mli
+++ b/engine/uState.mli
@@ -100,8 +100,6 @@ val restrict_universe_context : lbound:Univ.Level.t -> ContextSet.t -> LSet.t ->
universes are preserved. *)
val restrict : t -> Univ.LSet.t -> t
-val demote_seff_univs : Entries.universes_entry -> t -> t
-
type rigid =
| UnivRigid
| UnivFlexible of bool (** Is substitution by an algebraic ok? *)
@@ -110,7 +108,7 @@ val univ_rigid : rigid
val univ_flexible : rigid
val univ_flexible_alg : rigid
-val merge : ?loc:Loc.t -> sideff:bool -> extend:bool -> rigid -> t -> Univ.ContextSet.t -> t
+val merge : ?loc:Loc.t -> sideff:bool -> rigid -> t -> Univ.ContextSet.t -> t
val merge_subst : t -> UnivSubst.universe_opt_subst -> t
val emit_side_effects : Safe_typing.private_constants -> t -> t
diff --git a/ide/coq2.ico b/ide/coq2.ico
index bc1732fd99..bc1732fd99 100755..100644
--- a/ide/coq2.ico
+++ b/ide/coq2.ico
Binary files differ
diff --git a/ide/wg_ScriptView.ml b/ide/wg_ScriptView.ml
index 279815d671..181418d3d8 100644
--- a/ide/wg_ScriptView.ml
+++ b/ide/wg_ScriptView.ml
@@ -408,10 +408,8 @@ object (self)
| _ -> ()
method apply_unicode_binding () =
- (* Auxiliary method to reach the beginning of line or the
- nearest space before the iterator. *)
let rec get_line_start iter =
- if iter#starts_line || Glib.Unichar.isspace iter#char then iter
+ if iter#starts_line then iter
else get_line_start iter#backward_char
in
(* Main action *)
diff --git a/interp/modintern.ml b/interp/modintern.ml
index 955288244e..ddf5b2d7b1 100644
--- a/interp/modintern.ml
+++ b/interp/modintern.ml
@@ -12,7 +12,6 @@ open Declarations
open Libnames
open Constrexpr
open Constrintern
-open Declaremods
type module_internalization_error =
| NotAModuleNorModtype of string
@@ -21,9 +20,11 @@ type module_internalization_error =
exception ModuleInternalizationError of module_internalization_error
+type module_kind = Module | ModType | ModAny
+
let error_not_a_module_loc kind loc qid =
let s = string_of_qualid qid in
- let e = let open Declaremods in match kind with
+ let e = match kind with
| Module -> Modops.ModuleTypingError (Modops.NotAModule s)
| ModType -> Modops.ModuleTypingError (Modops.NotAModuleType s)
| ModAny -> ModuleInternalizationError (NotAModuleNorModtype s)
@@ -46,7 +47,6 @@ let error_application_to_module_type loc =
it is equal to the input kind when this one isn't ModAny. *)
let lookup_module_or_modtype kind qid =
- let open Declaremods in
let loc = qid.CAst.loc in
try
if kind == ModType then raise Not_found;
diff --git a/interp/modintern.mli b/interp/modintern.mli
index 75ab38c64a..72695a680e 100644
--- a/interp/modintern.mli
+++ b/interp/modintern.mli
@@ -28,5 +28,7 @@ exception ModuleInternalizationError of module_internalization_error
kind is never ModAny, and it is equal to the input kind when this one
isn't ModAny. *)
+type module_kind = Module | ModType | ModAny
+
val interp_module_ast :
- env -> Declaremods.module_kind -> module_ast -> module_struct_entry * Declaremods.module_kind * Univ.ContextSet.t
+ env -> module_kind -> module_ast -> module_struct_entry * module_kind * Univ.ContextSet.t
diff --git a/kernel/cooking.ml b/kernel/cooking.ml
index 0951b07d49..fae06f7163 100644
--- a/kernel/cooking.ml
+++ b/kernel/cooking.ml
@@ -161,7 +161,7 @@ type 'opaque result = {
cook_universes : universes;
cook_relevance : Sorts.relevance;
cook_inline : inline;
- cook_context : Constr.named_context option;
+ cook_context : Id.Set.t option;
}
let expmod_constr_subst cache modlist subst c =
@@ -239,14 +239,10 @@ let cook_constant { from = cb; info } =
| Undef _ as x -> x
| Def cs -> Def (Mod_subst.from_val (map (Mod_subst.force_constr cs)))
| OpaqueDef o ->
- OpaqueDef (Opaqueproof.discharge_direct_opaque info o)
+ OpaqueDef (Opaqueproof.discharge_opaque info o)
| Primitive _ -> CErrors.anomaly (Pp.str "Primitives cannot be cooked")
in
- let const_hyps =
- Context.Named.fold_outside (fun decl hyps ->
- List.filter (fun decl' -> not (Id.equal (NamedDecl.get_id decl) (NamedDecl.get_id decl')))
- hyps)
- hyps0 ~init:cb.const_hyps in
+ let const_hyps = Id.Set.diff (Context.Named.to_vars cb.const_hyps) (Context.Named.to_vars hyps0) in
let typ = abstract_constant_type (expmod cb.const_type) hyps in
{
cook_body = body;
diff --git a/kernel/cooking.mli b/kernel/cooking.mli
index 671cdf51fe..83a8b9edfc 100644
--- a/kernel/cooking.mli
+++ b/kernel/cooking.mli
@@ -23,7 +23,7 @@ type 'opaque result = {
cook_universes : universes;
cook_relevance : Sorts.relevance;
cook_inline : inline;
- cook_context : Constr.named_context option;
+ cook_context : Names.Id.Set.t option;
}
val cook_constant : recipe -> Opaqueproof.opaque result
diff --git a/kernel/entries.ml b/kernel/entries.ml
index 47e2f72b0e..1e6bc14935 100644
--- a/kernel/entries.ml
+++ b/kernel/entries.ml
@@ -61,7 +61,7 @@ type mutual_inductive_entry = {
type definition_entry = {
const_entry_body : constr;
(* List of section variables *)
- const_entry_secctx : Constr.named_context option;
+ const_entry_secctx : Id.Set.t option;
(* State id on which the completion of type checking is reported *)
const_entry_feedback : Stateid.t option;
const_entry_type : types option;
@@ -70,7 +70,7 @@ type definition_entry = {
type section_def_entry = {
secdef_body : constr;
- secdef_secctx : Constr.named_context option;
+ secdef_secctx : Id.Set.t option;
secdef_feedback : Stateid.t option;
secdef_type : types option;
}
@@ -78,7 +78,7 @@ type section_def_entry = {
type 'a opaque_entry = {
opaque_entry_body : 'a;
(* List of section variables *)
- opaque_entry_secctx : Constr.named_context;
+ opaque_entry_secctx : Id.Set.t;
(* State id on which the completion of type checking is reported *)
opaque_entry_feedback : Stateid.t option;
opaque_entry_type : types;
@@ -88,7 +88,7 @@ type 'a opaque_entry = {
type inline = int option (* inlining level, None for no inlining *)
type parameter_entry =
- Constr.named_context option * types in_universes_entry * inline
+ Id.Set.t option * types in_universes_entry * inline
type primitive_entry = {
prim_entry_type : types option;
diff --git a/pretyping/inferCumulativity.ml b/kernel/inferCumulativity.ml
index ed069eace0..3b8c2cd788 100644
--- a/pretyping/inferCumulativity.ml
+++ b/kernel/inferCumulativity.ml
@@ -77,7 +77,7 @@ let infer_sort cv_pb variances s =
| CUMUL ->
LSet.fold infer_level_leq (Universe.levels (Sorts.univ_of_sort s)) variances
-let infer_table_key infos variances c =
+let infer_table_key variances c =
let open Names in
match c with
| ConstKey (_, u) ->
@@ -103,7 +103,7 @@ let rec infer_fterm cv_pb infos variances hd stk =
| FRel _ -> infer_stack infos variances stk
| FInt _ -> infer_stack infos variances stk
| FFlex fl ->
- let variances = infer_table_key infos variances fl in
+ let variances = infer_table_key variances fl in
infer_stack infos variances stk
| FProj (_,c) ->
let variances = infer_fterm CONV infos variances c [] in
@@ -152,7 +152,7 @@ and infer_stack infos variances (stk:CClosure.stack) =
| Zfix (fx,a) ->
let variances = infer_fterm CONV infos variances fx [] in
infer_stack infos variances a
- | ZcaseT (ci,p,br,e) ->
+ | ZcaseT (_, p, br, e) ->
let variances = infer_fterm CONV infos variances (mk_clos e p) [] in
infer_vect infos variances (Array.map (mk_clos e) br)
| Zshift _ -> variances
@@ -195,7 +195,7 @@ let infer_inductive_core env params entries uctx =
Array.fold_left (fun variances u -> LMap.add u IrrelevantI variances)
LMap.empty uarray
in
- let env, params = Typeops.check_context env params in
+ let env, _ = Typeops.check_context env params in
let variances = List.fold_left (fun variances entry ->
let variances = infer_arity_constructor true
env variances entry.mind_entry_arity
@@ -213,9 +213,8 @@ let infer_inductive_core env params entries uctx =
let infer_inductive env mie =
let open Entries in
- let { mind_entry_params = params;
- mind_entry_inds = entries; } = mie
- in
+ let params = mie.mind_entry_params in
+ let entries = mie.mind_entry_inds in
let variances =
match mie.mind_entry_variance with
| None -> None
diff --git a/pretyping/inferCumulativity.mli b/kernel/inferCumulativity.mli
index a234e334d1..a234e334d1 100644
--- a/pretyping/inferCumulativity.mli
+++ b/kernel/inferCumulativity.mli
diff --git a/kernel/kernel.mllib b/kernel/kernel.mllib
index 59c1d5890f..20e742d7f8 100644
--- a/kernel/kernel.mllib
+++ b/kernel/kernel.mllib
@@ -43,9 +43,11 @@ Inductive
Typeops
IndTyping
Indtypes
+InferCumulativity
Cooking
Term_typing
Subtyping
Mod_typing
Nativelibrary
+Section
Safe_typing
diff --git a/kernel/nativevalues.ml b/kernel/nativevalues.ml
index e54118c775..f788832d5b 100644
--- a/kernel/nativevalues.ml
+++ b/kernel/nativevalues.ml
@@ -96,14 +96,14 @@ let mk_accu (a : atom) : t =
else
let data = { data with acc_arg = x :: data.acc_arg } in
let ans = Obj.repr (accumulate data) in
- let () = Obj.set_tag ans accumulate_tag in
+ let () = Obj.set_tag ans accumulate_tag [@ocaml.alert "--deprecated"] in
ans
in
let acc = { acc_atm = a; acc_arg = [] } in
let ans = Obj.repr (accumulate acc) in
(** FIXME: use another representation for accumulators, this causes naked
pointers. *)
- let () = Obj.set_tag ans accumulate_tag in
+ let () = Obj.set_tag ans accumulate_tag [@ocaml.alert "--deprecated"] in
(Obj.obj ans : t)
let get_accu (k : accumulator) =
diff --git a/kernel/opaqueproof.ml b/kernel/opaqueproof.ml
index e256466112..f0b706e4f5 100644
--- a/kernel/opaqueproof.ml
+++ b/kernel/opaqueproof.ml
@@ -24,7 +24,7 @@ type 'a delayed_universes =
| PrivateMonomorphic of 'a
| PrivatePolymorphic of int * Univ.ContextSet.t
-type opaque_proofterm = cooking_info list * (Constr.t * unit delayed_universes) option
+type opaque_proofterm = (Constr.t * unit delayed_universes) option
type indirect_accessor = {
access_proof : DirPath.t -> int -> opaque_proofterm;
@@ -38,10 +38,10 @@ let drop_mono = function
type proofterm = (constr * Univ.ContextSet.t delayed_universes) Future.computation
type opaque =
- | Indirect of substitution list * DirPath.t * int (* subst, lib, index *)
- | Direct of cooking_info list * proofterm
+| Indirect of substitution list * cooking_info list * DirPath.t * int (* subst, discharge, lib, index *)
+
type opaquetab = {
- opaque_val : (cooking_info list * proofterm) Int.Map.t;
+ opaque_val : proofterm Int.Map.t;
(** Actual proof terms *)
opaque_len : int;
(** Size of the above map *)
@@ -56,44 +56,33 @@ let empty_opaquetab = {
let not_here () =
CErrors.user_err Pp.(str "Cannot access opaque delayed proof")
-let create cu = Direct ([],cu)
-
-let turn_indirect dp o tab = match o with
- | Indirect (_,_,i) ->
- if not (Int.Map.mem i tab.opaque_val)
- then CErrors.anomaly (Pp.str "Indirect in a different table.")
- else CErrors.anomaly (Pp.str "Already an indirect opaque.")
- | Direct (d, cu) ->
- (* Invariant: direct opaques only exist inside sections, we turn them
- indirect as soon as we are at toplevel. At this moment, we perform
- hashconsing of their contents, potentially as a future. *)
- let hcons (c, u) =
- let c = Constr.hcons c in
- let u = match u with
- | PrivateMonomorphic u -> PrivateMonomorphic (Univ.hcons_universe_context_set u)
- | PrivatePolymorphic (n, u) -> PrivatePolymorphic (n, Univ.hcons_universe_context_set u)
- in
- (c, u)
- in
- let cu = Future.chain cu hcons in
- let id = tab.opaque_len in
- let opaque_val = Int.Map.add id (d,cu) tab.opaque_val in
- let opaque_dir =
- if DirPath.equal dp tab.opaque_dir then tab.opaque_dir
- else if DirPath.equal tab.opaque_dir DirPath.initial then dp
- else CErrors.anomaly
- (Pp.str "Using the same opaque table for multiple dirpaths.") in
- let ntab = { opaque_val; opaque_dir; opaque_len = id + 1 } in
- Indirect ([],dp,id), ntab
+let create dp cu tab =
+ let hcons (c, u) =
+ let c = Constr.hcons c in
+ let u = match u with
+ | PrivateMonomorphic u -> PrivateMonomorphic (Univ.hcons_universe_context_set u)
+ | PrivatePolymorphic (n, u) -> PrivatePolymorphic (n, Univ.hcons_universe_context_set u)
+ in
+ (c, u)
+ in
+ let cu = Future.chain cu hcons in
+ let id = tab.opaque_len in
+ let opaque_val = Int.Map.add id cu tab.opaque_val in
+ let opaque_dir =
+ if DirPath.equal dp tab.opaque_dir then tab.opaque_dir
+ else if DirPath.equal tab.opaque_dir DirPath.initial then dp
+ else CErrors.anomaly
+ (Pp.str "Using the same opaque table for multiple dirpaths.") in
+ let ntab = { opaque_val; opaque_dir; opaque_len = id + 1 } in
+ Indirect ([], [], dp, id), ntab
let subst_opaque sub = function
- | Indirect (s,dp,i) -> Indirect (sub::s,dp,i)
- | Direct _ -> CErrors.anomaly (Pp.str "Substituting a Direct opaque.")
+| Indirect (s, ci, dp, i) -> Indirect (sub :: s, ci, dp, i)
-let discharge_direct_opaque ci = function
- | Indirect _ -> CErrors.anomaly (Pp.str "Not a direct opaque.")
- | Direct (d, cu) ->
- Direct (ci :: d, cu)
+let discharge_opaque info = function
+| Indirect (s, ci, dp, i) ->
+ assert (CList.is_empty s);
+ Indirect ([], info :: ci, dp, i)
let join except cu = match except with
| None -> ignore (Future.join cu)
@@ -102,25 +91,21 @@ let join except cu = match except with
else ignore (Future.join cu)
let join_opaque ?except { opaque_val = prfs; opaque_dir = odp; _ } = function
- | Direct (_,cu) -> join except cu
- | Indirect (_,dp,i) ->
- if DirPath.equal dp odp then
- let (_, fp) = Int.Map.find i prfs in
- join except fp
+| Indirect (_,_,dp,i) ->
+ if DirPath.equal dp odp then
+ let fp = Int.Map.find i prfs in
+ join except fp
let force_proof access { opaque_val = prfs; opaque_dir = odp; _ } = function
- | Direct (d, cu) ->
- let (c, u) = Future.force cu in
- access.access_discharge d (c, drop_mono u)
- | Indirect (l,dp,i) ->
+ | Indirect (l,d,dp,i) ->
let c, u =
if DirPath.equal dp odp
then
- let (d, cu) = Int.Map.find i prfs in
+ let cu = Int.Map.find i prfs in
let (c, u) = Future.force cu in
access.access_discharge d (c, drop_mono u)
else
- let (d, cu) = access.access_proof dp i in
+ let cu = access.access_proof dp i in
match cu with
| None -> not_here ()
| Some (c, u) -> access.access_discharge d (c, u)
@@ -133,26 +118,19 @@ let get_mono (_, u) = match u with
| PrivatePolymorphic _ -> Univ.ContextSet.empty
let force_constraints _access { opaque_val = prfs; opaque_dir = odp; _ } = function
- | Direct (_,cu) ->
- get_mono (Future.force cu)
- | Indirect (_,dp,i) ->
+| Indirect (_,_,dp,i) ->
if DirPath.equal dp odp
then
- let ( _, cu) = Int.Map.find i prfs in
+ let cu = Int.Map.find i prfs in
get_mono (Future.force cu)
else Univ.ContextSet.empty
-let get_direct_constraints = function
-| Indirect _ -> CErrors.anomaly (Pp.str "Not a direct opaque.")
-| Direct (_, cu) ->
- Future.chain cu get_mono
-
module FMap = Future.UUIDMap
let dump ?(except = Future.UUIDSet.empty) { opaque_val = otab; opaque_len = n; _ } =
- let opaque_table = Array.make n ([], None) in
+ let opaque_table = Array.make n None in
let f2t_map = ref FMap.empty in
- let iter n (d, cu) =
+ let iter n cu =
let uid = Future.uuid cu in
let () = f2t_map := FMap.add (Future.uuid cu) n !f2t_map in
let c =
@@ -165,7 +143,7 @@ let dump ?(except = Future.UUIDSet.empty) { opaque_val = otab; opaque_len = n; _
CErrors.anomaly
Pp.(str"Proof object "++int n++str" is not checked nor to be checked")
in
- opaque_table.(n) <- (d, c)
+ opaque_table.(n) <- c
in
let () = Int.Map.iter iter otab in
opaque_table, !f2t_map
diff --git a/kernel/opaqueproof.mli b/kernel/opaqueproof.mli
index 7c53656c3c..1870241dcd 100644
--- a/kernel/opaqueproof.mli
+++ b/kernel/opaqueproof.mli
@@ -16,10 +16,7 @@ open Mod_subst
Opaque proof terms are special since:
- they can be lazily computed and substituted
- they are stored in an optionally loaded segment of .vo files
- An [opaque] proof terms holds the real data until fully discharged.
- In this case it is called [direct].
- When it is [turn_indirect] the data is relocated to an opaque table
- and the [opaque] is turned into an index. *)
+ An [opaque] proof terms holds an index into an opaque table. *)
type 'a delayed_universes =
| PrivateMonomorphic of 'a
@@ -33,12 +30,7 @@ type opaque
val empty_opaquetab : opaquetab
(** From a [proofterm] to some [opaque]. *)
-val create : proofterm -> opaque
-
-(** Turn a direct [opaque] into an indirect one. It is your responsibility to
- hashcons the inner term beforehand. The integer is an hint of the maximum id
- used so far *)
-val turn_indirect : DirPath.t -> opaque -> opaquetab -> opaque * opaquetab
+val create : DirPath.t -> proofterm -> opaquetab -> opaque * opaquetab
type work_list = (Univ.Instance.t * Id.t array) Cmap.t *
(Univ.Instance.t * Id.t array) Mindmap.t
@@ -47,14 +39,14 @@ type cooking_info = {
modlist : work_list;
abstract : Constr.named_context * Univ.Instance.t * Univ.AUContext.t }
-type opaque_proofterm = cooking_info list * (Constr.t * unit delayed_universes) option
+type opaque_proofterm = (Constr.t * unit delayed_universes) option
type indirect_accessor = {
access_proof : DirPath.t -> int -> opaque_proofterm;
access_discharge : cooking_info list ->
(Constr.t * unit delayed_universes) -> (Constr.t * unit delayed_universes);
}
-(** When stored indirectly, opaque terms are indexed by their library
+(** Opaque terms are indexed by their library
dirpath and an integer index. The two functions above activate
this indirect storage, by telling how to retrieve terms.
*)
@@ -63,11 +55,10 @@ type indirect_accessor = {
indirect opaque accessor given as an argument. *)
val force_proof : indirect_accessor -> opaquetab -> opaque -> constr * unit delayed_universes
val force_constraints : indirect_accessor -> opaquetab -> opaque -> Univ.ContextSet.t
-val get_direct_constraints : opaque -> Univ.ContextSet.t Future.computation
val subst_opaque : substitution -> opaque -> opaque
-val discharge_direct_opaque :
+val discharge_opaque :
cooking_info -> opaque -> opaque
val join_opaque : ?except:Future.UUIDSet.t -> opaquetab -> opaque -> unit
diff --git a/kernel/safe_typing.ml b/kernel/safe_typing.ml
index 6970a11e72..9b4d2e69ac 100644
--- a/kernel/safe_typing.ml
+++ b/kernel/safe_typing.ml
@@ -113,8 +113,16 @@ type library_info = DirPath.t * vodigest
(** Functor and funsig parameters, most recent first *)
type module_parameters = (MBId.t * module_type_body) list
+(** Part of the safe_env at a section opening time to be backtracked *)
+type section_data = {
+ rev_env : Environ.env;
+ rev_univ : Univ.ContextSet.t;
+ rev_objlabels : Label.Set.t;
+}
+
type safe_environment =
{ env : Environ.env;
+ sections : section_data Section.t;
modpath : ModPath.t;
modvariant : modvariant;
modresolver : Mod_subst.delta_resolver;
@@ -151,6 +159,7 @@ let empty_environment =
revstruct = [];
modlabels = Label.Set.empty;
objlabels = Label.Set.empty;
+ sections = Section.empty;
future_cst = [];
univ = Univ.ContextSet.empty;
engagement = None;
@@ -317,14 +326,23 @@ let universes_of_private eff =
let env_of_safe_env senv = senv.env
let env_of_senv = env_of_safe_env
+let sections_of_safe_env senv = senv.sections
+
type constraints_addition =
| Now of Univ.ContextSet.t
| Later of Univ.ContextSet.t Future.computation
let push_context_set poly cst senv =
- { senv with
- env = Environ.push_context_set ~strict:(not poly) cst senv.env;
- univ = Univ.ContextSet.union cst senv.univ }
+ if Univ.ContextSet.is_empty cst then senv
+ else
+ let sections =
+ if Section.is_empty senv.sections then senv.sections
+ else Section.push_constraints cst senv.sections
+ in
+ { senv with
+ env = Environ.push_context_set ~strict:(not poly) cst senv.env;
+ univ = Univ.ContextSet.union cst senv.univ;
+ sections }
let add_constraints cst senv =
match cst with
@@ -386,7 +404,7 @@ let check_current_library dir senv = match senv.modvariant with
(** When operating on modules, we're normally outside sections *)
let check_empty_context senv =
- assert (Environ.empty_context senv.env)
+ assert (Environ.empty_context senv.env && Section.is_empty senv.sections)
(** When adding a parameter to the current module/modtype,
it must have been freshly started *)
@@ -433,19 +451,30 @@ let safe_push_named d env =
with Not_found -> () in
Environ.push_named d env
-
let push_named_def (id,de) senv =
+ let sections = Section.push_local senv.sections in
let c, r, typ = Term_typing.translate_local_def senv.env id de in
let x = Context.make_annot id r in
let env'' = safe_push_named (LocalDef (x, c, typ)) senv.env in
- { senv with env = env'' }
+ { senv with sections; env = env'' }
let push_named_assum (x,t) senv =
+ let sections = Section.push_local senv.sections in
let t, r = Term_typing.translate_local_assum senv.env t in
let x = Context.make_annot x r in
let env'' = safe_push_named (LocalAssum (x,t)) senv.env in
- {senv with env=env''}
-
+ { senv with sections; env = env'' }
+
+let push_section_context (nas, ctx) senv =
+ let sections = Section.push_context (nas, ctx) senv.sections in
+ let senv = { senv with sections } in
+ let ctx = Univ.ContextSet.of_context ctx in
+ (* We check that the universes are fresh. FIXME: This should be done
+ implicitly, but we have to work around the API. *)
+ let () = assert (Univ.LSet.for_all (fun u -> not (Univ.LSet.mem u (fst senv.univ))) (fst ctx)) in
+ { senv with
+ env = Environ.push_context_set ~strict:false ctx senv.env;
+ univ = Univ.ContextSet.union ctx senv.univ }
(** {6 Insertion of new declarations to current environment } *)
@@ -527,8 +556,19 @@ let add_field ?(is_include=false) ((l,sfb) as field) gn senv =
| SFBmodule mb, M -> Modops.add_module mb senv.env
| _ -> assert false
in
+ let sections = match sfb, gn with
+ | SFBconst cb, C con ->
+ let poly = Declareops.constant_is_polymorphic cb in
+ Section.push_constant ~poly con senv.sections
+ | SFBmind mib, I mind ->
+ let poly = Declareops.inductive_is_polymorphic mib in
+ Section.push_inductive ~poly mind senv.sections
+ | _, (M | MT) -> senv.sections
+ | _ -> assert false
+ in
{ senv with
env = env';
+ sections;
revstruct = field :: senv.revstruct;
modlabels = Label.Set.union mlabs senv.modlabels;
objlabels = Label.Set.union olabs senv.objlabels }
@@ -549,30 +589,9 @@ type exported_private_constant = Constant.t
let add_constant_aux ~in_section senv (kn, cb) =
let l = Constant.label kn in
- let delayed_cst = match cb.const_body with
- | OpaqueDef o when not (Declareops.constant_is_polymorphic cb) ->
- let fc = Opaqueproof.get_direct_constraints o in
- begin match Future.peek_val fc with
- | None -> [Later fc]
- | Some c -> [Now c]
- end
- | Undef _ | Def _ | Primitive _ | OpaqueDef _ -> []
- in
(* This is the only place where we hashcons the contents of a constant body *)
let cb = if in_section then cb else Declareops.hcons_const_body cb in
- let cb, otab = match cb.const_body with
- | OpaqueDef lc when not in_section ->
- (* In coqc, opaque constants outside sections will be stored
- indirectly in a specific table *)
- let od, otab =
- Opaqueproof.turn_indirect
- (library_dp_of_senv senv) lc (Environ.opaque_tables senv.env) in
- { cb with const_body = OpaqueDef od }, otab
- | _ -> cb, (Environ.opaque_tables senv.env)
- in
- let senv = { senv with env = Environ.set_opaque_tables senv.env otab } in
let senv' = add_field (l,SFBconst cb) (C kn) senv in
- let senv' = add_constraints_list delayed_cst senv' in
let senv'' = match cb.const_body with
| Undef (Some lev) ->
update_resolver
@@ -703,7 +722,7 @@ let constant_entry_of_side_effect eff =
if Declareops.is_opaque cb then
OpaqueEff {
opaque_entry_body = Future.from_val ((p, Univ.ContextSet.empty), ());
- opaque_entry_secctx = cb.const_hyps;
+ opaque_entry_secctx = Context.Named.to_vars cb.const_hyps;
opaque_entry_feedback = None;
opaque_entry_type = cb.const_type;
opaque_entry_universes = univs;
@@ -711,7 +730,7 @@ let constant_entry_of_side_effect eff =
else
DefinitionEff {
const_entry_body = p;
- const_entry_secctx = Some cb.const_hyps;
+ const_entry_secctx = Some (Context.Named.to_vars cb.const_hyps);
const_entry_feedback = None;
const_entry_type = Some cb.const_type;
const_entry_universes = univs;
@@ -775,27 +794,30 @@ let export_side_effects mb env (b_ctx, eff) =
in
translate_seff trusted seff [] env
+let push_opaque_proof pf senv =
+ let o, otab = Opaqueproof.create (library_dp_of_senv senv) pf (Environ.opaque_tables senv.env) in
+ let senv = { senv with env = Environ.set_opaque_tables senv.env otab } in
+ senv, o
+
let export_private_constants ~in_section ce senv =
let exported, ce = export_side_effects senv.revstruct senv.env ce in
- let map univs p =
- let local = match univs with
+ let map senv (kn, c) = match c.const_body with
+ | OpaqueDef p ->
+ let local = match c.const_universes with
| Monomorphic _ -> Opaqueproof.PrivateMonomorphic Univ.ContextSet.empty
| Polymorphic auctx -> Opaqueproof.PrivatePolymorphic (Univ.AUContext.size auctx, Univ.ContextSet.empty)
in
- Opaqueproof.create (Future.from_val (p, local))
+ let senv, o = push_opaque_proof (Future.from_val (p, local)) senv in
+ senv, (kn, { c with const_body = OpaqueDef o })
+ | Def _ | Undef _ | Primitive _ as body ->
+ senv, (kn, { c with const_body = body })
in
- let map (kn, cb) = (kn, map_constant (fun c -> map cb.const_universes c) cb) in
- let bodies = List.map map exported in
+ let senv, bodies = List.fold_left_map map senv exported in
let exported = List.map (fun (kn, _) -> kn) exported in
+ (* No delayed constants to declare *)
let senv = List.fold_left (add_constant_aux ~in_section) senv bodies in
(ce, exported), senv
-let add_recipe ~in_section l r senv =
- let kn = Constant.make2 senv.modpath l in
- let cb = Term_typing.translate_recipe senv.env kn r in
- let senv = add_constant_aux ~in_section senv (kn, cb) in
- kn, senv
-
let add_constant (type a) ~(side_effect : a effect_entry) ~in_section l decl senv : (Constant.t * a) * safe_environment =
let kn = Constant.make2 senv.modpath l in
let cb =
@@ -811,8 +833,29 @@ let add_constant (type a) ~(side_effect : a effect_entry) ~in_section l decl sen
Term_typing.translate_constant Term_typing.Pure senv.env kn ce
in
let senv =
- let cb = map_constant (fun c -> Opaqueproof.create c) cb in
- add_constant_aux ~in_section senv (kn, cb) in
+ let senv, cb, delayed_cst = match cb.const_body with
+ | OpaqueDef fc ->
+ let senv, o = push_opaque_proof fc senv in
+ let delayed_cst =
+ if not (Declareops.constant_is_polymorphic cb) then
+ let map (_, u) = match u with
+ | Opaqueproof.PrivateMonomorphic ctx -> ctx
+ | Opaqueproof.PrivatePolymorphic _ -> assert false
+ in
+ let fc = Future.chain fc map in
+ match Future.peek_val fc with
+ | None -> [Later fc]
+ | Some c -> [Now c]
+ else []
+ in
+ senv, { cb with const_body = OpaqueDef o }, delayed_cst
+ | Undef _ | Def _ | Primitive _ as body ->
+ senv, { cb with const_body = body }, []
+ in
+ let senv = add_constant_aux ~in_section senv (kn, cb) in
+ add_constraints_list delayed_cst senv
+ in
+
let senv =
match decl with
| ConstantEntry (_,(Entries.PrimitiveEntry { Entries.prim_entry_content = CPrimitives.OT_type t; _ })) ->
@@ -902,6 +945,76 @@ let add_module l me inl senv =
in
(mp,mb.mod_delta),senv''
+(** {6 Interactive sections *)
+
+let open_section senv =
+ let custom = {
+ rev_env = senv.env;
+ rev_univ = senv.univ;
+ rev_objlabels = senv.objlabels;
+ } in
+ let sections = Section.open_section ~custom senv.sections in
+ { senv with sections }
+
+let close_section senv =
+ let open Section in
+ let sections0 = senv.sections in
+ let env0 = senv.env in
+ (* First phase: revert the declarations added in the section *)
+ let sections, entries, cstrs, revert = Section.close_section sections0 in
+ let rec pop_revstruct accu entries revstruct = match entries, revstruct with
+ | [], revstruct -> accu, revstruct
+ | _ :: _, [] ->
+ CErrors.anomaly (Pp.str "Unmatched section data")
+ | entry :: entries, (lbl, leaf) :: revstruct ->
+ let data = match entry, leaf with
+ | SecDefinition kn, SFBconst cb ->
+ let () = assert (Label.equal lbl (Constant.label kn)) in
+ `Definition (kn, cb)
+ | SecInductive ind, SFBmind mib ->
+ let () = assert (Label.equal lbl (MutInd.label ind)) in
+ `Inductive (ind, mib)
+ | (SecDefinition _ | SecInductive _), (SFBconst _ | SFBmind _) ->
+ CErrors.anomaly (Pp.str "Section content mismatch")
+ | (SecDefinition _ | SecInductive _), (SFBmodule _ | SFBmodtype _) ->
+ CErrors.anomaly (Pp.str "Module inside a section")
+ in
+ pop_revstruct (data :: accu) entries revstruct
+ in
+ let redo, revstruct = pop_revstruct [] entries senv.revstruct in
+ (* Don't revert the delayed constraints. If some delayed constraints were
+ forced inside the section, they have been turned into global monomorphic
+ that are going to be replayed. Those that are not forced are not readded
+ by {!add_constant_aux}. *)
+ let { rev_env = env; rev_univ = univ; rev_objlabels = objlabels } = revert in
+ (* Do not revert the opaque table, the discharged opaque constants are
+ referring to it. *)
+ let env = Environ.set_opaque_tables env (Environ.opaque_tables senv.env) in
+ let senv = { senv with env; revstruct; sections; univ; objlabels; } in
+ (* Second phase: replay the discharged section contents *)
+ let senv = add_constraints (Now cstrs) senv in
+ let modlist = Section.replacement_context env0 sections0 in
+ let cooking_info seg =
+ let { abstr_ctx; abstr_subst; abstr_uctx } = seg in
+ let abstract = (abstr_ctx, abstr_subst, abstr_uctx) in
+ { Opaqueproof.modlist; abstract }
+ in
+ let fold senv = function
+ | `Definition (kn, cb) ->
+ let in_section = not (Section.is_empty senv.sections) in
+ let info = cooking_info (Section.segment_of_constant env0 kn sections0) in
+ let r = { Cooking.from = cb; info } in
+ let cb = Term_typing.translate_recipe senv.env kn r in
+ (* Delayed constants are already in the global environment *)
+ add_constant_aux ~in_section senv (kn, cb)
+ | `Inductive (ind, mib) ->
+ let info = cooking_info (Section.segment_of_inductive env0 ind sections0) in
+ let mie = Cooking.cook_inductive info mib in
+ let mie = InferCumulativity.infer_inductive senv.env mie in
+ let _, senv = add_mind (MutInd.label ind) mie senv in
+ senv
+ in
+ List.fold_left fold senv redo
(** {6 Starting / ending interactive modules and module types } *)
diff --git a/kernel/safe_typing.mli b/kernel/safe_typing.mli
index fa53fa33fa..d97d61a72f 100644
--- a/kernel/safe_typing.mli
+++ b/kernel/safe_typing.mli
@@ -27,12 +27,16 @@ val digest_match : actual:vodigest -> required:vodigest -> bool
type safe_environment
+type section_data
+
val empty_environment : safe_environment
val is_initial : safe_environment -> bool
val env_of_safe_env : safe_environment -> Environ.env
+val sections_of_safe_env : safe_environment -> section_data Section.t
+
(** The safe_environment state monad *)
type safe_transformer0 = safe_environment -> safe_environment
@@ -67,15 +71,6 @@ val join_safe_environment :
val is_joined_environment : safe_environment -> bool
(** {6 Enriching a safe environment } *)
-(** Insertion of local declarations (Local or Variables) *)
-
-val push_named_assum : (Id.t * Constr.types) -> safe_transformer0
-
-(** Returns the full universe context necessary to typecheck the definition
- (futures are forced) *)
-val push_named_def :
- Id.t * Entries.section_def_entry -> safe_transformer0
-
(** Insertion of global axioms or definitions *)
type 'a effect_entry =
@@ -96,9 +91,6 @@ val add_constant :
side_effect:'a effect_entry -> in_section:bool -> Label.t -> global_declaration ->
(Constant.t * 'a) safe_transformer
-val add_recipe :
- in_section:bool -> Label.t -> Cooking.recipe -> Constant.t safe_transformer
-
(** Adding an inductive type *)
val add_mind :
@@ -140,6 +132,22 @@ val set_allow_sprop : bool -> safe_transformer0
val check_engagement : Environ.env -> Declarations.set_predicativity -> unit
+(** {6 Interactive section functions } *)
+
+val open_section : safe_transformer0
+
+val close_section : safe_transformer0
+
+(** Insertion of local declarations (Local or Variables) *)
+
+val push_named_assum : (Id.t * Constr.types) -> safe_transformer0
+
+val push_named_def :
+ Id.t * Entries.section_def_entry -> safe_transformer0
+
+(** Add local universes to a polymorphic section *)
+val push_section_context : (Name.t array * Univ.UContext.t) -> safe_transformer0
+
(** {6 Interactive module functions } *)
val start_module : Label.t -> ModPath.t safe_transformer
diff --git a/kernel/section.ml b/kernel/section.ml
new file mode 100644
index 0000000000..babd9fe7a1
--- /dev/null
+++ b/kernel/section.ml
@@ -0,0 +1,216 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2019 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+open Util
+open Names
+open Univ
+
+module NamedDecl = Context.Named.Declaration
+
+type section_entry =
+| SecDefinition of Constant.t
+| SecInductive of MutInd.t
+
+type 'a entry_map = 'a Cmap.t * 'a Mindmap.t
+
+type 'a section = {
+ sec_context : int;
+ (** Length of the named context suffix that has been introduced locally *)
+ sec_mono_universes : ContextSet.t;
+ sec_poly_universes : Name.t array * UContext.t;
+ (** Universes local to the section *)
+ has_poly_univs : bool;
+ (** Are there polymorphic universes or constraints, including in previous sections. *)
+ sec_entries : section_entry list;
+ (** Definitions introduced in the section *)
+ sec_data : (Instance.t * AUContext.t) entry_map;
+ (** Additional data synchronized with the section *)
+ sec_custom : 'a;
+}
+
+(** Sections can be nested with the proviso that no monomorphic section can be
+ opened inside a polymorphic one. The reverse is allowed. *)
+type 'a t = 'a section list
+
+let empty = []
+
+let is_empty = List.is_empty
+
+let has_poly_univs = function
+ | [] -> false
+ | sec :: _ -> sec.has_poly_univs
+
+let find_emap e (cmap, imap) = match e with
+| SecDefinition con -> Cmap.find con cmap
+| SecInductive ind -> Mindmap.find ind imap
+
+let add_emap e v (cmap, imap) = match e with
+| SecDefinition con -> (Cmap.add con v cmap, imap)
+| SecInductive ind -> (cmap, Mindmap.add ind v imap)
+
+let on_last_section f sections = match sections with
+| [] -> CErrors.user_err (Pp.str "No opened section")
+| sec :: rem -> f sec :: rem
+
+let with_last_section f sections = match sections with
+| [] -> f None
+| sec :: _ -> f (Some sec)
+
+let push_local s =
+ let on_sec sec = { sec with sec_context = sec.sec_context + 1 } in
+ on_last_section on_sec s
+
+let push_context (nas, ctx) s =
+ let on_sec sec =
+ if UContext.is_empty ctx then sec
+ else
+ let (snas, sctx) = sec.sec_poly_universes in
+ let sec_poly_universes = (Array.append snas nas, UContext.union sctx ctx) in
+ { sec with sec_poly_universes; has_poly_univs = true }
+ in
+ on_last_section on_sec s
+
+let is_polymorphic_univ u s =
+ let check sec =
+ let (_, uctx) = sec.sec_poly_universes in
+ Array.exists (fun u' -> Level.equal u u') (Instance.to_array (UContext.instance uctx))
+ in
+ List.exists check s
+
+let push_constraints uctx s =
+ let on_sec sec =
+ if sec.has_poly_univs && Constraint.exists (fun (l,_,r) -> is_polymorphic_univ l s || is_polymorphic_univ r s) (snd uctx)
+ then CErrors.user_err Pp.(str "Cannot add monomorphic constraints which refer to section polymorphic universes.");
+ let uctx' = sec.sec_mono_universes in
+ let sec_mono_universes = (ContextSet.union uctx uctx') in
+ { sec with sec_mono_universes }
+ in
+ on_last_section on_sec s
+
+let open_section ~custom sections =
+ let sec = {
+ sec_context = 0;
+ sec_mono_universes = ContextSet.empty;
+ sec_poly_universes = ([||], UContext.empty);
+ has_poly_univs = has_poly_univs sections;
+ sec_entries = [];
+ sec_data = (Cmap.empty, Mindmap.empty);
+ sec_custom = custom;
+ } in
+ sec :: sections
+
+let close_section sections =
+ match sections with
+ | sec :: sections ->
+ sections, sec.sec_entries, sec.sec_mono_universes, sec.sec_custom
+ | [] ->
+ CErrors.user_err (Pp.str "No opened section.")
+
+let make_decl_univs (nas,uctx) = abstract_universes nas uctx
+
+let push_global ~poly e s =
+ if is_empty s then s
+ else if has_poly_univs s && not poly
+ then CErrors.user_err
+ Pp.(str "Cannot add a universe monomorphic declaration when \
+ section polymorphic universes are present.")
+ else
+ let on_sec sec =
+ { sec with
+ sec_entries = e :: sec.sec_entries;
+ sec_data = add_emap e (make_decl_univs sec.sec_poly_universes) sec.sec_data;
+ }
+ in
+ on_last_section on_sec s
+
+let push_constant ~poly con s = push_global ~poly (SecDefinition con) s
+
+let push_inductive ~poly ind s = push_global ~poly (SecInductive ind) s
+
+type abstr_info = {
+ abstr_ctx : Constr.named_context;
+ abstr_subst : Instance.t;
+ abstr_uctx : AUContext.t;
+}
+
+let empty_segment = {
+ abstr_ctx = [];
+ abstr_subst = Instance.empty;
+ abstr_uctx = AUContext.empty;
+}
+
+let extract_hyps sec vars used =
+ (* Keep the section-local segment of variables *)
+ let vars = List.firstn sec.sec_context vars in
+ (* Only keep the part that is used by the declaration *)
+ List.filter (fun d -> Id.Set.mem (NamedDecl.get_id d) used) vars
+
+let section_segment_of_entry vars e hyps sections =
+ (* [vars] are the named hypotheses, [hyps] the subset that is declared by the
+ global *)
+ let with_sec s = match s with
+ | None ->
+ CErrors.user_err (Pp.str "No opened section.")
+ | Some sec ->
+ let hyps = extract_hyps sec vars hyps in
+ let inst, auctx = find_emap e sec.sec_data in
+ {
+ abstr_ctx = hyps;
+ abstr_subst = inst;
+ abstr_uctx = auctx;
+ }
+ in
+ with_last_section with_sec sections
+
+let segment_of_constant env con s =
+ let body = Environ.lookup_constant con env in
+ let vars = Environ.named_context env in
+ let used = Context.Named.to_vars body.Declarations.const_hyps in
+ section_segment_of_entry vars (SecDefinition con) used s
+
+let segment_of_inductive env mind s =
+ let mib = Environ.lookup_mind mind env in
+ let vars = Environ.named_context env in
+ let used = Context.Named.to_vars mib.Declarations.mind_hyps in
+ section_segment_of_entry vars (SecInductive mind) used s
+
+let instance_from_variable_context =
+ List.rev %> List.filter NamedDecl.is_local_assum %> List.map NamedDecl.get_id %> Array.of_list
+
+let extract_worklist info =
+ let args = instance_from_variable_context info.abstr_ctx in
+ info.abstr_subst, args
+
+let replacement_context env s =
+ let with_sec sec = match sec with
+ | None -> CErrors.user_err (Pp.str "No opened section.")
+ | Some sec ->
+ let cmap, imap = sec.sec_data in
+ let cmap = Cmap.mapi (fun con _ -> extract_worklist @@ segment_of_constant env con s) cmap in
+ let imap = Mindmap.mapi (fun ind _ -> extract_worklist @@ segment_of_inductive env ind s) imap in
+ (cmap, imap)
+ in
+ with_last_section with_sec s
+
+let is_in_section env gr s =
+ let with_sec sec = match sec with
+ | None -> false
+ | Some sec ->
+ let open GlobRef in
+ match gr with
+ | VarRef id ->
+ let vars = List.firstn sec.sec_context (Environ.named_context env) in
+ List.exists (fun decl -> Id.equal id (NamedDecl.get_id decl)) vars
+ | ConstRef con ->
+ Cmap.mem con (fst sec.sec_data)
+ | IndRef (ind, _) | ConstructRef ((ind, _), _) ->
+ Mindmap.mem ind (snd sec.sec_data)
+ in
+ with_last_section with_sec s
diff --git a/kernel/section.mli b/kernel/section.mli
new file mode 100644
index 0000000000..56b4d9ba8f
--- /dev/null
+++ b/kernel/section.mli
@@ -0,0 +1,85 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2019 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+open Names
+open Univ
+
+(** Kernel implementation of sections. *)
+
+type 'a t
+(** Type of sections with additional data ['a] *)
+
+val empty : 'a t
+
+val is_empty : 'a t -> bool
+(** Checks whether there is no opened section *)
+
+(** {6 Manipulating sections} *)
+
+type section_entry =
+| SecDefinition of Constant.t
+| SecInductive of MutInd.t
+
+val open_section : custom:'a -> 'a t -> 'a t
+(** Open a new section with the provided universe polymorphic status. Sections
+ can be nested, with the proviso that polymorphic sections cannot appear
+ inside a monomorphic one. A custom data can be attached to this section,
+ that will be returned by {!close_section}. *)
+
+val close_section : 'a t -> 'a t * section_entry list * ContextSet.t * 'a
+(** Close the current section and returns the entries defined inside, the set
+ of global monomorphic constraints added in this section, and the custom data
+ provided at the opening of the section. *)
+
+(** {6 Extending sections} *)
+
+val push_local : 'a t -> 'a t
+(** Extend the current section with a local definition (cf. push_named). *)
+
+val push_context : Name.t array * UContext.t -> 'a t -> 'a t
+(** Extend the current section with a local universe context. Assumes that the
+ last opened section is polymorphic. *)
+
+val push_constraints : ContextSet.t -> 'a t -> 'a t
+(** Extend the current section with a global universe context.
+ Assumes that the last opened section is monomorphic. *)
+
+val push_constant : poly:bool -> Constant.t -> 'a t -> 'a t
+(** Make the constant as having been defined in this section. *)
+
+val push_inductive : poly:bool -> MutInd.t -> 'a t -> 'a t
+(** Make the inductive block as having been defined in this section. *)
+
+(** {6 Retrieving section data} *)
+
+type abstr_info = private {
+ abstr_ctx : Constr.named_context;
+ (** Section variables of this prefix *)
+ abstr_subst : Univ.Instance.t;
+ (** Actual names of the abstracted variables *)
+ abstr_uctx : Univ.AUContext.t;
+ (** Universe quantification, same length as the substitution *)
+}
+(** Data needed to abstract over the section variable and universe hypotheses *)
+
+
+val empty_segment : abstr_info
+(** Nothing to abstract *)
+
+val segment_of_constant : Environ.env -> Constant.t -> 'a t -> abstr_info
+(** Section segment at the time of the constant declaration *)
+
+val segment_of_inductive : Environ.env -> MutInd.t -> 'a t -> abstr_info
+(** Section segment at the time of the inductive declaration *)
+
+val replacement_context : Environ.env -> 'a t -> Opaqueproof.work_list
+(** Section segments of all declarations from this section. *)
+
+val is_in_section : Environ.env -> GlobRef.t -> 'a t -> bool
diff --git a/kernel/term_typing.ml b/kernel/term_typing.ml
index b65e62ba30..f70b2960cf 100644
--- a/kernel/term_typing.ml
+++ b/kernel/term_typing.ml
@@ -221,9 +221,7 @@ let infer_declaration (type a) ~(trust : a trust) env (dcl : a constant_entry) =
let build_constant_declaration env result =
let open Cooking in
let typ = result.cook_type in
- let check declared inferred =
- let mk_set l = List.fold_right Id.Set.add (List.map NamedDecl.get_id l) Id.Set.empty in
- let inferred_set, declared_set = mk_set inferred, mk_set declared in
+ let check declared_set inferred_set =
if not (Id.Set.subset inferred_set declared_set) then
let l = Id.Set.elements (Id.Set.diff inferred_set declared_set) in
let n = List.length l in
@@ -239,11 +237,6 @@ let build_constant_declaration env result =
str "Proof using " ++ declared_vars ++ fnl () ++
str "to" ++ fnl () ++
str "Proof using " ++ inferred_vars) in
- let sort l =
- List.filter (fun decl ->
- let id = NamedDecl.get_id decl in
- List.exists (NamedDecl.get_id %> Names.Id.equal id) l)
- (named_context env) in
(* We try to postpone the computation of used section variables *)
let hyps, def =
let context_ids = List.map NamedDecl.get_id (named_context env) in
@@ -252,7 +245,7 @@ let build_constant_declaration env result =
| None ->
if List.is_empty context_ids then
(* Empty section context: no need to check *)
- [], def
+ Id.Set.empty, def
else
(* No declared section vars, and non-empty section context:
we must look at the body NOW, if any *)
@@ -264,16 +257,19 @@ let build_constant_declaration env result =
(* Opaque definitions always come with their section variables *)
assert false
in
- keep_hyps env (Id.Set.union ids_typ ids_def), def
+ Environ.really_needed env (Id.Set.union ids_typ ids_def), def
| Some declared ->
+ let needed = Environ.really_needed env declared in
+ (* Transitive closure ensured by the upper layers *)
+ let () = assert (Id.Set.equal needed declared) in
(* We use the declared set and chain a check of correctness *)
- sort declared,
+ declared,
match def with
| Undef _ | Primitive _ as x -> x (* nothing to check *)
| Def cs as x ->
let ids_typ = global_vars_set env typ in
let ids_def = global_vars_set env (Mod_subst.force_constr cs) in
- let inferred = keep_hyps env (Id.Set.union ids_typ ids_def) in
+ let inferred = Environ.really_needed env (Id.Set.union ids_typ ids_def) in
check declared inferred;
x
| OpaqueDef lc -> (* In this case we can postpone the check *)
@@ -281,12 +277,13 @@ let build_constant_declaration env result =
let kont c =
let ids_typ = global_vars_set env typ in
let ids_def = global_vars_set env c in
- let inferred = keep_hyps env (Id.Set.union ids_typ ids_def) in
+ let inferred = Environ.really_needed env (Id.Set.union ids_typ ids_def) in
check declared inferred
in
OpaqueDef (iter kont lc)
in
let univs = result.cook_universes in
+ let hyps = List.filter (fun d -> Id.Set.mem (NamedDecl.get_id d) hyps) (Environ.named_context env) in
let tps =
let res = Cbytegen.compile_constant_body ~fail_on_error:false env univs def in
Option.map Cemitcodes.from_val res
@@ -317,7 +314,10 @@ let translate_recipe env _kn r =
let univs = result.cook_universes in
let res = Cbytegen.compile_constant_body ~fail_on_error:false env univs result.cook_body in
let tps = Option.map Cemitcodes.from_val res in
- { const_hyps = Option.get result.cook_context;
+ let hyps = Option.get result.cook_context in
+ (* Trust the set of section hypotheses generated by Cooking *)
+ let hyps = List.filter (fun d -> Id.Set.mem (NamedDecl.get_id d) hyps) (Environ.named_context env) in
+ { const_hyps = hyps;
const_body = result.cook_body;
const_type = result.cook_type;
const_body_code = tps;
diff --git a/lib/flags.ml b/lib/flags.ml
index f09dc48f5d..7676665fe9 100644
--- a/lib/flags.ml
+++ b/lib/flags.ml
@@ -60,7 +60,7 @@ let we_are_parsing = ref false
(* Current means no particular compatibility consideration.
For correct comparisons, this constructor should remain the last one. *)
-type compat_version = V8_8 | V8_9 | Current
+type compat_version = V8_8 | V8_9 | V8_10 | Current
let compat_version = ref Current
@@ -71,6 +71,9 @@ let version_compare v1 v2 = match v1, v2 with
| V8_9, V8_9 -> 0
| V8_9, _ -> -1
| _, V8_9 -> 1
+ | V8_10, V8_10 -> 0
+ | V8_10, _ -> -1
+ | _, V8_10 -> 1
| Current, Current -> 0
let version_strictly_greater v = version_compare !compat_version v > 0
@@ -79,6 +82,7 @@ let version_less_or_equal v = not (version_strictly_greater v)
let pr_version = function
| V8_8 -> "8.8"
| V8_9 -> "8.9"
+ | V8_10 -> "8.10"
| Current -> "current"
(* Translate *)
diff --git a/lib/flags.mli b/lib/flags.mli
index 185a5f8425..3f72cc4b91 100644
--- a/lib/flags.mli
+++ b/lib/flags.mli
@@ -48,7 +48,7 @@ val we_are_parsing : bool ref
(* Set Printing All flag. For some reason it is a global flag *)
val raw_print : bool ref
-type compat_version = V8_8 | V8_9 | Current
+type compat_version = V8_8 | V8_9 | V8_10 | Current
val compat_version : compat_version ref
val version_compare : compat_version -> compat_version -> int
val version_strictly_greater : compat_version -> bool
diff --git a/library/global.ml b/library/global.ml
index 6bb4614aa4..c4685370d1 100644
--- a/library/global.ml
+++ b/library/global.ml
@@ -71,6 +71,11 @@ let globalize0 f = GlobalSafeEnv.set_safe_env (f (safe_env ()))
let globalize f =
let res,env = f (safe_env ()) in GlobalSafeEnv.set_safe_env env; res
+let globalize0_with_summary fs f =
+ let env = f (safe_env ()) in
+ Summary.unfreeze_summaries fs;
+ GlobalSafeEnv.set_safe_env env
+
let globalize_with_summary fs f =
let res,env = f (safe_env ()) in
Summary.unfreeze_summaries fs;
@@ -83,6 +88,7 @@ let i2l = Label.of_id
let push_named_assum a = globalize0 (Safe_typing.push_named_assum a)
let push_named_def d = globalize0 (Safe_typing.push_named_def d)
+let push_section_context c = globalize0 (Safe_typing.push_section_context c)
let add_constraints c = globalize0 (Safe_typing.add_constraints c)
let push_context_set b c = globalize0 (Safe_typing.push_context_set b c)
@@ -98,12 +104,14 @@ let set_allow_sprop b = globalize0 (Safe_typing.set_allow_sprop b)
let sprop_allowed () = Environ.sprop_allowed (env())
let export_private_constants ~in_section cd = globalize (Safe_typing.export_private_constants ~in_section cd)
let add_constant ~side_effect ~in_section id d = globalize (Safe_typing.add_constant ~side_effect ~in_section (i2l id) d)
-let add_recipe ~in_section id d = globalize (Safe_typing.add_recipe ~in_section (i2l id) d)
let add_mind id mie = globalize (Safe_typing.add_mind (i2l id) mie)
let add_modtype id me inl = globalize (Safe_typing.add_modtype (i2l id) me inl)
let add_module id me inl = globalize (Safe_typing.add_module (i2l id) me inl)
let add_include me ismod inl = globalize (Safe_typing.add_include me ismod inl)
+let open_section () = globalize0 Safe_typing.open_section
+let close_section fs = globalize0_with_summary fs Safe_typing.close_section
+
let start_module id = globalize (Safe_typing.start_module (i2l id))
let start_modtype id = globalize (Safe_typing.start_modtype (i2l id))
diff --git a/library/global.mli b/library/global.mli
index d0bd556d70..c45bf65d84 100644
--- a/library/global.mli
+++ b/library/global.mli
@@ -44,6 +44,7 @@ val sprop_allowed : unit -> bool
val push_named_assum : (Id.t * Constr.types) -> unit
val push_named_def : (Id.t * Entries.section_def_entry) -> unit
+val push_section_context : (Name.t array * Univ.UContext.t) -> unit
val export_private_constants : in_section:bool ->
Safe_typing.private_constants Entries.proof_output ->
@@ -51,7 +52,6 @@ val export_private_constants : in_section:bool ->
val add_constant :
side_effect:'a Safe_typing.effect_entry -> in_section:bool -> Id.t -> Safe_typing.global_declaration -> Constant.t * 'a
-val add_recipe : in_section:bool -> Id.t -> Cooking.recipe -> Constant.t
val add_mind :
Id.t -> Entries.mutual_inductive_entry -> MutInd.t
@@ -71,6 +71,15 @@ val add_include :
Entries.module_struct_entry -> bool -> Declarations.inline ->
Mod_subst.delta_resolver
+(** Sections *)
+
+val open_section : unit -> unit
+(** [poly] is true when the section should be universe polymorphic *)
+
+val close_section : Summary.frozen -> unit
+(** Close the section and reset the global state to the one at the time when
+ the section what opened. *)
+
(** Interactive modules and module types *)
val start_module : Id.t -> ModPath.t
diff --git a/library/lib.ml b/library/lib.ml
index 851f086961..0d9efe2d5d 100644
--- a/library/lib.ml
+++ b/library/lib.ml
@@ -410,87 +410,11 @@ let find_opening_node id =
- the list of substitution to do at section closing
*)
-type abstr_info = {
+type abstr_info = Section.abstr_info = private {
abstr_ctx : Constr.named_context;
abstr_subst : Univ.Instance.t;
abstr_uctx : Univ.AUContext.t;
}
-type abstr_list = abstr_info Names.Cmap.t * abstr_info Names.Mindmap.t
-
-type secentry =
- | Variable of {
- id:Names.Id.t;
- }
- | Context of Univ.ContextSet.t
-
-type section_data = {
- sec_entry : secentry list;
- sec_abstr : abstr_list;
- sec_poly : bool;
-}
-
-let empty_section_data ~poly = {
- sec_entry = [];
- sec_abstr = (Names.Cmap.empty,Names.Mindmap.empty);
- sec_poly = poly;
-}
-
-let sectab =
- Summary.ref ([] : section_data list) ~name:"section-context"
-
-let check_same_poly p sec =
- if p != sec.sec_poly then
- user_err Pp.(str "Cannot mix universe polymorphic and monomorphic declarations in sections.")
-
-let add_section ~poly () =
- List.iter (fun tab -> check_same_poly poly tab) !sectab;
- sectab := empty_section_data ~poly :: !sectab
-
-let add_section_variable ~name ~poly =
- match !sectab with
- | [] -> () (* because (Co-)Fixpoint temporarily uses local vars *)
- | s :: sl ->
- List.iter (fun tab -> check_same_poly poly tab) !sectab;
- let s = { s with sec_entry = Variable {id=name} :: s.sec_entry } in
- sectab := s :: sl
-
-let add_section_context ctx =
- match !sectab with
- | [] -> () (* because (Co-)Fixpoint temporarily uses local vars *)
- | s :: sl ->
- check_same_poly true s;
- let s = { s with sec_entry = Context ctx :: s.sec_entry } in
- sectab := s :: sl
-
-exception PolyFound (* make this a let exception once possible *)
-let is_polymorphic_univ u =
- try
- let open Univ in
- List.iter (fun s ->
- let vars = s.sec_entry in
- List.iter (function
- | Variable _ -> ()
- | Context (univs,_) ->
- if LSet.mem u univs then raise PolyFound
- ) vars
- ) !sectab;
- false
- with PolyFound -> true
-
-let extract_hyps poly (secs,ohyps) =
- let rec aux = function
- | (Variable {id}::idl, decl::hyps) when Names.Id.equal id (NamedDecl.get_id decl) ->
- let l, r = aux (idl,hyps) in
- decl :: l, r
- | (Variable _::idl,hyps) ->
- let l, r = aux (idl,hyps) in
- l, r
- | (Context ctx :: idl, hyps) ->
- let () = assert poly in
- let l, r = aux (idl, hyps) in
- l, Univ.ContextSet.union r ctx
- | [], _ -> [],Univ.ContextSet.empty
- in aux (secs,ohyps)
let instance_from_variable_context =
List.rev %> List.filter is_local_assum %> List.map NamedDecl.get_id %> Array.of_list
@@ -499,66 +423,18 @@ let extract_worklist info =
let args = instance_from_variable_context info.abstr_ctx in
info.abstr_subst, args
-let make_worklist (cmap, mmap) =
- Cmap.map extract_worklist cmap, Mindmap.map extract_worklist mmap
-
-let name_instance inst =
- (* FIXME: this should probably be done at an upper level, by storing the
- name information in the section data structure. *)
- let map lvl = match Univ.Level.name lvl with
- | None -> (* Having Prop/Set/Var as section universes makes no sense *)
- assert false
- | Some na ->
- try
- let qid = Nametab.shortest_qualid_of_universe na in
- Name (Libnames.qualid_basename qid)
- with Not_found ->
- (* Best-effort naming from the string representation of the level.
- See univNames.ml for a similar hack. *)
- Name (Id.of_string_soft (Univ.Level.to_string lvl))
- in
- Array.map map (Univ.Instance.to_array inst)
-
-let add_section_replacement g poly hyps =
- match !sectab with
- | [] -> ()
- | s :: sl ->
- let () = check_same_poly poly s in
- let sechyps,ctx = extract_hyps s.sec_poly (s.sec_entry, hyps) in
- let ctx = Univ.ContextSet.to_context ctx in
- let nas = name_instance (Univ.UContext.instance ctx) in
- let subst, ctx = Univ.abstract_universes nas ctx in
- let info = {
- abstr_ctx = sechyps;
- abstr_subst = subst;
- abstr_uctx = ctx;
- } in
- let s = { s with
- sec_abstr = g info s.sec_abstr;
- } in
- sectab := s :: sl
-
-let add_section_kn ~poly kn =
- let f x (l1,l2) = (l1,Names.Mindmap.add kn x l2) in
- add_section_replacement f poly
-
-let add_section_constant ~poly kn =
- let f x (l1,l2) = (Names.Cmap.add kn x l1,l2) in
- add_section_replacement f poly
-
-let replacement_context () = make_worklist (List.hd !sectab).sec_abstr
+let sections () = Safe_typing.sections_of_safe_env @@ Global.safe_env ()
+
+let replacement_context () =
+ Section.replacement_context (Global.env ()) (sections ())
let section_segment_of_constant con =
- Names.Cmap.find con (fst (List.hd !sectab).sec_abstr)
+ Section.segment_of_constant (Global.env ()) con (sections ())
let section_segment_of_mutual_inductive kn =
- Names.Mindmap.find kn (snd (List.hd !sectab).sec_abstr)
+ Section.segment_of_inductive (Global.env ()) kn (sections ())
-let empty_segment = {
- abstr_ctx = [];
- abstr_subst = Univ.Instance.empty;
- abstr_uctx = Univ.AUContext.empty;
-}
+let empty_segment = Section.empty_segment
let section_segment_of_reference = let open GlobRef in function
| ConstRef c -> section_segment_of_constant c
@@ -569,28 +445,24 @@ let section_segment_of_reference = let open GlobRef in function
let variable_section_segment_of_reference gr =
(section_segment_of_reference gr).abstr_ctx
+let is_in_section ref =
+ Section.is_in_section (Global.env ()) ref (sections ())
+
let section_instance = let open GlobRef in function
| VarRef id ->
- let eq = function
- | Variable {id=id'} -> Names.Id.equal id id'
- | Context _ -> false
- in
- if List.exists eq (List.hd !sectab).sec_entry
- then Univ.Instance.empty, [||]
- else raise Not_found
+ if is_in_section (VarRef id) then (Univ.Instance.empty, [||])
+ else raise Not_found
| ConstRef con ->
- let data = Names.Cmap.find con (fst (List.hd !sectab).sec_abstr) in
+ let data = section_segment_of_constant con in
extract_worklist data
| IndRef (kn,_) | ConstructRef ((kn,_),_) ->
- let data = Names.Mindmap.find kn (snd (List.hd !sectab).sec_abstr) in
+ let data = section_segment_of_mutual_inductive kn in
extract_worklist data
-let is_in_section ref =
- try ignore (section_instance ref); true with Not_found -> false
-
(*************)
(* Sections. *)
-let open_section ~poly id =
+let open_section id =
+ let () = Global.open_section () in
let opp = !lib_state.path_prefix in
let obj_dir = add_dirpath_suffix opp.Nametab.obj_dir id in
let prefix = Nametab.{ obj_dir; obj_mp = opp.obj_mp; obj_sec = add_dirpath_suffix opp.obj_sec id } in
@@ -600,9 +472,7 @@ let open_section ~poly id =
add_entry (make_foname id) (OpenedSection (prefix, fs));
(*Pushed for the lifetime of the section: removed by unfrozing the summary*)
Nametab.(push_dir (Until 1) obj_dir (GlobDirRef.DirOpenSection prefix));
- lib_state := { !lib_state with path_prefix = prefix };
- add_section ~poly ()
-
+ lib_state := { !lib_state with path_prefix = prefix }
(* Restore lib_stk and summaries as before the section opening, and
add a ClosedSection object. *)
@@ -631,7 +501,7 @@ let close_section () =
lib_state := { !lib_state with lib_stk = before };
pop_path_prefix ();
let newdecls = List.map discharge_item secdecls in
- Summary.unfreeze_summaries fs;
+ let () = Global.close_section fs in
List.iter (Option.iter (fun (id,o) -> add_discharged_leaf id o)) newdecls
(* State and initialization. *)
diff --git a/library/lib.mli b/library/lib.mli
index 9ffa69ef93..59d77480e9 100644
--- a/library/lib.mli
+++ b/library/lib.mli
@@ -147,7 +147,7 @@ val library_part : GlobRef.t -> DirPath.t
(** {6 Sections } *)
-val open_section : poly:bool -> Id.t -> unit
+val open_section : Id.t -> unit
val close_section : unit -> unit
(** {6 We can get and set the state of the operations (used in [States]). } *)
@@ -163,7 +163,7 @@ val drop_objects : frozen -> frozen
val init : unit -> unit
(** {6 Section management for discharge } *)
-type abstr_info = private {
+type abstr_info = Section.abstr_info = private {
abstr_ctx : Constr.named_context;
(** Section variables of this prefix *)
abstr_subst : Univ.Instance.t;
@@ -181,14 +181,8 @@ val variable_section_segment_of_reference : GlobRef.t -> Constr.named_context
val section_instance : GlobRef.t -> Univ.Instance.t * Id.t array
val is_in_section : GlobRef.t -> bool
-val add_section_variable : name:Id.t -> poly:bool -> unit
-val add_section_context : Univ.ContextSet.t -> unit
-val add_section_constant : poly:bool -> Constant.t -> Constr.named_context -> unit
-val add_section_kn : poly:bool -> MutInd.t -> Constr.named_context -> unit
val replacement_context : unit -> Opaqueproof.work_list
-val is_polymorphic_univ : Univ.Level.t -> bool
-
(** {6 Discharge: decrease the section level if in the current section } *)
(* XXX Why can't we use the kernel functions ? *)
diff --git a/library/library.mllib b/library/library.mllib
index c34d8911e8..a6188f7661 100644
--- a/library/library.mllib
+++ b/library/library.mllib
@@ -5,7 +5,6 @@ Summary
Nametab
Global
Lib
-Declaremods
States
Kindops
Goptions
diff --git a/parsing/pcoq.ml b/parsing/pcoq.ml
index e0d63a723e..0a41bba8ce 100644
--- a/parsing/pcoq.ml
+++ b/parsing/pcoq.ml
@@ -597,7 +597,7 @@ let unfreeze (grams, lex) =
(** No need to provide an init function : the grammar state is
statically available, and already empty initially, while
the lexer state should not be reset, since it contains
- keywords declared in g_*.ml4 *)
+ keywords declared in g_*.mlg *)
let parser_summary_tag =
Summary.declare_summary_tag "GRAMMAR_LEXER"
diff --git a/parsing/pcoq.mli b/parsing/pcoq.mli
index 10f78a5a72..ca5adf8ab3 100644
--- a/parsing/pcoq.mli
+++ b/parsing/pcoq.mli
@@ -108,7 +108,7 @@ end
- "f" constr(x) (developer gives an EXTEND rule)
|
- | macro-generation in tacextend.ml4/vernacextend.ml4/argextend.ml4
+ | macro-generation in tacextend.mlg/vernacextend.mlg/argextend.mlg
V
[GramTerminal "f";
GramNonTerminal (ConstrArgType, Aentry ("constr","constr"), Some "x")]
diff --git a/plugins/cc/README b/plugins/cc/README
index c616b5daab..7df7b971e8 100644
--- a/plugins/cc/README
+++ b/plugins/cc/README
@@ -9,7 +9,7 @@ Files :
- ccalgo.ml : congruence closure algorithm
- ccproof.ml : proof generation code
-- cctac.ml4 : the tactic itself
+- cctac.mlg : the tactic itself
- CCSolve.v : a small Ltac tactic based on congruence
Known Bugs : the congruence tactic can fail due to type dependencies.
diff --git a/plugins/cc/ccproof.ml b/plugins/cc/ccproof.ml
index ef012e5092..f47a14cdc7 100644
--- a/plugins/cc/ccproof.ml
+++ b/plugins/cc/ccproof.ml
@@ -9,7 +9,7 @@
(************************************************************************)
(* This file uses the (non-compressed) union-find structure to generate *)
-(* proof-trees that will be transformed into proof-terms in cctac.ml4 *)
+(* proof-trees that will be transformed into proof-terms in cctac.mlg *)
open CErrors
open Constr
diff --git a/plugins/funind/functional_principles_proofs.ml b/plugins/funind/functional_principles_proofs.ml
index ca33e4e757..7be049269c 100644
--- a/plugins/funind/functional_principles_proofs.ml
+++ b/plugins/funind/functional_principles_proofs.ml
@@ -920,20 +920,10 @@ let generate_equation_lemma evd fnames f fun_num nb_params nb_args rec_args_num
]
in
(* Pp.msgnl (str "lemma type (2) " ++ Printer.pr_lconstr_env (Global.env ()) evd lemma_type); *)
- let info = Lemmas.Info.make
- ~scope:(DeclareDef.Global Declare.ImportDefaultBehavior)
- ~kind:(Decls.(IsProof Theorem)) () in
-
- let lemma = Lemmas.start_lemma
- (*i The next call to mk_equation_id is valid since we are constructing the lemma
- Ensures by: obvious
- i*)
- ~name:(mk_equation_id f_id)
- ~poly:false
- ~info
- evd
- lemma_type
- in
+
+ (*i The next call to mk_equation_id is valid since we are
+ constructing the lemma Ensures by: obvious i*)
+ let lemma = Lemmas.start_lemma ~name:(mk_equation_id f_id) ~poly:false evd lemma_type in
let lemma,_ = Lemmas.by (Proofview.V82.tactic prove_replacement) lemma in
let () = Lemmas.save_lemma_proved ~lemma ~opaque:Proof_global.Transparent ~idopt:None in
evd
diff --git a/plugins/funind/gen_principle.ml b/plugins/funind/gen_principle.ml
index 570b72136c..6011af74e5 100644
--- a/plugins/funind/gen_principle.ml
+++ b/plugins/funind/gen_principle.ml
@@ -1387,15 +1387,7 @@ let derive_correctness (funs: Constr.pconstant list) (graphs:inductive list) =
i*)
let lem_id = mk_correct_id f_id in
let (typ,_) = lemmas_types_infos.(i) in
- let info = Lemmas.Info.make
- ~scope:(DeclareDef.Global Declare.ImportDefaultBehavior)
- ~kind:(Decls.(IsProof Theorem)) () in
- let lemma = Lemmas.start_lemma
- ~name:lem_id
- ~poly:false
- ~info
- !evd
- typ in
+ let lemma = Lemmas.start_lemma ~name:lem_id ~poly:false !evd typ in
let lemma = fst @@ Lemmas.by
(Proofview.V82.tactic (proving_tac i)) lemma in
let () = Lemmas.save_lemma_proved ~lemma ~opaque:Proof_global.Transparent ~idopt:None in
@@ -1456,11 +1448,7 @@ let derive_correctness (funs: Constr.pconstant list) (graphs:inductive list) =
Ensures by: obvious
i*)
let lem_id = mk_complete_id f_id in
- let info = Lemmas.Info.make
- ~scope:(DeclareDef.Global Declare.ImportDefaultBehavior)
- ~kind:Decls.(IsProof Theorem) () in
- let lemma = Lemmas.start_lemma ~name:lem_id ~poly:false ~info
- sigma (fst lemmas_types_infos.(i)) in
+ let lemma = Lemmas.start_lemma ~name:lem_id ~poly:false sigma (fst lemmas_types_infos.(i)) in
let lemma = fst (Lemmas.by
(Proofview.V82.tactic (observe_tac ("prove completeness ("^(Id.to_string f_id)^")")
(proving_tac i))) lemma) in
diff --git a/plugins/funind/recdef.ml b/plugins/funind/recdef.ml
index c62aa0cf6b..4c5eab1a9b 100644
--- a/plugins/funind/recdef.ml
+++ b/plugins/funind/recdef.ml
@@ -1332,9 +1332,7 @@ let open_new_goal ~lemma build_proof sigma using_lemmas ref_ goal_name (gls_type
let lemma = build_proof env (Evd.from_env env) start_tac end_tac in
Lemmas.save_lemma_proved ~lemma ~opaque:opacity ~idopt:None
in
- let info = Lemmas.Info.make ~hook:(DeclareDef.Hook.make hook)
- ~scope:(DeclareDef.Global Declare.ImportDefaultBehavior) ~kind:(Decls.(IsProof Lemma))
- () in
+ let info = Lemmas.Info.make ~hook:(DeclareDef.Hook.make hook) () in
let lemma = Lemmas.start_lemma
~name:na
~poly:false (* FIXME *) ~info
@@ -1376,7 +1374,7 @@ let com_terminate
nb_args ctx
hook =
let start_proof env ctx tac_start tac_end =
- let info = Lemmas.Info.make ~hook ~scope:(DeclareDef.Global ImportDefaultBehavior) ~kind:Decls.(IsProof Lemma) () in
+ let info = Lemmas.Info.make ~hook () in
let lemma = Lemmas.start_lemma ~name:thm_name
~poly:false (*FIXME*)
~info
diff --git a/plugins/ltac/tacarg.ml b/plugins/ltac/tacarg.ml
index 9e8e86d4fc..252c15478d 100644
--- a/plugins/ltac/tacarg.ml
+++ b/plugins/ltac/tacarg.ml
@@ -20,7 +20,7 @@ let make0 ?dyn name =
wit
let wit_intropattern = make0 "intropattern" (* To keep after deprecation phase but it will get a different parsing semantics (Tactic Notation and TACTIC EXTEND) in pltac.ml *)
-let wit_simple_intropattern = make0 "simple_intropattern"
+let wit_simple_intropattern = make0 ~dyn:(val_tag (topwit wit_intropattern)) "simple_intropattern"
let wit_quant_hyp = make0 "quant_hyp"
let wit_constr_with_bindings = make0 "constr_with_bindings"
let wit_open_constr_with_bindings = make0 "open_constr_with_bindings"
diff --git a/plugins/ltac/taccoerce.ml b/plugins/ltac/taccoerce.ml
index e64129d204..da89a027e2 100644
--- a/plugins/ltac/taccoerce.ml
+++ b/plugins/ltac/taccoerce.ml
@@ -145,11 +145,8 @@ let coerce_to_constr_context v =
else raise (CannotCoerceTo "a term context")
let is_intro_pattern v =
- if has_type v (topwit wit_intropattern [@warning "-3"]) then
- Some (out_gen (topwit wit_intropattern [@warning "-3"]) v).CAst.v
- else
- if has_type v (topwit wit_simple_intropattern) then
- Some (out_gen (topwit wit_simple_intropattern) v).CAst.v
+ if has_type v (topwit wit_intro_pattern) then
+ Some (out_gen (topwit wit_intro_pattern) v).CAst.v
else
None
diff --git a/plugins/micromega/ZifyInst.v b/plugins/micromega/ZifyInst.v
index 3c44113604..1217e8a5f7 100644
--- a/plugins/micromega/ZifyInst.v
+++ b/plugins/micromega/ZifyInst.v
@@ -172,6 +172,10 @@ Program Instance Op_Z_of_N : UnOp Z.of_N :=
{ TUOp := (fun x => x) ; TUOpInj := fun x => eq_refl (Z.of_N x) }.
Add UnOp Op_Z_of_N.
+Instance Op_Z_to_N : UnOp Z.to_N :=
+ { TUOp := fun x => Z.max 0 x ; TUOpInj := ltac:(now intro x; destruct x) }.
+Add UnOp Op_Z_to_N.
+
Instance Op_Z_neg : UnOp Z.neg :=
{ TUOp := Z.opp ; TUOpInj := (fun x => eq_refl (Zneg x))}.
Add UnOp Op_Z_neg.
diff --git a/plugins/micromega/coq_micromega.ml b/plugins/micromega/coq_micromega.ml
index ceb651abed..1772a3c333 100644
--- a/plugins/micromega/coq_micromega.ml
+++ b/plugins/micromega/coq_micromega.ml
@@ -50,6 +50,13 @@ let get_lia_option () =
let get_lra_option () =
!lra_proof_depth
+(* Enable/disable caches *)
+
+let use_lia_cache = ref true
+let use_nia_cache = ref true
+let use_nra_cache = ref true
+let use_csdp_cache = ref true
+
let () =
let int_opt l vref =
@@ -88,8 +95,38 @@ let () =
optwrite = (fun x -> Certificate.dump_file := x)
} in
+ let lia_cache_opt =
+ {
+ optdepr = false;
+ optname = "cache of lia (.lia.cache)";
+ optkey = ["Lia" ; "Cache"];
+ optread = (fun () -> !use_lia_cache);
+ optwrite = (fun x -> use_lia_cache := x)
+ } in
+
+ let nia_cache_opt =
+ {
+ optdepr = false;
+ optname = "cache of nia (.nia.cache)";
+ optkey = ["Nia" ; "Cache"];
+ optread = (fun () -> !use_nia_cache);
+ optwrite = (fun x -> use_nia_cache := x)
+ } in
+
+ let nra_cache_opt =
+ {
+ optdepr = false;
+ optname = "cache of nra (.nra.cache)";
+ optkey = ["Nra" ; "Cache"];
+ optread = (fun () -> !use_nra_cache);
+ optwrite = (fun x -> use_nra_cache := x)
+ } in
+
let () = declare_bool_option solver_opt in
+ let () = declare_bool_option lia_cache_opt in
+ let () = declare_bool_option nia_cache_opt in
+ let () = declare_bool_option nra_cache_opt in
let () = declare_stringopt_option dump_file_opt in
let () = declare_int_option (int_opt ["Lra"; "Depth"] lra_proof_depth) in
let () = declare_int_option (int_opt ["Lia"; "Depth"] lia_proof_depth) in
@@ -745,7 +782,7 @@ struct
(** [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 gl.env evd x y with
+ 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
begin
@@ -769,15 +806,16 @@ struct
({vars=vars';gl=gl'}, CamlToCoq.positive n)
let get_rank env v =
- let evd = env.gl.sigma in
+ let gl = env.gl in
let rec _get_rank env n =
match env with
| [] -> raise (Invalid_argument "get_rank")
| e::l ->
- if EConstr.eq_constr evd e v
- then n
- else _get_rank l (n+1) in
+ 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
@@ -1978,13 +2016,47 @@ type provername = string * int option
open Persistent_cache
-module Cache = PHashtable(struct
- type t = (provername * micromega_polys)
- let equal = (=)
- let hash = Hashtbl.hash
-end)
-let csdp_cache = ".csdp.cache"
+module MakeCache(T : sig type prover_option
+ type coeff
+ val hash_prover_option : int -> prover_option -> int
+ val hash_coeff : int -> coeff -> int
+ val eq_prover_option : prover_option -> prover_option -> bool
+ val eq_coeff : coeff -> coeff -> bool
+
+ end) =
+ struct
+ module E =
+ struct
+ type t = T.prover_option * (T.coeff Mc.pol * Mc.op1) list
+
+ let equal = Hash.(eq_pair T.eq_prover_option (CList.equal (eq_pair (eq_pol T.eq_coeff) Hash.eq_op1)))
+
+ let hash =
+ let hash_cstr = Hash.(hash_pair (hash_pol T.hash_coeff) hash_op1) in
+ Hash.( (hash_pair T.hash_prover_option (List.fold_left hash_cstr)) 0)
+ end
+
+ include PHashtable(E)
+
+ let memo_opt use_cache cache_file f =
+ let memof = memo cache_file f in
+ fun x -> if !use_cache then memof x else f x
+
+ end
+
+
+
+module CacheCsdp = MakeCache(struct
+ type prover_option = provername
+ type coeff = Mc.q
+ let hash_prover_option = Hash.(hash_pair hash_string
+ (hash_elt (Option.hash (fun x -> x))))
+ let eq_prover_option = Hash.(eq_pair String.equal
+ (Option.equal Int.equal))
+ let hash_coeff = Hash.hash_q
+ let eq_coeff = Hash.eq_q
+ end)
(**
* Build the command to call csdpcert, and launch it. This in turn will call
@@ -2017,7 +2089,7 @@ let really_call_csdpcert : provername -> micromega_polys -> Sos_types.positivste
*)
let xcall_csdpcert =
- Cache.memo csdp_cache (fun (prover,pb) -> really_call_csdpcert prover pb)
+ CacheCsdp.memo_opt use_csdp_cache ".csdp.cache" (fun (prover,pb) -> really_call_csdpcert prover pb)
(**
* Prover callback functions.
@@ -2112,23 +2184,31 @@ let compact_pt pt f =
let lift_pexpr_prover p l = p (List.map (fun (e,o) -> Mc.denorm e , o) l)
-module CacheZ = PHashtable(struct
- type prover_option = bool * bool* int
- type t = prover_option * ((Mc.z Mc.pol * Mc.op1) list)
- let equal = (=)
- let hash = Hashtbl.hash
-end)
+module CacheZ = MakeCache(struct
+ type prover_option = bool * bool* int
+ type coeff = Mc.z
+ let hash_prover_option : int -> prover_option -> int = Hash.hash_elt Hashtbl.hash
+ let eq_prover_option : prover_option -> prover_option -> bool = (=)
+ let eq_coeff = Hash.eq_z
+ let hash_coeff = Hash.hash_z
+ end)
-module CacheQ = PHashtable(struct
- type t = int * ((Mc.q Mc.pol * Mc.op1) list)
- let equal = (=)
- let hash = Hashtbl.hash
-end)
+module CacheQ = MakeCache(struct
+ type prover_option = int
+ type coeff = Mc.q
+ let hash_prover_option : int -> int -> int = Hash.hash_elt Hashtbl.hash
+ let eq_prover_option = Int.equal
+ let eq_coeff = Hash.eq_q
+ let hash_coeff = Hash.hash_q
+ end)
-let memo_zlinear_prover = CacheZ.memo ".lia.cache" (fun ((_,ce,b),s) -> lift_pexpr_prover (Certificate.lia ce b) s)
-let memo_nlia = CacheZ.memo ".nia.cache" (fun ((_,ce,b),s) -> lift_pexpr_prover (Certificate.nlia ce b) s)
-let memo_nra = CacheQ.memo ".nra.cache" (fun (o,s) -> lift_pexpr_prover (Certificate.nlinear_prover o) s)
+let memo_lia = CacheZ.memo_opt use_lia_cache ".lia.cache"
+ (fun ((_,ce,b),s) -> lift_pexpr_prover (Certificate.lia ce b) s)
+let memo_nlia = CacheZ.memo_opt use_nia_cache ".nia.cache"
+ (fun ((_,ce,b),s) -> lift_pexpr_prover (Certificate.nlia ce b) s)
+let memo_nra = CacheQ.memo_opt use_nra_cache ".nra.cache"
+ (fun (o,s) -> lift_pexpr_prover (Certificate.nlinear_prover o) s)
@@ -2154,63 +2234,63 @@ let linear_prover_R = {
}
let nlinear_prover_R = {
- name = "nra";
- get_option = get_lra_option;
- prover = memo_nra ;
- hyps = hyps_of_cone ;
- compact = compact_cone ;
- pp_prf = pp_psatz pp_q ;
- pp_f = fun o x -> pp_pol pp_q o (fst x)
+ name = "nra";
+ get_option = get_lra_option;
+ prover = memo_nra ;
+ hyps = hyps_of_cone ;
+ compact = compact_cone ;
+ pp_prf = pp_psatz pp_q ;
+ pp_f = fun o x -> pp_pol pp_q o (fst x)
}
let non_linear_prover_Q str o = {
- name = "real nonlinear prover";
+ name = "real nonlinear prover";
get_option = (fun () -> (str,o));
- prover = (fun (o,l) -> call_csdpcert_q o l);
- hyps = hyps_of_cone;
- compact = compact_cone ;
- pp_prf = pp_psatz pp_q ;
- pp_f = fun o x -> pp_pol pp_q o (fst x)
+ prover = (fun (o,l) -> call_csdpcert_q o l);
+ hyps = hyps_of_cone;
+ compact = compact_cone ;
+ pp_prf = pp_psatz pp_q ;
+ pp_f = fun o x -> pp_pol pp_q o (fst x)
}
let non_linear_prover_R str o = {
- name = "real nonlinear prover";
- get_option = (fun () -> (str,o));
- prover = (fun (o,l) -> call_csdpcert_q o l);
- hyps = hyps_of_cone;
- compact = compact_cone;
- pp_prf = pp_psatz pp_q;
- pp_f = fun o x -> pp_pol pp_q o (fst x)
+ name = "real nonlinear prover";
+ get_option = (fun () -> (str,o));
+ prover = (fun (o,l) -> call_csdpcert_q o l);
+ hyps = hyps_of_cone;
+ compact = compact_cone;
+ pp_prf = pp_psatz pp_q;
+ pp_f = fun o x -> pp_pol pp_q o (fst x)
}
let non_linear_prover_Z str o = {
- name = "real nonlinear prover";
+ name = "real nonlinear prover";
get_option = (fun () -> (str,o));
- prover = (fun (o,l) -> lift_ratproof (call_csdpcert_z o) l);
- hyps = hyps_of_pt;
- compact = compact_pt;
- pp_prf = pp_proof_term;
- pp_f = fun o x -> pp_pol pp_z o (fst x)
+ prover = (fun (o,l) -> lift_ratproof (call_csdpcert_z o) l);
+ hyps = hyps_of_pt;
+ compact = compact_pt;
+ pp_prf = pp_proof_term;
+ pp_f = fun o x -> pp_pol pp_z o (fst x)
}
let linear_Z = {
- name = "lia";
- get_option = get_lia_option;
- prover = memo_zlinear_prover ;
- hyps = hyps_of_pt;
- compact = compact_pt;
- pp_prf = pp_proof_term;
- pp_f = fun o x -> pp_pol pp_z o (fst x)
+ name = "lia";
+ get_option = get_lia_option;
+ prover = memo_lia ;
+ hyps = hyps_of_pt;
+ compact = compact_pt;
+ pp_prf = pp_proof_term;
+ pp_f = fun o x -> pp_pol pp_z o (fst x)
}
let nlinear_Z = {
- name = "nlia";
- get_option = get_lia_option;
- prover = memo_nlia ;
- hyps = hyps_of_pt;
- compact = compact_pt;
- pp_prf = pp_proof_term;
- pp_f = fun o x -> pp_pol pp_z o (fst x)
+ name = "nlia";
+ get_option = get_lia_option;
+ prover = memo_nlia ;
+ hyps = hyps_of_pt;
+ compact = compact_pt;
+ pp_prf = pp_proof_term;
+ pp_f = fun o x -> pp_pol pp_z o (fst x)
}
(**
diff --git a/plugins/micromega/mutils.ml b/plugins/micromega/mutils.ml
index 537b6175b4..39905f8c52 100644
--- a/plugins/micromega/mutils.ml
+++ b/plugins/micromega/mutils.ml
@@ -233,6 +233,13 @@ struct
| Zpos p -> (positive_big_int p)
| Zneg p -> minus_big_int (positive_big_int p)
+ let z x =
+ match x with
+ | Z0 -> 0
+ | Zpos p -> index p
+ | Zneg p -> - (index p)
+
+
let q_to_num {qnum = x ; qden = y} =
Big_int (z_big_int x) // (Big_int (z_big_int (Zpos y)))
@@ -420,6 +427,80 @@ let command exe_path args vl =
stdout_read; stdout_write;
stderr_read; stderr_write])
+(** Hashing utilities *)
+
+module Hash =
+ struct
+
+ module Mc = Micromega
+
+ open Hashset.Combine
+
+ let int_of_eq_op1 = Mc.(function
+ | Equal -> 0
+ | NonEqual -> 1
+ | Strict -> 2
+ | NonStrict -> 3)
+
+ let eq_op1 o1 o2 = int_of_eq_op1 o1 = int_of_eq_op1 o2
+
+ let hash_op1 h o = combine h (int_of_eq_op1 o)
+
+
+ let rec eq_positive p1 p2 =
+ match p1 , p2 with
+ | Mc.XH , Mc.XH -> true
+ | Mc.XI p1 , Mc.XI p2 -> eq_positive p1 p2
+ | Mc.XO p1 , Mc.XO p2 -> eq_positive p1 p2
+ | _ , _ -> false
+
+ let eq_z z1 z2 =
+ match z1 , z2 with
+ | Mc.Z0 , Mc.Z0 -> true
+ | Mc.Zpos p1, Mc.Zpos p2
+ | Mc.Zneg p1, Mc.Zneg p2 -> eq_positive p1 p2
+ | _ , _ -> false
+
+ let eq_q {Mc.qnum = qn1 ; Mc.qden = qd1} {Mc.qnum = qn2 ; Mc.qden = qd2} =
+ eq_z qn1 qn2 && eq_positive qd1 qd2
+
+ let rec eq_pol eq p1 p2 =
+ match p1 , p2 with
+ | Mc.Pc c1 , Mc.Pc c2 -> eq c1 c2
+ | Mc.Pinj(i1,p1) , Mc.Pinj(i2,p2) -> eq_positive i1 i2 && eq_pol eq p1 p2
+ | Mc.PX(p1,i1,p1') , Mc.PX(p2,i2,p2') ->
+ eq_pol eq p1 p2 && eq_positive i1 i2 && eq_pol eq p1' p2'
+ | _ , _ -> false
+
+
+ let eq_pair eq1 eq2 (x1,y1) (x2,y2) =
+ eq1 x1 x2 && eq2 y1 y2
+
+
+ let hash_pol helt =
+ let rec hash acc = function
+ | Mc.Pc c -> helt (combine acc 1) c
+ | Mc.Pinj(p,c) -> hash (combine (combine acc 1) (CoqToCaml.index p)) c
+ | Mc.PX(p1,i,p2) -> hash (hash (combine (combine acc 2) (CoqToCaml.index i)) p1) p2 in
+ hash
+
+
+ let hash_pair h1 h2 h (e1,e2) =
+ h2 (h1 h e1) e2
+
+ let hash_elt f h e = combine h (f e)
+
+ let hash_string h (e:string) = hash_elt Hashtbl.hash h e
+
+ let hash_z = hash_elt CoqToCaml.z
+
+ let hash_q = hash_elt (fun q -> Hashtbl.hash (CoqToCaml.q_to_num q))
+
+ end
+
+
+
+
(* Local Variables: *)
(* coding: utf-8 *)
(* End: *)
diff --git a/plugins/micromega/mutils.mli b/plugins/micromega/mutils.mli
index 8dbdea39e2..9692bc631b 100644
--- a/plugins/micromega/mutils.mli
+++ b/plugins/micromega/mutils.mli
@@ -67,14 +67,46 @@ end
module CoqToCaml : sig
val z_big_int : Micromega.z -> Big_int.big_int
- val q_to_num : Micromega.q -> Num.num
- val positive : Micromega.positive -> int
- val n : Micromega.n -> int
- val nat : Micromega.nat -> int
- val index : Micromega.positive -> int
+ val z : Micromega.z -> int
+ val q_to_num : Micromega.q -> Num.num
+ val positive : Micromega.positive -> int
+ val n : Micromega.n -> int
+ val nat : Micromega.nat -> int
+ val index : Micromega.positive -> int
end
+module Hash : sig
+
+ val eq_op1 : Micromega.op1 -> Micromega.op1 -> bool
+
+ val eq_positive : Micromega.positive -> Micromega.positive -> bool
+
+ val eq_z : Micromega.z -> Micromega.z -> bool
+
+ val eq_q : Micromega.q -> Micromega.q -> bool
+
+ val eq_pol : ('a -> 'a -> bool) -> 'a Micromega.pol -> 'a Micromega.pol -> bool
+
+ val eq_pair : ('a -> 'a -> bool) -> ('b -> 'b -> bool) -> 'a * 'b -> 'a * 'b -> bool
+
+ val hash_op1 : int -> Micromega.op1 -> int
+
+ val hash_pol : (int -> 'a -> int) -> int -> 'a Micromega.pol -> int
+
+ val hash_pair : (int -> 'a -> int) -> (int -> 'b -> int) -> int -> 'a * 'b -> int
+
+ val hash_z : int -> Micromega.z -> int
+
+ val hash_q : int -> Micromega.q -> int
+
+ val hash_string : int -> string -> int
+
+ val hash_elt : ('a -> int) -> int -> 'a -> int
+
+end
+
+
val ppcm : Big_int.big_int -> Big_int.big_int -> Big_int.big_int
val all_pairs : ('a -> 'a -> 'b) -> 'a list -> 'b list
diff --git a/plugins/micromega/persistent_cache.ml b/plugins/micromega/persistent_cache.ml
index 14a1bc9712..14e2e40846 100644
--- a/plugins/micromega/persistent_cache.ml
+++ b/plugins/micromega/persistent_cache.ml
@@ -127,7 +127,7 @@ let open_in f =
match read_key_elem inch with
| None -> ()
| Some (key,elem) ->
- Table.replace htbl key elem ;
+ Table.add htbl key elem ;
xload () in
try
(* Locking of the (whole) file while reading *)
@@ -164,7 +164,7 @@ let add t k e =
else
let fd = descr_of_out_channel outch in
begin
- Table.replace tbl k e ;
+ Table.add tbl k e ;
do_under_lock Write fd
(fun _ ->
Marshal.to_channel outch (k,e) [Marshal.No_sharing] ;
diff --git a/plugins/setoid_ring/InitialRing.v b/plugins/setoid_ring/InitialRing.v
index a98a963207..dc096554c8 100644
--- a/plugins/setoid_ring/InitialRing.v
+++ b/plugins/setoid_ring/InitialRing.v
@@ -828,31 +828,31 @@ Ltac ring_elements set ext rspec pspec sspec dspec rk :=
end in
ring_elements set ext rspec pspec sspec dspec rk
ltac:(fun arth ext_r morph p_spec s_spec d_spec =>
- match type of morph with
+ lazymatch type of morph with
| @ring_morph ?R ?r0 ?rI ?radd ?rmul ?rsub ?ropp ?req
?C ?c0 ?c1 ?cadd ?cmul ?csub ?copp ?ceq_b ?phi =>
let gen_lemma2_0 :=
constr:(gen_lemma2 R r0 rI radd rmul rsub ropp req set ext_r arth
C c0 c1 cadd cmul csub copp ceq_b phi morph) in
- match p_spec with
+ lazymatch p_spec with
| @mkhypo (power_theory _ _ _ ?Cp_phi ?rpow) ?pp_spec =>
let gen_lemma2_1 := constr:(gen_lemma2_0 _ Cp_phi rpow pp_spec) in
- match d_spec with
+ lazymatch d_spec with
| @mkhypo (div_theory _ _ _ _ ?cdiv) ?dd_spec =>
let gen_lemma2_2 := constr:(gen_lemma2_1 cdiv dd_spec) in
- match s_spec with
+ lazymatch s_spec with
| @mkhypo (sign_theory _ _ ?get_sign) ?ss_spec =>
let lemma2 := constr:(gen_lemma2_2 get_sign ss_spec) in
let lemma1 :=
constr:(ring_correct set ext_r arth morph pp_spec dd_spec) in
fun f => f arth ext_r morph lemma1 lemma2
- | _ => fail 4 "ring: bad sign specification"
+ | _ => fail "ring: bad sign specification"
end
- | _ => fail 3 "ring: bad coefficient division specification"
+ | _ => fail "ring: bad coefficient division specification"
end
- | _ => fail 2 "ring: bad power specification"
+ | _ => fail "ring: bad power specification"
end
- | _ => fail 1 "ring internal error: ring_lemmas, please report"
+ | _ => fail "ring internal error: ring_lemmas, please report"
end).
(* Tactic for constant *)
diff --git a/plugins/ssr/ssrfun.v b/plugins/ssr/ssrfun.v
index 0ce3752a51..dc774e811e 100644
--- a/plugins/ssr/ssrfun.v
+++ b/plugins/ssr/ssrfun.v
@@ -166,7 +166,7 @@ Require Import ssreflect.
right_loop inv op <-> op, inv obey the inverse loop right axiom:
(x op y) op (inv y) = x for all x, y.
rev_right_loop inv op <-> op, inv obey the inverse loop reverse right
- axiom: (x op y) op (inv y) = x for all x, y.
+ axiom: (x op (inv y)) op y = x for all x, y.
Note that familiar "cancellation" identities like x + y - y = x or
x - y + y = x are respectively instances of right_loop and rev_right_loop
The corresponding lemmas will use the K and NK/VK suffixes, respectively.
diff --git a/pretyping/pretyping.mllib b/pretyping/pretyping.mllib
index 0ca39f0404..7e140f4399 100644
--- a/pretyping/pretyping.mllib
+++ b/pretyping/pretyping.mllib
@@ -4,7 +4,6 @@ Locusops
Pretype_errors
Reductionops
Inductiveops
-InferCumulativity
Arguments_renaming
Retyping
Vnorm
diff --git a/printing/prettyp.ml b/printing/prettyp.ml
index fb0b1eca8d..c995887f31 100644
--- a/printing/prettyp.ml
+++ b/printing/prettyp.ml
@@ -38,11 +38,11 @@ type object_pr = {
print_constant_with_infos : Opaqueproof.indirect_accessor -> Constant.t -> UnivNames.univ_name_list option -> Pp.t;
print_section_variable : env -> Evd.evar_map -> variable -> Pp.t;
print_syntactic_def : env -> KerName.t -> Pp.t;
- print_module : bool -> ModPath.t -> Pp.t;
- print_modtype : ModPath.t -> Pp.t;
+ print_module : mod_ops:Printmod.mod_ops -> bool -> ModPath.t -> Pp.t;
+ print_modtype : mod_ops:Printmod.mod_ops -> ModPath.t -> Pp.t;
print_named_decl : env -> Evd.evar_map -> Constr.named_declaration -> Pp.t;
- print_library_entry : Opaqueproof.indirect_accessor -> env -> Evd.evar_map -> bool -> (object_name * Lib.node) -> Pp.t option;
- print_context : Opaqueproof.indirect_accessor -> env -> Evd.evar_map -> bool -> int option -> Lib.library_segment -> Pp.t;
+ print_library_entry : mod_ops:Printmod.mod_ops -> Opaqueproof.indirect_accessor -> env -> Evd.evar_map -> bool -> (object_name * Lib.node) -> Pp.t option;
+ print_context : mod_ops:Printmod.mod_ops -> Opaqueproof.indirect_accessor -> env -> Evd.evar_map -> bool -> int option -> Lib.library_segment -> Pp.t;
print_typed_value_in_env : Environ.env -> Evd.evar_map -> EConstr.constr * EConstr.types -> Pp.t;
print_eval : Reductionops.reduction_function -> env -> Evd.evar_map -> Constrexpr.constr_expr -> EConstr.unsafe_judgment -> Pp.t;
}
@@ -618,7 +618,7 @@ let gallina_print_syntactic_def env kn =
Constrextern.without_specific_symbols
[Notation.SynDefRule kn] (pr_glob_constr_env env) c)
-let gallina_print_leaf_entry indirect_accessor env sigma with_values ((sp,kn as oname),lobj) =
+let gallina_print_leaf_entry ~mod_ops indirect_accessor env sigma with_values ((sp,kn as oname),lobj) =
let sep = if with_values then " = " else " : " in
match lobj with
| AtomicObject o ->
@@ -639,17 +639,17 @@ let gallina_print_leaf_entry indirect_accessor env sigma with_values ((sp,kn as
end
| ModuleObject _ ->
let (mp,l) = KerName.repr kn in
- Some (print_module with_values (MPdot (mp,l)))
+ Some (print_module ~mod_ops with_values (MPdot (mp,l)))
| ModuleTypeObject _ ->
let (mp,l) = KerName.repr kn in
- Some (print_modtype (MPdot (mp,l)))
+ Some (print_modtype ~mod_ops (MPdot (mp,l)))
| _ -> None
-let gallina_print_library_entry indirect_accessor env sigma with_values ent =
+let gallina_print_library_entry ~mod_ops indirect_accessor env sigma with_values ent =
let pr_name (sp,_) = Id.print (basename sp) in
match ent with
| (oname,Lib.Leaf lobj) ->
- gallina_print_leaf_entry indirect_accessor env sigma with_values (oname,lobj)
+ gallina_print_leaf_entry ~mod_ops indirect_accessor env sigma with_values (oname,lobj)
| (oname,Lib.OpenedSection (dir,_)) ->
Some (str " >>>>>>> Section " ++ pr_name oname)
| (_,Lib.CompilingLibrary { Nametab.obj_dir; _ }) ->
@@ -657,10 +657,10 @@ let gallina_print_library_entry indirect_accessor env sigma with_values ent =
| (oname,Lib.OpenedModule _) ->
Some (str " >>>>>>> Module " ++ pr_name oname)
-let gallina_print_context indirect_accessor env sigma with_values =
+let gallina_print_context ~mod_ops indirect_accessor env sigma with_values =
let rec prec n = function
| h::rest when Option.is_empty n || Option.get n > 0 ->
- (match gallina_print_library_entry indirect_accessor env sigma with_values h with
+ (match gallina_print_library_entry ~mod_ops indirect_accessor env sigma with_values h with
| None -> prec n rest
| Some pp -> prec (Option.map ((+) (-1)) n) rest ++ pp ++ fnl ())
| _ -> mt ()
@@ -698,8 +698,8 @@ let print_syntactic_def x = !object_pr.print_syntactic_def x
let print_module x = !object_pr.print_module x
let print_modtype x = !object_pr.print_modtype x
let print_named_decl x = !object_pr.print_named_decl x
-let print_library_entry x = !object_pr.print_library_entry x
-let print_context x = !object_pr.print_context x
+let print_library_entry ~mod_ops x = !object_pr.print_library_entry ~mod_ops x
+let print_context ~mod_ops x = !object_pr.print_context ~mod_ops x
let print_typed_value_in_env x = !object_pr.print_typed_value_in_env x
let print_eval x = !object_pr.print_eval x
@@ -720,10 +720,12 @@ let print_safe_judgment env sigma j =
(*********************)
(* *)
-let print_full_context indirect_accessor env sigma = print_context indirect_accessor env sigma true None (Lib.contents ())
-let print_full_context_typ indirect_accessor env sigma = print_context indirect_accessor env sigma false None (Lib.contents ())
+let print_full_context ~mod_ops indirect_accessor env sigma =
+ print_context ~mod_ops indirect_accessor env sigma true None (Lib.contents ())
+let print_full_context_typ ~mod_ops indirect_accessor env sigma =
+ print_context ~mod_ops indirect_accessor env sigma false None (Lib.contents ())
-let print_full_pure_context ~library_accessor env sigma =
+let print_full_pure_context ~mod_ops ~library_accessor env sigma =
let rec prec = function
| ((_,kn),Lib.Leaf AtomicObject lobj)::rest ->
let pp = match object_tag lobj with
@@ -758,11 +760,11 @@ let print_full_pure_context ~library_accessor env sigma =
| ((_,kn),Lib.Leaf ModuleObject _)::rest ->
(* TODO: make it reparsable *)
let (mp,l) = KerName.repr kn in
- prec rest ++ print_module true (MPdot (mp,l)) ++ str "." ++ fnl () ++ fnl ()
+ prec rest ++ print_module ~mod_ops true (MPdot (mp,l)) ++ str "." ++ fnl () ++ fnl ()
| ((_,kn),Lib.Leaf ModuleTypeObject _)::rest ->
(* TODO: make it reparsable *)
let (mp,l) = KerName.repr kn in
- prec rest ++ print_modtype (MPdot (mp,l)) ++ str "." ++ fnl () ++ fnl ()
+ prec rest ++ print_modtype ~mod_ops (MPdot (mp,l)) ++ str "." ++ fnl () ++ fnl ()
| _::rest -> prec rest
| _ -> mt () in
prec (Lib.contents ())
@@ -787,11 +789,11 @@ let read_sec_context qid =
let cxt = Lib.contents () in
List.rev (get_cxt [] cxt)
-let print_sec_context indirect_accessor env sigma sec =
- print_context indirect_accessor env sigma true None (read_sec_context sec)
+let print_sec_context ~mod_ops indirect_accessor env sigma sec =
+ print_context ~mod_ops indirect_accessor env sigma true None (read_sec_context sec)
-let print_sec_context_typ indirect_accessor env sigma sec =
- print_context indirect_accessor env sigma false None (read_sec_context sec)
+let print_sec_context_typ ~mod_ops indirect_accessor env sigma sec =
+ print_context ~mod_ops indirect_accessor env sigma false None (read_sec_context sec)
let maybe_error_reject_univ_decl na udecl =
let open GlobRef in
@@ -801,7 +803,7 @@ let maybe_error_reject_univ_decl na udecl =
(* TODO Print na somehow *)
user_err ~hdr:"reject_univ_decl" (str "This object does not support universe names.")
-let print_any_name indirect_accessor env sigma na udecl =
+let print_any_name ~mod_ops indirect_accessor env sigma na udecl =
maybe_error_reject_univ_decl na udecl;
let open GlobRef in
match na with
@@ -810,9 +812,10 @@ let print_any_name indirect_accessor env sigma na udecl =
| Term (ConstructRef ((sp,_),_)) -> print_inductive sp udecl
| Term (VarRef sp) -> print_section_variable env sigma sp
| Syntactic kn -> print_syntactic_def env kn
- | Dir (Nametab.GlobDirRef.DirModule Nametab.{ obj_dir; obj_mp; _ } ) -> print_module (printable_body obj_dir) obj_mp
+ | Dir (Nametab.GlobDirRef.DirModule Nametab.{ obj_dir; obj_mp; _ } ) ->
+ print_module ~mod_ops (printable_body obj_dir) obj_mp
| Dir _ -> mt ()
- | ModuleType mp -> print_modtype mp
+ | ModuleType mp -> print_modtype ~mod_ops mp
| Other (obj, info) -> info.print obj
| Undefined qid ->
try (* Var locale de but, pas var de section... donc pas d'implicits *)
@@ -824,15 +827,15 @@ let print_any_name indirect_accessor env sigma na udecl =
user_err
~hdr:"print_name" (pr_qualid qid ++ spc () ++ str "not a defined object.")
-let print_name indirect_accessor env sigma na udecl =
+let print_name ~mod_ops indirect_accessor env sigma na udecl =
match na with
| {loc; v=Constrexpr.ByNotation (ntn,sc)} ->
- print_any_name indirect_accessor env sigma
+ print_any_name ~mod_ops indirect_accessor env sigma
(Term (Notation.interp_notation_as_global_reference ?loc (fun _ -> true)
ntn sc))
udecl
| {loc; v=Constrexpr.AN ref} ->
- print_any_name indirect_accessor env sigma (locate_any_name ref) udecl
+ print_any_name ~mod_ops indirect_accessor env sigma (locate_any_name ref) udecl
let print_opaque_name indirect_accessor env sigma qid =
let open GlobRef in
@@ -888,8 +891,8 @@ let print_about env sigma na udecl =
print_about_any ?loc env sigma (locate_any_name ref) udecl
(* for debug *)
-let inspect indirect_accessor env sigma depth =
- print_context indirect_accessor env sigma false (Some depth) (Lib.contents ())
+let inspect ~mod_ops indirect_accessor env sigma depth =
+ print_context ~mod_ops indirect_accessor env sigma false (Some depth) (Lib.contents ())
(*************************************************************************)
(* Pretty-printing functions coming from classops.ml *)
diff --git a/printing/prettyp.mli b/printing/prettyp.mli
index 4299bcc880..c8b361d95b 100644
--- a/printing/prettyp.mli
+++ b/printing/prettyp.mli
@@ -19,28 +19,35 @@ val assumptions_for_print : Name.t list -> Termops.names_context
val print_closed_sections : bool ref
val print_context
- : Opaqueproof.indirect_accessor
+ : mod_ops:Printmod.mod_ops
+ -> Opaqueproof.indirect_accessor
-> env -> Evd.evar_map
-> bool -> int option -> Lib.library_segment -> Pp.t
val print_library_entry
- : Opaqueproof.indirect_accessor
+ : mod_ops:Printmod.mod_ops
+ -> Opaqueproof.indirect_accessor
-> env -> Evd.evar_map
-> bool -> (Libobject.object_name * Lib.node) -> Pp.t option
val print_full_context
- : Opaqueproof.indirect_accessor -> env -> Evd.evar_map -> Pp.t
+ : mod_ops:Printmod.mod_ops
+ -> Opaqueproof.indirect_accessor -> env -> Evd.evar_map -> Pp.t
val print_full_context_typ
- : Opaqueproof.indirect_accessor -> env -> Evd.evar_map -> Pp.t
+ : mod_ops:Printmod.mod_ops
+ -> Opaqueproof.indirect_accessor -> env -> Evd.evar_map -> Pp.t
val print_full_pure_context
- : library_accessor:Opaqueproof.indirect_accessor
+ : mod_ops:Printmod.mod_ops
+ -> library_accessor:Opaqueproof.indirect_accessor
-> env
-> Evd.evar_map
-> Pp.t
val print_sec_context
- : Opaqueproof.indirect_accessor -> env -> Evd.evar_map -> qualid -> Pp.t
+ : mod_ops:Printmod.mod_ops
+ -> Opaqueproof.indirect_accessor -> env -> Evd.evar_map -> qualid -> Pp.t
val print_sec_context_typ
- : Opaqueproof.indirect_accessor -> env -> Evd.evar_map -> qualid -> Pp.t
+ : mod_ops:Printmod.mod_ops
+ -> Opaqueproof.indirect_accessor -> env -> Evd.evar_map -> qualid -> Pp.t
val print_judgment : env -> Evd.evar_map -> EConstr.unsafe_judgment -> Pp.t
val print_safe_judgment : env -> Evd.evar_map -> Safe_typing.judgment -> Pp.t
val print_eval :
@@ -48,7 +55,8 @@ val print_eval :
Constrexpr.constr_expr -> EConstr.unsafe_judgment -> Pp.t
val print_name
- : Opaqueproof.indirect_accessor
+ : mod_ops:Printmod.mod_ops
+ -> Opaqueproof.indirect_accessor
-> env -> Evd.evar_map -> qualid Constrexpr.or_by_notation
-> UnivNames.univ_name_list option -> Pp.t
val print_opaque_name
@@ -69,7 +77,10 @@ val print_typeclasses : unit -> Pp.t
val print_instances : GlobRef.t -> Pp.t
val print_all_instances : unit -> Pp.t
-val inspect : Opaqueproof.indirect_accessor -> env -> Evd.evar_map -> int -> Pp.t
+val inspect
+ : mod_ops:Printmod.mod_ops
+ -> Opaqueproof.indirect_accessor
+ -> env -> Evd.evar_map -> int -> Pp.t
(** {5 Locate} *)
@@ -105,11 +116,11 @@ type object_pr = {
print_constant_with_infos : Opaqueproof.indirect_accessor -> Constant.t -> UnivNames.univ_name_list option -> Pp.t;
print_section_variable : env -> Evd.evar_map -> variable -> Pp.t;
print_syntactic_def : env -> KerName.t -> Pp.t;
- print_module : bool -> ModPath.t -> Pp.t;
- print_modtype : ModPath.t -> Pp.t;
+ print_module : mod_ops:Printmod.mod_ops -> bool -> ModPath.t -> Pp.t;
+ print_modtype : mod_ops:Printmod.mod_ops -> ModPath.t -> Pp.t;
print_named_decl : env -> Evd.evar_map -> Constr.named_declaration -> Pp.t;
- print_library_entry : Opaqueproof.indirect_accessor -> env -> Evd.evar_map -> bool -> (Libobject.object_name * Lib.node) -> Pp.t option;
- print_context : Opaqueproof.indirect_accessor -> env -> Evd.evar_map -> bool -> int option -> Lib.library_segment -> Pp.t;
+ print_library_entry : mod_ops:Printmod.mod_ops -> Opaqueproof.indirect_accessor -> env -> Evd.evar_map -> bool -> (Libobject.object_name * Lib.node) -> Pp.t option;
+ print_context : mod_ops:Printmod.mod_ops -> Opaqueproof.indirect_accessor -> env -> Evd.evar_map -> bool -> int option -> Lib.library_segment -> Pp.t;
print_typed_value_in_env : Environ.env -> Evd.evar_map -> EConstr.constr * EConstr.types -> Pp.t;
print_eval : Reductionops.reduction_function -> env -> Evd.evar_map -> Constrexpr.constr_expr -> EConstr.unsafe_judgment -> Pp.t;
}
diff --git a/printing/printer.ml b/printing/printer.ml
index 328082fbc2..10a31ac256 100644
--- a/printing/printer.ml
+++ b/printing/printer.ml
@@ -635,27 +635,34 @@ let () =
optwrite = (fun v -> should_print_dependent_evars := v) }
let print_dependent_evars gl sigma seeds =
- let constraints = print_evar_constraints gl sigma in
- let evars () =
- if !should_print_dependent_evars then
- let evars = Evarutil.gather_dependent_evars sigma seeds in
- let evars =
- Evar.Map.fold begin fun e i s ->
- let e' = pr_internal_existential_key e in
- match i with
- | None -> s ++ str" " ++ e' ++ str " open,"
- | Some i ->
- s ++ str " " ++ e' ++ str " using " ++
- Evar.Set.fold begin fun d s ->
- pr_internal_existential_key d ++ str " " ++ s
- end i (str ",")
- end evars (str "")
+ if !should_print_dependent_evars then
+ let mt_pp = mt () in
+ let evars = Evarutil.gather_dependent_evars sigma seeds in
+ let evars_pp = Evar.Map.fold (fun e i s ->
+ let e' = pr_internal_existential_key e in
+ let sep = if s = mt_pp then "" else ", " in
+ s ++ str sep ++ e' ++
+ (match i with
+ | None -> str ":" ++ (Termops.pr_existential_key sigma e)
+ | Some i ->
+ let using = Evar.Set.fold (fun d s ->
+ s ++ str " " ++ (pr_internal_existential_key d))
+ i mt_pp in
+ str " using" ++ using))
+ evars mt_pp
+ in
+ let evars_current_pp = match gl with
+ | None -> mt_pp
+ | Some gl ->
+ let evars_current = Evarutil.gather_dependent_evars sigma [ gl ] in
+ Evar.Map.fold (fun e _ s ->
+ s ++ str " " ++ (pr_internal_existential_key e))
+ evars_current mt_pp
in
cut () ++ cut () ++
- str "(dependent evars:" ++ evars ++ str ")"
- else mt ()
- in
- constraints ++ evars ()
+ str "(dependent evars: " ++ evars_pp ++
+ str "; in current goal:" ++ evars_current_pp ++ str ")"
+ else mt ()
module GoalMap = Evar.Map
@@ -732,6 +739,10 @@ let pr_subgoals ?(pr_first=true) ?(diffs=false) ?os_map
else
pr_rec 1 (g::l)
in
+ let pr_evar_info gl sigma seeds =
+ let first_goal = if pr_first then gl else None in
+ print_evar_constraints gl sigma ++ print_dependent_evars first_goal sigma seeds
+ in
(* Side effect! This has to be made more robust *)
let () =
match close_cmd with
@@ -742,23 +753,21 @@ let pr_subgoals ?(pr_first=true) ?(diffs=false) ?os_map
(* Main function *)
match goals with
| [] ->
- begin
- let exl = Evd.undefined_map sigma in
- if Evar.Map.is_empty exl then
- (str"No more subgoals." ++ print_dependent_evars None sigma seeds)
- else
- let pei = pr_evars_int sigma ~shelf ~given_up:[] 1 exl in
- v 0 ((str "No more subgoals,"
- ++ str " but there are non-instantiated existential variables:"
- ++ cut () ++ (hov 0 pei)
- ++ print_dependent_evars None sigma seeds
- ++ cut () ++ str "You can use Grab Existential Variables."))
- end
+ let exl = Evd.undefined_map sigma in
+ if Evar.Map.is_empty exl then
+ v 0 (str "No more subgoals." ++ pr_evar_info None sigma seeds)
+ else
+ let pei = pr_evars_int sigma ~shelf ~given_up:[] 1 exl in
+ v 0 ((str "No more subgoals,"
+ ++ str " but there are non-instantiated existential variables:"
+ ++ cut () ++ (hov 0 pei)
+ ++ pr_evar_info None sigma seeds
+ ++ cut () ++ str "You can use Grab Existential Variables."))
| g1::rest ->
let goals = print_multiple_goals g1 rest in
let ngoals = List.length rest+1 in
v 0 (
- int ngoals ++ focused_if_needed ++ str(String.plural ngoals "subgoal")
+ 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"")
@@ -766,7 +775,7 @@ let pr_subgoals ?(pr_first=true) ?(diffs=false) ?os_map
++ (if unfocused=[] then str ""
else (cut() ++ cut() ++ str "*** Unfocused goals:" ++ cut()
++ pr_rec (List.length rest + 2) unfocused))
- ++ print_dependent_evars (Some g1) sigma seeds
+ ++ pr_evar_info (Some g1) sigma seeds
)
let pr_open_subgoals_diff ?(quiet=false) ?(diffs=false) ?oproof proof =
diff --git a/printing/printer.mli b/printing/printer.mli
index d62d3789d3..87b09ff755 100644
--- a/printing/printer.mli
+++ b/printing/printer.mli
@@ -186,6 +186,7 @@ val pr_ne_evar_set : Pp.t -> Pp.t -> evar_map ->
Evar.Set.t -> Pp.t
val print_and_diff : Proof.t option -> Proof.t option -> unit
+val print_dependent_evars : Evar.t option -> evar_map -> Evar.t list -> Pp.t
(** Declarations for the "Print Assumption" command *)
type axiom =
diff --git a/printing/printmod.ml b/printing/printmod.ml
index 141469ff9c..03921bca30 100644
--- a/printing/printmod.ml
+++ b/printing/printmod.ml
@@ -240,9 +240,14 @@ let nametab_register_body mp dir (l,body) =
mip.mind_consnames)
mib.mind_packets
-let nametab_register_module_body mp struc =
+type mod_ops =
+ { import_module : export:bool -> ModPath.t -> unit
+ ; process_module_binding : MBId.t -> Declarations.module_alg_expr -> unit
+ }
+
+let nametab_register_module_body ~mod_ops mp struc =
(* If [mp] is a globally visible module, we simply import it *)
- try Declaremods.import_module ~export:false mp
+ try mod_ops.import_module ~export:false mp
with Not_found ->
(* Otherwise we try to emulate an import by playing with nametab *)
nametab_register_dir mp;
@@ -252,7 +257,7 @@ let get_typ_expr_alg mtb = match mtb.mod_type_alg with
| Some (NoFunctor me) -> me
| _ -> raise Not_found
-let nametab_register_modparam mbid mtb =
+let nametab_register_modparam ~mod_ops mbid mtb =
let id = MBId.to_id mbid in
match mtb.mod_type with
| MoreFunctor _ -> id (* functorial param : nothing to register *)
@@ -260,7 +265,7 @@ let nametab_register_modparam mbid mtb =
(* We first try to use the algebraic type expression if any,
via a Declaremods function that converts back to module entries *)
try
- let () = Declaremods.process_module_binding mbid (get_typ_expr_alg mtb) in
+ let () = mod_ops.process_module_binding mbid (get_typ_expr_alg mtb) in
id
with e when CErrors.noncritical e ->
(* Otherwise, we try to play with the nametab ourselves *)
@@ -314,9 +319,9 @@ let print_body is_impl extent env mp (l,body) =
let print_struct is_impl extent env mp struc =
prlist_with_sep spc (print_body is_impl extent env mp) struc
-let print_structure is_type extent env mp locals struc =
+let print_structure ~mod_ops is_type extent env mp locals struc =
let env' = Modops.add_structure mp struc Mod_subst.empty_delta_resolver env in
- nametab_register_module_body mp struc;
+ nametab_register_module_body ~mod_ops mp struc;
let kwd = if is_type then "Sig" else "Struct" in
hv 2 (keyword kwd ++ spc () ++ print_struct false extent env' mp struc ++
brk (1,-2) ++ keyword "End")
@@ -362,31 +367,31 @@ let print_mod_expr env mp locals = function
(str"(" ++ prlist_with_sep spc (print_modpath locals) lapp ++ str")")
| MEwith _ -> assert false (* No 'with' syntax for modules *)
-let rec print_functor fty fatom is_type extent env mp locals = function
- | NoFunctor me -> fatom is_type extent env mp locals me
+let rec print_functor ~mod_ops fty fatom is_type extent env mp locals = function
+ | NoFunctor me -> fatom ~mod_ops is_type extent env mp locals me
| MoreFunctor (mbid,mtb1,me2) ->
- let id = nametab_register_modparam mbid mtb1 in
+ let id = nametab_register_modparam ~mod_ops mbid mtb1 in
let mp1 = MPbound mbid in
- let pr_mtb1 = fty extent env mp1 locals mtb1 in
+ let pr_mtb1 = fty ~mod_ops extent env mp1 locals mtb1 in
let env' = Modops.add_module_type mp1 mtb1 env in
let locals' = (mbid, get_new_id locals (MBId.to_id mbid))::locals in
let kwd = if is_type then "Funsig" else "Functor" in
hov 2
(keyword kwd ++ spc () ++
str "(" ++ Id.print id ++ str ":" ++ pr_mtb1 ++ str ")" ++
- spc() ++ print_functor fty fatom is_type extent env' mp locals' me2)
+ spc() ++ print_functor ~mod_ops fty fatom is_type extent env' mp locals' me2)
-let rec print_expression x =
- print_functor
+let rec print_expression ~mod_ops x =
+ print_functor ~mod_ops
print_modtype
- (function true -> print_typ_expr | false -> fun _ -> print_mod_expr) x
+ (fun ~mod_ops -> function true -> print_typ_expr | false -> fun _ -> print_mod_expr) x
-and print_signature x =
- print_functor print_modtype print_structure x
+and print_signature ~mod_ops x =
+ print_functor ~mod_ops print_modtype print_structure x
-and print_modtype extent env mp locals mtb = match mtb.mod_type_alg with
- | Some me -> print_expression true extent env mp locals me
- | None -> print_signature true extent env mp locals mtb.mod_type
+and print_modtype ~mod_ops extent env mp locals mtb = match mtb.mod_type_alg with
+ | Some me -> print_expression ~mod_ops true extent env mp locals me
+ | None -> print_signature ~mod_ops true extent env mp locals mtb.mod_type
let rec printable_body dir =
let dir = pop_dirpath dir in
@@ -403,52 +408,52 @@ let rec printable_body dir =
(** Since we might play with nametab above, we should reset to prior
state after the printing *)
-let print_expression' is_type extent env mp me =
+let print_expression' ~mod_ops is_type extent env mp me =
States.with_state_protection
- (fun e -> print_expression is_type extent env mp [] e) me
+ (fun e -> print_expression ~mod_ops is_type extent env mp [] e) me
-let print_signature' is_type extent env mp me =
+let print_signature' ~mod_ops is_type extent env mp me =
States.with_state_protection
- (fun e -> print_signature is_type extent env mp [] e) me
+ (fun e -> print_signature ~mod_ops is_type extent env mp [] e) me
-let unsafe_print_module extent env mp with_body mb =
+let unsafe_print_module ~mod_ops extent env mp with_body mb =
let name = print_modpath [] mp in
let pr_equals = spc () ++ str ":= " in
let body = match with_body, mb.mod_expr with
| false, _
| true, Abstract -> mt()
- | _, Algebraic me -> pr_equals ++ print_expression' false extent env mp me
- | _, Struct sign -> pr_equals ++ print_signature' false extent env mp sign
- | _, FullStruct -> pr_equals ++ print_signature' false extent env mp mb.mod_type
+ | _, Algebraic me -> pr_equals ++ print_expression' ~mod_ops false extent env mp me
+ | _, Struct sign -> pr_equals ++ print_signature' ~mod_ops false extent env mp sign
+ | _, FullStruct -> pr_equals ++ print_signature' ~mod_ops false extent env mp mb.mod_type
in
let modtype = match mb.mod_expr, mb.mod_type_alg with
| FullStruct, _ -> mt ()
- | _, Some ty -> brk (1,1) ++ str": " ++ print_expression' true extent env mp ty
- | _, _ -> brk (1,1) ++ str": " ++ print_signature' true extent env mp mb.mod_type
+ | _, Some ty -> brk (1,1) ++ str": " ++ print_expression' ~mod_ops true extent env mp ty
+ | _, _ -> brk (1,1) ++ str": " ++ print_signature' ~mod_ops true extent env mp mb.mod_type
in
hv 0 (keyword "Module" ++ spc () ++ name ++ modtype ++ body)
exception ShortPrinting
-let print_module with_body mp =
+let print_module ~mod_ops with_body mp =
let me = Global.lookup_module mp in
try
if !short then raise ShortPrinting;
- unsafe_print_module WithContents
+ unsafe_print_module ~mod_ops WithContents
(Global.env ()) mp with_body me ++ fnl ()
with e when CErrors.noncritical e ->
- unsafe_print_module OnlyNames
+ unsafe_print_module ~mod_ops OnlyNames
(Global.env ()) mp with_body me ++ fnl ()
-let print_modtype kn =
+let print_modtype ~mod_ops kn =
let mtb = Global.lookup_modtype kn in
let name = print_kn [] kn in
hv 1
(keyword "Module Type" ++ spc () ++ name ++ str " =" ++ spc () ++
try
if !short then raise ShortPrinting;
- print_signature' true WithContents
+ print_signature' ~mod_ops true WithContents
(Global.env ()) kn mtb.mod_type
with e when CErrors.noncritical e ->
- print_signature' true OnlyNames
+ print_signature' ~mod_ops true OnlyNames
(Global.env ()) kn mtb.mod_type)
diff --git a/printing/printmod.mli b/printing/printmod.mli
index 8fd1cb4183..4c9245ee27 100644
--- a/printing/printmod.mli
+++ b/printing/printmod.mli
@@ -16,5 +16,11 @@ val printable_body : DirPath.t -> bool
val pr_mutual_inductive_body : Environ.env ->
MutInd.t -> Declarations.mutual_inductive_body ->
UnivNames.univ_name_list option -> Pp.t
-val print_module : bool -> ModPath.t -> Pp.t
-val print_modtype : ModPath.t -> Pp.t
+
+type mod_ops =
+ { import_module : export:bool -> ModPath.t -> unit
+ ; process_module_binding : MBId.t -> Declarations.module_alg_expr -> unit
+ }
+
+val print_module : mod_ops:mod_ops -> bool -> ModPath.t -> Pp.t
+val print_modtype : mod_ops:mod_ops -> ModPath.t -> Pp.t
diff --git a/stm/stm.ml b/stm/stm.ml
index 1042061021..5c6df26cbb 100644
--- a/stm/stm.ml
+++ b/stm/stm.ml
@@ -1056,7 +1056,7 @@ end (* }}} *)
(* Wrapper for the proof-closing special path for Qed *)
let stm_qed_delay_proof ?route ~proof ~info ~id ~st ~loc ~control pending : Vernacstate.t =
set_id_for_feedback ?route dummy_doc id;
- Vernacentries.interp_qed_delayed_proof ~proof ~info ~st ~control (CAst.make ?loc pending)
+ Vernacinterp.interp_qed_delayed_proof ~proof ~info ~st ~control (CAst.make ?loc pending)
(* Wrapper for Vernacentries.interp to set the feedback id *)
(* It is currently called 19 times, this number should be certainly
@@ -1083,7 +1083,7 @@ let stm_vernac_interp ?route id st { verbose; expr } : Vernacstate.t =
(stm_pperr_endline Pp.(fun () -> str "ignoring " ++ Ppvernac.pr_vernac expr); st)
else begin
stm_pperr_endline Pp.(fun () -> str "interpreting " ++ Ppvernac.pr_vernac expr);
- Vernacentries.interp ?verbosely:(Some verbose) ~st expr
+ Vernacinterp.interp ?verbosely:(Some verbose) ~st expr
end
(****************************** CRUFT *****************************************)
@@ -1743,9 +1743,9 @@ end = struct (* {{{ *)
assert (Univ.ContextSet.is_empty uctx)
in
let pr = Constr.hcons pr in
- let (ci, dummy) = p.(bucket) in
+ let dummy = p.(bucket) in
let () = assert (Option.is_empty dummy) in
- p.(bucket) <- ci, Some (pr, priv);
+ p.(bucket) <- Some (pr, priv);
Univ.ContextSet.union cst uc, false
let check_task name l i =
@@ -1970,7 +1970,7 @@ end = struct (* {{{ *)
let stm_fail ~st fail f =
if fail then
- Vernacentries.with_fail ~st f
+ Vernacinterp.with_fail ~st f
else
f ()
@@ -2891,7 +2891,7 @@ let process_transaction ~doc ?(newtip=Stateid.fresh ())
|> Exninfo.iraise
else
- let proof_mode = Some (Vernacentries.get_default_proof_mode ()) in
+ let proof_mode = Some (Vernacinterp.get_default_proof_mode ()) in
let id = VCS.new_node ~id:newtip proof_mode () in
let bname = VCS.mk_branch_name x in
VCS.checkout VCS.Branch.master;
diff --git a/stm/vernac_classifier.ml b/stm/vernac_classifier.ml
index 8d600c2859..24976d8c1f 100644
--- a/stm/vernac_classifier.ml
+++ b/stm/vernac_classifier.ml
@@ -51,7 +51,7 @@ let stm_allow_nested_proofs_option_name = ["Nested";"Proofs";"Allowed"]
let options_affecting_stm_scheduling =
[ Attributes.universe_polymorphism_option_name;
stm_allow_nested_proofs_option_name;
- Vernacentries.proof_mode_opt_name;
+ Vernacinterp.proof_mode_opt_name;
Attributes.program_mode_option_name;
Proof_using.proof_using_opt_name;
]
diff --git a/tactics/declare.ml b/tactics/declare.ml
index 3a02e5451a..3590146dfb 100644
--- a/tactics/declare.ml
+++ b/tactics/declare.ml
@@ -35,22 +35,32 @@ type import_status = ImportDefaultBehavior | ImportNeedQualified
(** Monomorphic universes need to survive sections. *)
-let input_universe_context : Univ.ContextSet.t -> Libobject.obj =
- declare_object @@ local_object "Monomorphic section universes"
- ~cache:(fun (na, uctx) -> Global.push_context_set false uctx)
- ~discharge:(fun (_, x) -> Some x)
+let name_instance inst =
+ let map lvl = match Univ.Level.name lvl with
+ | None -> (* Having Prop/Set/Var as section universes makes no sense *)
+ assert false
+ | Some na ->
+ try
+ let qid = Nametab.shortest_qualid_of_universe na in
+ Name (Libnames.qualid_basename qid)
+ with Not_found ->
+ (* Best-effort naming from the string representation of the level.
+ See univNames.ml for a similar hack. *)
+ Name (Id.of_string_soft (Univ.Level.to_string lvl))
+ in
+ Array.map map (Univ.Instance.to_array inst)
let declare_universe_context ~poly ctx =
if poly then
- (Global.push_context_set true ctx; Lib.add_section_context ctx)
+ let uctx = Univ.ContextSet.to_context ctx in
+ let nas = name_instance (Univ.UContext.instance uctx) in
+ Global.push_section_context (nas, uctx)
else
- Lib.add_anonymous_leaf (input_universe_context ctx)
+ Global.push_context_set false ctx
(** Declaration of constants and parameters *)
type constant_obj = {
- cst_decl : Cooking.recipe option;
- (** Non-empty only when rebuilding a constant after a section *)
cst_kind : Decls.logical_kind;
cst_locl : import_status;
}
@@ -58,7 +68,7 @@ type constant_obj = {
type 'a proof_entry = {
proof_entry_body : 'a Entries.const_entry_body;
(* List of section variables *)
- proof_entry_secctx : Constr.named_context option;
+ proof_entry_secctx : Id.Set.t option;
(* State id on which the completion of type checking is reported *)
proof_entry_feedback : Stateid.t option;
proof_entry_type : Constr.types option;
@@ -81,12 +91,6 @@ let load_constant i ((sp,kn), obj) =
Nametab.push (Nametab.Until i) sp (GlobRef.ConstRef con);
Dumpglob.add_constant_kind con obj.cst_kind
-let cooking_info segment =
- let modlist = replacement_context () in
- let { abstr_ctx = named_ctx; abstr_subst = subst; abstr_uctx = uctx } = segment in
- let abstract = (named_ctx, subst, uctx) in
- { Opaqueproof.modlist; abstract }
-
(* Opening means making the name without its module qualification available *)
let open_constant i ((sp,kn), obj) =
(* Never open a local definition *)
@@ -106,33 +110,20 @@ let check_exists id =
let cache_constant ((sp,kn), obj) =
(* Invariant: the constant must exist in the logical environment, except when
redefining it when exiting a section. See [discharge_constant]. *)
- let id = Libnames.basename sp in
let kn' =
- match obj.cst_decl with
- | None ->
- if Global.exists_objlabel (Label.of_id (Libnames.basename sp))
- then Constant.make1 kn
- else CErrors.anomaly Pp.(str"Missing constant " ++ Id.print(Libnames.basename sp) ++ str".")
- | Some r ->
- Global.add_recipe ~in_section:(Lib.sections_are_opened ()) id r
+ if Global.exists_objlabel (Label.of_id (Libnames.basename sp))
+ then Constant.make1 kn
+ else CErrors.anomaly Pp.(str"Missing constant " ++ Id.print(Libnames.basename sp) ++ str".")
in
assert (Constant.equal kn' (Constant.make1 kn));
Nametab.push (Nametab.Until 1) sp (GlobRef.ConstRef (Constant.make1 kn));
- let cst = Global.lookup_constant kn' in
- add_section_constant ~poly:(Declareops.constant_is_polymorphic cst) kn' cst.const_hyps;
Dumpglob.add_constant_kind (Constant.make1 kn) obj.cst_kind
let discharge_constant ((sp, kn), obj) =
- let con = Constant.make1 kn in
- let from = Global.lookup_constant con in
- let info = cooking_info (section_segment_of_constant con) in
- (* This is a hack: when leaving a section, we lose the constant definition, so
- we have to store it in the libobject to be able to retrieve it after. *)
- Some { obj with cst_decl = Some { Cooking.from; info } }
+ Some obj
(* Hack to reduce the size of .vo: we keep only what load/open needs *)
let dummy_constant cst = {
- cst_decl = None;
cst_kind = cst.cst_kind;
cst_locl = cst.cst_locl;
}
@@ -157,7 +148,6 @@ let update_tables c =
let register_constant kn kind local =
let o = inConstant {
- cst_decl = None;
cst_kind = kind;
cst_locl = local;
} in
@@ -234,7 +224,7 @@ let cast_opaque_proof_entry e =
ids_typ, vars
in
let () = if Aux_file.recording () then record_aux env hyp_typ hyp_def in
- keep_hyps env (Id.Set.union hyp_typ hyp_def)
+ Environ.really_needed env (Id.Set.union hyp_typ hyp_def)
| Some hyps -> hyps
in
{
@@ -308,7 +298,7 @@ let declare_private_constant ?role ?(local = ImportDefaultBehavior) ~name ~kind
(** Declaration of section variables and local definitions *)
type variable_declaration =
| SectionLocalDef of Evd.side_effects proof_entry
- | SectionLocalAssum of { typ:Constr.types; univs:Univ.ContextSet.t; poly:bool; impl:Glob_term.binding_kind }
+ | SectionLocalAssum of { typ:Constr.types; impl:Glob_term.binding_kind; }
(* This object is only for things which iterate over objects to find
variables (only Prettyp.print_context AFAICT) *)
@@ -321,11 +311,10 @@ let declare_variable ~name ~kind d =
if Decls.variable_exists name then
raise (AlreadyDeclared (None, name));
- let impl,opaque,poly = match d with (* Fails if not well-typed *)
- | SectionLocalAssum {typ;univs;poly;impl} ->
- let () = declare_universe_context ~poly univs in
+ let impl,opaque = match d with (* Fails if not well-typed *)
+ | SectionLocalAssum {typ;impl} ->
let () = Global.push_named_assum (name,typ) in
- impl, true, poly
+ impl, true
| SectionLocalDef (de) ->
(* The body should already have been forced upstream because it is a
section-local definition, but it's not enforced by typing *)
@@ -348,13 +337,11 @@ let declare_variable ~name ~kind d =
secdef_type = de.proof_entry_type;
} in
let () = Global.push_named_def (name, se) in
- Glob_term.Explicit, de.proof_entry_opaque,
- poly
+ Glob_term.Explicit, de.proof_entry_opaque
in
Nametab.push (Nametab.Until 1) (Libnames.make_path DirPath.empty name) (GlobRef.VarRef name);
- add_section_variable ~name ~poly;
Decls.(add_variable_data name {opaque;kind});
- add_anonymous_leaf (inVariable ());
+ ignore(add_leaf name (inVariable ()) : Libobject.object_name);
Impargs.declare_var_implicits ~impl name;
Notation.declare_ref_arguments_scope Evd.empty (GlobRef.VarRef name)
@@ -366,12 +353,17 @@ let declare_inductive_argument_scopes kn mie =
Notation.declare_ref_arguments_scope Evd.empty (GlobRef.ConstructRef ((kn,i),j));
done) mie.mind_entry_inds
-let inductive_names sp kn mie =
+type inductive_obj = {
+ ind_names : (Id.t * Id.t list) list
+ (* For each block, name of the type + name of constructors *)
+}
+
+let inductive_names sp kn obj =
let (dp,_) = Libnames.repr_path sp in
let kn = Global.mind_of_delta_kn kn in
let names, _ =
List.fold_left
- (fun (names, n) ind ->
+ (fun (names, n) (typename, consnames) ->
let ind_p = (kn,n) in
let names, _ =
List.fold_left
@@ -380,70 +372,37 @@ let inductive_names sp kn mie =
Libnames.make_path dp l
in
((sp, GlobRef.ConstructRef (ind_p,p)) :: names, p+1))
- (names, 1) ind.mind_entry_consnames in
- let sp = Libnames.make_path dp ind.mind_entry_typename
+ (names, 1) consnames in
+ let sp = Libnames.make_path dp typename
in
((sp, GlobRef.IndRef ind_p) :: names, n+1))
- ([], 0) mie.mind_entry_inds
+ ([], 0) obj.ind_names
in names
-let load_inductive i ((sp,kn),mie) =
- let names = inductive_names sp kn mie in
+let load_inductive i ((sp, kn), names) =
+ let names = inductive_names sp kn names in
List.iter (fun (sp, ref) -> Nametab.push (Nametab.Until i) sp ref ) names
-let open_inductive i ((sp,kn),mie) =
- let names = inductive_names sp kn mie in
+let open_inductive i ((sp, kn), names) =
+ let names = inductive_names sp kn names in
List.iter (fun (sp, ref) -> Nametab.push (Nametab.Exactly i) sp ref) names
-let cache_inductive ((sp,kn),mie) =
- let names = inductive_names sp kn mie in
- List.iter check_exists (List.map (fun p -> Libnames.basename (fst p)) names);
- let id = Libnames.basename sp in
- let kn' = Global.add_mind id mie in
- assert (MutInd.equal kn' (MutInd.make1 kn));
- let mind = Global.lookup_mind kn' in
- add_section_kn ~poly:(Declareops.inductive_is_polymorphic mind) kn' mind.mind_hyps;
+let cache_inductive ((sp, kn), names) =
+ let names = inductive_names sp kn names in
List.iter (fun (sp, ref) -> Nametab.push (Nametab.Until 1) sp ref) names
-let discharge_inductive ((sp,kn),mie) =
- let mind = Global.mind_of_delta_kn kn in
- let mie = Global.lookup_mind mind in
- let info = cooking_info (section_segment_of_mutual_inductive mind) in
- Some (Cooking.cook_inductive info mie)
-
-let dummy_one_inductive_entry mie = {
- mind_entry_typename = mie.mind_entry_typename;
- mind_entry_arity = Constr.mkProp;
- mind_entry_template = false;
- mind_entry_consnames = mie.mind_entry_consnames;
- mind_entry_lc = []
-}
-
-(* Hack to reduce the size of .vo: we keep only what load/open needs *)
-let dummy_inductive_entry m = {
- mind_entry_params = [];
- mind_entry_record = None;
- mind_entry_finite = Declarations.BiFinite;
- mind_entry_inds = List.map dummy_one_inductive_entry m.mind_entry_inds;
- mind_entry_universes = default_univ_entry;
- mind_entry_variance = None;
- mind_entry_private = None;
-}
-
-(* reinfer subtyping constraints for inductive after section is dischared. *)
-let rebuild_inductive mind_ent =
- let env = Global.env () in
- InferCumulativity.infer_inductive env mind_ent
+let discharge_inductive ((sp, kn), names) =
+ Some names
-let inInductive : mutual_inductive_entry -> obj =
+let inInductive : inductive_obj -> obj =
declare_object {(default_object "INDUCTIVE") with
cache_function = cache_inductive;
load_function = load_inductive;
open_function = open_inductive;
- classify_function = (fun a -> Substitute (dummy_inductive_entry a));
+ classify_function = (fun a -> Substitute a);
subst_function = ident_subst_function;
discharge_function = discharge_inductive;
- rebuild_function = rebuild_inductive }
+ }
let cache_prim (_,(p,c)) = Recordops.register_primitive_projection p c
@@ -500,7 +459,11 @@ let declare_mind mie =
let id = match mie.mind_entry_inds with
| ind::_ -> ind.mind_entry_typename
| [] -> CErrors.anomaly (Pp.str "cannot declare an empty list of inductives.") in
- let (sp,kn as oname) = add_leaf id (inInductive mie) in
+ let map_names mip = (mip.mind_entry_typename, mip.mind_entry_consnames) in
+ let names = List.map map_names mie.mind_entry_inds in
+ List.iter (fun (typ, cons) -> check_exists typ; List.iter check_exists cons) names;
+ let _kn' = Global.add_mind id mie in
+ let (sp,kn as oname) = add_leaf id (inInductive { ind_names = names }) in
if is_unsafe_typing_flags() then feedback_axiom();
let mind = Global.mind_of_delta_kn kn in
let isprim = declare_projections mie.mind_entry_universes mind in
@@ -632,35 +595,19 @@ let do_universe ~poly l =
let ctx = List.fold_left (fun ctx (_,qid) -> Univ.LSet.add (Univ.Level.make qid) ctx)
Univ.LSet.empty l, Univ.Constraint.empty
in
- let () = declare_universe_context ~poly ctx in
let src = if poly then BoundUniv else UnqualifiedUniv in
- Lib.add_anonymous_leaf (input_univ_names (src, l))
+ let () = Lib.add_anonymous_leaf (input_univ_names (src, l)) in
+ declare_universe_context ~poly ctx
let do_constraint ~poly l =
let open Univ in
let u_of_id x =
- let level = Pretyping.interp_known_glob_level (Evd.from_env (Global.env ())) x in
- Lib.is_polymorphic_univ level, level
- in
- let in_section = Lib.sections_are_opened () in
- let () =
- if poly && not in_section then
- CErrors.user_err ~hdr:"Constraint"
- (str"Cannot declare polymorphic constraints outside sections")
- in
- let check_poly p p' =
- if poly then ()
- else if p || p' then
- CErrors.user_err ~hdr:"Constraint"
- (str "Cannot declare a global constraint on " ++
- str "a polymorphic universe, use "
- ++ str "Polymorphic Constraint instead")
+ Pretyping.interp_known_glob_level (Evd.from_env (Global.env ())) x
in
let constraints = List.fold_left (fun acc (l, d, r) ->
- let p, lu = u_of_id l and p', ru = u_of_id r in
- check_poly p p';
- Constraint.add (lu, d, ru) acc)
- Constraint.empty l
+ let lu = u_of_id l and ru = u_of_id r in
+ Constraint.add (lu, d, ru) acc)
+ Constraint.empty l
in
let uctx = ContextSet.add_constraints constraints ContextSet.empty in
declare_universe_context ~poly uctx
diff --git a/tactics/declare.mli b/tactics/declare.mli
index 4cb876cecb..f4bfdb1547 100644
--- a/tactics/declare.mli
+++ b/tactics/declare.mli
@@ -23,7 +23,7 @@ open Entries
type 'a proof_entry = {
proof_entry_body : 'a Entries.const_entry_body;
(* List of section variables *)
- proof_entry_secctx : Constr.named_context option;
+ proof_entry_secctx : Id.Set.t option;
(* State id on which the completion of type checking is reported *)
proof_entry_feedback : Stateid.t option;
proof_entry_type : Constr.types option;
@@ -36,7 +36,7 @@ type 'a proof_entry = {
type variable_declaration =
| SectionLocalDef of Evd.side_effects proof_entry
- | SectionLocalAssum of { typ:types; univs:Univ.ContextSet.t; poly:bool; impl:Glob_term.binding_kind }
+ | SectionLocalAssum of { typ:types; impl:Glob_term.binding_kind; }
type 'a constant_entry =
| DefinitionEntry of 'a proof_entry
diff --git a/tactics/pfedit.ml b/tactics/pfedit.ml
index 5be7b4fa28..413c6540a3 100644
--- a/tactics/pfedit.ml
+++ b/tactics/pfedit.ml
@@ -124,8 +124,7 @@ let build_constant_by_tactic ~name ctx sign ~poly typ tac =
let { entries; universes } = close_proof ~opaque:Transparent ~keep_body_ucst_separate:false (fun x -> x) pf in
match entries with
| [entry] ->
- let univs = UState.demote_seff_univs entry.Declare.proof_entry_universes universes in
- entry, status, univs
+ entry, status, universes
| _ ->
CErrors.anomaly Pp.(str "[build_constant_by_tactic] close_proof returned more than one proof term")
with reraise ->
@@ -141,7 +140,7 @@ let build_by_tactic ?(side_eff=true) env sigma ~poly typ tac =
if side_eff then Safe_typing.inline_private_constants env (body, eff.Evd.seff_private)
else body
in
- let univs = UState.merge ~sideff:side_eff ~extend:true Evd.univ_rigid univs ctx in
+ let univs = UState.merge ~sideff:side_eff Evd.univ_rigid univs ctx in
cb, status, univs
let refine_by_tactic ~name ~poly env sigma ty tac =
diff --git a/tactics/proof_global.ml b/tactics/proof_global.ml
index a2929e45cd..b723922642 100644
--- a/tactics/proof_global.ml
+++ b/tactics/proof_global.ml
@@ -36,7 +36,7 @@ type opacity_flag = Opaque | Transparent
type t =
{ endline_tactic : Genarg.glob_generic_argument option
- ; section_vars : Constr.named_context option
+ ; section_vars : Id.Set.t option
; proof : Proof.t
; udecl: UState.universe_decl
(** Initial universe declarations *)
@@ -128,7 +128,7 @@ let set_used_variables ps l =
if not (Option.is_empty ps.section_vars) then
CErrors.user_err Pp.(str "Used section variables can be declared only once");
(* EJGA: This is always empty thus we should modify the type *)
- (ctx, []), { ps with section_vars = Some ctx}
+ (ctx, []), { ps with section_vars = Some (Context.Named.to_vars ctx) }
let get_open_goals ps =
let Proof.{ goals; stack; shelf } = Proof.data ps.proof in
diff --git a/tactics/proof_global.mli b/tactics/proof_global.mli
index d15e23c2cc..b9d1b37a11 100644
--- a/tactics/proof_global.mli
+++ b/tactics/proof_global.mli
@@ -17,7 +17,7 @@ type t
(* Should be moved into a proper view *)
val get_proof : t -> Proof.t
val get_proof_name : t -> Names.Id.t
-val get_used_variables : t -> Constr.named_context option
+val get_used_variables : t -> Names.Id.Set.t option
(** Get the universe declaration associated to the current proof. *)
val get_universe_decl : t -> UState.universe_decl
diff --git a/test-suite/bugs/closed/bug_10669.v b/test-suite/bugs/closed/bug_10669.v
new file mode 100644
index 0000000000..433e300acb
--- /dev/null
+++ b/test-suite/bugs/closed/bug_10669.v
@@ -0,0 +1,12 @@
+
+Context (A0:Type) (B0:A0).
+Definition foo0 := B0.
+
+Set Universe Polymorphism.
+Context (A1:Type) (B1:A1).
+Definition foo1 := B1.
+
+Section S.
+ Context (A2:Type) (B2:A2).
+ Definition foo2 := B2.
+End S.
diff --git a/test-suite/bugs/closed/bug_10757.v b/test-suite/bugs/closed/bug_10757.v
new file mode 100644
index 0000000000..a531f6e563
--- /dev/null
+++ b/test-suite/bugs/closed/bug_10757.v
@@ -0,0 +1,38 @@
+Require Import Program Extraction ExtrOcamlBasic.
+Print sig.
+Section FIXPOINT.
+
+Variable A: Type.
+
+Variable eq: A -> A -> Prop.
+Variable beq: A -> A -> bool.
+Hypothesis beq_eq: forall x y, beq x y = true -> eq x y.
+Hypothesis beq_neq: forall x y, beq x y = false -> ~eq x y.
+
+Variable le: A -> A -> Prop.
+Hypothesis le_trans: forall x y z, le x y -> le y z -> le x z.
+
+Definition gt (x y: A) := le y x /\ ~eq y x.
+Hypothesis gt_wf: well_founded gt.
+
+Variable F: A -> A.
+Hypothesis F_mon: forall x y, le x y -> le (F x) (F y).
+
+Program Fixpoint iterate
+ (x: A) (PRE: le x (F x)) (SMALL: forall z, le (F z) z -> le x z)
+ {wf gt x}
+ : {y : A | eq y (F y) /\ forall z, le (F z) z -> le y z } :=
+ let x' := F x in
+ match beq x x' with
+ | true => x
+ | false => iterate x' _ _
+ end.
+Next Obligation.
+ split.
+- auto.
+- apply beq_neq. auto.
+Qed.
+
+End FIXPOINT.
+
+Recursive Extraction iterate.
diff --git a/test-suite/bugs/closed/bug_10778.v b/test-suite/bugs/closed/bug_10778.v
new file mode 100644
index 0000000000..25d729b7e6
--- /dev/null
+++ b/test-suite/bugs/closed/bug_10778.v
@@ -0,0 +1,32 @@
+(* Test that fresh avoid the variables of intro patterns but also of
+ simple intro patterns *)
+
+Ltac exploit_main t T pat cleanup
+ :=
+ (lazymatch T with
+ | ?U1 -> ?U2 =>
+ let H := fresh
+ in
+idtac "H=" H;
+ assert U1 as H;
+ [cleanup () | exploit_main (t H) U2 pat ltac:(fun _ => clear H; cleanup ())]
+ | _ =>
+ pose proof t as pat;
+ cleanup ()
+ end).
+
+Tactic Notation "exploit" constr(t) "as" simple_intropattern(pat)
+ :=
+ exploit_main t ltac:(type of t) pat ltac:(fun _ => idtac).
+
+Goal (True -> True) -> True.
+intro H0. exploit H0 as H.
+Abort.
+
+Tactic Notation "exploit'" constr(t) "as" intropattern(pat)
+ :=
+ exploit_main t ltac:(type of t) pat ltac:(fun _ => idtac).
+
+Goal (True -> True) -> True.
+intro H0. exploit' H0 as H.
+Abort.
diff --git a/test-suite/bugs/closed/bug_10888.v b/test-suite/bugs/closed/bug_10888.v
new file mode 100644
index 0000000000..3c2e8011d7
--- /dev/null
+++ b/test-suite/bugs/closed/bug_10888.v
@@ -0,0 +1,11 @@
+
+Module Type T.
+Context {A:Type}.
+End T.
+
+Module M(X:T).
+ Import X.
+ Check X.A.
+ Check A.
+ Definition B := A.
+End M.
diff --git a/test-suite/bugs/closed/bug_9512.v b/test-suite/bugs/closed/bug_9512.v
new file mode 100644
index 0000000000..25285622a9
--- /dev/null
+++ b/test-suite/bugs/closed/bug_9512.v
@@ -0,0 +1,35 @@
+Require Import Coq.ZArith.BinInt Coq.omega.Omega Coq.micromega.Lia.
+
+Set Primitive Projections.
+Record params := { width : Z }.
+Definition p : params := Build_params 64.
+
+Set Printing All.
+
+Goal width p = 0%Z -> width p = 0%Z.
+ intros.
+
+ assert_succeeds (enough True; [omega|]).
+ assert_succeeds (enough True; [lia|]).
+
+(* H : @eq Z (width p) Z0 *)
+(* ============================ *)
+(* @eq Z (width p) Z0 *)
+
+ change tt with tt in H.
+
+(* H : @eq Z (width p) Z0 *)
+(* ============================ *)
+(* @eq Z (width p) Z0 *)
+
+ assert_succeeds (enough True; [lia|]).
+ (* Tactic failure: <tactic closure> fails. *)
+ (* assert_succeeds (enough True; [omega|]). *)
+ (* Tactic failure: <tactic closure> fails. *)
+
+ (* omega. *)
+ (* Error: Omega can't solve this system *)
+
+ lia.
+ (* Tactic failure: Cannot find witness. *)
+Qed.
diff --git a/test-suite/bugs/opened/bug_1596.v b/test-suite/bugs/opened/bug_1596.v
index 820022d995..27cb731151 100644
--- a/test-suite/bugs/opened/bug_1596.v
+++ b/test-suite/bugs/opened/bug_1596.v
@@ -69,9 +69,8 @@ Definition t := (X.t * Y.t)%type.
elim (X.lt_not_eq H2 H3).
elim H0;clear H0;intros.
right.
- split.
- eauto.
- eauto.
+ split;
+ eauto with ordered_type.
Qed.
Lemma lt_not_eq : forall (x y:t),(lt x y)->~(eq x y).
@@ -97,7 +96,7 @@ Definition t := (X.t * Y.t)%type.
apply EQ.
split;trivial.
apply GT.
- right;auto.
+ right;auto with ordered_type.
apply GT.
left;trivial.
Defined.
diff --git a/test-suite/ltac2/constr.v b/test-suite/ltac2/constr.v
new file mode 100644
index 0000000000..39601d99a8
--- /dev/null
+++ b/test-suite/ltac2/constr.v
@@ -0,0 +1,12 @@
+Require Import Ltac2.Constr Ltac2.Init Ltac2.Control.
+Import Unsafe.
+
+Ltac2 Eval match (kind '(nat -> bool)) with
+ | Prod a b c => a
+ | _ => throw Match_failure end.
+
+Set Allow StrictProp.
+Axiom something : SProp.
+Ltac2 Eval match (kind '(forall x : something, bool)) with
+ | Prod a b c => a
+ | _ => throw Match_failure end.
diff --git a/test-suite/micromega/bug_9162.v b/test-suite/micromega/bug_9162.v
new file mode 100644
index 0000000000..4aedf57faf
--- /dev/null
+++ b/test-suite/micromega/bug_9162.v
@@ -0,0 +1,8 @@
+Require Import ZArith Lia.
+Local Open Scope Z_scope.
+
+Goal Z.of_N (Z.to_N 0) = 0.
+Proof. lia. Qed.
+
+Goal forall q, (Z.of_N (Z.to_N 0) = 0 -> q = 0) -> Z.of_N (Z.to_N 0) = q.
+Proof. lia. Qed.
diff --git a/test-suite/output-coqtop/DependentEvars.out b/test-suite/output-coqtop/DependentEvars.out
new file mode 100644
index 0000000000..9ca3fa3357
--- /dev/null
+++ b/test-suite/output-coqtop/DependentEvars.out
@@ -0,0 +1,91 @@
+
+Coq <
+Coq < Coq < 1 subgoal
+
+ ============================
+ forall P Q R : Prop, (Q -> R) -> (P -> Q) -> (P -> Q) -> P -> R
+
+(dependent evars: ; in current goal:)
+
+strange_imp_trans <
+strange_imp_trans < No more subgoals.
+
+(dependent evars: ; in current goal:)
+
+strange_imp_trans <
+Coq < Coq < 1 subgoal
+
+ ============================
+ forall P Q : Prop, (P -> Q) /\ P -> Q
+
+(dependent evars: ; in current goal:)
+
+modpon <
+modpon < No more subgoals.
+
+(dependent evars: ; in current goal:)
+
+modpon <
+Coq < Coq <
+Coq < P1 is declared
+P2 is declared
+P3 is declared
+P4 is declared
+
+Coq < p12 is declared
+
+Coq < p123 is declared
+
+Coq < p34 is declared
+
+Coq < Coq < 1 subgoal
+
+ P1, P2, P3, P4 : Prop
+ p12 : P1 -> P2
+ p123 : (P1 -> P2) -> P3
+ p34 : P3 -> P4
+ ============================
+ P4
+
+(dependent evars: ; in current goal:)
+
+p14 <
+p14 < 4 focused subgoals
+(shelved: 2)
+
+ P1, P2, P3, P4 : Prop
+ p12 : P1 -> P2
+ p123 : (P1 -> P2) -> P3
+ p34 : P3 -> P4
+ ============================
+ ?Q -> P4
+
+subgoal 2 is:
+ ?P -> ?Q
+subgoal 3 is:
+ ?P -> ?Q
+subgoal 4 is:
+ ?P
+
+(dependent evars: ?X4:?P, ?X5:?Q; in current goal: ?X5)
+
+p14 < 3 focused subgoals
+(shelved: 2)
+
+ P1, P2, P3, P4 : Prop
+ p12 : P1 -> P2
+ p123 : (P1 -> P2) -> P3
+ p34 : P3 -> P4
+ ============================
+ ?P -> (?Goal2 -> P4) /\ ?Goal2
+
+subgoal 2 is:
+ ?P -> (?Goal2 -> P4) /\ ?Goal2
+subgoal 3 is:
+ ?P
+
+(dependent evars: ?X4:?P, ?X5 using ?X10 ?X11, ?X10 using ?X11, ?X11:?Goal2; in current goal: ?X4 ?X5 ?X10 ?X11)
+
+p14 <
+Coq <
+Coq <
diff --git a/test-suite/output-coqtop/DependentEvars.v b/test-suite/output-coqtop/DependentEvars.v
new file mode 100644
index 0000000000..5a59054073
--- /dev/null
+++ b/test-suite/output-coqtop/DependentEvars.v
@@ -0,0 +1,24 @@
+Set Printing Dependent Evars Line.
+Lemma strange_imp_trans :
+ forall P Q R : Prop, (Q -> R) -> (P -> Q) -> (P -> Q) -> P -> R.
+Proof.
+ auto.
+Qed.
+
+Lemma modpon : forall P Q : Prop, (P -> Q) /\ P -> Q.
+Proof.
+ tauto.
+Qed.
+
+Section eex.
+ Variables P1 P2 P3 P4 : Prop.
+ Hypothesis p12 : P1 -> P2.
+ Hypothesis p123 : (P1 -> P2) -> P3.
+ Hypothesis p34 : P3 -> P4.
+
+ Lemma p14 : P4.
+ Proof.
+ eapply strange_imp_trans.
+ apply modpon.
+ Abort.
+End eex.
diff --git a/test-suite/output-coqtop/DependentEvars2.out b/test-suite/output-coqtop/DependentEvars2.out
new file mode 100644
index 0000000000..29ebba7c86
--- /dev/null
+++ b/test-suite/output-coqtop/DependentEvars2.out
@@ -0,0 +1,120 @@
+
+Coq <
+Coq < Coq < 1 subgoal
+
+ ============================
+ forall P Q R : Prop, (Q -> R) -> (P -> Q) -> (P -> Q) -> P -> R
+
+(dependent evars: ; in current goal:)
+
+strange_imp_trans <
+strange_imp_trans < No more subgoals.
+
+(dependent evars: ; in current goal:)
+
+strange_imp_trans <
+Coq < Coq < 1 subgoal
+
+ ============================
+ forall P Q : Prop, (P -> Q) /\ P -> Q
+
+(dependent evars: ; in current goal:)
+
+modpon <
+modpon < No more subgoals.
+
+(dependent evars: ; in current goal:)
+
+modpon <
+Coq < Coq <
+Coq < P1 is declared
+P2 is declared
+P3 is declared
+P4 is declared
+
+Coq < p12 is declared
+
+Coq < p123 is declared
+
+Coq < p34 is declared
+
+Coq < Coq < 1 subgoal
+
+ P1, P2, P3, P4 : Prop
+ p12 : P1 -> P2
+ p123 : (P1 -> P2) -> P3
+ p34 : P3 -> P4
+ ============================
+ P4
+
+(dependent evars: ; in current goal:)
+
+p14 <
+p14 < Second proof:
+
+p14 < 4 focused subgoals
+(shelved: 2)
+
+ P1, P2, P3, P4 : Prop
+ p12 : P1 -> P2
+ p123 : (P1 -> P2) -> P3
+ p34 : P3 -> P4
+ ============================
+ ?Q -> P4
+
+subgoal 2 is:
+ ?P -> ?Q
+subgoal 3 is:
+ ?P -> ?Q
+subgoal 4 is:
+ ?P
+
+(dependent evars: ?X4:?P, ?X5:?Q; in current goal: ?X5)
+
+p14 < 1 focused subgoal
+(shelved: 2)
+
+ P1, P2, P3, P4 : Prop
+ p12 : P1 -> P2
+ p123 : (P1 -> P2) -> P3
+ p34 : P3 -> P4
+ ============================
+ ?Q -> P4
+
+(dependent evars: ?X4:?P, ?X5:?Q; in current goal: ?X5)
+
+p14 < This subproof is complete, but there are some unfocused goals.
+Try unfocusing with "}".
+
+3 subgoals
+(shelved: 2)
+
+subgoal 1 is:
+ ?P -> (?Goal2 -> P4) /\ ?Goal2
+subgoal 2 is:
+ ?P -> (?Goal2 -> P4) /\ ?Goal2
+subgoal 3 is:
+ ?P
+
+(dependent evars: ?X4:?P, ?X5 using ?X10 ?X11, ?X10 using ?X11, ?X11:?Goal2; in current goal:)
+
+p14 < 3 focused subgoals
+(shelved: 2)
+
+ P1, P2, P3, P4 : Prop
+ p12 : P1 -> P2
+ p123 : (P1 -> P2) -> P3
+ p34 : P3 -> P4
+ ============================
+ ?P -> (?Goal2 -> P4) /\ ?Goal2
+
+subgoal 2 is:
+ ?P -> (?Goal2 -> P4) /\ ?Goal2
+subgoal 3 is:
+ ?P
+
+(dependent evars: ?X4:?P, ?X5 using ?X10 ?X11, ?X10 using ?X11, ?X11:?Goal2; in current goal: ?X4 ?X5 ?X10 ?X11)
+
+p14 <
+Coq <
+Coq <
diff --git a/test-suite/output-coqtop/DependentEvars2.v b/test-suite/output-coqtop/DependentEvars2.v
new file mode 100644
index 0000000000..d0f3a4012e
--- /dev/null
+++ b/test-suite/output-coqtop/DependentEvars2.v
@@ -0,0 +1,27 @@
+Set Printing Dependent Evars Line.
+Lemma strange_imp_trans :
+ forall P Q R : Prop, (Q -> R) -> (P -> Q) -> (P -> Q) -> P -> R.
+Proof.
+ auto.
+Qed.
+
+Lemma modpon : forall P Q : Prop, (P -> Q) /\ P -> Q.
+Proof.
+ tauto.
+Qed.
+
+Section eex.
+ Variables P1 P2 P3 P4 : Prop.
+ Hypothesis p12 : P1 -> P2.
+ Hypothesis p123 : (P1 -> P2) -> P3.
+ Hypothesis p34 : P3 -> P4.
+
+ Lemma p14 : P4.
+ Proof.
+ idtac "Second proof:".
+ eapply strange_imp_trans.
+ {
+ apply modpon.
+ }
+ Abort.
+End eex.
diff --git a/test-suite/output/UnivBinders.out b/test-suite/output/UnivBinders.out
index a89fd64999..d48d8b900f 100644
--- a/test-suite/output/UnivBinders.out
+++ b/test-suite/output/UnivBinders.out
@@ -38,10 +38,10 @@ Argument scopes are [type_scope _]
bar@{u} = nat
: Wrap@{u} Set
(* u |= Set < u *)
-foo@{u UnivBinders.17 v} =
-Type@{UnivBinders.17} -> Type@{v} -> Type@{u}
- : Type@{max(u+1,UnivBinders.17+1,v+1)}
-(* u UnivBinders.17 v |= *)
+foo@{u UnivBinders.18 v} =
+Type@{UnivBinders.18} -> Type@{v} -> Type@{u}
+ : Type@{max(u+1,UnivBinders.18+1,v+1)}
+(* u UnivBinders.18 v |= *)
Type@{i} -> Type@{j}
: Type@{max(i+1,j+1)}
(* {j i} |= *)
@@ -68,19 +68,19 @@ mono
The command has indeed failed with message:
Universe u already exists.
bobmorane =
-let tt := Type@{UnivBinders.33} in
-let ff := Type@{UnivBinders.35} in tt -> ff
- : Type@{max(UnivBinders.32,UnivBinders.34)}
+let tt := Type@{UnivBinders.34} in
+let ff := Type@{UnivBinders.36} in tt -> ff
+ : Type@{max(UnivBinders.33,UnivBinders.35)}
The command has indeed failed with message:
Universe u already bound.
foo@{E M N} =
Type@{M} -> Type@{N} -> Type@{E}
: Type@{max(E+1,M+1,N+1)}
(* E M N |= *)
-foo@{u UnivBinders.17 v} =
-Type@{UnivBinders.17} -> Type@{v} -> Type@{u}
- : Type@{max(u+1,UnivBinders.17+1,v+1)}
-(* u UnivBinders.17 v |= *)
+foo@{u UnivBinders.18 v} =
+Type@{UnivBinders.18} -> Type@{v} -> Type@{u}
+ : Type@{max(u+1,UnivBinders.18+1,v+1)}
+(* u UnivBinders.18 v |= *)
Inductive Empty@{E} : Type@{E} :=
(* E |= *)
Record PWrap (A : Type@{E}) : Type@{E} := pwrap { punwrap : A }
@@ -143,26 +143,26 @@ Applied.infunct@{u v} =
inmod@{u} -> Type@{v}
: Type@{max(u+1,v+1)}
(* u v |= *)
-axfoo@{i UnivBinders.57 UnivBinders.58} :
-Type@{UnivBinders.57} -> Type@{i}
-(* i UnivBinders.57 UnivBinders.58 |= *)
+axfoo@{i UnivBinders.59 UnivBinders.60} :
+Type@{UnivBinders.59} -> Type@{i}
+(* i UnivBinders.59 UnivBinders.60 |= *)
axfoo is universe polymorphic
Argument scope is [type_scope]
Expands to: Constant UnivBinders.axfoo
-axbar@{i UnivBinders.57 UnivBinders.58} :
-Type@{UnivBinders.58} -> Type@{i}
-(* i UnivBinders.57 UnivBinders.58 |= *)
+axbar@{i UnivBinders.59 UnivBinders.60} :
+Type@{UnivBinders.60} -> Type@{i}
+(* i UnivBinders.59 UnivBinders.60 |= *)
axbar is universe polymorphic
Argument scope is [type_scope]
Expands to: Constant UnivBinders.axbar
-axfoo' : Type@{axbar'.u0} -> Type@{axbar'.i}
+axfoo' : Type@{axfoo'.u0} -> Type@{axfoo'.i}
axfoo' is not universe polymorphic
Argument scope is [type_scope]
Expands to: Constant UnivBinders.axfoo'
-axbar' : Type@{axbar'.u0} -> Type@{axbar'.i}
+axbar' : Type@{axfoo'.u0} -> Type@{axfoo'.i}
axbar' is not universe polymorphic
Argument scope is [type_scope]
diff --git a/test-suite/prerequisite/ssr_mini_mathcomp.v b/test-suite/prerequisite/ssr_mini_mathcomp.v
index 74f94a9bed..d293dc0533 100644
--- a/test-suite/prerequisite/ssr_mini_mathcomp.v
+++ b/test-suite/prerequisite/ssr_mini_mathcomp.v
@@ -196,7 +196,7 @@ Definition clone_subType U v :=
Variable sT : subType.
-CoInductive Sub_spec : sT -> Type := SubSpec x Px : Sub_spec (Sub x Px).
+Variant Sub_spec : sT -> Type := SubSpec x Px : Sub_spec (Sub x Px).
Lemma SubP u : Sub_spec u.
Proof. by case: sT Sub_spec SubSpec u => T' _ C rec /= _. Qed.
@@ -209,7 +209,7 @@ Definition insub x :=
Definition insubd u0 x := odflt u0 (insub x).
-CoInductive insub_spec x : option sT -> Type :=
+Variant insub_spec x : option sT -> Type :=
| InsubSome u of P x & val u = x : insub_spec x (Some u)
| InsubNone of ~~ P x : insub_spec x None.
@@ -568,7 +568,7 @@ Fixpoint nth s n {struct n} :=
Fixpoint rcons s z := if s is x :: s' then x :: rcons s' z else [:: z].
-CoInductive last_spec : seq T -> Type :=
+Variant last_spec : seq T -> Type :=
| LastNil : last_spec [::]
| LastRcons s x : last_spec (rcons s x).
@@ -1292,7 +1292,7 @@ Open Scope big_scope.
(* packages both in in a term in which i occurs; it also depends on the *)
(* iterated <op>, as this can give more information on the expected type of *)
(* the <general_term>, thus allowing for the insertion of coercions. *)
-CoInductive bigbody R I := BigBody of I & (R -> R -> R) & bool & R.
+Variant bigbody R I := BigBody of I & (R -> R -> R) & bool & R.
Definition applybig {R I} (body : bigbody R I) x :=
let: BigBody _ op b v := body in if b then op v x else x.
diff --git a/test-suite/success/CompatCurrentFlag.v b/test-suite/success/CompatCurrentFlag.v
index 81469d79c3..fd6101bf89 100644
--- a/test-suite/success/CompatCurrentFlag.v
+++ b/test-suite/success/CompatCurrentFlag.v
@@ -1,3 +1,3 @@
-(* -*- coq-prog-args: ("-compat" "8.10") -*- *)
+(* -*- coq-prog-args: ("-compat" "8.11") -*- *)
(** Check that the current compatibility flag actually requires the relevant modules. *)
-Import Coq.Compat.Coq810.
+Import Coq.Compat.Coq811.
diff --git a/test-suite/success/CompatOldFlag.v b/test-suite/success/CompatOldFlag.v
index afeb57f9f2..f774cef44f 100644
--- a/test-suite/success/CompatOldFlag.v
+++ b/test-suite/success/CompatOldFlag.v
@@ -1,5 +1,5 @@
-(* -*- coq-prog-args: ("-compat" "8.8") -*- *)
+(* -*- coq-prog-args: ("-compat" "8.9") -*- *)
(** Check that the current-minus-two compatibility flag actually requires the relevant modules. *)
+Import Coq.Compat.Coq811.
Import Coq.Compat.Coq810.
Import Coq.Compat.Coq89.
-Import Coq.Compat.Coq88.
diff --git a/test-suite/success/CompatOldOldFlag.v b/test-suite/success/CompatOldOldFlag.v
new file mode 100644
index 0000000000..20eef955b4
--- /dev/null
+++ b/test-suite/success/CompatOldOldFlag.v
@@ -0,0 +1,6 @@
+(* -*- coq-prog-args: ("-compat" "8.8") -*- *)
+(** Check that the current-minus-three compatibility flag actually requires the relevant modules. *)
+Import Coq.Compat.Coq811.
+Import Coq.Compat.Coq810.
+Import Coq.Compat.Coq89.
+Import Coq.Compat.Coq88.
diff --git a/test-suite/success/CompatPreviousFlag.v b/test-suite/success/CompatPreviousFlag.v
index c8f75915c8..1c5ccc1a92 100644
--- a/test-suite/success/CompatPreviousFlag.v
+++ b/test-suite/success/CompatPreviousFlag.v
@@ -1,4 +1,4 @@
-(* -*- coq-prog-args: ("-compat" "8.9") -*- *)
+(* -*- coq-prog-args: ("-compat" "8.10") -*- *)
(** Check that the current-minus-one compatibility flag actually requires the relevant modules. *)
+Import Coq.Compat.Coq811.
Import Coq.Compat.Coq810.
-Import Coq.Compat.Coq89.
diff --git a/test-suite/success/section_poly.v b/test-suite/success/section_poly.v
new file mode 100644
index 0000000000..1e2201f2de
--- /dev/null
+++ b/test-suite/success/section_poly.v
@@ -0,0 +1,74 @@
+
+
+Section Foo.
+
+ Variable X : Type.
+
+ Polymorphic Section Bar.
+
+ Variable A : Type.
+
+ Definition id (a:A) := a.
+
+End Bar.
+Check id@{_}.
+End Foo.
+Check id@{_}.
+
+Polymorphic Section Foo.
+Variable A : Type.
+Section Bar.
+ Variable B : Type.
+
+ Inductive prod := Prod : A -> B -> prod.
+End Bar.
+Check prod@{_}.
+End Foo.
+Check prod@{_ _}.
+
+Section Foo.
+
+ Universe K.
+ Inductive bla := Bla : Type@{K} -> bla.
+
+ Polymorphic Definition bli@{j} := Type@{j} -> bla.
+
+ Definition bloo := bli@{_}.
+
+ Polymorphic Universe i.
+
+ Fail Definition x := Type.
+ Fail Inductive x : Type := .
+ Polymorphic Definition x := Type.
+ Polymorphic Inductive y : x := .
+
+ Variable A : Type. (* adds a mono univ for the Type, which is unrelated to the others *)
+
+ Fail Variable B : (y : Type@{i}).
+ (* not allowed: mono constraint (about a fresh univ for y) regarding
+ poly univ i *)
+
+ Polymorphic Variable B : Type. (* new polymorphic stuff always OK *)
+
+ Variable C : Type@{i}. (* no new univs so no problems *)
+
+ Polymorphic Definition thing := bloo -> y -> A -> B.
+
+End Foo.
+Check bli@{_}.
+Check bloo@{}.
+
+Check thing@{_ _ _}.
+
+Section Foo.
+
+ Polymorphic Universes i k.
+ Universe j.
+ Fail Constraint i < j.
+ Fail Constraint i < k.
+
+ (* referring to mono univs in poly constraints is OK. *)
+ Polymorphic Constraint i < j. Polymorphic Constraint j < k.
+
+ Polymorphic Definition foo := Type@{j}.
+End Foo.
diff --git a/test-suite/tools/update-compat/run.sh b/test-suite/tools/update-compat/run.sh
index 7ff5571ffb..61273c4f37 100755
--- a/test-suite/tools/update-compat/run.sh
+++ b/test-suite/tools/update-compat/run.sh
@@ -6,4 +6,4 @@ SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )"
# we assume that the script lives in test-suite/tools/update-compat/,
# and that update-compat.py lives in dev/tools/
cd "${SCRIPT_DIR}/../../.."
-dev/tools/update-compat.py --assert-unchanged --release || exit $?
+dev/tools/update-compat.py --assert-unchanged --master || exit $?
diff --git a/theories/Compat/Coq810.v b/theories/Compat/Coq810.v
index d24af2186f..c611d356ce 100644
--- a/theories/Compat/Coq810.v
+++ b/theories/Compat/Coq810.v
@@ -9,3 +9,5 @@
(************************************************************************)
(** Compatibility file for making Coq act similar to Coq v8.10 *)
+
+Require Export Coq.Compat.Coq811.
diff --git a/theories/Compat/Coq811.v b/theories/Compat/Coq811.v
new file mode 100644
index 0000000000..4a9a041d4e
--- /dev/null
+++ b/theories/Compat/Coq811.v
@@ -0,0 +1,11 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2019 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+(** Compatibility file for making Coq act similar to Coq v8.11 *)
diff --git a/theories/FSets/FMapAVL.v b/theories/FSets/FMapAVL.v
index 8627ff7353..7c69350db4 100644
--- a/theories/FSets/FMapAVL.v
+++ b/theories/FSets/FMapAVL.v
@@ -593,14 +593,14 @@ Qed.
Lemma MapsTo_1 :
forall m x y e, X.eq x y -> MapsTo x e m -> MapsTo y e m.
Proof.
- induction m; simpl; intuition_in; eauto.
+ induction m; simpl; intuition_in; eauto with ordered_type.
Qed.
Hint Immediate MapsTo_1 : core.
Lemma In_1 :
forall m x y, X.eq x y -> In x m -> In y m.
Proof.
- intros m x y; induction m; simpl; intuition_in; eauto.
+ intros m x y; induction m; simpl; intuition_in; eauto with ordered_type.
Qed.
Lemma In_node_iff :
@@ -671,7 +671,7 @@ Qed.
Lemma lt_tree_trans :
forall x y, X.lt x y -> forall m, lt_tree x m -> lt_tree y m.
Proof.
- eauto.
+ eauto with ordered_type.
Qed.
Lemma gt_tree_not_in :
@@ -683,7 +683,7 @@ Qed.
Lemma gt_tree_trans :
forall x y, X.lt y x -> forall m, gt_tree x m -> gt_tree y m.
Proof.
- eauto.
+ eauto with ordered_type.
Qed.
Hint Resolve lt_tree_not_in lt_tree_trans gt_tree_not_in gt_tree_trans : core.
@@ -707,7 +707,7 @@ Qed.
Lemma is_empty_1 : forall m, Empty m -> is_empty m = true.
Proof.
destruct m as [|r x e l h]; simpl; auto.
- intro H; elim (H x e); auto.
+ intro H; elim (H x e); auto with ordered_type.
Qed.
Lemma is_empty_2 : forall m, is_empty m = true -> Empty m.
@@ -732,7 +732,7 @@ Lemma find_1 : forall m x e, bst m -> MapsTo x e m -> find x m = Some e.
Proof.
intros m x; functional induction (find x m); auto; intros; clearf;
inv bst; intuition_in; simpl; auto;
- try solve [order | absurd (X.lt x y); eauto | absurd (X.lt y x); eauto].
+ try solve [order | absurd (X.lt x y); eauto with ordered_type | absurd (X.lt y x); eauto with ordered_type].
Qed.
Lemma find_2 : forall m x e, find x m = Some e -> MapsTo x e m.
@@ -832,8 +832,8 @@ Lemma bal_bst : forall l x e r, bst l -> bst r ->
Proof.
intros l x e r; functional induction (bal l x e r); intros; clearf;
inv bst; repeat apply create_bst; auto; unfold create; try constructor;
- (apply lt_tree_node || apply gt_tree_node); auto;
- (eapply lt_tree_trans || eapply gt_tree_trans); eauto.
+ (apply lt_tree_node || apply gt_tree_node); auto with ordered_type;
+ (eapply lt_tree_trans || eapply gt_tree_trans); eauto with ordered_type.
Qed.
Hint Resolve bal_bst : core.
@@ -865,7 +865,7 @@ Lemma add_in : forall m x y e,
Proof.
intros m x y e; functional induction (add x e m); auto; intros;
try (rewrite bal_in, IHt); intuition_in.
- apply In_1 with x; auto.
+ apply In_1 with x; auto with ordered_type.
Qed.
Lemma add_bst : forall m x e, bst m -> bst (add x e m).
@@ -874,14 +874,14 @@ Proof.
inv bst; try apply bal_bst; auto;
intro z; rewrite add_in; intuition.
apply MX.eq_lt with x; auto.
- apply MX.lt_eq with x; auto.
+ apply MX.lt_eq with x; auto with ordered_type.
Qed.
Hint Resolve add_bst : core.
Lemma add_1 : forall m x y e, X.eq x y -> MapsTo y e (add x e m).
Proof.
intros m x y e; functional induction (add x e m);
- intros; inv bst; try rewrite bal_mapsto; unfold create; eauto.
+ intros; inv bst; try rewrite bal_mapsto; unfold create; eauto with ordered_type.
Qed.
Lemma add_2 : forall m x y e e', ~X.eq x y ->
@@ -912,7 +912,7 @@ Proof.
intros; rewrite find_mapsto_equiv; auto.
split; eauto using add_2, add_3.
destruct X.compare; try (apply H0; order).
- auto using find_1, add_1.
+ auto using find_1, add_1 with ordered_type.
Qed.
(** * Extraction of minimum binding *)
@@ -971,7 +971,7 @@ Proof.
generalize (remove_min_in ll lx ld lr _x m#1).
rewrite e0; simpl; intros.
rewrite (bal_in l' x d r y) in H.
- assert (In m#1 (Node ll lx ld lr _x)) by (rewrite H4; auto); clear H4.
+ assert (In m#1 (Node ll lx ld lr _x)) by (rewrite H4; auto with ordered_type); clear H4.
assert (X.lt m#1 x) by order.
decompose [or] H; order.
Qed.
@@ -1050,7 +1050,7 @@ Proof.
(* EQ *)
inv bst; clear e0.
rewrite merge_in; intuition; [ order | order | intuition_in ].
- elim H4; eauto.
+ elim H4; eauto with ordered_type.
(* GT *)
inv bst; clear e0.
rewrite bal_in; auto.
@@ -1069,7 +1069,7 @@ Proof.
destruct H; eauto.
(* EQ *)
inv bst.
- apply merge_bst; eauto.
+ apply merge_bst; eauto with ordered_type.
(* GT *)
inv bst.
apply bal_bst; auto.
@@ -1124,8 +1124,8 @@ Lemma join_bst : forall l x d r, bst l -> bst r ->
Proof.
join_tac; auto; try (simpl; auto; fail); inv bst; apply bal_bst; auto;
clear Hrl Hlr; intro; intros; rewrite join_in in *.
- intuition; [ apply MX.lt_eq with x | ]; eauto.
- intuition; [ apply MX.eq_lt with x | ]; eauto.
+ intuition; [ apply MX.lt_eq with x | ]; eauto with ordered_type.
+ intuition; [ apply MX.eq_lt with x | ]; eauto with ordered_type.
Qed.
Hint Resolve join_bst : core.
@@ -1135,8 +1135,8 @@ Lemma join_find : forall l x d r y,
Proof.
join_tac; auto; inv bst;
simpl (join (Leaf elt));
- try (assert (X.lt lx x) by auto);
- try (assert (X.lt x rx) by auto);
+ try (assert (X.lt lx x) by auto with ordered_type);
+ try (assert (X.lt x rx) by auto with ordered_type);
rewrite ?add_find, ?bal_find; auto.
simpl; destruct X.compare; auto.
@@ -1260,7 +1260,7 @@ Proof.
change (bst (m2',xd)#1). rewrite <-e1; eauto.
intros y Hy.
apply H1; auto.
- rewrite remove_min_in, e1; simpl; auto.
+ rewrite remove_min_in, e1; simpl; auto with ordered_type.
change (gt_tree (m2',xd)#2#1 (m2',xd)#1). rewrite <-e1; eauto.
Qed.
Hint Resolve concat_bst : core.
@@ -1283,9 +1283,9 @@ Proof.
simpl; destruct X.compare as [Hlt| |Hlt]; simpl; auto.
destruct (find y m2'); auto.
symmetry; rewrite not_find_iff; auto; intro.
- apply (MX.lt_not_gt Hlt); apply H1; auto; rewrite H3; auto.
+ apply (MX.lt_not_gt Hlt); apply H1; auto; rewrite H3; auto with ordered_type.
- intros z Hz; apply H1; auto; rewrite H3; auto.
+ intros z Hz; apply H1; auto; rewrite H3; auto with ordered_type.
Qed.
@@ -1338,12 +1338,12 @@ Proof.
apply InA_InfA with (eqA:=eqke); auto with *. intros (y',e') H6.
destruct (elements_aux_mapsto r acc y' e'); intuition.
red; simpl; eauto.
- red; simpl; eauto.
- intros.
+ red; simpl; eauto with ordered_type.
+ intros x e0 y0 H H6.
inversion_clear H.
destruct H7; simpl in *.
order.
- destruct (elements_aux_mapsto r acc x e0); intuition eauto.
+ destruct (elements_aux_mapsto r acc x e0); intuition eauto with ordered_type.
Qed.
Lemma elements_sort : forall s : t elt, bst s -> sort ltk (elements s).
@@ -1567,7 +1567,7 @@ Lemma mapi_1 : forall (m: tree elt)(x:key)(e:elt),
MapsTo x e m -> exists y, X.eq y x /\ MapsTo x (f y e) (mapi f m).
Proof.
induction m; simpl; inversion_clear 1; auto.
-exists k; auto.
+exists k; auto with ordered_type.
destruct (IHm1 _ _ H0).
exists x0; intuition.
destruct (IHm2 _ _ H0).
@@ -2072,7 +2072,7 @@ Module IntMake_ord (I:Int)(X: OrderedType)(D : OrderedType) <:
X.eq x1 x2 -> D.eq d1 d2 ->
Cmp c l1 l2 -> Cmp c ((x1,d1)::l1) ((x2,d2)::l2).
Proof.
- destruct c; simpl; intros; P.MX.elim_comp; auto.
+ destruct c; simpl; intros; P.MX.elim_comp; auto with ordered_type.
Qed.
Hint Resolve cons_Cmp : core.
diff --git a/theories/FSets/FMapFacts.v b/theories/FSets/FMapFacts.v
index 1a531542cc..758f9d41b0 100644
--- a/theories/FSets/FMapFacts.v
+++ b/theories/FSets/FMapFacts.v
@@ -1822,7 +1822,7 @@ Module OrdProperties (M:S).
destruct (gtb (x,e) (a,e')); destruct (gtb (x,e) (b,e'')); auto.
unfold O.ltk in *; simpl in *; intros.
symmetry; rewrite H2.
- apply ME.eq_lt with a; auto.
+ apply ME.eq_lt with a; auto with ordered_type.
rewrite <- H1; auto.
unfold O.ltk in *; simpl in *; intros.
rewrite H1.
@@ -1869,7 +1869,7 @@ Module OrdProperties (M:S).
rewrite <- elements_mapsto_iff in H1.
assert (~E.eq x t0).
contradict H.
- exists e0; apply MapsTo_1 with t0; auto.
+ exists e0; apply MapsTo_1 with t0; auto with ordered_type.
ME.order.
apply (@filter_sort _ eqke); auto with *; clean_eauto.
intros.
@@ -1888,9 +1888,9 @@ Module OrdProperties (M:S).
find_mapsto_iff, (H0 t0), <- find_mapsto_iff,
add_mapsto_iff by (auto with *).
unfold O.eqke, O.ltk; simpl.
- destruct (E.compare t0 x); intuition; try fold (~E.eq x t0); auto.
+ destruct (E.compare t0 x); intuition; try fold (~E.eq x t0); auto with ordered_type.
- elim H; exists e0; apply MapsTo_1 with t0; auto.
- - fold (~E.lt t0 x); auto.
+ - fold (~E.lt t0 x); auto with ordered_type.
Qed.
Lemma elements_Add_Above : forall m m' x e,
@@ -1905,7 +1905,7 @@ Module OrdProperties (M:S).
destruct x0; destruct y.
rewrite <- elements_mapsto_iff in H1.
unfold O.eqke, O.ltk in *; simpl in *; destruct H3.
- apply ME.lt_eq with x; auto.
+ apply ME.lt_eq with x; auto with ordered_type.
apply H; firstorder.
inversion H3.
red; intros a; destruct a.
@@ -1991,7 +1991,7 @@ Module OrdProperties (M:S).
injection H as [= -> ->].
inversion_clear H1.
red in H; simpl in *; intuition.
- elim H0; eauto.
+ elim H0; eauto with ordered_type.
inversion H.
change (max_elt_aux (p::l) = Some (x,e)) in H.
generalize (IHl x e H); clear IHl; intros IHl.
@@ -2007,9 +2007,9 @@ Module OrdProperties (M:S).
inversion_clear H2.
inversion_clear H5.
red in H2; simpl in H2; ME.order.
- eapply IHl; eauto.
+ eapply IHl; eauto with ordered_type.
econstructor; eauto.
- red; eauto.
+ red; eauto with ordered_type.
inversion H2; auto.
Qed.
@@ -2022,7 +2022,7 @@ Module OrdProperties (M:S).
induction (elements m).
simpl; try discriminate.
destruct a; destruct l; simpl in *.
- injection H; intros; subst; constructor; red; auto.
+ injection H; intros; subst; constructor; red; auto with ordered_type.
constructor 2; auto.
Qed.
@@ -2069,7 +2069,7 @@ Module OrdProperties (M:S).
destruct (elements m).
simpl; try discriminate.
destruct p; simpl in *.
- injection H; intros; subst; constructor; red; auto.
+ injection H; intros; subst; constructor; red; auto with ordered_type.
Qed.
Lemma min_elt_Empty :
@@ -2106,7 +2106,7 @@ Module OrdProperties (M:S).
apply IHn.
assert (S n = S (cardinal (remove k m))).
rewrite Heqn.
- eapply cardinal_2; eauto with map.
+ eapply cardinal_2; eauto with map ordered_type.
inversion H1; auto.
eapply max_elt_Above; eauto.
@@ -2133,7 +2133,7 @@ Module OrdProperties (M:S).
apply IHn.
assert (S n = S (cardinal (remove k m))).
rewrite Heqn.
- eapply cardinal_2; eauto with map.
+ eapply cardinal_2; eauto with map ordered_type.
inversion H1; auto.
eapply min_elt_Below; eauto.
diff --git a/theories/FSets/FMapFullAVL.v b/theories/FSets/FMapFullAVL.v
index 8ca9401a06..0ef356b582 100644
--- a/theories/FSets/FMapFullAVL.v
+++ b/theories/FSets/FMapFullAVL.v
@@ -712,7 +712,7 @@ Module IntMake_ord (I:Int)(X: OrderedType)(D : OrderedType) <:
X.eq x1 x2 -> D.eq d1 d2 ->
Cmp c l1 l2 -> Cmp c ((x1,d1)::l1) ((x2,d2)::l2).
Proof.
- destruct c; simpl; intros; MX.elim_comp; auto.
+ destruct c; simpl; intros; MX.elim_comp; auto with ordered_type.
Qed.
Hint Resolve cons_Cmp : core.
diff --git a/theories/FSets/FMapList.v b/theories/FSets/FMapList.v
index b21d809059..cad528644a 100644
--- a/theories/FSets/FMapList.v
+++ b/theories/FSets/FMapList.v
@@ -68,7 +68,7 @@ Proof.
intros m.
case m;auto.
intros (k,e) l inlist.
- absurd (InA eqke (k, e) ((k, e) :: l));auto.
+ absurd (InA eqke (k, e) ((k, e) :: l)); auto with ordered_type.
Qed.
Lemma is_empty_2 : forall m, is_empty m = true -> Empty m.
@@ -106,14 +106,14 @@ Proof.
elim (sort_inv sorted);auto.
elim (In_inv belong1);auto.
intro abs.
- absurd (X.eq x k');auto.
+ absurd (X.eq x k'); auto with ordered_type.
Qed.
Lemma mem_2 : forall m (Hm:Sort m) x, mem x m = true -> In x m.
Proof.
intros m Hm x; generalize Hm; clear Hm; unfold PX.In,PX.MapsTo.
functional induction (mem x m); intros sorted hyp;try ((inversion hyp);fail).
- exists _x; auto.
+ exists _x; auto with ordered_type.
induction IHb; auto.
exists x0; auto.
inversion_clear sorted; auto.
@@ -135,7 +135,7 @@ Function find (k:key) (s: t elt) {struct s} : option elt :=
Lemma find_2 : forall m x e, find x m = Some e -> MapsTo x e m.
Proof.
intros m x. unfold PX.MapsTo.
- functional induction (find x m);simpl;intros e' eqfind; inversion eqfind; auto.
+ functional induction (find x m);simpl;intros e' eqfind; inversion eqfind; auto with ordered_type.
Qed.
Lemma find_1 : forall m (Hm:Sort m) x e, MapsTo x e m -> find x m = Some e.
@@ -174,7 +174,7 @@ Lemma add_1 : forall m x y e, X.eq x y -> MapsTo y e (add x e m).
Proof.
intros m x y e; generalize y; clear y.
unfold PX.MapsTo.
- functional induction (add x e m);simpl;auto.
+ functional induction (add x e m);simpl;auto with ordered_type.
Qed.
Lemma add_2 : forall m x y e e',
@@ -195,12 +195,12 @@ Qed.
Lemma add_3 : forall m x y e e',
~ X.eq x y -> MapsTo y e (add x e' m) -> MapsTo y e m.
-Proof.
+Proof with auto with ordered_type.
intros m x y e e'. generalize y e; clear y e; unfold PX.MapsTo.
functional induction (add x e' m);simpl; intros.
- apply (In_inv_3 H0); compute; auto.
- apply (In_inv_3 H0); compute; auto.
- constructor 2; apply (In_inv_3 H0); compute; auto.
+ apply (In_inv_3 H0)...
+ apply (In_inv_3 H0)...
+ constructor 2; apply (In_inv_3 H0)...
inversion_clear H0; auto.
Qed.
@@ -254,7 +254,7 @@ Proof.
clear e0;inversion_clear Hm.
apply Sort_Inf_NotIn with x0; auto.
- apply Inf_eq with (k',x0);auto; compute; apply X.eq_trans with x; auto.
+ apply Inf_eq with (k',x0);auto; compute; apply X.eq_trans with x; auto with ordered_type.
clear e0;inversion_clear Hm.
assert (notin:~ In y (remove x l)) by auto.
@@ -374,13 +374,13 @@ Definition Equivb cmp m m' :=
Lemma equal_1 : forall m (Hm:Sort m) m' (Hm': Sort m') cmp,
Equivb cmp m m' -> equal cmp m m' = true.
-Proof.
+Proof with auto with ordered_type.
intros m Hm m' Hm' cmp; generalize Hm Hm'; clear Hm Hm'.
functional induction (equal cmp m m'); simpl; subst;auto; unfold Equivb;
intuition; subst.
match goal with H: X.compare _ _ = _ |- _ => clear H end.
assert (cmp_e_e':cmp e e' = true).
- apply H1 with x; auto.
+ apply H1 with x...
rewrite cmp_e_e'; simpl.
apply IHb; auto.
inversion_clear Hm; auto.
@@ -388,7 +388,7 @@ Proof.
unfold Equivb; intuition.
destruct (H0 k).
assert (In k ((x,e) ::l)).
- destruct H as (e'', hyp); exists e''; auto.
+ destruct H as (e'', hyp); exists e''...
destruct (In_inv (H2 H4)); auto.
inversion_clear Hm.
elim (Sort_Inf_NotIn H6 H7).
@@ -396,20 +396,20 @@ Proof.
apply MapsTo_eq with k; auto; order.
destruct (H0 k).
assert (In k ((x',e') ::l')).
- destruct H as (e'', hyp); exists e''; auto.
+ destruct H as (e'', hyp); exists e''...
destruct (In_inv (H3 H4)); auto.
inversion_clear Hm'.
elim (Sort_Inf_NotIn H6 H7).
destruct H as (e'', hyp); exists e''; auto.
apply MapsTo_eq with k; auto; order.
- apply H1 with k; destruct (X.eq_dec x k); auto.
+ apply H1 with k; destruct (X.eq_dec x k)...
destruct (X.compare x x') as [Hlt|Heq|Hlt]; try contradiction; clear y.
destruct (H0 x).
assert (In x ((x',e')::l')).
apply H; auto.
- exists e; auto.
+ exists e...
destruct (In_inv H3).
order.
inversion_clear Hm'.
@@ -420,7 +420,7 @@ Proof.
destruct (H0 x').
assert (In x' ((x,e)::l)).
apply H2; auto.
- exists e'; auto.
+ exists e'...
destruct (In_inv H3).
order.
inversion_clear Hm.
@@ -434,13 +434,13 @@ Proof.
clear H1;destruct p as (k,e).
destruct (H0 k).
destruct H1.
- exists e; auto.
+ exists e...
inversion H1.
destruct p as (x,e).
destruct (H0 x).
destruct H.
- exists e; auto.
+ exists e...
inversion H.
destruct p;destruct p0;contradiction.
@@ -449,7 +449,7 @@ Qed.
Lemma equal_2 : forall m (Hm:Sort m) m' (Hm:Sort m') cmp,
equal cmp m m' = true -> Equivb cmp m m'.
-Proof.
+Proof with auto with ordered_type.
intros m Hm m' Hm' cmp; generalize Hm Hm'; clear Hm Hm'.
functional induction (equal cmp m m'); simpl; subst;auto; unfold Equivb;
intuition; try discriminate; subst;
@@ -464,16 +464,16 @@ Proof.
exists e'; constructor; split; trivial; apply X.eq_trans with x; auto.
destruct (H k).
destruct (H9 H8) as (e'',hyp).
- exists e''; auto.
+ exists e''...
inversion_clear Hm;inversion_clear Hm'.
destruct (andb_prop _ _ H); clear H.
destruct (IHb H1 H3 H6).
destruct (In_inv H0).
- exists e; constructor; split; trivial; apply X.eq_trans with x'; auto.
+ exists e; constructor; split; trivial; apply X.eq_trans with x'...
destruct (H k).
destruct (H10 H8) as (e'',hyp).
- exists e''; auto.
+ exists e''...
inversion_clear Hm;inversion_clear Hm'.
destruct (andb_prop _ _ H); clear H.
@@ -615,7 +615,8 @@ Proof.
inversion_clear 1.
exists x'.
destruct H0; simpl in *.
- split; auto.
+ split.
+ auto with ordered_type.
constructor 1.
unfold eqke in *; simpl in *; intuition congruence.
destruct IHm as (y, hyp); auto.
@@ -946,7 +947,7 @@ Proof.
destruct (IHm0 H0) as (_,H4); apply H4; auto.
case_eq (find x m0); intros; auto.
assert (eqk (elt:=oee') (k,(oo,oo')) (x,(oo,oo'))).
- red; auto.
+ red; auto with ordered_type.
destruct (Sort_Inf_NotIn H0 (Inf_eq (eqk_sym H5) H1)).
exists p; apply find_2; auto.
(* k < x *)
@@ -1315,7 +1316,7 @@ Proof.
apply (IHm1 H0 (Build_slist H5)); intuition.
Qed.
-Ltac cmp_solve := unfold eq, lt; simpl; try Raw.MX.elim_comp; auto.
+Ltac cmp_solve := unfold eq, lt; simpl; try Raw.MX.elim_comp; auto with ordered_type.
Definition compare : forall m1 m2, Compare lt eq m1 m2.
Proof.
diff --git a/theories/FSets/FSetBridge.v b/theories/FSets/FSetBridge.v
index 6e08c38a49..f0b31e6986 100644
--- a/theories/FSets/FSetBridge.v
+++ b/theories/FSets/FSetBridge.v
@@ -63,11 +63,11 @@ Module DepOfNodep (Import M: S) <: Sdep with Module E := M.E.
{s' : t | forall y : elt, In y s' <-> ~ E.eq x y /\ In y s}.
Proof.
intros; exists (remove x s); intuition.
- absurd (In x (remove x s)); auto with set.
- apply In_1 with y; auto.
+ absurd (In x (remove x s)); auto with set ordered_type.
+ apply In_1 with y; auto with ordered_type.
elim (E.eq_dec x y); intros; auto.
- absurd (In x (remove x s)); auto with set.
- apply In_1 with y; auto.
+ absurd (In x (remove x s)); auto with set ordered_type.
+ apply In_1 with y; auto with ordered_type.
eauto with set.
Qed.
@@ -470,7 +470,7 @@ Module NodepOfDep (M: Sdep) <: S with Module E := M.E.
Hint Resolve elements_3 : core.
Lemma elements_3w : forall s : t, NoDupA E.eq (elements s).
- Proof. auto. Qed.
+ Proof. auto with ordered_type. Qed.
Definition min_elt (s : t) : option elt :=
match min_elt s with
diff --git a/theories/FSets/FSetProperties.v b/theories/FSets/FSetProperties.v
index c6b2e0a09d..e500debc73 100644
--- a/theories/FSets/FSetProperties.v
+++ b/theories/FSets/FSetProperties.v
@@ -939,7 +939,7 @@ Module OrdProperties (M:S).
generalize (gtb_1 x a)(gtb_1 x b); destruct (gtb x a); destruct (gtb x b); auto.
intros.
symmetry; rewrite H1.
- apply ME.eq_lt with a; auto.
+ apply ME.eq_lt with a; auto with ordered_type.
rewrite <- H0; auto.
intros.
rewrite H0.
@@ -1013,7 +1013,7 @@ Module OrdProperties (M:S).
intros.
inversion_clear H2.
rewrite <- elements_iff in H1.
- apply ME.lt_eq with x; auto.
+ apply ME.lt_eq with x; auto with ordered_type.
inversion H3.
red; intros a.
rewrite InA_app_iff, InA_cons, InA_nil by auto with *.
@@ -1052,7 +1052,7 @@ Module OrdProperties (M:S).
apply X0 with (remove e s) e; auto with set.
apply IHn.
assert (S n = S (cardinal (remove e s))).
- rewrite Heqn; apply cardinal_2 with e; auto with set.
+ rewrite Heqn; apply cardinal_2 with e; auto with set ordered_type.
inversion H0; auto.
red; intros.
rewrite remove_iff in H0; destruct H0.
@@ -1073,7 +1073,7 @@ Module OrdProperties (M:S).
apply X0 with (remove e s) e; auto with set.
apply IHn.
assert (S n = S (cardinal (remove e s))).
- rewrite Heqn; apply cardinal_2 with e; auto with set.
+ rewrite Heqn; apply cardinal_2 with e; auto with set ordered_type.
inversion H0; auto.
red; intros.
rewrite remove_iff in H0; destruct H0.
diff --git a/theories/Init/Logic.v b/theories/Init/Logic.v
index 09a32e9483..4d84d61f9f 100644
--- a/theories/Init/Logic.v
+++ b/theories/Init/Logic.v
@@ -274,6 +274,22 @@ Inductive ex (A:Type) (P:A -> Prop) : Prop :=
ex_intro : forall x:A, P x -> ex (A:=A) P.
Register ex as core.ex.type.
+Register ex_intro as core.ex.intro.
+
+Section Projections.
+
+ Variables (A:Prop) (P:A->Prop).
+
+ Definition ex_proj1 (x:ex P) : A :=
+ match x with ex_intro _ a _ => a end.
+
+ Definition ex_proj2 (x:ex P) : P (ex_proj1 x) :=
+ match x with ex_intro _ _ b => b end.
+
+ Register ex_proj1 as core.ex.proj1.
+ Register ex_proj2 as core.ex.proj2.
+
+End Projections.
Inductive ex2 (A:Type) (P Q:A -> Prop) : Prop :=
ex_intro2 : forall x:A, P x -> Q x -> ex2 (A:=A) P Q.
diff --git a/theories/Reals/ConstructiveCauchyReals.v b/theories/Reals/ConstructiveCauchyReals.v
index 004854e751..965d31d403 100644
--- a/theories/Reals/ConstructiveCauchyReals.v
+++ b/theories/Reals/ConstructiveCauchyReals.v
@@ -15,34 +15,32 @@ Require Import Qround.
Require Import Logic.ConstructiveEpsilon.
Require CMorphisms.
-Open Scope Q.
+(** The constructive Cauchy real numbers, ie the Cauchy sequences
+ of rational numbers. This file is not supposed to be imported,
+ except in Rdefinitions.v, Raxioms.v, Rcomplete_constr.v
+ and ConstructiveRIneq.v.
-(* The constructive Cauchy real numbers, ie the Cauchy sequences
- of rational numbers. This file is not supposed to be imported,
- except in Rdefinitions.v, Raxioms.v, Rcomplete_constr.v
- and ConstructiveRIneq.v.
+ Constructive real numbers should be considered abstractly,
+ forgetting the fact that they are implemented as rational sequences.
+ All useful lemmas of this file are exposed in ConstructiveRIneq.v,
+ under more abstract names, like Rlt_asym instead of CRealLt_asym.
- Constructive real numbers should be considered abstractly,
- forgetting the fact that they are implemented as rational sequences.
- All useful lemmas of this file are exposed in ConstructiveRIneq.v,
- under more abstract names, like Rlt_asym instead of CRealLt_asym.
+ Cauchy reals are Cauchy sequences of rational numbers,
+ equipped with explicit moduli of convergence and
+ an equivalence relation (the difference converges to zero).
- Cauchy reals are Cauchy sequences of rational numbers,
- equipped with explicit moduli of convergence and
- an equivalence relation (the difference converges to zero).
+ Without convergence moduli, we would fail to prove that a Cauchy
+ sequence of constructive reals converges.
- Without convergence moduli, we would fail to prove that a Cauchy
- sequence of constructive reals converges.
+ Because of the Specker sequences (increasing, computable
+ and bounded sequences of rationals that do not converge
+ to a computable real number), constructive reals do not
+ follow the least upper bound principle.
- Because of the Specker sequences (increasing, computable
- and bounded sequences of rationals that do not converge
- to a computable real number), constructive reals do not
- follow the least upper bound principle.
-
- The double quantification on p q is needed to avoid
- forall un, QSeqEquiv un (fun _ => un O) (fun q => O)
- which says nothing about the limit of un.
+ The double quantification on p q is needed to avoid
+ forall un, QSeqEquiv un (fun _ => un O) (fun q => O)
+ which says nothing about the limit of un.
*)
Definition QSeqEquiv (un vn : nat -> Q) (cvmod : positive -> nat)
: Prop
@@ -213,7 +211,7 @@ Delimit Scope CReal_scope with CReal.
(* Automatically open scope R_scope for arguments of type R *)
Bind Scope CReal_scope with CReal.
-Open Scope CReal_scope.
+Local Open Scope CReal_scope.
(* So QSeqEquiv is the equivalence relation of this constructive pre-order *)
@@ -470,7 +468,8 @@ Qed.
Lemma CRealLt_above : forall (x y : CReal),
CRealLt x y
-> { k : positive | forall p:positive,
- Pos.le k p -> Qlt (2 # k) (proj1_sig y (Pos.to_nat p) - proj1_sig x (Pos.to_nat p)) }.
+ Pos.le k p -> Qlt (2 # k) (proj1_sig y (Pos.to_nat p)
+ - proj1_sig x (Pos.to_nat p)) }.
Proof.
intros x y [n maj].
pose proof (CRealLt_aboveSig x y n maj).
@@ -544,10 +543,9 @@ Proof.
Qed.
Lemma CRealLt_dec : forall x y z : CReal,
- CRealLt x y -> CRealLt x z + CRealLt z y.
+ x < y -> sum (x < z) (z < y).
Proof.
- intros [xn limx] [yn limy] [zn limz] clt.
- destruct clt as [n inf].
+ intros [xn limx] [yn limy] [zn limz] [n inf].
unfold proj1_sig in inf.
remember (yn (Pos.to_nat n) - xn (Pos.to_nat n) - (2 # n)) as eps.
assert (Qlt 0 eps) as epsPos.
@@ -629,33 +627,33 @@ Defined.
Definition linear_order_T x y z := CRealLt_dec x z y.
-Lemma CRealLe_Lt_trans : forall x y z : CReal,
+Lemma CReal_le_lt_trans : forall x y z : CReal,
x <= y -> y < z -> x < z.
Proof.
intros.
destruct (linear_order_T y x z H0). contradiction. apply c.
-Qed.
+Defined.
-Lemma CRealLt_Le_trans : forall x y z : CReal,
+Lemma CReal_lt_le_trans : forall x y z : CReal,
x < y -> y <= z -> x < z.
Proof.
intros.
destruct (linear_order_T x z y H). apply c. contradiction.
-Qed.
+Defined.
-Lemma CRealLe_trans : forall x y z : CReal,
+Lemma CReal_le_trans : forall x y z : CReal,
x <= y -> y <= z -> x <= z.
Proof.
intros. intro abs. apply H0.
- apply (CRealLt_Le_trans _ x); assumption.
+ apply (CReal_lt_le_trans _ x); assumption.
Qed.
-Lemma CRealLt_trans : forall x y z : CReal,
+Lemma CReal_lt_trans : forall x y z : CReal,
x < y -> y < z -> x < z.
Proof.
- intros. apply (CRealLt_Le_trans _ y _ H).
+ intros. apply (CReal_lt_le_trans _ y _ H).
apply CRealLt_asym. exact H0.
-Qed.
+Defined.
Lemma CRealEq_trans : forall x y z : CReal,
CRealEq x y -> CRealEq y z -> CRealEq x z.
@@ -776,6 +774,7 @@ Defined.
Notation "0" := (inject_Q 0) : CReal_scope.
Notation "1" := (inject_Q 1) : CReal_scope.
+Notation "2" := (inject_Q 2) : CReal_scope.
Lemma CRealLt_0_1 : CRealLt (inject_Q 0) (inject_Q 1).
Proof.
@@ -859,6 +858,56 @@ Proof.
apply Pos.le_max_r. apply le_refl.
Qed.
+Lemma inject_Q_compare : forall (x : CReal) (p : positive),
+ x <= inject_Q (proj1_sig x (Pos.to_nat p) + (1#p)).
+Proof.
+ intros. intros [n nmaj].
+ destruct x as [xn xcau]; simpl in nmaj.
+ apply (Qplus_lt_l _ _ (1#p)) in nmaj.
+ ring_simplify in nmaj.
+ destruct (Pos.max_dec p n).
+ - apply Pos.max_l_iff in e.
+ apply Pos2Nat.inj_le in e.
+ specialize (xcau n (Pos.to_nat n) (Pos.to_nat p) (le_refl _) e).
+ apply (Qlt_le_trans _ _ (Qabs (xn (Pos.to_nat n) + -1 * xn (Pos.to_nat p)))) in nmaj.
+ 2: apply Qle_Qabs.
+ apply (Qlt_trans _ _ _ nmaj) in xcau.
+ apply (Qplus_lt_l _ _ (-(1#n)-(1#p))) in xcau. ring_simplify in xcau.
+ setoid_replace ((2 # n) + -1 * (1 # n)) with (1#n)%Q in xcau.
+ discriminate xcau. setoid_replace (-1 * (1 # n)) with (-1#n)%Q. 2: reflexivity.
+ rewrite Qinv_plus_distr. reflexivity.
+ - apply Pos.max_r_iff, Pos2Nat.inj_le in e.
+ specialize (xcau p (Pos.to_nat n) (Pos.to_nat p) e (le_refl _)).
+ apply (Qlt_le_trans _ _ (Qabs (xn (Pos.to_nat n) + -1 * xn (Pos.to_nat p)))) in nmaj.
+ 2: apply Qle_Qabs.
+ apply (Qlt_trans _ _ _ nmaj) in xcau.
+ apply (Qplus_lt_l _ _ (-(1#p))) in xcau. ring_simplify in xcau. discriminate.
+Qed.
+
+
+Add Parametric Morphism : inject_Q
+ with signature Qeq ==> CRealEq
+ as inject_Q_morph.
+Proof.
+ split.
+ - intros [n abs]. simpl in abs. rewrite H in abs.
+ unfold Qminus in abs. rewrite Qplus_opp_r in abs. discriminate abs.
+ - intros [n abs]. simpl in abs. rewrite H in abs.
+ unfold Qminus in abs. rewrite Qplus_opp_r in abs. discriminate abs.
+Qed.
+
+Instance inject_Q_morph_T
+ : CMorphisms.Proper
+ (CMorphisms.respectful Qeq CRealEq) inject_Q.
+Proof.
+ split.
+ - intros [n abs]. simpl in abs. rewrite H in abs.
+ unfold Qminus in abs. rewrite Qplus_opp_r in abs. discriminate abs.
+ - intros [n abs]. simpl in abs. rewrite H in abs.
+ unfold Qminus in abs. rewrite Qplus_opp_r in abs. discriminate abs.
+Qed.
+
+
(* Algebraic operations *)
@@ -1029,9 +1078,7 @@ Proof.
Qed.
Lemma CReal_plus_lt_compat_l :
- forall x y z : CReal,
- CRealLt y z
- -> CRealLt (CReal_plus x y) (CReal_plus x z).
+ forall x y z : CReal, y < z -> x + y < x + z.
Proof.
intros.
apply CRealLt_above in H. destruct H as [n maj].
@@ -1047,6 +1094,13 @@ Proof.
simpl; ring.
Qed.
+Lemma CReal_plus_lt_compat_r :
+ forall x y z : CReal, y < z -> y + x < z + x.
+Proof.
+ intros. do 2 rewrite <- (CReal_plus_comm x).
+ apply CReal_plus_lt_compat_l. assumption.
+Qed.
+
Lemma CReal_plus_lt_reg_l :
forall x y z : CReal, x + y < x + z -> y < z.
Proof.
@@ -1068,6 +1122,20 @@ Proof.
apply CReal_plus_lt_reg_l in H. exact H.
Qed.
+Lemma CReal_plus_le_reg_l :
+ forall x y z : CReal, x + y <= x + z -> y <= z.
+Proof.
+ intros. intro abs. apply H. clear H.
+ apply CReal_plus_lt_compat_l. exact abs.
+Qed.
+
+Lemma CReal_plus_le_reg_r :
+ forall x y z : CReal, y + x <= z + x -> y <= z.
+Proof.
+ intros. intro abs. apply H. clear H.
+ apply CReal_plus_lt_compat_r. exact abs.
+Qed.
+
Lemma CReal_plus_le_compat_l : forall r r1 r2, r1 <= r2 -> r + r1 <= r + r2.
Proof.
intros. intro abs. apply CReal_plus_lt_reg_l in abs. contradiction.
@@ -1076,12 +1144,21 @@ Qed.
Lemma CReal_plus_le_lt_compat :
forall r1 r2 r3 r4 : CReal, r1 <= r2 -> r3 < r4 -> r1 + r3 < r2 + r4.
Proof.
- intros; apply CRealLe_Lt_trans with (r2 + r3).
+ intros; apply CReal_le_lt_trans with (r2 + r3).
intro abs. rewrite CReal_plus_comm, (CReal_plus_comm r1) in abs.
apply CReal_plus_lt_reg_l in abs. contradiction.
apply CReal_plus_lt_compat_l; exact H0.
Qed.
+Lemma CReal_plus_le_compat :
+ forall r1 r2 r3 r4 : CReal, r1 <= r2 -> r3 <= r4 -> r1 + r3 <= r2 + r4.
+Proof.
+ intros; apply CReal_le_trans with (r2 + r3).
+ intro abs. rewrite CReal_plus_comm, (CReal_plus_comm r1) in abs.
+ apply CReal_plus_lt_reg_l in abs. contradiction.
+ apply CReal_plus_le_compat_l; exact H0.
+Qed.
+
Lemma CReal_plus_opp_r : forall x : CReal,
x + - x == 0.
Proof.
@@ -1140,1812 +1217,110 @@ Proof.
Qed.
Lemma CReal_plus_eq_reg_l : forall (r r1 r2 : CReal),
- CRealEq (CReal_plus r r1) (CReal_plus r r2)
- -> CRealEq r1 r2.
+ r + r1 == r + r2 -> r1 == r2.
Proof.
intros. destruct H. split.
- intro abs. apply (CReal_plus_lt_compat_l r) in abs. contradiction.
- intro abs. apply (CReal_plus_lt_compat_l r) in abs. contradiction.
Qed.
-Fixpoint BoundFromZero (qn : nat -> Q) (k : nat) (A : positive) { struct k }
- : (forall n:nat, le k n -> Qlt (Qabs (qn n)) (Z.pos A # 1))
- -> { B : positive | forall n:nat, Qlt (Qabs (qn n)) (Z.pos B # 1) }.
-Proof.
- intro H. destruct k.
- - exists A. intros. apply H. apply le_0_n.
- - destruct (Qarchimedean (Qabs (qn k))) as [a maj].
- apply (BoundFromZero qn k (Pos.max A a)).
- intros n H0. destruct (Nat.le_gt_cases n k).
- + pose proof (Nat.le_antisymm n k H1 H0). subst k.
- apply (Qlt_le_trans _ (Z.pos a # 1)). apply maj.
- unfold Qle; simpl. rewrite Pos.mul_1_r. rewrite Pos.mul_1_r.
- apply Pos.le_max_r.
- + apply (Qlt_le_trans _ (Z.pos A # 1)). apply H.
- apply H1. unfold Qle; simpl. rewrite Pos.mul_1_r. rewrite Pos.mul_1_r.
- apply Pos.le_max_l.
-Qed.
-
-Lemma QCauchySeq_bounded (qn : nat -> Q) (cvmod : positive -> nat)
- : QCauchySeq qn cvmod
- -> { A : positive | forall n:nat, Qlt (Qabs (qn n)) (Z.pos A # 1) }.
-Proof.
- intros. remember (Zplus (Qnum (Qabs (qn (cvmod xH)))) 1) as z.
- assert (Z.lt 0 z) as zPos.
- { subst z. assert (Qle 0 (Qabs (qn (cvmod 1%positive)))).
- apply Qabs_nonneg. destruct (Qabs (qn (cvmod 1%positive))). simpl.
- unfold Qle in H0. simpl in H0. rewrite Zmult_1_r in H0.
- apply (Z.lt_le_trans 0 1). unfold Z.lt. auto.
- rewrite <- (Zplus_0_l 1). rewrite Zplus_assoc. apply Zplus_le_compat_r.
- rewrite Zplus_0_r. assumption. }
- assert { A : positive | forall n:nat,
- le (cvmod xH) n -> Qlt ((Qabs (qn n)) * (1#A)) 1 }.
- destruct z eqn:des.
- - exfalso. apply (Z.lt_irrefl 0). assumption.
- - exists p. intros. specialize (H xH (cvmod xH) n (le_refl _) H0).
- assert (Qlt (Qabs (qn n)) (Qabs (qn (cvmod 1%positive)) + 1)).
- { apply (Qplus_lt_l _ _ (-Qabs (qn (cvmod 1%positive)))).
- rewrite <- (Qplus_comm 1). rewrite <- Qplus_assoc. rewrite Qplus_opp_r.
- rewrite Qplus_0_r. apply (Qle_lt_trans _ (Qabs (qn n - qn (cvmod 1%positive)))).
- apply Qabs_triangle_reverse. rewrite Qabs_Qminus. assumption. }
- apply (Qlt_le_trans _ ((Qabs (qn (cvmod 1%positive)) + 1) * (1#p))).
- apply Qmult_lt_r. unfold Qlt. simpl. unfold Z.lt. auto. assumption.
- unfold Qle. simpl. rewrite Zmult_1_r. rewrite Zmult_1_r. rewrite Zmult_1_r.
- rewrite Pos.mul_1_r. rewrite Pos2Z.inj_mul. rewrite Heqz.
- destruct (Qabs (qn (cvmod 1%positive))) eqn:desAbs.
- rewrite Z.mul_add_distr_l. rewrite Zmult_1_r.
- apply Zplus_le_compat_r. rewrite <- (Zmult_1_l (QArith_base.Qnum (Qnum # Qden))).
- rewrite Zmult_assoc. apply Zmult_le_compat_r. rewrite Zmult_1_r.
- simpl. unfold Z.le. rewrite <- Pos2Z.inj_compare.
- unfold Pos.compare. destruct Qden; discriminate.
- simpl. assert (Qle 0 (Qnum # Qden)). rewrite <- desAbs.
- apply Qabs_nonneg. unfold Qle in H2. simpl in H2. rewrite Zmult_1_r in H2.
- assumption.
- - exfalso. inversion zPos.
- - destruct H0. apply (BoundFromZero _ (cvmod xH) x). intros n H0.
- specialize (q n H0). setoid_replace (Z.pos x # 1)%Q with (/(1#x))%Q.
- rewrite <- (Qmult_1_l (/(1#x))). apply Qlt_shift_div_l.
- reflexivity. apply q. reflexivity.
-Qed.
-
-Lemma CReal_mult_cauchy
- : forall (xn yn zn : nat -> Q) (Ay Az : positive) (cvmod : positive -> nat),
- QSeqEquiv xn yn cvmod
- -> QCauchySeq zn Pos.to_nat
- -> (forall n:nat, Qlt (Qabs (yn n)) (Z.pos Ay # 1))
- -> (forall n:nat, Qlt (Qabs (zn n)) (Z.pos Az # 1))
- -> QSeqEquiv (fun n:nat => xn n * zn n) (fun n:nat => yn n * zn n)
- (fun p => max (cvmod (2 * (Pos.max Ay Az) * p)%positive)
- (Pos.to_nat (2 * (Pos.max Ay Az) * p)%positive)).
-Proof.
- intros xn yn zn Ay Az cvmod limx limz majy majz.
- remember (Pos.mul 2 (Pos.max Ay Az)) as z.
- intros k p q H H0.
- assert (Pos.to_nat k <> O) as kPos.
- { intro absurd. pose proof (Pos2Nat.is_pos k).
- rewrite absurd in H1. inversion H1. }
- setoid_replace (xn p * zn p - yn q * zn q)%Q
- with ((xn p - yn q) * zn p + yn q * (zn p - zn q))%Q.
- 2: ring.
- apply (Qle_lt_trans _ (Qabs ((xn p - yn q) * zn p)
- + Qabs (yn q * (zn p - zn q)))).
- apply Qabs_triangle. rewrite Qabs_Qmult. rewrite Qabs_Qmult.
- setoid_replace (1#k)%Q with ((1#2*k) + (1#2*k))%Q.
- apply Qplus_lt_le_compat.
- - apply (Qle_lt_trans _ ((1#z * k) * Qabs (zn p)%nat)).
- + apply Qmult_le_compat_r. apply Qle_lteq. left. apply limx.
- apply (le_trans _ (Init.Nat.max (cvmod (z * k)%positive) (Pos.to_nat (z * k)))).
- apply Nat.le_max_l. assumption.
- apply (le_trans _ (Init.Nat.max (cvmod (z * k)%positive) (Pos.to_nat (z * k)))).
- apply Nat.le_max_l. assumption. apply Qabs_nonneg.
- + subst z. rewrite <- (Qmult_1_r (1 # 2 * k)).
- rewrite <- Pos.mul_assoc. rewrite <- (Pos.mul_comm k). rewrite Pos.mul_assoc.
- rewrite (factorDenom _ _ (2 * k)). rewrite <- Qmult_assoc.
- apply Qmult_lt_l. unfold Qlt. simpl. unfold Z.lt. auto.
- apply (Qle_lt_trans _ (Qabs (zn p)%nat * (1 # Az))).
- rewrite <- (Qmult_comm (1 # Az)). apply Qmult_le_compat_r.
- unfold Qle. simpl. rewrite Pos2Z.inj_max. apply Z.le_max_r.
- apply Qabs_nonneg. rewrite <- (Qmult_inv_r (1#Az)).
- rewrite Qmult_comm. apply Qmult_lt_l. reflexivity.
- setoid_replace (/(1#Az))%Q with (Z.pos Az # 1)%Q. apply majz.
- reflexivity. intro abs. inversion abs.
- - apply (Qle_trans _ ((1 # z * k) * Qabs (yn q)%nat)).
- + rewrite Qmult_comm. apply Qmult_le_compat_r. apply Qle_lteq.
- left. apply limz.
- apply (le_trans _ (max (cvmod (z * k)%positive)
- (Pos.to_nat (z * k)%positive))).
- apply Nat.le_max_r. assumption.
- apply (le_trans _ (max (cvmod (z * k)%positive)
- (Pos.to_nat (z * k)%positive))).
- apply Nat.le_max_r. assumption. apply Qabs_nonneg.
- + subst z. rewrite <- (Qmult_1_r (1 # 2 * k)).
- rewrite <- Pos.mul_assoc. rewrite <- (Pos.mul_comm k). rewrite Pos.mul_assoc.
- rewrite (factorDenom _ _ (2 * k)). rewrite <- Qmult_assoc.
- apply Qle_lteq. left.
- apply Qmult_lt_l. unfold Qlt. simpl. unfold Z.lt. auto.
- apply (Qle_lt_trans _ (Qabs (yn q)%nat * (1 # Ay))).
- rewrite <- (Qmult_comm (1 # Ay)). apply Qmult_le_compat_r.
- unfold Qle. simpl. rewrite Pos2Z.inj_max. apply Z.le_max_l.
- apply Qabs_nonneg. rewrite <- (Qmult_inv_r (1#Ay)).
- rewrite Qmult_comm. apply Qmult_lt_l. reflexivity.
- setoid_replace (/(1#Ay))%Q with (Z.pos Ay # 1)%Q. apply majy.
- reflexivity. intro abs. inversion abs.
- - rewrite Qinv_plus_distr. unfold Qeq. reflexivity.
-Qed.
-
-Lemma linear_max : forall (p Ax Ay : positive) (i : nat),
- le (Pos.to_nat p) i
- -> (Init.Nat.max (Pos.to_nat (2 * Pos.max Ax Ay * p))
- (Pos.to_nat (2 * Pos.max Ax Ay * p)) <= Pos.to_nat (2 * Pos.max Ax Ay) * i)%nat.
-Proof.
- intros. rewrite max_l. 2: apply le_refl.
- rewrite Pos2Nat.inj_mul. apply Nat.mul_le_mono_nonneg.
- apply le_0_n. apply le_refl. apply le_0_n. apply H.
-Qed.
-
-Definition CReal_mult (x y : CReal) : CReal.
-Proof.
- destruct x as [xn limx]. destruct y as [yn limy].
- destruct (QCauchySeq_bounded xn Pos.to_nat limx) as [Ax majx].
- destruct (QCauchySeq_bounded yn Pos.to_nat limy) as [Ay majy].
- pose proof (CReal_mult_cauchy xn xn yn Ax Ay Pos.to_nat limx limy majx majy).
- exists (fun n : nat => xn (Pos.to_nat (2 * Pos.max Ax Ay)* n)%nat
- * yn (Pos.to_nat (2 * Pos.max Ax Ay) * n)%nat).
- intros p n k H0 H1.
- apply H; apply linear_max; assumption.
-Defined.
-
-Infix "*" := CReal_mult : CReal_scope.
-
-Lemma CReal_mult_unfold : forall x y : CReal,
- QSeqEquivEx (proj1_sig (CReal_mult x y))
- (fun n : nat => proj1_sig x n * proj1_sig y n)%Q.
-Proof.
- intros [xn limx] [yn limy]. unfold CReal_mult ; simpl.
- destruct (QCauchySeq_bounded xn Pos.to_nat limx) as [Ax majx].
- destruct (QCauchySeq_bounded yn Pos.to_nat limy) as [Ay majy].
- simpl.
- pose proof (CReal_mult_cauchy xn xn yn Ax Ay Pos.to_nat limx limy majx majy).
- exists (fun p : positive =>
- Init.Nat.max (Pos.to_nat (2 * Pos.max Ax Ay * p))
- (Pos.to_nat (2 * Pos.max Ax Ay * p))).
- intros p n k H0 H1. rewrite max_l in H0, H1.
- 2: apply le_refl. 2: apply le_refl.
- apply H. apply linear_max.
- apply (le_trans _ (Pos.to_nat (2 * Pos.max Ax Ay * p))).
- rewrite <- (mult_1_l (Pos.to_nat p)). rewrite Pos2Nat.inj_mul.
- apply Nat.mul_le_mono_nonneg. auto. apply Pos2Nat.is_pos.
- apply le_0_n. apply le_refl. apply H0. rewrite max_l.
- apply H1. apply le_refl.
-Qed.
-
-Lemma CReal_mult_assoc_bounded_r : forall (xn yn zn : nat -> Q),
- QSeqEquivEx xn yn (* both are Cauchy with same limit *)
- -> QSeqEquiv zn zn Pos.to_nat
- -> QSeqEquivEx (fun n => xn n * zn n)%Q (fun n => yn n * zn n)%Q.
-Proof.
- intros. destruct H as [cvmod cveq].
- destruct (QCauchySeq_bounded yn (fun k => cvmod (2 * k)%positive)
- (QSeqEquiv_cau_r xn yn cvmod cveq))
- as [Ay majy].
- destruct (QCauchySeq_bounded zn Pos.to_nat H0) as [Az majz].
- exists (fun p => max (cvmod (2 * (Pos.max Ay Az) * p)%positive)
- (Pos.to_nat (2 * (Pos.max Ay Az) * p)%positive)).
- apply CReal_mult_cauchy; assumption.
-Qed.
-
-Lemma CReal_mult_assoc : forall x y z : CReal,
- CRealEq (CReal_mult (CReal_mult x y) z)
- (CReal_mult x (CReal_mult y z)).
-Proof.
- intros. apply CRealEq_diff. apply CRealEq_modindep.
- apply (QSeqEquivEx_trans _ (fun n => proj1_sig x n * proj1_sig y n * proj1_sig z n)%Q).
- - apply (QSeqEquivEx_trans _ (fun n => proj1_sig (CReal_mult x y) n * proj1_sig z n)%Q).
- apply CReal_mult_unfold.
- destruct x as [xn limx], y as [yn limy], z as [zn limz]; unfold CReal_mult; simpl.
- destruct (QCauchySeq_bounded xn Pos.to_nat limx) as [Ax majx].
- destruct (QCauchySeq_bounded yn Pos.to_nat limy) as [Ay majy].
- destruct (QCauchySeq_bounded zn Pos.to_nat limz) as [Az majz].
- apply CReal_mult_assoc_bounded_r. 2: apply limz.
- simpl.
- pose proof (CReal_mult_cauchy xn xn yn Ax Ay Pos.to_nat limx limy majx majy).
- exists (fun p : positive =>
- Init.Nat.max (Pos.to_nat (2 * Pos.max Ax Ay * p))
- (Pos.to_nat (2 * Pos.max Ax Ay * p))).
- intros p n k H0 H1. rewrite max_l in H0, H1.
- 2: apply le_refl. 2: apply le_refl.
- apply H. apply linear_max.
- apply (le_trans _ (Pos.to_nat (2 * Pos.max Ax Ay * p))).
- rewrite <- (mult_1_l (Pos.to_nat p)). rewrite Pos2Nat.inj_mul.
- apply Nat.mul_le_mono_nonneg. auto. apply Pos2Nat.is_pos.
- apply le_0_n. apply le_refl. apply H0. rewrite max_l.
- apply H1. apply le_refl.
- - apply (QSeqEquivEx_trans _ (fun n => proj1_sig x n * proj1_sig (CReal_mult y z) n)%Q).
- 2: apply QSeqEquivEx_sym; apply CReal_mult_unfold.
- destruct x as [xn limx], y as [yn limy], z as [zn limz]; unfold CReal_mult; simpl.
- destruct (QCauchySeq_bounded xn Pos.to_nat limx) as [Ax majx].
- destruct (QCauchySeq_bounded yn Pos.to_nat limy) as [Ay majy].
- destruct (QCauchySeq_bounded zn Pos.to_nat limz) as [Az majz].
- simpl.
- pose proof (CReal_mult_assoc_bounded_r (fun n0 : nat => yn n0 * zn n0)%Q (fun n : nat =>
- yn (Pos.to_nat (Pos.max Ay Az)~0 * n)%nat
- * zn (Pos.to_nat (Pos.max Ay Az)~0 * n)%nat)%Q xn)
- as [cvmod cveq].
-
- pose proof (CReal_mult_cauchy yn yn zn Ay Az Pos.to_nat limy limz majy majz).
- exists (fun p : positive =>
- Init.Nat.max (Pos.to_nat (2 * Pos.max Ay Az * p))
- (Pos.to_nat (2 * Pos.max Ay Az * p))).
- intros p n k H0 H1. rewrite max_l in H0, H1.
- 2: apply le_refl. 2: apply le_refl.
- apply H. rewrite max_l. apply H0. apply le_refl.
- apply linear_max.
- apply (le_trans _ (Pos.to_nat (2 * Pos.max Ay Az * p))).
- rewrite <- (mult_1_l (Pos.to_nat p)). rewrite Pos2Nat.inj_mul.
- apply Nat.mul_le_mono_nonneg. auto. apply Pos2Nat.is_pos.
- apply le_0_n. apply le_refl. apply H1.
- apply limx.
- exists cvmod. intros p k n H1 H2. specialize (cveq p k n H1 H2).
- setoid_replace (xn k * yn k * zn k -
- xn n *
- (yn (Pos.to_nat (Pos.max Ay Az)~0 * n)%nat *
- zn (Pos.to_nat (Pos.max Ay Az)~0 * n)%nat))%Q
- with ((fun n : nat => yn n * zn n * xn n) k -
- (fun n : nat =>
- yn (Pos.to_nat (Pos.max Ay Az)~0 * n)%nat *
- zn (Pos.to_nat (Pos.max Ay Az)~0 * n)%nat *
- xn n) n)%Q.
- apply cveq. ring.
-Qed.
-
-Lemma CReal_mult_comm : forall x y : CReal,
- CRealEq (CReal_mult x y) (CReal_mult y x).
-Proof.
- intros. apply CRealEq_diff. apply CRealEq_modindep.
- apply (QSeqEquivEx_trans _ (fun n => proj1_sig y n * proj1_sig x n)%Q).
- destruct x as [xn limx], y as [yn limy]; simpl.
- 2: apply QSeqEquivEx_sym; apply CReal_mult_unfold.
- destruct (QCauchySeq_bounded xn Pos.to_nat limx) as [Ax majx].
- destruct (QCauchySeq_bounded yn Pos.to_nat limy) as [Ay majy]; simpl.
- apply QSeqEquivEx_sym.
-
- pose proof (CReal_mult_cauchy yn yn xn Ay Ax Pos.to_nat limy limx majy majx).
- exists (fun p : positive =>
- Init.Nat.max (Pos.to_nat (2 * Pos.max Ay Ax * p))
- (Pos.to_nat (2 * Pos.max Ay Ax * p))).
- intros p n k H0 H1. rewrite max_l in H0, H1.
- 2: apply le_refl. 2: apply le_refl.
- rewrite (Qmult_comm (xn (Pos.to_nat (Pos.max Ax Ay)~0 * k)%nat)).
- apply (H p n). rewrite max_l. apply H0. apply le_refl.
- rewrite max_l. apply (le_trans _ k). apply H1.
- rewrite <- (mult_1_l k). rewrite mult_assoc.
- apply Nat.mul_le_mono_nonneg. auto. rewrite mult_1_r.
- apply Pos2Nat.is_pos. apply le_0_n. apply le_refl.
- apply le_refl.
-Qed.
-
-(* Axiom Rmult_eq_compat_l *)
-Lemma CReal_mult_proper_l : forall x y z : CReal,
- CRealEq y z -> CRealEq (CReal_mult x y) (CReal_mult x z).
-Proof.
- intros. apply CRealEq_diff. apply CRealEq_modindep.
- apply (QSeqEquivEx_trans _ (fun n => proj1_sig x n * proj1_sig y n)%Q).
- apply CReal_mult_unfold.
- rewrite CRealEq_diff in H. rewrite <- CRealEq_modindep in H.
- apply QSeqEquivEx_sym.
- apply (QSeqEquivEx_trans _ (fun n => proj1_sig x n * proj1_sig z n)%Q).
- apply CReal_mult_unfold.
- destruct x as [xn limx], y as [yn limy], z as [zn limz]; simpl.
- destruct H. simpl in H.
- destruct (QCauchySeq_bounded xn Pos.to_nat limx) as [Ax majx].
- destruct (QCauchySeq_bounded zn Pos.to_nat limz) as [Az majz].
- pose proof (CReal_mult_cauchy yn zn xn Az Ax x H limx majz majx).
- apply QSeqEquivEx_sym.
- exists (fun p : positive =>
- Init.Nat.max (x (2 * Pos.max Az Ax * p)%positive)
- (Pos.to_nat (2 * Pos.max Az Ax * p))).
- intros p n k H1 H2. specialize (H0 p n k H1 H2).
- setoid_replace (xn n * yn n - xn k * zn k)%Q
- with (yn n * xn n - zn k * xn k)%Q.
- apply H0. ring.
-Qed.
-
-Lemma CReal_mult_lt_0_compat : forall x y : CReal,
- CRealLt (inject_Q 0) x
- -> CRealLt (inject_Q 0) y
- -> CRealLt (inject_Q 0) (CReal_mult x y).
-Proof.
- intros. destruct H as [x0 H], H0 as [x1 H0].
- pose proof (CRealLt_aboveSig (inject_Q 0) x x0 H).
- pose proof (CRealLt_aboveSig (inject_Q 0) y x1 H0).
- destruct x as [xn limx], y as [yn limy].
- simpl in H, H1, H2. simpl.
- destruct (QCauchySeq_bounded xn Pos.to_nat limx) as [Ax majx].
- destruct (QCauchySeq_bounded yn Pos.to_nat limy) as [Ay majy].
- destruct (Qarchimedean (/ (xn (Pos.to_nat x0) - 0 - (2 # x0)))).
- destruct (Qarchimedean (/ (yn (Pos.to_nat x1) - 0 - (2 # x1)))).
- exists (Pos.max x0 x~0 * Pos.max x1 x2~0)%positive.
- simpl. unfold Qminus. rewrite Qplus_0_r.
- rewrite <- Pos2Nat.inj_mul.
- unfold Qminus in H1, H2.
- specialize (H1 ((Pos.max Ax Ay)~0 * (Pos.max x0 x~0 * Pos.max x1 x2~0))%positive).
- assert (Pos.max x1 x2~0 <= (Pos.max Ax Ay)~0 * (Pos.max x0 x~0 * Pos.max x1 x2~0))%positive.
- { apply Pos2Nat.inj_le.
- rewrite Pos.mul_assoc. rewrite Pos2Nat.inj_mul.
- rewrite <- (mult_1_l (Pos.to_nat (Pos.max x1 x2~0))).
- rewrite mult_assoc. apply Nat.mul_le_mono_nonneg. auto.
- rewrite mult_1_r. apply Pos2Nat.is_pos. apply le_0_n.
- apply le_refl. }
- specialize (H2 ((Pos.max Ax Ay)~0 * (Pos.max x0 x~0 * Pos.max x1 x2~0))%positive H3).
- rewrite Qplus_0_r in H1, H2.
- apply (Qlt_trans _ ((2 # Pos.max x0 x~0) * (2 # Pos.max x1 x2~0))).
- unfold Qlt; simpl. assert (forall p : positive, (Z.pos p < Z.pos p~0)%Z).
- intro p. rewrite <- (Z.mul_1_l (Z.pos p)).
- replace (Z.pos p~0) with (2 * Z.pos p)%Z. apply Z.mul_lt_mono_pos_r.
- apply Pos2Z.is_pos. reflexivity. reflexivity.
- apply H4.
- apply (Qlt_trans _ ((2 # Pos.max x0 x~0) * (yn (Pos.to_nat ((Pos.max Ax Ay)~0 * (Pos.max x0 x~0 * Pos.max x1 x2~0)))))).
- apply Qmult_lt_l. reflexivity. apply H2. apply Qmult_lt_r.
- apply (Qlt_trans 0 (2 # Pos.max x1 x2~0)). reflexivity. apply H2.
- apply H1. rewrite Pos.mul_comm. apply Pos2Nat.inj_le.
- rewrite <- Pos.mul_assoc. rewrite Pos2Nat.inj_mul.
- rewrite <- (mult_1_r (Pos.to_nat (Pos.max x0 x~0))).
- rewrite <- mult_assoc. apply Nat.mul_le_mono_nonneg.
- apply le_0_n. apply le_refl. auto.
- rewrite mult_1_l. apply Pos2Nat.is_pos.
-Qed.
-
-Lemma CReal_mult_plus_distr_l : forall r1 r2 r3 : CReal,
- r1 * (r2 + r3) == (r1 * r2) + (r1 * r3).
-Proof.
- intros x y z. apply CRealEq_diff. apply CRealEq_modindep.
- apply (QSeqEquivEx_trans _ (fun n => proj1_sig x n
- * (proj1_sig (CReal_plus y z) n))%Q).
- apply CReal_mult_unfold.
- apply (QSeqEquivEx_trans _ (fun n => proj1_sig (CReal_mult x y) n
- + proj1_sig (CReal_mult x z) n))%Q.
- 2: apply QSeqEquivEx_sym; exists (fun p => Pos.to_nat (2 * p))
- ; apply CReal_plus_unfold.
- apply (QSeqEquivEx_trans _ (fun n => proj1_sig x n
- * (proj1_sig y n + proj1_sig z n))%Q).
- - pose proof (CReal_plus_unfold y z).
- destruct x as [xn limx], y as [yn limy], z as [zn limz]; simpl; simpl in H.
- destruct (QCauchySeq_bounded xn Pos.to_nat limx) as [Ax majx].
- destruct (QCauchySeq_bounded yn Pos.to_nat limy) as [Ay majy].
- destruct (QCauchySeq_bounded zn Pos.to_nat limz) as [Az majz].
- pose proof (CReal_mult_cauchy (fun n => yn (n + (n + 0))%nat + zn (n + (n + 0))%nat)%Q
- (fun n => yn n + zn n)%Q
- xn (Ay + Az) Ax
- (fun p => Pos.to_nat (2 * p)) H limx).
- exists (fun p : positive => (Pos.to_nat (2 * (2 * Pos.max (Ay + Az) Ax * p)))).
- intros p n k H1 H2.
- setoid_replace (xn n * (yn (n + (n + 0))%nat + zn (n + (n + 0))%nat) - xn k * (yn k + zn k))%Q
- with ((yn (n + (n + 0))%nat + zn (n + (n + 0))%nat) * xn n - (yn k + zn k) * xn k)%Q.
- 2: ring.
- assert (Pos.to_nat (2 * Pos.max (Ay + Az) Ax * p) <=
- Pos.to_nat 2 * Pos.to_nat (2 * Pos.max (Ay + Az) Ax * p))%nat.
- { rewrite (Pos2Nat.inj_mul 2).
- rewrite <- (mult_1_l (Pos.to_nat (2 * Pos.max (Ay + Az) Ax * p))).
- rewrite mult_assoc. apply Nat.mul_le_mono_nonneg. auto.
- simpl. auto. apply le_0_n. apply le_refl. }
- apply H0. intro n0. apply (Qle_lt_trans _ (Qabs (yn n0) + Qabs (zn n0))).
- apply Qabs_triangle. rewrite Pos2Z.inj_add.
- rewrite <- Qinv_plus_distr. apply Qplus_lt_le_compat.
- apply majy. apply Qlt_le_weak. apply majz.
- apply majx. rewrite max_l.
- apply H1. rewrite (Pos2Nat.inj_mul 2). apply H3.
- rewrite max_l. apply H2. rewrite (Pos2Nat.inj_mul 2).
- apply H3.
- - destruct x as [xn limx], y as [yn limy], z as [zn limz]; simpl.
- destruct (QCauchySeq_bounded xn Pos.to_nat limx) as [Ax majx].
- destruct (QCauchySeq_bounded yn Pos.to_nat limy) as [Ay majy].
- destruct (QCauchySeq_bounded zn Pos.to_nat limz) as [Az majz].
- simpl.
- exists (fun p : positive => (Pos.to_nat (2 * (Pos.max (Pos.max Ax Ay) Az) * (2 * p)))).
- intros p n k H H0.
- setoid_replace (xn n * (yn n + zn n) -
- (xn (Pos.to_nat (Pos.max Ax Ay)~0 * k)%nat *
- yn (Pos.to_nat (Pos.max Ax Ay)~0 * k)%nat +
- xn (Pos.to_nat (Pos.max Ax Az)~0 * k)%nat *
- zn (Pos.to_nat (Pos.max Ax Az)~0 * k)%nat))%Q
- with (xn n * yn n - (xn (Pos.to_nat (Pos.max Ax Ay)~0 * k)%nat *
- yn (Pos.to_nat (Pos.max Ax Ay)~0 * k)%nat)
- + (xn n * zn n - xn (Pos.to_nat (Pos.max Ax Az)~0 * k)%nat *
- zn (Pos.to_nat (Pos.max Ax Az)~0 * k)%nat))%Q.
- 2: ring.
- apply (Qle_lt_trans _ (Qabs (xn n * yn n - (xn (Pos.to_nat (Pos.max Ax Ay)~0 * k)%nat *
- yn (Pos.to_nat (Pos.max Ax Ay)~0 * k)%nat))
- + Qabs (xn n * zn n - xn (Pos.to_nat (Pos.max Ax Az)~0 * k)%nat *
- zn (Pos.to_nat (Pos.max Ax Az)~0 * k)%nat))).
- apply Qabs_triangle.
- setoid_replace (1#p)%Q with ((1#2*p) + (1#2*p))%Q.
- apply Qplus_lt_le_compat.
- + pose proof (CReal_mult_cauchy xn xn yn Ax Ay Pos.to_nat limx limy).
- apply H1. apply majx. apply majy. rewrite max_l.
- apply (le_trans _ (Pos.to_nat (2 * Pos.max (Pos.max Ax Ay) Az * (2 * p)))).
- rewrite (Pos.mul_comm 2). rewrite <- Pos.mul_assoc.
- rewrite <- (Pos.mul_comm (Pos.max (Pos.max Ax Ay) Az)).
- rewrite <- Pos.mul_assoc.
- rewrite Pos2Nat.inj_mul.
- rewrite (Pos2Nat.inj_mul (Pos.max (Pos.max Ax Ay) Az)).
- apply Nat.mul_le_mono_nonneg. apply le_0_n.
- apply Pos2Nat.inj_le. apply Pos.le_max_l.
- apply le_0_n. apply le_refl. apply H. apply le_refl.
- rewrite max_l. apply (le_trans _ k).
- apply (le_trans _ (Pos.to_nat (2 * Pos.max (Pos.max Ax Ay) Az * (2 * p)))).
- rewrite (Pos.mul_comm 2). rewrite <- Pos.mul_assoc.
- rewrite <- (Pos.mul_comm (Pos.max (Pos.max Ax Ay) Az)).
- rewrite <- Pos.mul_assoc.
- rewrite Pos2Nat.inj_mul.
- rewrite (Pos2Nat.inj_mul (Pos.max (Pos.max Ax Ay) Az)).
- apply Nat.mul_le_mono_nonneg. apply le_0_n.
- apply Pos2Nat.inj_le. apply Pos.le_max_l.
- apply le_0_n. apply le_refl. apply H0.
- rewrite <- (mult_1_l k). rewrite mult_assoc.
- apply Nat.mul_le_mono_nonneg. auto.
- rewrite mult_1_r. apply Pos2Nat.is_pos. apply le_0_n.
- apply le_refl. apply le_refl.
- + apply Qlt_le_weak.
- pose proof (CReal_mult_cauchy xn xn zn Ax Az Pos.to_nat limx limz).
- apply H1. apply majx. apply majz. rewrite max_l. 2: apply le_refl.
- apply (le_trans _ (Pos.to_nat (2 * Pos.max (Pos.max Ax Ay) Az * (2 * p)))).
- rewrite (Pos.mul_comm 2). rewrite <- Pos.mul_assoc.
- rewrite <- (Pos.mul_comm (Pos.max (Pos.max Ax Ay) Az)).
- rewrite <- Pos.mul_assoc.
- rewrite Pos2Nat.inj_mul.
- rewrite (Pos2Nat.inj_mul (Pos.max (Pos.max Ax Ay) Az)).
- apply Nat.mul_le_mono_nonneg. apply le_0_n.
- rewrite <- Pos.max_assoc. rewrite (Pos.max_comm Ay Az).
- rewrite Pos.max_assoc. apply Pos2Nat.inj_le. apply Pos.le_max_l.
- apply le_0_n. apply le_refl. apply H.
- rewrite max_l. apply (le_trans _ k).
- apply (le_trans _ (Pos.to_nat (2 * Pos.max (Pos.max Ax Ay) Az * (2 * p)))).
- rewrite (Pos.mul_comm 2). rewrite <- Pos.mul_assoc.
- rewrite <- (Pos.mul_comm (Pos.max (Pos.max Ax Ay) Az)).
- rewrite <- Pos.mul_assoc.
- rewrite Pos2Nat.inj_mul.
- rewrite (Pos2Nat.inj_mul (Pos.max (Pos.max Ax Ay) Az)).
- apply Nat.mul_le_mono_nonneg. apply le_0_n.
- rewrite <- Pos.max_assoc. rewrite (Pos.max_comm Ay Az).
- rewrite Pos.max_assoc. apply Pos2Nat.inj_le. apply Pos.le_max_l.
- apply le_0_n. apply le_refl. apply H0.
- rewrite <- (mult_1_l k). rewrite mult_assoc.
- apply Nat.mul_le_mono_nonneg. auto.
- rewrite mult_1_r. apply Pos2Nat.is_pos. apply le_0_n.
- apply le_refl. apply le_refl.
- + rewrite Qinv_plus_distr. unfold Qeq. reflexivity.
-Qed.
-
-Lemma CReal_mult_plus_distr_r : forall r1 r2 r3 : CReal,
- (r2 + r3) * r1 == (r2 * r1) + (r3 * r1).
-Proof.
- intros.
- rewrite CReal_mult_comm, CReal_mult_plus_distr_l,
- <- (CReal_mult_comm r1), <- (CReal_mult_comm r1).
- reflexivity.
-Qed.
-
-Lemma CReal_mult_1_l : forall r: CReal, 1 * r == r.
-Proof.
- intros [rn limr]. split.
- - intros [m maj]. simpl in maj.
- destruct (QCauchySeq_bounded (fun _ : nat => 1%Q) Pos.to_nat (ConstCauchy 1)).
- destruct (QCauchySeq_bounded rn Pos.to_nat limr).
- simpl in maj. rewrite Qmult_1_l in maj.
- specialize (limr m).
- apply (Qlt_not_le (2 # m) (1 # m)).
- apply (Qlt_trans _ (rn (Pos.to_nat m) - rn (Pos.to_nat (Pos.max x x0)~0 * Pos.to_nat m)%nat)).
- apply maj.
- apply (Qle_lt_trans _ (Qabs (rn (Pos.to_nat m) - rn (Pos.to_nat (Pos.max x x0)~0 * Pos.to_nat m)%nat))).
- apply Qle_Qabs. apply limr. apply le_refl.
- rewrite <- (mult_1_l (Pos.to_nat m)). rewrite mult_assoc.
- apply Nat.mul_le_mono_nonneg. auto. rewrite mult_1_r.
- apply Pos2Nat.is_pos. apply le_0_n. apply le_refl.
- apply Z.mul_le_mono_nonneg. discriminate. discriminate.
- discriminate. apply Z.le_refl.
- - intros [m maj]. simpl in maj.
- destruct (QCauchySeq_bounded (fun _ : nat => 1%Q) Pos.to_nat (ConstCauchy 1)).
- destruct (QCauchySeq_bounded rn Pos.to_nat limr).
- simpl in maj. rewrite Qmult_1_l in maj.
- specialize (limr m).
- apply (Qlt_not_le (2 # m) (1 # m)).
- apply (Qlt_trans _ (rn (Pos.to_nat (Pos.max x x0)~0 * Pos.to_nat m)%nat - rn (Pos.to_nat m))).
- apply maj.
- apply (Qle_lt_trans _ (Qabs (rn (Pos.to_nat (Pos.max x x0)~0 * Pos.to_nat m)%nat - rn (Pos.to_nat m)))).
- apply Qle_Qabs. apply limr.
- rewrite <- (mult_1_l (Pos.to_nat m)). rewrite mult_assoc.
- apply Nat.mul_le_mono_nonneg. auto. rewrite mult_1_r.
- apply Pos2Nat.is_pos. apply le_0_n. apply le_refl.
- apply le_refl. apply Z.mul_le_mono_nonneg. discriminate. discriminate.
- discriminate. apply Z.le_refl.
-Qed.
-
-Lemma CReal_isRingExt : ring_eq_ext CReal_plus CReal_mult CReal_opp CRealEq.
-Proof.
- split.
- - intros x y H z t H0. apply CReal_plus_morph; assumption.
- - intros x y H z t H0. apply (CRealEq_trans _ (CReal_mult x t)).
- apply CReal_mult_proper_l. apply H0.
- apply (CRealEq_trans _ (CReal_mult t x)). apply CReal_mult_comm.
- apply (CRealEq_trans _ (CReal_mult t y)).
- apply CReal_mult_proper_l. apply H. apply CReal_mult_comm.
- - intros x y H. apply (CReal_plus_eq_reg_l x).
- apply (CRealEq_trans _ (inject_Q 0)). apply CReal_plus_opp_r.
- apply (CRealEq_trans _ (CReal_plus y (CReal_opp y))).
- apply CRealEq_sym. apply CReal_plus_opp_r.
- apply CReal_plus_proper_r. apply CRealEq_sym. apply H.
-Qed.
-
-Lemma CReal_isRing : ring_theory (inject_Q 0) (inject_Q 1)
- CReal_plus CReal_mult
- CReal_minus CReal_opp
- CRealEq.
-Proof.
- intros. split.
- - apply CReal_plus_0_l.
- - apply CReal_plus_comm.
- - intros x y z. symmetry. apply CReal_plus_assoc.
- - apply CReal_mult_1_l.
- - apply CReal_mult_comm.
- - intros x y z. symmetry. apply CReal_mult_assoc.
- - intros x y z. rewrite <- (CReal_mult_comm z).
- rewrite CReal_mult_plus_distr_l.
- apply (CRealEq_trans _ (CReal_plus (CReal_mult x z) (CReal_mult z y))).
- apply CReal_plus_proper_r. apply CReal_mult_comm.
- apply CReal_plus_proper_l. apply CReal_mult_comm.
- - intros x y. apply CRealEq_refl.
- - apply CReal_plus_opp_r.
-Qed.
-
-Add Parametric Morphism : CReal_mult
- with signature CRealEq ==> CRealEq ==> CRealEq
- as CReal_mult_morph.
-Proof.
- apply CReal_isRingExt.
-Qed.
-
-Instance CReal_mult_morph_T
- : CMorphisms.Proper
- (CMorphisms.respectful CRealEq (CMorphisms.respectful CRealEq CRealEq)) CReal_mult.
-Proof.
- apply CReal_isRingExt.
-Qed.
-
-Add Parametric Morphism : CReal_opp
- with signature CRealEq ==> CRealEq
- as CReal_opp_morph.
-Proof.
- apply (Ropp_ext CReal_isRingExt).
-Qed.
-
-Instance CReal_opp_morph_T
- : CMorphisms.Proper
- (CMorphisms.respectful CRealEq CRealEq) CReal_opp.
-Proof.
- apply CReal_isRingExt.
-Qed.
-
-Add Parametric Morphism : CReal_minus
- with signature CRealEq ==> CRealEq ==> CRealEq
- as CReal_minus_morph.
-Proof.
- intros. unfold CReal_minus. rewrite H,H0. reflexivity.
-Qed.
-
-Instance CReal_minus_morph_T
- : CMorphisms.Proper
- (CMorphisms.respectful CRealEq (CMorphisms.respectful CRealEq CRealEq)) CReal_minus.
-Proof.
- intros x y exy z t ezt. unfold CReal_minus. rewrite exy,ezt. reflexivity.
-Qed.
-
-Add Ring CRealRing : CReal_isRing.
-
Lemma CReal_opp_0 : -0 == 0.
Proof.
- ring.
+ apply (CReal_plus_eq_reg_l 0).
+ rewrite CReal_plus_0_r, CReal_plus_opp_r. reflexivity.
Qed.
Lemma CReal_opp_plus_distr : forall r1 r2, - (r1 + r2) == - r1 + - r2.
Proof.
- intros; ring.
+ intros. apply (CReal_plus_eq_reg_l (r1+r2)).
+ rewrite CReal_plus_opp_r, (CReal_plus_comm (-r1)), CReal_plus_assoc.
+ rewrite <- (CReal_plus_assoc r2), CReal_plus_opp_r, CReal_plus_0_l.
+ rewrite CReal_plus_opp_r. reflexivity.
Qed.
Lemma CReal_opp_involutive : forall x:CReal, --x == x.
Proof.
- intro x. ring.
+ intros. apply (CReal_plus_eq_reg_l (-x)).
+ rewrite CReal_plus_opp_l, CReal_plus_opp_r. reflexivity.
Qed.
Lemma CReal_opp_gt_lt_contravar : forall r1 r2, r1 > r2 -> - r1 < - r2.
Proof.
unfold CRealGt; intros.
apply (CReal_plus_lt_reg_l (r2 + r1)).
- setoid_replace (r2 + r1 + - r1) with r2 by ring.
- setoid_replace (r2 + r1 + - r2) with r1 by ring.
- exact H.
-Qed.
-
-(**********)
-Lemma CReal_mult_0_l : forall r, 0 * r == 0.
-Proof.
- intro; ring.
-Qed.
-
-Lemma CReal_mult_0_r : forall r, r * 0 == 0.
-Proof.
- intro; ring.
-Qed.
-
-(**********)
-Lemma CReal_mult_1_r : forall r, r * 1 == r.
-Proof.
- intro; ring.
-Qed.
-
-Lemma CReal_opp_mult_distr_l
- : forall r1 r2 : CReal, CRealEq (CReal_opp (CReal_mult r1 r2))
- (CReal_mult (CReal_opp r1) r2).
-Proof.
- intros. ring.
+ rewrite CReal_plus_assoc, CReal_plus_opp_r, CReal_plus_0_r.
+ rewrite CReal_plus_comm, <- CReal_plus_assoc, CReal_plus_opp_l.
+ rewrite CReal_plus_0_l. exact H.
Qed.
-Lemma CReal_mult_lt_compat_l : forall x y z : CReal,
- 0 < x -> y < z -> x*y < x*z.
+Lemma CReal_opp_ge_le_contravar : forall r1 r2, r1 >= r2 -> - r1 <= - r2.
Proof.
- intros. apply (CReal_plus_lt_reg_l
- (CReal_opp (CReal_mult x y))).
- rewrite CReal_plus_comm. pose proof CReal_plus_opp_r.
- unfold CReal_minus in H1. rewrite H1.
- rewrite CReal_mult_comm, CReal_opp_mult_distr_l, CReal_mult_comm.
- rewrite <- CReal_mult_plus_distr_l.
- apply CReal_mult_lt_0_compat. exact H.
- apply (CReal_plus_lt_reg_l y).
- rewrite CReal_plus_comm, CReal_plus_0_l.
- rewrite <- CReal_plus_assoc, H1, CReal_plus_0_l. exact H0.
+ intros. intro abs. apply H. clear H.
+ apply (CReal_plus_lt_reg_r (-r1-r2)).
+ unfold CReal_minus. rewrite <- CReal_plus_assoc, CReal_plus_opp_r, CReal_plus_0_l.
+ rewrite (CReal_plus_comm (-r1)), <- CReal_plus_assoc, CReal_plus_opp_r, CReal_plus_0_l.
+ exact abs.
Qed.
-Lemma CReal_mult_lt_compat_r : forall x y z : CReal,
- 0 < x -> y < z -> y*x < z*x.
+Lemma inject_Q_plus : forall q r : Q,
+ inject_Q (q + r) == inject_Q q + inject_Q r.
Proof.
- intros. rewrite <- (CReal_mult_comm x), <- (CReal_mult_comm x).
- apply (CReal_mult_lt_compat_l x); assumption.
-Qed.
-
-Lemma CReal_mult_eq_reg_l : forall (r r1 r2 : CReal),
- r # 0
- -> CRealEq (CReal_mult r r1) (CReal_mult r r2)
- -> CRealEq r1 r2.
-Proof.
- intros. destruct H; split.
- - intro abs. apply (CReal_mult_lt_compat_l (-r)) in abs.
- rewrite <- CReal_opp_mult_distr_l, <- CReal_opp_mult_distr_l, H0 in abs.
- exact (CRealLt_irrefl _ abs). apply (CReal_plus_lt_reg_l r).
- rewrite CReal_plus_opp_r, CReal_plus_comm, CReal_plus_0_l. exact c.
- - intro abs. apply (CReal_mult_lt_compat_l (-r)) in abs.
- rewrite <- CReal_opp_mult_distr_l, <- CReal_opp_mult_distr_l, H0 in abs.
- exact (CRealLt_irrefl _ abs). apply (CReal_plus_lt_reg_l r).
- rewrite CReal_plus_opp_r, CReal_plus_comm, CReal_plus_0_l. exact c.
- - intro abs. apply (CReal_mult_lt_compat_l r) in abs. rewrite H0 in abs.
- exact (CRealLt_irrefl _ abs). exact c.
- - intro abs. apply (CReal_mult_lt_compat_l r) in abs. rewrite H0 in abs.
- exact (CRealLt_irrefl _ abs). exact c.
-Qed.
-
-
-
-(*********************************************************)
-(** * Field *)
-(*********************************************************)
-
-(**********)
-Fixpoint INR (n:nat) : CReal :=
- match n with
- | O => 0
- | S O => 1
- | S n => INR n + 1
- end.
-Arguments INR n%nat.
-
-(* compact representation for 2*p *)
-Fixpoint IPR_2 (p:positive) : CReal :=
- match p with
- | xH => 1 + 1
- | xO p => IPR_2 p + IPR_2 p
- | xI p => (1 + IPR_2 p) + (1 + IPR_2 p)
- end.
-
-Definition IPR (p:positive) : CReal :=
- match p with
- | xH => 1
- | xO p => IPR_2 p
- | xI p => 1 + IPR_2 p
- end.
-Arguments IPR p%positive : simpl never.
-
-(**********)
-Definition IZR (z:Z) : CReal :=
- match z with
- | Z0 => 0
- | Zpos n => IPR n
- | Zneg n => - IPR n
- end.
-Arguments IZR z%Z : simpl never.
-
-Notation "2" := (IZR 2) : CReal_scope.
-
-(**********)
-Lemma S_INR : forall n:nat, INR (S n) == INR n + 1.
-Proof.
- intro; destruct n. rewrite CReal_plus_0_l. reflexivity. reflexivity.
-Qed.
-
-Lemma le_succ_r_T : forall n m : nat, (n <= S m)%nat -> {(n <= m)%nat} + {n = S m}.
-Proof.
- intros. destruct (le_lt_dec n m). left. exact l.
- right. apply Nat.le_succ_r in H. destruct H.
- exfalso. apply (le_not_lt n m); assumption. exact H.
-Qed.
-
-Lemma lt_INR : forall n m:nat, (n < m)%nat -> INR n < INR m.
-Proof.
- induction m.
- - intros. exfalso. inversion H.
- - intros. unfold lt in H. apply le_S_n in H. destruct m.
- assert (n = 0)%nat.
- { inversion H. reflexivity. }
- subst n. apply CRealLt_0_1. apply le_succ_r_T in H. destruct H.
- rewrite S_INR. apply (CRealLt_trans _ (INR (S m) + 0)).
- rewrite CReal_plus_comm, CReal_plus_0_l. apply IHm.
- apply le_n_S. exact l.
- apply CReal_plus_lt_compat_l. exact CRealLt_0_1.
- subst n. rewrite (S_INR (S m)). rewrite <- (CReal_plus_0_l).
- rewrite (CReal_plus_comm 0), CReal_plus_assoc.
- apply CReal_plus_lt_compat_l. rewrite CReal_plus_0_l.
- exact CRealLt_0_1.
-Qed.
-
-(**********)
-Lemma S_O_plus_INR : forall n:nat, INR (1 + n) == INR 1 + INR n.
-Proof.
- intros; destruct n.
- - rewrite CReal_plus_comm, CReal_plus_0_l. reflexivity.
- - rewrite CReal_plus_comm. reflexivity.
-Qed.
-
-(**********)
-Lemma plus_INR : forall n m:nat, INR (n + m) == INR n + INR m.
-Proof.
- intros n m; induction n as [| n Hrecn].
- - rewrite CReal_plus_0_l. reflexivity.
- - replace (S n + m)%nat with (S (n + m)); auto with arith.
- repeat rewrite S_INR.
- rewrite Hrecn; ring.
-Qed.
-
-(**********)
-Lemma minus_INR : forall n m:nat, (m <= n)%nat -> INR (n - m) == INR n - INR m.
-Proof.
- intros n m le; pattern m, n; apply le_elim_rel.
- intros. rewrite <- minus_n_O. unfold CReal_minus.
- unfold INR. ring.
- intros; repeat rewrite S_INR; simpl.
- unfold CReal_minus. rewrite H0. ring. exact le.
-Qed.
-
-(*********)
-Lemma mult_INR : forall n m:nat, INR (n * m) == INR n * INR m.
-Proof.
- intros n m; induction n as [| n Hrecn].
- - rewrite CReal_mult_0_l. reflexivity.
- - intros; repeat rewrite S_INR; simpl.
- rewrite plus_INR. rewrite Hrecn; ring.
-Qed.
-
-(**********)
-Lemma IZN : forall n:Z, (0 <= n)%Z -> { m : nat | n = Z.of_nat m }.
-Proof.
- intros. exists (Z.to_nat n). rewrite Z2Nat.id. reflexivity. assumption.
-Qed.
-
-Lemma INR_IPR : forall p, INR (Pos.to_nat p) == IPR p.
-Proof.
- assert (H: forall p, INR (Pos.to_nat p) + INR (Pos.to_nat p) == IPR_2 p).
- { induction p as [p|p|].
- - unfold IPR_2; rewrite Pos2Nat.inj_xI, S_INR, mult_INR, <- IHp.
- setoid_replace (INR 2) with (1 + 1). 2: reflexivity. ring.
- - unfold IPR_2; rewrite Pos2Nat.inj_xO, mult_INR, <- IHp.
- setoid_replace (INR 2) with (1 + 1). 2: reflexivity. ring.
- - reflexivity. }
- intros [p|p|] ; unfold IPR.
- rewrite Pos2Nat.inj_xI, S_INR, mult_INR, <- H.
- setoid_replace (INR 2) with (1 + 1). 2: reflexivity. ring.
- rewrite Pos2Nat.inj_xO, mult_INR, <- H.
- setoid_replace (INR 2) with (1 + 1). 2: reflexivity. ring.
- easy.
-Qed.
-
-(* This is stronger than Req to injectQ, because it
- concerns all the rational sequence, not only its limit. *)
-Lemma FinjectP2_CReal : forall (p:positive) (k:nat),
- (proj1_sig (IPR_2 p) k == Z.pos p~0 # 1)%Q.
-Proof.
- induction p.
- - intros. replace (IPR_2 p~1) with (1 + IPR_2 p + (1+ IPR_2 p)).
- 2: reflexivity. do 2 rewrite CReal_plus_nth. rewrite IHp.
- simpl. rewrite Pos2Z.inj_xO, (Pos2Z.inj_xO (p~1)), Pos2Z.inj_xI.
- generalize (2*Z.pos p)%Z. intro z.
- do 2 rewrite Qinv_plus_distr. apply f_equal2.
- 2: reflexivity. unfold Qnum. ring.
- - intros. replace (IPR_2 p~0) with (IPR_2 p + IPR_2 p).
- 2: reflexivity. rewrite CReal_plus_nth, IHp.
- rewrite Qinv_plus_distr. apply f_equal2. 2: reflexivity.
- unfold Qnum. rewrite (Pos2Z.inj_xO (p~0)). ring.
- - intros. reflexivity.
-Qed.
-
-Lemma FinjectP_CReal : forall (p:positive) (k:nat),
- (proj1_sig (IPR p) k == Z.pos p # 1)%Q.
-Proof.
- destruct p.
- - intros. unfold IPR.
- rewrite CReal_plus_nth, FinjectP2_CReal. unfold Qeq; simpl.
- rewrite Pos.mul_1_r. reflexivity.
- - intros. unfold IPR. rewrite FinjectP2_CReal. reflexivity.
- - intros. reflexivity.
-Qed.
-
-(* Inside this Cauchy real implementation, we can give
- an instantaneous witness of this inequality, because
- we know a priori that it will work. *)
-Lemma IPR_pos : forall p:positive, 0 < IPR p.
-Proof.
- intro p. exists 3%positive. simpl.
- rewrite FinjectP_CReal. apply (Qlt_le_trans _ 1). reflexivity.
- unfold Qle; simpl.
- rewrite <- (Zpos_max_1 (p*1*1)). apply Z.le_max_l.
-Defined.
-
-Lemma IPR_double : forall p:positive, IPR (2*p) == 2 * IPR p.
-Proof.
- intro p.
- destruct p; rewrite (CReal_mult_plus_distr_r _ 1 1), CReal_mult_1_l; reflexivity.
-Qed.
-
-(**********)
-Lemma INR_IZR_INZ : forall n:nat, INR n == IZR (Z.of_nat n).
-Proof.
- intros [|n].
- easy.
- simpl Z.of_nat. unfold IZR.
- now rewrite <- INR_IPR, SuccNat2Pos.id_succ.
-Qed.
-
-Lemma plus_IZR_NEG_POS :
- forall p q:positive, IZR (Zpos p + Zneg q) == IZR (Zpos p) + IZR (Zneg q).
-Proof.
- intros p q; simpl. rewrite Z.pos_sub_spec.
- case Pos.compare_spec; intros H; unfold IZR.
- subst. ring.
- rewrite <- 3!INR_IPR, Pos2Nat.inj_sub.
- rewrite minus_INR.
- 2: (now apply lt_le_weak, Pos2Nat.inj_lt).
- ring.
- trivial.
- rewrite <- 3!INR_IPR, Pos2Nat.inj_sub.
- rewrite minus_INR.
- 2: (now apply lt_le_weak, Pos2Nat.inj_lt).
- ring. trivial.
-Qed.
-
-Lemma plus_IPR : forall n m:positive, IPR (n + m) == IPR n + IPR m.
-Proof.
- intros. repeat rewrite <- INR_IPR.
- rewrite Pos2Nat.inj_add. apply plus_INR.
-Qed.
-
-(**********)
-Lemma plus_IZR : forall n m:Z, IZR (n + m) == IZR n + IZR m.
-Proof.
- intro z; destruct z; intro t; destruct t; intros.
- - rewrite CReal_plus_0_l. reflexivity.
- - rewrite CReal_plus_0_l. rewrite Z.add_0_l. reflexivity.
- - rewrite CReal_plus_0_l. reflexivity.
- - rewrite CReal_plus_comm,CReal_plus_0_l. reflexivity.
- - rewrite <- Pos2Z.inj_add. unfold IZR. apply plus_IPR.
- - apply plus_IZR_NEG_POS.
- - rewrite CReal_plus_comm,CReal_plus_0_l, Z.add_0_r. reflexivity.
- - rewrite Z.add_comm; rewrite CReal_plus_comm; apply plus_IZR_NEG_POS.
- - simpl. unfold IZR. rewrite <- 3!INR_IPR, Pos2Nat.inj_add, plus_INR.
- ring.
-Qed.
-
-Lemma mult_IPR : forall n m:positive, IPR (n * m) == IPR n * IPR m.
-Proof.
- intros. repeat rewrite <- INR_IPR.
- rewrite Pos2Nat.inj_mul. apply mult_INR.
-Qed.
-
-Lemma mult_IZR : forall n m:Z, IZR (n * m) == IZR n * IZR m.
-Proof.
- intros n m. destruct n.
- - rewrite CReal_mult_0_l. rewrite Z.mul_0_l. reflexivity.
- - destruct m. rewrite Z.mul_0_r, CReal_mult_0_r. reflexivity.
- simpl; unfold IZR. apply mult_IPR.
- simpl. unfold IZR. rewrite mult_IPR. ring.
- - destruct m. rewrite Z.mul_0_r, CReal_mult_0_r. reflexivity.
- simpl. unfold IZR. rewrite mult_IPR. ring.
- simpl. unfold IZR. rewrite mult_IPR. ring.
-Qed.
-
-Lemma opp_IZR : forall n:Z, IZR (- n) == - IZR n.
-Proof.
- intros [|z|z]; unfold IZR. rewrite CReal_opp_0. reflexivity.
- reflexivity. rewrite CReal_opp_involutive. reflexivity.
-Qed.
-
-Lemma minus_IZR : forall n m:Z, IZR (n - m) == IZR n - IZR m.
-Proof.
- intros; unfold Z.sub, CReal_minus.
- rewrite <- opp_IZR.
- apply plus_IZR.
-Qed.
-
-Lemma IZR_lt : forall n m:Z, (n < m)%Z -> IZR n < IZR m.
-Proof.
- assert (forall n:Z, Z.lt 0 n -> 0 < IZR n) as posCase.
- { intros. destruct (IZN n). apply Z.lt_le_incl. apply H.
- subst n. rewrite <- INR_IZR_INZ. apply (lt_INR 0).
- apply Nat2Z.inj_lt. apply H. }
- intros. apply (CReal_plus_lt_reg_r (-(IZR n))).
- pose proof minus_IZR. unfold CReal_minus in H0.
- repeat rewrite <- H0. unfold Zminus.
- rewrite Z.add_opp_diag_r. apply posCase.
- rewrite (Z.add_lt_mono_l _ _ n). ring_simplify. apply H.
-Qed.
-
-Lemma Z_R_minus : forall n m:Z, IZR n - IZR m == IZR (n - m).
-Proof.
- intros z1 z2; unfold CReal_minus; unfold Z.sub.
- rewrite plus_IZR, opp_IZR. reflexivity.
-Qed.
-
-Lemma lt_0_IZR : forall n:Z, 0 < IZR n -> (0 < n)%Z.
-Proof.
- intro z; case z; simpl; intros.
- elim (CRealLt_irrefl _ H).
- easy. exfalso.
- apply (CRealLt_asym 0 (IZR (Z.neg p))). exact H.
- apply (IZR_lt (Z.neg p) 0). reflexivity.
-Qed.
-
-Lemma lt_IZR : forall n m:Z, IZR n < IZR m -> (n < m)%Z.
-Proof.
- intros z1 z2 H; apply Z.lt_0_sub.
- apply lt_0_IZR.
- rewrite <- Z_R_minus. apply (CReal_plus_lt_reg_l (IZR z1)).
- ring_simplify. exact H.
-Qed.
-
-Lemma IZR_le : forall n m:Z, (n <= m)%Z -> IZR n <= IZR m.
-Proof.
- intros m n H. intro abs. apply (lt_IZR n m) in abs. omega.
-Qed.
-
-Lemma CReal_iterate_one : forall (n : nat),
- IZR (Z.of_nat n) == inject_Q (Z.of_nat n # 1).
-Proof.
- induction n.
- - apply CRealEq_refl.
- - replace (Z.of_nat (S n)) with (1 + Z.of_nat n)%Z.
- rewrite plus_IZR.
- rewrite IHn. clear IHn. apply CRealEq_diff. intro k. simpl.
- rewrite Z.mul_1_r. rewrite Z.mul_1_r. rewrite Z.mul_1_r.
- rewrite Z.add_opp_diag_r. discriminate.
- replace (S n) with (1 + n)%nat. 2: reflexivity.
- rewrite (Nat2Z.inj_add 1 n). reflexivity.
-Qed.
-
-(* The constant sequences of rationals are CRealEq to
- the rational operations on the unity. *)
-Lemma FinjectZ_CReal : forall z : Z,
- IZR z == inject_Q (z # 1).
-Proof.
- intros. destruct z.
- - apply CRealEq_refl.
- - simpl. pose proof (CReal_iterate_one (Pos.to_nat p)).
- rewrite positive_nat_Z in H. apply H.
- - simpl. apply (CReal_plus_eq_reg_l (IZR (Z.pos p))).
- pose proof CReal_plus_opp_r. rewrite H.
- pose proof (CReal_iterate_one (Pos.to_nat p)).
- rewrite positive_nat_Z in H0. rewrite H0.
- apply CRealEq_diff. intro n. simpl. rewrite Z.pos_sub_diag.
- discriminate.
-Qed.
-
-
-(* Axiom Rarchimed_constr *)
-Lemma Rarchimedean
- : forall x:CReal,
- { n:Z & x < IZR n < x+2 }.
-Proof.
- (* Locate x within 1/4 and pick the first integer above this interval. *)
- intros [xn limx].
- pose proof (Qlt_floor (xn 4%nat + (1#4))). unfold inject_Z in H.
- pose proof (Qfloor_le (xn 4%nat + (1#4))). unfold inject_Z in H0.
- remember (Qfloor (xn 4%nat + (1#4)))%Z as n.
- exists (n+1)%Z. split.
- - rewrite FinjectZ_CReal.
- assert (Qlt 0 ((n + 1 # 1) - (xn 4%nat + (1 # 4)))) as epsPos.
- { unfold Qminus. rewrite <- Qlt_minus_iff. exact H. }
- destruct (Qarchimedean (/((1#2)*((n + 1 # 1) - (xn 4%nat + (1 # 4)))))) as [k kmaj].
- exists (Pos.max 4 k). simpl.
- apply (Qlt_trans _ ((n + 1 # 1) - (xn 4%nat + (1 # 4)))).
- + setoid_replace (Z.pos k # 1)%Q with (/(1#k))%Q in kmaj. 2: reflexivity.
- rewrite <- Qinv_lt_contravar in kmaj. 2: reflexivity.
- apply (Qle_lt_trans _ (2#k)).
- rewrite <- (Qmult_le_l _ _ (1#2)).
- setoid_replace ((1 # 2) * (2 # k))%Q with (1#k)%Q. 2: reflexivity.
- setoid_replace ((1 # 2) * (2 # Pos.max 4 k))%Q with (1#Pos.max 4 k)%Q. 2: reflexivity.
- unfold Qle; simpl. apply Pos2Z.pos_le_pos. apply Pos.le_max_r.
- reflexivity.
- rewrite <- (Qmult_lt_l _ _ (1#2)).
- setoid_replace ((1 # 2) * (2 # k))%Q with (1#k)%Q. exact kmaj.
- reflexivity. reflexivity. rewrite <- (Qmult_0_r (1#2)).
- rewrite Qmult_lt_l. exact epsPos. reflexivity.
- + rewrite <- (Qplus_lt_r _ _ (xn (Pos.to_nat (Pos.max 4 k)) - (n + 1 # 1) + (1#4))).
- ring_simplify.
- apply (Qle_lt_trans _ (Qabs (xn (Pos.to_nat (Pos.max 4 k)) - xn 4%nat))).
- apply Qle_Qabs. apply limx.
- rewrite Pos2Nat.inj_max. apply Nat.le_max_l. apply le_refl.
- - apply (CReal_plus_lt_reg_l (-IZR 2)). ring_simplify.
- do 2 rewrite FinjectZ_CReal.
- exists 4%positive. simpl.
- rewrite <- Qinv_plus_distr.
- rewrite <- (Qplus_lt_r _ _ ((n#1) - (1#2))). ring_simplify.
- apply (Qle_lt_trans _ (xn 4%nat + (1 # 4)) _ H0).
- unfold Pos.to_nat; simpl.
- rewrite <- (Qplus_lt_r _ _ (-xn 4%nat)). ring_simplify.
- reflexivity.
-Qed.
-
-Lemma CRealLtDisjunctEpsilon : forall a b c d : CReal,
- (CRealLtProp a b \/ CRealLtProp c d) -> CRealLt a b + CRealLt c d.
-Proof.
- intros.
- assert (exists n : nat, n <> O /\
- (Qlt (2 # Pos.of_nat n) (proj1_sig b n - proj1_sig a n)
- \/ Qlt (2 # Pos.of_nat n) (proj1_sig d n - proj1_sig c n))).
- { destruct H. destruct H as [n maj]. exists (Pos.to_nat n). split.
- intro abs. destruct (Pos2Nat.is_succ n). rewrite H in abs.
- inversion abs. left. rewrite Pos2Nat.id. apply maj.
- destruct H as [n maj]. exists (Pos.to_nat n). split.
- intro abs. destruct (Pos2Nat.is_succ n). rewrite H in abs.
- inversion abs. right. rewrite Pos2Nat.id. apply maj. }
- apply constructive_indefinite_ground_description_nat in H0.
- - destruct H0 as [n [nPos maj]].
- destruct (Qlt_le_dec (2 # Pos.of_nat n)
- (proj1_sig b n - proj1_sig a n)).
- left. exists (Pos.of_nat n). rewrite Nat2Pos.id. apply q. apply nPos.
- assert (2 # Pos.of_nat n < proj1_sig d n - proj1_sig c n)%Q.
- destruct maj. exfalso.
- apply (Qlt_not_le (2 # Pos.of_nat n) (proj1_sig b n - proj1_sig a n)); assumption.
- assumption. clear maj. right. exists (Pos.of_nat n). rewrite Nat2Pos.id.
- apply H0. apply nPos.
- - clear H0. clear H. intro n. destruct n. right.
- intros [abs _]. exact (abs (eq_refl O)).
- destruct (Qlt_le_dec (2 # Pos.of_nat (S n)) (proj1_sig b (S n) - proj1_sig a (S n))).
- left. split. discriminate. left. apply q.
- destruct (Qlt_le_dec (2 # Pos.of_nat (S n)) (proj1_sig d (S n) - proj1_sig c (S n))).
- left. split. discriminate. right. apply q0.
- right. intros [_ [abs|abs]].
- apply (Qlt_not_le (2 # Pos.of_nat (S n))
- (proj1_sig b (S n) - proj1_sig a (S n))); assumption.
- apply (Qlt_not_le (2 # Pos.of_nat (S n))
- (proj1_sig d (S n) - proj1_sig c (S n))); assumption.
-Qed.
-
-Lemma CRealShiftReal : forall (x : CReal) (k : nat),
- QCauchySeq (fun n => proj1_sig x (plus n k)) Pos.to_nat.
-Proof.
- intros x k n p q H H0.
- destruct x as [xn cau]; unfold proj1_sig.
- destruct k. rewrite plus_0_r. rewrite plus_0_r. apply cau; assumption.
- specialize (cau (n + Pos.of_nat (S k))%positive (p + S k)%nat (q + S k)%nat).
- apply (Qlt_trans _ (1 # n + Pos.of_nat (S k))).
- apply cau. rewrite Pos2Nat.inj_add. rewrite Nat2Pos.id.
- apply Nat.add_le_mono_r. apply H. discriminate.
- rewrite Pos2Nat.inj_add. rewrite Nat2Pos.id.
- apply Nat.add_le_mono_r. apply H0. discriminate.
- apply Pos2Nat.inj_lt; simpl. rewrite Pos2Nat.inj_add.
- rewrite <- (plus_0_r (Pos.to_nat n)). rewrite <- plus_assoc.
- apply Nat.add_lt_mono_l. apply Pos2Nat.is_pos.
-Qed.
-
-Lemma CRealShiftEqual : forall (x : CReal) (k : nat),
- CRealEq x (exist _ (fun n => proj1_sig x (plus n k)) (CRealShiftReal x k)).
-Proof.
- intros. split.
- - intros [n maj]. destruct x as [xn cau]; simpl in maj.
- specialize (cau n (Pos.to_nat n + k)%nat (Pos.to_nat n)).
- apply Qlt_not_le in maj. apply maj. clear maj.
- apply (Qle_trans _ (Qabs (xn (Pos.to_nat n + k)%nat - xn (Pos.to_nat n)))).
- apply Qle_Qabs. apply (Qle_trans _ (1#n)). apply Zlt_le_weak.
- apply cau. rewrite <- (plus_0_r (Pos.to_nat n)).
- rewrite <- plus_assoc. apply Nat.add_le_mono_l. apply le_0_n.
- apply le_refl. apply Z.mul_le_mono_pos_r. apply Pos2Z.is_pos.
- discriminate.
- - intros [n maj]. destruct x as [xn cau]; simpl in maj.
- specialize (cau n (Pos.to_nat n) (Pos.to_nat n + k)%nat).
- apply Qlt_not_le in maj. apply maj. clear maj.
- apply (Qle_trans _ (Qabs (xn (Pos.to_nat n) - xn (Pos.to_nat n + k)%nat))).
- apply Qle_Qabs. apply (Qle_trans _ (1#n)). apply Zlt_le_weak.
- apply cau. apply le_refl. rewrite <- (plus_0_r (Pos.to_nat n)).
- rewrite <- plus_assoc. apply Nat.add_le_mono_l. apply le_0_n.
- apply Z.mul_le_mono_pos_r. apply Pos2Z.is_pos. discriminate.
-Qed.
-
-(* Find an equal negative real number, which rational sequence
- stays below 0, so that it can be inversed. *)
-Definition CRealNegShift (x : CReal)
- : CRealLt x (inject_Q 0)
- -> { y : prod positive CReal | CRealEq x (snd y)
- /\ forall n:nat, Qlt (proj1_sig (snd y) n) (-1 # fst y) }.
-Proof.
- intro xNeg.
- pose proof (CRealLt_aboveSig x (inject_Q 0)).
- pose proof (CRealShiftReal x).
- pose proof (CRealShiftEqual x).
- destruct xNeg as [n maj], x as [xn cau]; simpl in maj.
- specialize (H n maj); simpl in H.
- destruct (Qarchimedean (/ (0 - xn (Pos.to_nat n) - (2 # n)))) as [a _].
- remember (Pos.max n a~0) as k.
- clear Heqk. clear maj. clear n.
- exists (pair k
- (exist _ (fun n => xn (plus n (Pos.to_nat k))) (H0 (Pos.to_nat k)))).
- split. apply H1. intro n. simpl. apply Qlt_minus_iff.
- destruct n.
- - specialize (H k).
- unfold Qminus in H. rewrite Qplus_0_l in H. apply Qlt_minus_iff in H.
- unfold Qminus. rewrite Qplus_comm.
- apply (Qlt_trans _ (- xn (Pos.to_nat k)%nat - (2 #k))). apply H.
- unfold Qminus. simpl. apply Qplus_lt_r.
- apply Z.mul_lt_mono_pos_r. simpl. apply Pos2Z.is_pos.
- reflexivity. apply Pos.le_refl.
- - apply (Qlt_trans _ (-(2 # k) - xn (S n + Pos.to_nat k)%nat)).
- rewrite <- (Nat2Pos.id (S n)). rewrite <- Pos2Nat.inj_add.
- specialize (H (Pos.of_nat (S n) + k)%positive).
- unfold Qminus in H. rewrite Qplus_0_l in H. apply Qlt_minus_iff in H.
- unfold Qminus. rewrite Qplus_comm. apply H. apply Pos2Nat.inj_le.
- rewrite <- (plus_0_l (Pos.to_nat k)). rewrite Pos2Nat.inj_add.
- apply Nat.add_le_mono_r. apply le_0_n. discriminate.
- apply Qplus_lt_l.
- apply Z.mul_lt_mono_pos_r. simpl. apply Pos2Z.is_pos.
- reflexivity.
-Qed.
-
-Definition CRealPosShift (x : CReal)
- : CRealLt (inject_Q 0) x
- -> { y : prod positive CReal | CRealEq x (snd y)
- /\ forall n:nat, Qlt (1 # fst y) (proj1_sig (snd y) n) }.
-Proof.
- intro xPos.
- pose proof (CRealLt_aboveSig (inject_Q 0) x).
- pose proof (CRealShiftReal x).
- pose proof (CRealShiftEqual x).
- destruct xPos as [n maj], x as [xn cau]; simpl in maj.
- simpl in H. specialize (H n).
- destruct (Qarchimedean (/ (xn (Pos.to_nat n) - 0 - (2 # n)))) as [a _].
- specialize (H maj); simpl in H.
- remember (Pos.max n a~0) as k.
- clear Heqk. clear maj. clear n.
- exists (pair k
- (exist _ (fun n => xn (plus n (Pos.to_nat k))) (H0 (Pos.to_nat k)))).
- split. apply H1. intro n. simpl. apply Qlt_minus_iff.
- destruct n.
- - specialize (H k).
- unfold Qminus in H. rewrite Qplus_0_r in H.
- simpl. rewrite <- Qlt_minus_iff.
- apply (Qlt_trans _ (2 #k)).
- apply Z.mul_lt_mono_pos_r. simpl. apply Pos2Z.is_pos.
- reflexivity. apply H. apply Pos.le_refl.
- - rewrite <- Qlt_minus_iff. apply (Qlt_trans _ (2 # k)).
- apply Z.mul_lt_mono_pos_r. simpl. apply Pos2Z.is_pos.
- reflexivity. specialize (H (Pos.of_nat (S n) + k)%positive).
- unfold Qminus in H. rewrite Qplus_0_r in H.
- rewrite Pos2Nat.inj_add in H. rewrite Nat2Pos.id in H.
- apply H. apply Pos2Nat.inj_le.
- rewrite <- (plus_0_l (Pos.to_nat k)). rewrite Pos2Nat.inj_add.
- apply Nat.add_le_mono_r. apply le_0_n. discriminate.
-Qed.
-
-Lemma CReal_inv_neg : forall (yn : nat -> Q) (k : positive),
- (QCauchySeq yn Pos.to_nat)
- -> (forall n : nat, yn n < -1 # k)%Q
- -> QCauchySeq (fun n : nat => / yn (Pos.to_nat k ^ 2 * n)%nat) Pos.to_nat.
-Proof.
- (* Prove the inverse sequence is Cauchy *)
- intros yn k cau maj n p q H0 H1.
- setoid_replace (/ yn (Pos.to_nat k ^ 2 * p)%nat -
- / yn (Pos.to_nat k ^ 2 * q)%nat)%Q
- with ((yn (Pos.to_nat k ^ 2 * q)%nat -
- yn (Pos.to_nat k ^ 2 * p)%nat)
- / (yn (Pos.to_nat k ^ 2 * q)%nat *
- yn (Pos.to_nat k ^ 2 * p)%nat)).
- + apply (Qle_lt_trans _ (Qabs (yn (Pos.to_nat k ^ 2 * q)%nat
- - yn (Pos.to_nat k ^ 2 * p)%nat)
- / (1 # (k^2)))).
- assert (1 # k ^ 2
- < Qabs (yn (Pos.to_nat k ^ 2 * q)%nat * yn (Pos.to_nat k ^ 2 * p)%nat))%Q.
- { rewrite Qabs_Qmult. unfold "^"%positive; simpl.
- rewrite factorDenom. rewrite Pos.mul_1_r.
- apply (Qlt_trans _ ((1#k) * Qabs (yn (Pos.to_nat k * (Pos.to_nat k * 1) * p)%nat))).
- apply Qmult_lt_l. reflexivity. rewrite Qabs_neg.
- specialize (maj (Pos.to_nat k * (Pos.to_nat k * 1) * p)%nat).
- apply Qlt_minus_iff in maj. apply Qlt_minus_iff.
- rewrite Qplus_comm. setoid_replace (-(1#k))%Q with (-1 # k)%Q. apply maj.
- reflexivity. apply (Qle_trans _ (-1 # k)). apply Zlt_le_weak.
- apply maj. discriminate.
- apply Qmult_lt_r. apply (Qlt_trans 0 (1#k)). reflexivity.
- rewrite Qabs_neg.
- specialize (maj (Pos.to_nat k * (Pos.to_nat k * 1) * p)%nat).
- apply Qlt_minus_iff in maj. apply Qlt_minus_iff.
- rewrite Qplus_comm. setoid_replace (-(1#k))%Q with (-1 # k)%Q. apply maj.
- reflexivity. apply (Qle_trans _ (-1 # k)). apply Zlt_le_weak.
- apply maj. discriminate.
- rewrite Qabs_neg.
- specialize (maj (Pos.to_nat k * (Pos.to_nat k * 1) * q)%nat).
- apply Qlt_minus_iff in maj. apply Qlt_minus_iff.
- rewrite Qplus_comm. setoid_replace (-(1#k))%Q with (-1 # k)%Q. apply maj.
- reflexivity. apply (Qle_trans _ (-1 # k)). apply Zlt_le_weak.
- apply maj. discriminate. }
- unfold Qdiv. rewrite Qabs_Qmult. rewrite Qabs_Qinv.
- rewrite Qmult_comm. rewrite <- (Qmult_comm (/ (1 # k ^ 2))).
- apply Qmult_le_compat_r. apply Qlt_le_weak.
- rewrite <- Qmult_1_l. apply Qlt_shift_div_r.
- apply (Qlt_trans 0 (1 # k ^ 2)). reflexivity. apply H.
- rewrite Qmult_comm. apply Qlt_shift_div_l.
- reflexivity. rewrite Qmult_1_l. apply H.
- apply Qabs_nonneg. simpl in maj.
- specialize (cau (n * (k^2))%positive
- (Pos.to_nat k ^ 2 * q)%nat
- (Pos.to_nat k ^ 2 * p)%nat).
- apply Qlt_shift_div_r. reflexivity.
- apply (Qlt_le_trans _ (1 # n * k ^ 2)). apply cau.
- rewrite Pos2Nat.inj_mul. rewrite mult_comm.
- unfold "^"%positive. simpl. rewrite Pos2Nat.inj_mul.
- rewrite <- mult_assoc. rewrite <- mult_assoc.
- apply Nat.mul_le_mono_nonneg_l. apply le_0_n.
- rewrite (mult_1_r). rewrite Pos.mul_1_r.
- apply Nat.mul_le_mono_nonneg_l. apply le_0_n.
- apply (le_trans _ (q+0)). rewrite plus_0_r. assumption.
- rewrite plus_0_r. apply le_refl.
- rewrite Pos2Nat.inj_mul. rewrite mult_comm.
- unfold "^"%positive; simpl. rewrite Pos2Nat.inj_mul.
- rewrite <- mult_assoc. rewrite <- mult_assoc.
- apply Nat.mul_le_mono_nonneg_l. apply le_0_n.
- rewrite (mult_1_r). rewrite Pos.mul_1_r.
- apply Nat.mul_le_mono_nonneg_l. apply le_0_n.
- apply (le_trans _ (p+0)). rewrite plus_0_r. assumption.
- rewrite plus_0_r. apply le_refl.
- rewrite factorDenom. apply Qle_refl.
- + field. split. intro abs.
- specialize (maj (Pos.to_nat k ^ 2 * p)%nat).
- rewrite abs in maj. inversion maj.
- intro abs.
- specialize (maj (Pos.to_nat k ^ 2 * q)%nat).
- rewrite abs in maj. inversion maj.
-Qed.
-
-Lemma CReal_inv_pos : forall (yn : nat -> Q) (k : positive),
- (QCauchySeq yn Pos.to_nat)
- -> (forall n : nat, 1 # k < yn n)%Q
- -> QCauchySeq (fun n : nat => / yn (Pos.to_nat k ^ 2 * n)%nat) Pos.to_nat.
-Proof.
- intros yn k cau maj n p q H0 H1.
- setoid_replace (/ yn (Pos.to_nat k ^ 2 * p)%nat -
- / yn (Pos.to_nat k ^ 2 * q)%nat)%Q
- with ((yn (Pos.to_nat k ^ 2 * q)%nat -
- yn (Pos.to_nat k ^ 2 * p)%nat)
- / (yn (Pos.to_nat k ^ 2 * q)%nat *
- yn (Pos.to_nat k ^ 2 * p)%nat)).
- + apply (Qle_lt_trans _ (Qabs (yn (Pos.to_nat k ^ 2 * q)%nat
- - yn (Pos.to_nat k ^ 2 * p)%nat)
- / (1 # (k^2)))).
- assert (1 # k ^ 2
- < Qabs (yn (Pos.to_nat k ^ 2 * q)%nat * yn (Pos.to_nat k ^ 2 * p)%nat))%Q.
- { rewrite Qabs_Qmult. unfold "^"%positive; simpl.
- rewrite factorDenom. rewrite Pos.mul_1_r.
- apply (Qlt_trans _ ((1#k) * Qabs (yn (Pos.to_nat k * (Pos.to_nat k * 1) * p)%nat))).
- apply Qmult_lt_l. reflexivity. rewrite Qabs_pos.
- specialize (maj (Pos.to_nat k * (Pos.to_nat k * 1) * p)%nat).
- apply maj. apply (Qle_trans _ (1 # k)).
- discriminate. apply Zlt_le_weak. apply maj.
- apply Qmult_lt_r. apply (Qlt_trans 0 (1#k)). reflexivity.
- rewrite Qabs_pos.
- specialize (maj (Pos.to_nat k * (Pos.to_nat k * 1) * p)%nat).
- apply maj. apply (Qle_trans _ (1 # k)). discriminate.
- apply Zlt_le_weak. apply maj.
- rewrite Qabs_pos.
- specialize (maj (Pos.to_nat k * (Pos.to_nat k * 1) * q)%nat).
- apply maj. apply (Qle_trans _ (1 # k)). discriminate.
- apply Zlt_le_weak. apply maj. }
- unfold Qdiv. rewrite Qabs_Qmult. rewrite Qabs_Qinv.
- rewrite Qmult_comm. rewrite <- (Qmult_comm (/ (1 # k ^ 2))).
- apply Qmult_le_compat_r. apply Qlt_le_weak.
- rewrite <- Qmult_1_l. apply Qlt_shift_div_r.
- apply (Qlt_trans 0 (1 # k ^ 2)). reflexivity. apply H.
- rewrite Qmult_comm. apply Qlt_shift_div_l.
- reflexivity. rewrite Qmult_1_l. apply H.
- apply Qabs_nonneg. simpl in maj.
- specialize (cau (n * (k^2))%positive
- (Pos.to_nat k ^ 2 * q)%nat
- (Pos.to_nat k ^ 2 * p)%nat).
- apply Qlt_shift_div_r. reflexivity.
- apply (Qlt_le_trans _ (1 # n * k ^ 2)). apply cau.
- rewrite Pos2Nat.inj_mul. rewrite mult_comm.
- unfold "^"%positive. simpl. rewrite Pos2Nat.inj_mul.
- rewrite <- mult_assoc. rewrite <- mult_assoc.
- apply Nat.mul_le_mono_nonneg_l. apply le_0_n.
- rewrite (mult_1_r). rewrite Pos.mul_1_r.
- apply Nat.mul_le_mono_nonneg_l. apply le_0_n.
- apply (le_trans _ (q+0)). rewrite plus_0_r. assumption.
- rewrite plus_0_r. apply le_refl.
- rewrite Pos2Nat.inj_mul. rewrite mult_comm.
- unfold "^"%positive; simpl. rewrite Pos2Nat.inj_mul.
- rewrite <- mult_assoc. rewrite <- mult_assoc.
- apply Nat.mul_le_mono_nonneg_l. apply le_0_n.
- rewrite (mult_1_r). rewrite Pos.mul_1_r.
- apply Nat.mul_le_mono_nonneg_l. apply le_0_n.
- apply (le_trans _ (p+0)). rewrite plus_0_r. assumption.
- rewrite plus_0_r. apply le_refl.
- rewrite factorDenom. apply Qle_refl.
- + field. split. intro abs.
- specialize (maj (Pos.to_nat k ^ 2 * p)%nat).
- rewrite abs in maj. inversion maj.
- intro abs.
- specialize (maj (Pos.to_nat k ^ 2 * q)%nat).
- rewrite abs in maj. inversion maj.
-Qed.
-
-Definition CReal_inv (x : CReal) (xnz : x # 0) : CReal.
-Proof.
- destruct xnz as [xNeg | xPos].
- - destruct (CRealNegShift x xNeg) as [[k y] [_ maj]].
- destruct y as [yn cau]; unfold proj1_sig, snd, fst in maj.
- exists (fun n => Qinv (yn (mult (Pos.to_nat k^2) n))).
- apply (CReal_inv_neg yn). apply cau. apply maj.
- - destruct (CRealPosShift x xPos) as [[k y] [_ maj]].
- destruct y as [yn cau]; unfold proj1_sig, snd, fst in maj.
- exists (fun n => Qinv (yn (mult (Pos.to_nat k^2) n))).
- apply (CReal_inv_pos yn). apply cau. apply maj.
-Defined.
-
-Notation "/ x" := (CReal_inv x) (at level 35, right associativity) : CReal_scope.
-
-Lemma CReal_inv_0_lt_compat
- : forall (r : CReal) (rnz : r # 0),
- 0 < r -> 0 < ((/ r) rnz).
-Proof.
- intros. unfold CReal_inv. simpl.
- destruct rnz.
- - exfalso. apply CRealLt_asym in H. contradiction.
- - destruct (CRealPosShift r c) as [[k rpos] [req maj]].
- clear req. destruct rpos as [rn cau]; simpl in maj.
- unfold CRealLt; simpl.
- destruct (Qarchimedean (rn 1%nat)) as [A majA].
- exists (2 * (A + 1))%positive. unfold Qminus. rewrite Qplus_0_r.
- rewrite <- (Qmult_1_l (Qinv (rn (Pos.to_nat k * (Pos.to_nat k * 1) * Pos.to_nat (2 * (A + 1)))%nat))).
- apply Qlt_shift_div_l. apply (Qlt_trans 0 (1#k)). reflexivity.
- apply maj. rewrite <- (Qmult_inv_r (Z.pos A + 1 # 1)).
- setoid_replace (2 # 2 * (A + 1))%Q with (Qinv (Z.pos A + 1 # 1)).
- 2: reflexivity.
- rewrite Qmult_comm. apply Qmult_lt_r. reflexivity.
- rewrite mult_1_r. rewrite <- Pos2Nat.inj_mul. rewrite <- Pos2Nat.inj_mul.
- rewrite <- (Qplus_lt_l _ _ (- rn 1%nat)).
- apply (Qle_lt_trans _ (Qabs (rn (Pos.to_nat (k * k * (2 * (A + 1)))) + - rn 1%nat))).
- apply Qle_Qabs. apply (Qlt_le_trans _ 1). apply cau.
- apply Pos2Nat.is_pos. apply le_refl.
- rewrite <- Qinv_plus_distr. rewrite <- (Qplus_comm 1).
- rewrite <- Qplus_0_r. rewrite <- Qplus_assoc. rewrite <- Qplus_assoc.
- rewrite Qplus_le_r. rewrite Qplus_0_l. apply Qlt_le_weak.
- apply Qlt_minus_iff in majA. apply majA.
- intro abs. inversion abs.
-Qed.
-
-Lemma CReal_linear_shift : forall (x : CReal) (k : nat),
- le 1 k -> QCauchySeq (fun n => proj1_sig x (k * n)%nat) Pos.to_nat.
-Proof.
- intros [xn limx] k lek p n m H H0. unfold proj1_sig.
- apply limx. apply (le_trans _ n). apply H.
- rewrite <- (mult_1_l n). rewrite mult_assoc.
- apply Nat.mul_le_mono_nonneg_r. apply le_0_n.
- rewrite mult_1_r. apply lek. apply (le_trans _ m). apply H0.
- rewrite <- (mult_1_l m). rewrite mult_assoc.
- apply Nat.mul_le_mono_nonneg_r. apply le_0_n.
- rewrite mult_1_r. apply lek.
-Qed.
-
-Lemma CReal_linear_shift_eq : forall (x : CReal) (k : nat) (kPos : le 1 k),
- CRealEq x
- (exist (fun n : nat -> Q => QCauchySeq n Pos.to_nat)
- (fun n : nat => proj1_sig x (k * n)%nat) (CReal_linear_shift x k kPos)).
-Proof.
- intros. apply CRealEq_diff. intro n.
- destruct x as [xn limx]; unfold proj1_sig.
- specialize (limx n (Pos.to_nat n) (k * Pos.to_nat n)%nat).
- apply (Qle_trans _ (1 # n)). apply Qlt_le_weak. apply limx.
- apply le_refl. rewrite <- (mult_1_l (Pos.to_nat n)).
- rewrite mult_assoc. apply Nat.mul_le_mono_nonneg_r. apply le_0_n.
- rewrite mult_1_r. apply kPos. apply Z.mul_le_mono_nonneg_r.
- discriminate. discriminate.
-Qed.
-
-Lemma CReal_inv_l : forall (r:CReal) (rnz : r # 0),
- ((/ r) rnz) * r == 1.
-Proof.
- intros. unfold CReal_inv; simpl.
- destruct rnz.
- - (* r < 0 *) destruct (CRealNegShift r c) as [[k rneg] [req maj]].
- simpl in req. apply CRealEq_diff. apply CRealEq_modindep.
- apply (QSeqEquivEx_trans _
- (proj1_sig (CReal_mult ((let
- (yn, cau) as s
- return ((forall n : nat, proj1_sig s n < -1 # k) -> CReal) := rneg in
- fun maj0 : forall n : nat, yn n < -1 # k =>
- exist (fun x : nat -> Q => QCauchySeq x Pos.to_nat)
- (fun n : nat => Qinv (yn (Pos.to_nat k * (Pos.to_nat k * 1) * n))%nat)
- (CReal_inv_neg yn k cau maj0)) maj) rneg)))%Q.
- + apply CRealEq_modindep. apply CRealEq_diff.
- apply CReal_mult_proper_l. apply req.
- + assert (le 1 (Pos.to_nat k * (Pos.to_nat k * 1))%nat). rewrite mult_1_r.
- rewrite <- Pos2Nat.inj_mul. apply Pos2Nat.is_pos.
- apply (QSeqEquivEx_trans _
- (proj1_sig (CReal_mult ((let
- (yn, cau) as s
- return ((forall n : nat, proj1_sig s n < -1 # k) -> CReal) := rneg in
- fun maj0 : forall n : nat, yn n < -1 # k =>
- exist (fun x : nat -> Q => QCauchySeq x Pos.to_nat)
- (fun n : nat => Qinv (yn (Pos.to_nat k * (Pos.to_nat k * 1) * n)%nat))
- (CReal_inv_neg yn k cau maj0)) maj)
- (exist _ (fun n => proj1_sig rneg (Pos.to_nat k * (Pos.to_nat k * 1) * n)%nat) (CReal_linear_shift rneg _ H)))))%Q.
- apply CRealEq_modindep. apply CRealEq_diff.
- apply CReal_mult_proper_l. apply CReal_linear_shift_eq.
- destruct r as [rn limr], rneg as [rnn limneg]; simpl.
- destruct (QCauchySeq_bounded
- (fun n : nat => Qinv (rnn (Pos.to_nat k * (Pos.to_nat k * 1) * n)%nat))
- Pos.to_nat (CReal_inv_neg rnn k limneg maj)).
- destruct (QCauchySeq_bounded
- (fun n : nat => rnn (Pos.to_nat k * (Pos.to_nat k * 1) * n)%nat)
- Pos.to_nat
- (CReal_linear_shift
- (exist (fun x0 : nat -> Q => QCauchySeq x0 Pos.to_nat) rnn limneg)
- (Pos.to_nat k * (Pos.to_nat k * 1)) H)) ; simpl.
- exists (fun n => 1%nat). intros p n m H0 H1. rewrite Qmult_comm.
- rewrite Qmult_inv_r. unfold Qminus. rewrite Qplus_opp_r.
- reflexivity. intro abs.
- specialize (maj (Pos.to_nat k * (Pos.to_nat k * 1)
- * (Pos.to_nat (Pos.max x x0)~0 * n))%nat).
- simpl in maj. rewrite abs in maj. inversion maj.
- - (* r > 0 *) destruct (CRealPosShift r c) as [[k rneg] [req maj]].
- simpl in req. apply CRealEq_diff. apply CRealEq_modindep.
- apply (QSeqEquivEx_trans _
- (proj1_sig (CReal_mult ((let
- (yn, cau) as s
- return ((forall n : nat, 1 # k < proj1_sig s n) -> CReal) := rneg in
- fun maj0 : forall n : nat, 1 # k < yn n =>
- exist (fun x : nat -> Q => QCauchySeq x Pos.to_nat)
- (fun n : nat => Qinv (yn (Pos.to_nat k * (Pos.to_nat k * 1) * n)%nat))
- (CReal_inv_pos yn k cau maj0)) maj) rneg)))%Q.
- + apply CRealEq_modindep. apply CRealEq_diff.
- apply CReal_mult_proper_l. apply req.
- + assert (le 1 (Pos.to_nat k * (Pos.to_nat k * 1))%nat). rewrite mult_1_r.
- rewrite <- Pos2Nat.inj_mul. apply Pos2Nat.is_pos.
- apply (QSeqEquivEx_trans _
- (proj1_sig (CReal_mult ((let
- (yn, cau) as s
- return ((forall n : nat, 1 # k < proj1_sig s n) -> CReal) := rneg in
- fun maj0 : forall n : nat, 1 # k < yn n =>
- exist (fun x : nat -> Q => QCauchySeq x Pos.to_nat)
- (fun n : nat => Qinv (yn (Pos.to_nat k * (Pos.to_nat k * 1) * n)%nat))
- (CReal_inv_pos yn k cau maj0)) maj)
- (exist _ (fun n => proj1_sig rneg (Pos.to_nat k * (Pos.to_nat k * 1) * n)%nat) (CReal_linear_shift rneg _ H)))))%Q.
- apply CRealEq_modindep. apply CRealEq_diff.
- apply CReal_mult_proper_l. apply CReal_linear_shift_eq.
- destruct r as [rn limr], rneg as [rnn limneg]; simpl.
- destruct (QCauchySeq_bounded
- (fun n : nat => Qinv (rnn (Pos.to_nat k * (Pos.to_nat k * 1) * n)%nat))
- Pos.to_nat (CReal_inv_pos rnn k limneg maj)).
- destruct (QCauchySeq_bounded
- (fun n : nat => rnn (Pos.to_nat k * (Pos.to_nat k * 1) * n)%nat)
- Pos.to_nat
- (CReal_linear_shift
- (exist (fun x0 : nat -> Q => QCauchySeq x0 Pos.to_nat) rnn limneg)
- (Pos.to_nat k * (Pos.to_nat k * 1)) H)) ; simpl.
- exists (fun n => 1%nat). intros p n m H0 H1. rewrite Qmult_comm.
- rewrite Qmult_inv_r. unfold Qminus. rewrite Qplus_opp_r.
- reflexivity. intro abs.
- specialize (maj (Pos.to_nat k * (Pos.to_nat k * 1)
- * (Pos.to_nat (Pos.max x x0)~0 * n))%nat).
- simpl in maj. rewrite abs in maj. inversion maj.
-Qed.
-
-Lemma CReal_inv_r : forall (r:CReal) (rnz : r # 0),
- r * ((/ r) rnz) == 1.
-Proof.
- intros. rewrite CReal_mult_comm, CReal_inv_l.
- reflexivity.
-Qed.
-
-Lemma CReal_inv_1 : forall nz : 1 # 0, (/ 1) nz == 1.
-Proof.
- intros. rewrite <- (CReal_mult_1_l ((/1) nz)). rewrite CReal_inv_r.
- reflexivity.
-Qed.
-
-Lemma CReal_inv_mult_distr :
- forall r1 r2 (r1nz : r1 # 0) (r2nz : r2 # 0) (rmnz : (r1*r2) # 0),
- (/ (r1 * r2)) rmnz == (/ r1) r1nz * (/ r2) r2nz.
-Proof.
- intros. apply (CReal_mult_eq_reg_l r1). exact r1nz.
- rewrite <- CReal_mult_assoc. rewrite CReal_inv_r. rewrite CReal_mult_1_l.
- apply (CReal_mult_eq_reg_l r2). exact r2nz.
- rewrite CReal_inv_r. rewrite <- CReal_mult_assoc.
- rewrite (CReal_mult_comm r2 r1). rewrite CReal_inv_r.
- reflexivity.
-Qed.
-
-Lemma Rinv_eq_compat : forall x y (rxnz : x # 0) (rynz : y # 0),
- x == y
- -> (/ x) rxnz == (/ y) rynz.
-Proof.
- intros. apply (CReal_mult_eq_reg_l x). exact rxnz.
- rewrite CReal_inv_r, H, CReal_inv_r. reflexivity.
-Qed.
-
-Lemma CReal_mult_lt_reg_l : forall r r1 r2, 0 < r -> r * r1 < r * r2 -> r1 < r2.
-Proof.
- intros z x y H H0.
- apply (CReal_mult_lt_compat_l ((/z) (inr H))) in H0.
- repeat rewrite <- CReal_mult_assoc in H0. rewrite CReal_inv_l in H0.
- repeat rewrite CReal_mult_1_l in H0. apply H0.
- apply CReal_inv_0_lt_compat. exact H.
-Qed.
-
-Lemma CReal_mult_lt_reg_r : forall r r1 r2, 0 < r -> r1 * r < r2 * r -> r1 < r2.
-Proof.
- intros.
- apply CReal_mult_lt_reg_l with r.
- exact H.
- now rewrite 2!(CReal_mult_comm r).
-Qed.
-
-Lemma CReal_mult_eq_reg_r : forall r r1 r2, r1 * r == r2 * r -> r # 0 -> r1 == r2.
-Proof.
- intros. apply (CReal_mult_eq_reg_l r). exact H0.
- now rewrite 2!(CReal_mult_comm r).
-Qed.
-
-Lemma CReal_mult_eq_compat_l : forall r r1 r2, r1 == r2 -> r * r1 == r * r2.
-Proof.
- intros. rewrite H. reflexivity.
-Qed.
-
-Lemma CReal_mult_eq_compat_r : forall r r1 r2, r1 == r2 -> r1 * r == r2 * r.
-Proof.
- intros. rewrite H. reflexivity.
-Qed.
-
-Fixpoint pow (r:CReal) (n:nat) : CReal :=
- match n with
- | O => 1
- | S n => r * (pow r n)
- end.
-
-
-(**********)
-Definition IQR (q:Q) : CReal :=
- match q with
- | Qmake a b => IZR a * (CReal_inv (IPR b)) (inr (IPR_pos b))
- end.
-Arguments IQR q%Q : simpl never.
-
-Lemma mult_IPR_IZR : forall (n:positive) (m:Z), IZR (Z.pos n * m) == IPR n * IZR m.
-Proof.
- intros. rewrite mult_IZR. apply CReal_mult_eq_compat_r. reflexivity.
-Qed.
-
-Lemma plus_IQR : forall n m:Q, IQR (n + m) == IQR n + IQR m.
-Proof.
- intros. destruct n,m; unfold Qplus,IQR; simpl.
- rewrite plus_IZR. repeat rewrite mult_IZR.
- setoid_replace ((/ IPR (Qden * Qden0)) (inr (IPR_pos (Qden * Qden0))))
- with ((/ IPR Qden) (inr (IPR_pos Qden))
- * (/ IPR Qden0) (inr (IPR_pos Qden0))).
- rewrite CReal_mult_plus_distr_r.
- repeat rewrite CReal_mult_assoc. rewrite <- (CReal_mult_assoc (IZR (Z.pos Qden))).
- rewrite CReal_inv_r, CReal_mult_1_l.
- rewrite (CReal_mult_comm ((/IPR Qden) (inr (IPR_pos Qden)))).
- rewrite <- (CReal_mult_assoc (IZR (Z.pos Qden0))).
- rewrite CReal_inv_r, CReal_mult_1_l. reflexivity. unfold IZR.
- rewrite <- (CReal_inv_mult_distr
- _ _ _ _ (inr (CReal_mult_lt_0_compat _ _ (IPR_pos _) (IPR_pos _)))).
- apply Rinv_eq_compat. apply mult_IPR.
-Qed.
-
-Lemma IQR_pos : forall q:Q, Qlt 0 q -> 0 < IQR q.
-Proof.
- intros. destruct q; unfold IQR.
- apply CReal_mult_lt_0_compat. apply (IZR_lt 0).
- unfold Qlt in H; simpl in H.
- rewrite Z.mul_1_r in H. apply H.
- apply CReal_inv_0_lt_compat. apply IPR_pos.
+ split.
+ - intros [n nmaj]. simpl in nmaj.
+ ring_simplify in nmaj. discriminate.
+ - intros [n nmaj]. simpl in nmaj.
+ ring_simplify in nmaj. discriminate.
Qed.
-Lemma opp_IQR : forall q:Q, IQR (- q) == - IQR q.
+Lemma inject_Q_one : inject_Q 1 == 1.
Proof.
- intros [a b]; unfold IQR; simpl.
- rewrite CReal_opp_mult_distr_l.
- rewrite opp_IZR. reflexivity.
+ split.
+ - intros [n nmaj]. simpl in nmaj.
+ ring_simplify in nmaj. discriminate.
+ - intros [n nmaj]. simpl in nmaj.
+ ring_simplify in nmaj. discriminate.
Qed.
-Lemma lt_IQR : forall n m:Q, IQR n < IQR m -> (n < m)%Q.
+Lemma inject_Q_lt : forall q r : Q,
+ Qlt q r -> inject_Q q < inject_Q r.
Proof.
- intros. destruct n,m; unfold IQR in H.
- unfold Qlt; simpl. apply (CReal_mult_lt_compat_r (IPR Qden)) in H.
- rewrite CReal_mult_assoc in H. rewrite CReal_inv_l in H.
- rewrite CReal_mult_1_r in H. rewrite (CReal_mult_comm (IZR Qnum0)) in H.
- apply (CReal_mult_lt_compat_l (IPR Qden0)) in H.
- do 2 rewrite <- CReal_mult_assoc in H. rewrite CReal_inv_r in H.
- rewrite CReal_mult_1_l in H.
- rewrite (CReal_mult_comm (IZR Qnum0)) in H.
- do 2 rewrite <- mult_IPR_IZR in H. apply lt_IZR in H.
- rewrite Z.mul_comm. rewrite (Z.mul_comm Qnum0).
- apply H. apply IPR_pos. apply IPR_pos.
+ intros. destruct (Qarchimedean (/(r-q))).
+ exists (2*x)%positive; simpl.
+ setoid_replace (2 # x~0)%Q with (/(Z.pos x#1))%Q. 2: reflexivity.
+ apply Qlt_shift_inv_r. reflexivity.
+ apply (Qmult_lt_l _ _ (r-q)) in q0. rewrite Qmult_inv_r in q0.
+ exact q0. intro abs. rewrite Qlt_minus_iff in H.
+ unfold Qminus in abs. rewrite abs in H. discriminate H.
+ unfold Qminus. rewrite <- Qlt_minus_iff. exact H.
Qed.
-Lemma CReal_mult_le_compat_l_half : forall r r1 r2,
- 0 < r -> r1 <= r2 -> r * r1 <= r * r2.
+Lemma opp_inject_Q : forall q : Q,
+ inject_Q (-q) == - inject_Q q.
Proof.
- intros. intro abs. apply (CReal_mult_lt_reg_l) in abs.
- contradiction. apply H.
+ split.
+ - intros [n maj]. simpl in maj. ring_simplify in maj. discriminate.
+ - intros [n maj]. simpl in maj. ring_simplify in maj. discriminate.
Qed.
-Lemma IQR_lt : forall n m:Q, Qlt n m -> IQR n < IQR m.
+Lemma lt_inject_Q : forall q r : Q,
+ inject_Q q < inject_Q r -> Qlt q r.
Proof.
- intros. apply (CReal_plus_lt_reg_r (-IQR n)).
- rewrite CReal_plus_opp_r. rewrite <- opp_IQR. rewrite <- plus_IQR.
- apply IQR_pos. apply (Qplus_lt_l _ _ n).
- ring_simplify. apply H.
+ intros. destruct H. simpl in q0.
+ apply Qlt_minus_iff, (Qlt_trans _ (2#x)).
+ reflexivity. exact q0.
Qed.
-Lemma IQR_nonneg : forall q:Q, Qle 0 q -> 0 <= (IQR q).
+Lemma le_inject_Q : forall q r : Q,
+ inject_Q q <= inject_Q r -> Qle q r.
Proof.
- intros [a b] H. unfold IQR.
- apply (CRealLe_trans _ ((/ IPR b) (inr (IPR_pos b)) * 0)).
- rewrite CReal_mult_0_r. apply CRealLe_refl.
- rewrite (CReal_mult_comm (IZR a)). apply CReal_mult_le_compat_l_half.
- apply CReal_inv_0_lt_compat. apply IPR_pos.
- apply (IZR_le 0 a). unfold Qle in H; simpl in H.
- rewrite Z.mul_1_r in H. apply H.
+ intros. destruct (Qlt_le_dec r q). 2: exact q0.
+ exfalso. apply H. clear H. apply inject_Q_lt. exact q0.
Qed.
-Lemma IQR_le : forall n m:Q, Qle n m -> IQR n <= IQR m.
+Lemma inject_Q_le : forall q r : Q,
+ Qle q r -> inject_Q q <= inject_Q r.
Proof.
- intros. intro abs. apply (CReal_plus_lt_compat_l (-IQR n)) in abs.
- rewrite CReal_plus_opp_l, <- opp_IQR, <- plus_IQR in abs.
- apply IQR_nonneg in abs. contradiction. apply (Qplus_le_l _ _ n).
- ring_simplify. apply H.
+ intros. intros [n maj]. simpl in maj.
+ apply (Qlt_not_le _ _ maj). apply (Qle_trans _ 0).
+ apply (Qplus_le_l _ _ r). ring_simplify. exact H. discriminate.
Qed.
-
-Add Parametric Morphism : IQR
- with signature Qeq ==> CRealEq
- as IQR_morph.
-Proof.
- intros. destruct x,y; unfold IQR.
- unfold Qeq in H; simpl in H.
- apply (CReal_mult_eq_reg_r (IZR (Z.pos Qden))).
- 2: right; apply IPR_pos.
- rewrite CReal_mult_assoc. rewrite CReal_inv_l. rewrite CReal_mult_1_r.
- rewrite (CReal_mult_comm (IZR Qnum0)).
- apply (CReal_mult_eq_reg_l (IZR (Z.pos Qden0))).
- right; apply IPR_pos.
- rewrite <- CReal_mult_assoc, <- CReal_mult_assoc, CReal_inv_r.
- rewrite CReal_mult_1_l.
- repeat rewrite <- mult_IZR.
- rewrite <- H. rewrite Zmult_comm. reflexivity.
-Qed.
-
-Instance IQR_morph_T
- : CMorphisms.Proper
- (CMorphisms.respectful Qeq CRealEq) IQR.
-Proof.
- intros x y H. destruct x,y; unfold IQR.
- unfold Qeq in H; simpl in H.
- apply (CReal_mult_eq_reg_r (IZR (Z.pos Qden))).
- 2: right; apply IPR_pos.
- rewrite CReal_mult_assoc. rewrite CReal_inv_l. rewrite CReal_mult_1_r.
- rewrite (CReal_mult_comm (IZR Qnum0)).
- apply (CReal_mult_eq_reg_l (IZR (Z.pos Qden0))).
- right; apply IPR_pos.
- rewrite <- CReal_mult_assoc, <- CReal_mult_assoc, CReal_inv_r.
- rewrite CReal_mult_1_l.
- repeat rewrite <- mult_IZR.
- rewrite <- H. rewrite Zmult_comm. reflexivity.
-Qed.
-
-Lemma CReal_invQ : forall (b : positive) (pos : Qlt 0 (Z.pos b # 1)),
- CRealEq (CReal_inv (inject_Q (Z.pos b # 1)) (inr (CReal_injectQPos (Z.pos b # 1) pos)))
- (inject_Q (1 # b)).
-Proof.
- intros.
- apply (CReal_mult_eq_reg_l (inject_Q (Z.pos b # 1))).
- - right. apply CReal_injectQPos. exact pos.
- - rewrite CReal_mult_comm, CReal_inv_l.
- apply CRealEq_diff. intro n. simpl;
- destruct (QCauchySeq_bounded (fun _ : nat => 1 # b)%Q Pos.to_nat (ConstCauchy (1 # b))),
- (QCauchySeq_bounded (fun _ : nat => Z.pos b # 1)%Q Pos.to_nat (ConstCauchy (Z.pos b # 1))); simpl.
- do 2 rewrite Pos.mul_1_r. rewrite Z.pos_sub_diag. discriminate.
-Qed.
-
-(* The constant sequences of rationals are CRealEq to
- the rational operations on the unity. *)
-Lemma FinjectQ_CReal : forall q : Q,
- IQR q == inject_Q q.
-Proof.
- intros [a b]. unfold IQR.
- pose proof (CReal_iterate_one (Pos.to_nat b)).
- rewrite positive_nat_Z in H. simpl in H.
- assert (0 < Z.pos b # 1)%Q as pos. reflexivity.
- apply (CRealEq_trans _ (CReal_mult (IZR a)
- (CReal_inv (inject_Q (Z.pos b # 1)) (inr (CReal_injectQPos (Z.pos b # 1) pos))))).
- - apply CReal_mult_proper_l.
- apply (CReal_mult_eq_reg_l (IPR b)).
- right. apply IPR_pos.
- rewrite CReal_mult_comm, CReal_inv_l, H, CReal_mult_comm, CReal_inv_l. reflexivity.
- - rewrite FinjectZ_CReal. rewrite CReal_invQ. apply CRealEq_diff. intro n.
- simpl;
- destruct (QCauchySeq_bounded (fun _ : nat => a # 1)%Q Pos.to_nat (ConstCauchy (a # 1))),
- (QCauchySeq_bounded (fun _ : nat => 1 # b)%Q Pos.to_nat (ConstCauchy (1 # b))); simpl.
- rewrite Z.mul_1_r. rewrite <- Z.mul_add_distr_r.
- rewrite Z.add_opp_diag_r. rewrite Z.mul_0_l. simpl.
- discriminate.
-Qed.
-
-Lemma CReal_gen_inject : forall (n : nat),
- gen_phiZ (inject_Q 0) (inject_Q 1) CReal_plus CReal_mult CReal_opp
- (Z.of_nat n)
- == inject_Q (Z.of_nat n # 1).
-Proof.
- induction n.
- - apply CRealEq_refl.
- - replace (Z.of_nat (S n)) with (1 + Z.of_nat n)%Z.
- rewrite (gen_phiZ_add CRealEq_rel CReal_isRingExt CReal_isRing).
- rewrite IHn. clear IHn. apply CRealEq_diff. intro k. simpl.
- rewrite Z.mul_1_r. rewrite Z.mul_1_r. rewrite Z.mul_1_r.
- rewrite Z.add_opp_diag_r. discriminate.
- replace (S n) with (1 + n)%nat. 2: reflexivity.
- rewrite (Nat2Z.inj_add 1 n). reflexivity.
-Qed.
-
-Lemma CRealArchimedean
- : forall x:CReal, { n:Z & CRealLt x (gen_phiZ (inject_Q 0) (inject_Q 1) CReal_plus
- CReal_mult CReal_opp n) }.
-Proof.
- intros [xn limx]. destruct (Qarchimedean (xn 1%nat)) as [k kmaj].
- exists (Z.pos (2 + k)). rewrite <- (positive_nat_Z (2 + k)).
- rewrite CReal_gen_inject. rewrite (positive_nat_Z (2 + k)).
- exists xH.
- setoid_replace (2 # 1)%Q with
- ((Z.pos (2 + k) # 1) - (Z.pos k # 1))%Q.
- - apply Qplus_lt_r. apply Qlt_minus_iff. rewrite Qopp_involutive.
- apply Qlt_minus_iff in kmaj. rewrite Qplus_comm. apply kmaj.
- - unfold Qminus. setoid_replace (- (Z.pos k # 1))%Q with (-Z.pos k # 1)%Q.
- 2: reflexivity. rewrite Qinv_plus_distr.
- rewrite Pos2Z.inj_add. rewrite <- Zplus_assoc.
- rewrite Zplus_opp_r. reflexivity.
-Qed.
-
-
-Close Scope CReal_scope.
-
-Close Scope Q.
diff --git a/theories/Reals/ConstructiveCauchyRealsMult.v b/theories/Reals/ConstructiveCauchyRealsMult.v
new file mode 100644
index 0000000000..d6d4e84560
--- /dev/null
+++ b/theories/Reals/ConstructiveCauchyRealsMult.v
@@ -0,0 +1,1415 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2019 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+(************************************************************************)
+
+(* The multiplication and division of Cauchy reals. *)
+
+Require Import QArith.
+Require Import Qabs.
+Require Import Qround.
+Require Import Logic.ConstructiveEpsilon.
+Require Export Reals.ConstructiveCauchyReals.
+Require CMorphisms.
+
+Local Open Scope CReal_scope.
+
+Fixpoint BoundFromZero (qn : nat -> Q) (k : nat) (A : positive) { struct k }
+ : (forall n:nat, le k n -> Qlt (Qabs (qn n)) (Z.pos A # 1))
+ -> { B : positive | forall n:nat, Qlt (Qabs (qn n)) (Z.pos B # 1) }.
+Proof.
+ intro H. destruct k.
+ - exists A. intros. apply H. apply le_0_n.
+ - destruct (Qarchimedean (Qabs (qn k))) as [a maj].
+ apply (BoundFromZero qn k (Pos.max A a)).
+ intros n H0. destruct (Nat.le_gt_cases n k).
+ + pose proof (Nat.le_antisymm n k H1 H0). subst k.
+ apply (Qlt_le_trans _ (Z.pos a # 1)). apply maj.
+ unfold Qle; simpl. rewrite Pos.mul_1_r. rewrite Pos.mul_1_r.
+ apply Pos.le_max_r.
+ + apply (Qlt_le_trans _ (Z.pos A # 1)). apply H.
+ apply H1. unfold Qle; simpl. rewrite Pos.mul_1_r. rewrite Pos.mul_1_r.
+ apply Pos.le_max_l.
+Qed.
+
+Lemma QCauchySeq_bounded (qn : nat -> Q) (cvmod : positive -> nat)
+ : QCauchySeq qn cvmod
+ -> { A : positive | forall n:nat, Qlt (Qabs (qn n)) (Z.pos A # 1) }.
+Proof.
+ intros. remember (Zplus (Qnum (Qabs (qn (cvmod xH)))) 1) as z.
+ assert (Z.lt 0 z) as zPos.
+ { subst z. assert (Qle 0 (Qabs (qn (cvmod 1%positive)))).
+ apply Qabs_nonneg. destruct (Qabs (qn (cvmod 1%positive))). simpl.
+ unfold Qle in H0. simpl in H0. rewrite Zmult_1_r in H0.
+ apply (Z.lt_le_trans 0 1). unfold Z.lt. auto.
+ rewrite <- (Zplus_0_l 1). rewrite Zplus_assoc. apply Zplus_le_compat_r.
+ rewrite Zplus_0_r. assumption. }
+ assert { A : positive | forall n:nat,
+ le (cvmod xH) n -> Qlt ((Qabs (qn n)) * (1#A)) 1 }.
+ destruct z eqn:des.
+ - exfalso. apply (Z.lt_irrefl 0). assumption.
+ - exists p. intros. specialize (H xH (cvmod xH) n (le_refl _) H0).
+ assert (Qlt (Qabs (qn n)) (Qabs (qn (cvmod 1%positive)) + 1)).
+ { apply (Qplus_lt_l _ _ (-Qabs (qn (cvmod 1%positive)))).
+ rewrite <- (Qplus_comm 1). rewrite <- Qplus_assoc. rewrite Qplus_opp_r.
+ rewrite Qplus_0_r. apply (Qle_lt_trans _ (Qabs (qn n - qn (cvmod 1%positive)))).
+ apply Qabs_triangle_reverse. rewrite Qabs_Qminus. assumption. }
+ apply (Qlt_le_trans _ ((Qabs (qn (cvmod 1%positive)) + 1) * (1#p))).
+ apply Qmult_lt_r. unfold Qlt. simpl. unfold Z.lt. auto. assumption.
+ unfold Qle. simpl. rewrite Zmult_1_r. rewrite Zmult_1_r. rewrite Zmult_1_r.
+ rewrite Pos.mul_1_r. rewrite Pos2Z.inj_mul. rewrite Heqz.
+ destruct (Qabs (qn (cvmod 1%positive))) eqn:desAbs.
+ rewrite Z.mul_add_distr_l. rewrite Zmult_1_r.
+ apply Zplus_le_compat_r. rewrite <- (Zmult_1_l (QArith_base.Qnum (Qnum # Qden))).
+ rewrite Zmult_assoc. apply Zmult_le_compat_r. rewrite Zmult_1_r.
+ simpl. unfold Z.le. rewrite <- Pos2Z.inj_compare.
+ unfold Pos.compare. destruct Qden; discriminate.
+ simpl. assert (Qle 0 (Qnum # Qden)). rewrite <- desAbs.
+ apply Qabs_nonneg. unfold Qle in H2. simpl in H2. rewrite Zmult_1_r in H2.
+ assumption.
+ - exfalso. inversion zPos.
+ - destruct H0. apply (BoundFromZero _ (cvmod xH) x). intros n H0.
+ specialize (q n H0). setoid_replace (Z.pos x # 1)%Q with (/(1#x))%Q.
+ rewrite <- (Qmult_1_l (/(1#x))). apply Qlt_shift_div_l.
+ reflexivity. apply q. reflexivity.
+Qed.
+
+Lemma CReal_mult_cauchy
+ : forall (xn yn zn : nat -> Q) (Ay Az : positive) (cvmod : positive -> nat),
+ QSeqEquiv xn yn cvmod
+ -> QCauchySeq zn Pos.to_nat
+ -> (forall n:nat, Qlt (Qabs (yn n)) (Z.pos Ay # 1))
+ -> (forall n:nat, Qlt (Qabs (zn n)) (Z.pos Az # 1))
+ -> QSeqEquiv (fun n:nat => xn n * zn n) (fun n:nat => yn n * zn n)
+ (fun p => max (cvmod (2 * (Pos.max Ay Az) * p)%positive)
+ (Pos.to_nat (2 * (Pos.max Ay Az) * p)%positive)).
+Proof.
+ intros xn yn zn Ay Az cvmod limx limz majy majz.
+ remember (Pos.mul 2 (Pos.max Ay Az)) as z.
+ intros k p q H H0.
+ assert (Pos.to_nat k <> O) as kPos.
+ { intro absurd. pose proof (Pos2Nat.is_pos k).
+ rewrite absurd in H1. inversion H1. }
+ setoid_replace (xn p * zn p - yn q * zn q)%Q
+ with ((xn p - yn q) * zn p + yn q * (zn p - zn q))%Q.
+ 2: ring.
+ apply (Qle_lt_trans _ (Qabs ((xn p - yn q) * zn p)
+ + Qabs (yn q * (zn p - zn q)))).
+ apply Qabs_triangle. rewrite Qabs_Qmult. rewrite Qabs_Qmult.
+ setoid_replace (1#k)%Q with ((1#2*k) + (1#2*k))%Q.
+ apply Qplus_lt_le_compat.
+ - apply (Qle_lt_trans _ ((1#z * k) * Qabs (zn p)%nat)).
+ + apply Qmult_le_compat_r. apply Qle_lteq. left. apply limx.
+ apply (le_trans _ (Init.Nat.max (cvmod (z * k)%positive) (Pos.to_nat (z * k)))).
+ apply Nat.le_max_l. assumption.
+ apply (le_trans _ (Init.Nat.max (cvmod (z * k)%positive) (Pos.to_nat (z * k)))).
+ apply Nat.le_max_l. assumption. apply Qabs_nonneg.
+ + subst z. rewrite <- (Qmult_1_r (1 # 2 * k)).
+ rewrite <- Pos.mul_assoc. rewrite <- (Pos.mul_comm k). rewrite Pos.mul_assoc.
+ rewrite (factorDenom _ _ (2 * k)). rewrite <- Qmult_assoc.
+ apply Qmult_lt_l. unfold Qlt. simpl. unfold Z.lt. auto.
+ apply (Qle_lt_trans _ (Qabs (zn p)%nat * (1 # Az))).
+ rewrite <- (Qmult_comm (1 # Az)). apply Qmult_le_compat_r.
+ unfold Qle. simpl. rewrite Pos2Z.inj_max. apply Z.le_max_r.
+ apply Qabs_nonneg. rewrite <- (Qmult_inv_r (1#Az)).
+ rewrite Qmult_comm. apply Qmult_lt_l. reflexivity.
+ setoid_replace (/(1#Az))%Q with (Z.pos Az # 1)%Q. apply majz.
+ reflexivity. intro abs. inversion abs.
+ - apply (Qle_trans _ ((1 # z * k) * Qabs (yn q)%nat)).
+ + rewrite Qmult_comm. apply Qmult_le_compat_r. apply Qle_lteq.
+ left. apply limz.
+ apply (le_trans _ (max (cvmod (z * k)%positive)
+ (Pos.to_nat (z * k)%positive))).
+ apply Nat.le_max_r. assumption.
+ apply (le_trans _ (max (cvmod (z * k)%positive)
+ (Pos.to_nat (z * k)%positive))).
+ apply Nat.le_max_r. assumption. apply Qabs_nonneg.
+ + subst z. rewrite <- (Qmult_1_r (1 # 2 * k)).
+ rewrite <- Pos.mul_assoc. rewrite <- (Pos.mul_comm k). rewrite Pos.mul_assoc.
+ rewrite (factorDenom _ _ (2 * k)). rewrite <- Qmult_assoc.
+ apply Qle_lteq. left.
+ apply Qmult_lt_l. unfold Qlt. simpl. unfold Z.lt. auto.
+ apply (Qle_lt_trans _ (Qabs (yn q)%nat * (1 # Ay))).
+ rewrite <- (Qmult_comm (1 # Ay)). apply Qmult_le_compat_r.
+ unfold Qle. simpl. rewrite Pos2Z.inj_max. apply Z.le_max_l.
+ apply Qabs_nonneg. rewrite <- (Qmult_inv_r (1#Ay)).
+ rewrite Qmult_comm. apply Qmult_lt_l. reflexivity.
+ setoid_replace (/(1#Ay))%Q with (Z.pos Ay # 1)%Q. apply majy.
+ reflexivity. intro abs. inversion abs.
+ - rewrite Qinv_plus_distr. unfold Qeq. reflexivity.
+Qed.
+
+Lemma linear_max : forall (p Ax Ay : positive) (i : nat),
+ le (Pos.to_nat p) i
+ -> (Init.Nat.max (Pos.to_nat (2 * Pos.max Ax Ay * p))
+ (Pos.to_nat (2 * Pos.max Ax Ay * p)) <= Pos.to_nat (2 * Pos.max Ax Ay) * i)%nat.
+Proof.
+ intros. rewrite max_l. 2: apply le_refl.
+ rewrite Pos2Nat.inj_mul. apply Nat.mul_le_mono_nonneg.
+ apply le_0_n. apply le_refl. apply le_0_n. apply H.
+Qed.
+
+Definition CReal_mult (x y : CReal) : CReal.
+Proof.
+ destruct x as [xn limx]. destruct y as [yn limy].
+ destruct (QCauchySeq_bounded xn Pos.to_nat limx) as [Ax majx].
+ destruct (QCauchySeq_bounded yn Pos.to_nat limy) as [Ay majy].
+ pose proof (CReal_mult_cauchy xn xn yn Ax Ay Pos.to_nat limx limy majx majy).
+ exists (fun n : nat => xn (Pos.to_nat (2 * Pos.max Ax Ay)* n)%nat
+ * yn (Pos.to_nat (2 * Pos.max Ax Ay) * n)%nat).
+ intros p n k H0 H1.
+ apply H; apply linear_max; assumption.
+Defined.
+
+Infix "*" := CReal_mult : CReal_scope.
+
+Lemma CReal_mult_unfold : forall x y : CReal,
+ QSeqEquivEx (proj1_sig (CReal_mult x y))
+ (fun n : nat => proj1_sig x n * proj1_sig y n)%Q.
+Proof.
+ intros [xn limx] [yn limy]. unfold CReal_mult ; simpl.
+ destruct (QCauchySeq_bounded xn Pos.to_nat limx) as [Ax majx].
+ destruct (QCauchySeq_bounded yn Pos.to_nat limy) as [Ay majy].
+ simpl.
+ pose proof (CReal_mult_cauchy xn xn yn Ax Ay Pos.to_nat limx limy majx majy).
+ exists (fun p : positive =>
+ Init.Nat.max (Pos.to_nat (2 * Pos.max Ax Ay * p))
+ (Pos.to_nat (2 * Pos.max Ax Ay * p))).
+ intros p n k H0 H1. rewrite max_l in H0, H1.
+ 2: apply le_refl. 2: apply le_refl.
+ apply H. apply linear_max.
+ apply (le_trans _ (Pos.to_nat (2 * Pos.max Ax Ay * p))).
+ rewrite <- (mult_1_l (Pos.to_nat p)). rewrite Pos2Nat.inj_mul.
+ apply Nat.mul_le_mono_nonneg. auto. apply Pos2Nat.is_pos.
+ apply le_0_n. apply le_refl. apply H0. rewrite max_l.
+ apply H1. apply le_refl.
+Qed.
+
+Lemma CReal_mult_assoc_bounded_r : forall (xn yn zn : nat -> Q),
+ QSeqEquivEx xn yn (* both are Cauchy with same limit *)
+ -> QSeqEquiv zn zn Pos.to_nat
+ -> QSeqEquivEx (fun n => xn n * zn n)%Q (fun n => yn n * zn n)%Q.
+Proof.
+ intros. destruct H as [cvmod cveq].
+ destruct (QCauchySeq_bounded yn (fun k => cvmod (2 * k)%positive)
+ (QSeqEquiv_cau_r xn yn cvmod cveq))
+ as [Ay majy].
+ destruct (QCauchySeq_bounded zn Pos.to_nat H0) as [Az majz].
+ exists (fun p => max (cvmod (2 * (Pos.max Ay Az) * p)%positive)
+ (Pos.to_nat (2 * (Pos.max Ay Az) * p)%positive)).
+ apply CReal_mult_cauchy; assumption.
+Qed.
+
+Lemma CReal_mult_assoc : forall x y z : CReal,
+ CRealEq (CReal_mult (CReal_mult x y) z)
+ (CReal_mult x (CReal_mult y z)).
+Proof.
+ intros. apply CRealEq_diff. apply CRealEq_modindep.
+ apply (QSeqEquivEx_trans _ (fun n => proj1_sig x n * proj1_sig y n * proj1_sig z n)%Q).
+ - apply (QSeqEquivEx_trans _ (fun n => proj1_sig (CReal_mult x y) n * proj1_sig z n)%Q).
+ apply CReal_mult_unfold.
+ destruct x as [xn limx], y as [yn limy], z as [zn limz]; unfold CReal_mult; simpl.
+ destruct (QCauchySeq_bounded xn Pos.to_nat limx) as [Ax majx].
+ destruct (QCauchySeq_bounded yn Pos.to_nat limy) as [Ay majy].
+ destruct (QCauchySeq_bounded zn Pos.to_nat limz) as [Az majz].
+ apply CReal_mult_assoc_bounded_r. 2: apply limz.
+ simpl.
+ pose proof (CReal_mult_cauchy xn xn yn Ax Ay Pos.to_nat limx limy majx majy).
+ exists (fun p : positive =>
+ Init.Nat.max (Pos.to_nat (2 * Pos.max Ax Ay * p))
+ (Pos.to_nat (2 * Pos.max Ax Ay * p))).
+ intros p n k H0 H1. rewrite max_l in H0, H1.
+ 2: apply le_refl. 2: apply le_refl.
+ apply H. apply linear_max.
+ apply (le_trans _ (Pos.to_nat (2 * Pos.max Ax Ay * p))).
+ rewrite <- (mult_1_l (Pos.to_nat p)). rewrite Pos2Nat.inj_mul.
+ apply Nat.mul_le_mono_nonneg. auto. apply Pos2Nat.is_pos.
+ apply le_0_n. apply le_refl. apply H0. rewrite max_l.
+ apply H1. apply le_refl.
+ - apply (QSeqEquivEx_trans _ (fun n => proj1_sig x n * proj1_sig (CReal_mult y z) n)%Q).
+ 2: apply QSeqEquivEx_sym; apply CReal_mult_unfold.
+ destruct x as [xn limx], y as [yn limy], z as [zn limz]; unfold CReal_mult; simpl.
+ destruct (QCauchySeq_bounded xn Pos.to_nat limx) as [Ax majx].
+ destruct (QCauchySeq_bounded yn Pos.to_nat limy) as [Ay majy].
+ destruct (QCauchySeq_bounded zn Pos.to_nat limz) as [Az majz].
+ simpl.
+ pose proof (CReal_mult_assoc_bounded_r (fun n0 : nat => yn n0 * zn n0)%Q (fun n : nat =>
+ yn (Pos.to_nat (Pos.max Ay Az)~0 * n)%nat
+ * zn (Pos.to_nat (Pos.max Ay Az)~0 * n)%nat)%Q xn)
+ as [cvmod cveq].
+
+ pose proof (CReal_mult_cauchy yn yn zn Ay Az Pos.to_nat limy limz majy majz).
+ exists (fun p : positive =>
+ Init.Nat.max (Pos.to_nat (2 * Pos.max Ay Az * p))
+ (Pos.to_nat (2 * Pos.max Ay Az * p))).
+ intros p n k H0 H1. rewrite max_l in H0, H1.
+ 2: apply le_refl. 2: apply le_refl.
+ apply H. rewrite max_l. apply H0. apply le_refl.
+ apply linear_max.
+ apply (le_trans _ (Pos.to_nat (2 * Pos.max Ay Az * p))).
+ rewrite <- (mult_1_l (Pos.to_nat p)). rewrite Pos2Nat.inj_mul.
+ apply Nat.mul_le_mono_nonneg. auto. apply Pos2Nat.is_pos.
+ apply le_0_n. apply le_refl. apply H1.
+ apply limx.
+ exists cvmod. intros p k n H1 H2. specialize (cveq p k n H1 H2).
+ setoid_replace (xn k * yn k * zn k -
+ xn n *
+ (yn (Pos.to_nat (Pos.max Ay Az)~0 * n)%nat *
+ zn (Pos.to_nat (Pos.max Ay Az)~0 * n)%nat))%Q
+ with ((fun n : nat => yn n * zn n * xn n) k -
+ (fun n : nat =>
+ yn (Pos.to_nat (Pos.max Ay Az)~0 * n)%nat *
+ zn (Pos.to_nat (Pos.max Ay Az)~0 * n)%nat *
+ xn n) n)%Q.
+ apply cveq. ring.
+Qed.
+
+Lemma CReal_mult_comm : forall x y : CReal,
+ CRealEq (CReal_mult x y) (CReal_mult y x).
+Proof.
+ intros. apply CRealEq_diff. apply CRealEq_modindep.
+ apply (QSeqEquivEx_trans _ (fun n => proj1_sig y n * proj1_sig x n)%Q).
+ destruct x as [xn limx], y as [yn limy]; simpl.
+ 2: apply QSeqEquivEx_sym; apply CReal_mult_unfold.
+ destruct (QCauchySeq_bounded xn Pos.to_nat limx) as [Ax majx].
+ destruct (QCauchySeq_bounded yn Pos.to_nat limy) as [Ay majy]; simpl.
+ apply QSeqEquivEx_sym.
+
+ pose proof (CReal_mult_cauchy yn yn xn Ay Ax Pos.to_nat limy limx majy majx).
+ exists (fun p : positive =>
+ Init.Nat.max (Pos.to_nat (2 * Pos.max Ay Ax * p))
+ (Pos.to_nat (2 * Pos.max Ay Ax * p))).
+ intros p n k H0 H1. rewrite max_l in H0, H1.
+ 2: apply le_refl. 2: apply le_refl.
+ rewrite (Qmult_comm (xn (Pos.to_nat (Pos.max Ax Ay)~0 * k)%nat)).
+ apply (H p n). rewrite max_l. apply H0. apply le_refl.
+ rewrite max_l. apply (le_trans _ k). apply H1.
+ rewrite <- (mult_1_l k). rewrite mult_assoc.
+ apply Nat.mul_le_mono_nonneg. auto. rewrite mult_1_r.
+ apply Pos2Nat.is_pos. apply le_0_n. apply le_refl.
+ apply le_refl.
+Qed.
+
+Lemma CReal_mult_proper_l : forall x y z : CReal,
+ CRealEq y z -> CRealEq (CReal_mult x y) (CReal_mult x z).
+Proof.
+ intros. apply CRealEq_diff. apply CRealEq_modindep.
+ apply (QSeqEquivEx_trans _ (fun n => proj1_sig x n * proj1_sig y n)%Q).
+ apply CReal_mult_unfold.
+ rewrite CRealEq_diff in H. rewrite <- CRealEq_modindep in H.
+ apply QSeqEquivEx_sym.
+ apply (QSeqEquivEx_trans _ (fun n => proj1_sig x n * proj1_sig z n)%Q).
+ apply CReal_mult_unfold.
+ destruct x as [xn limx], y as [yn limy], z as [zn limz]; simpl.
+ destruct H. simpl in H.
+ destruct (QCauchySeq_bounded xn Pos.to_nat limx) as [Ax majx].
+ destruct (QCauchySeq_bounded zn Pos.to_nat limz) as [Az majz].
+ pose proof (CReal_mult_cauchy yn zn xn Az Ax x H limx majz majx).
+ apply QSeqEquivEx_sym.
+ exists (fun p : positive =>
+ Init.Nat.max (x (2 * Pos.max Az Ax * p)%positive)
+ (Pos.to_nat (2 * Pos.max Az Ax * p))).
+ intros p n k H1 H2. specialize (H0 p n k H1 H2).
+ setoid_replace (xn n * yn n - xn k * zn k)%Q
+ with (yn n * xn n - zn k * xn k)%Q.
+ apply H0. ring.
+Qed.
+
+Lemma CReal_mult_lt_0_compat : forall x y : CReal,
+ CRealLt (inject_Q 0) x
+ -> CRealLt (inject_Q 0) y
+ -> CRealLt (inject_Q 0) (CReal_mult x y).
+Proof.
+ intros. destruct H as [x0 H], H0 as [x1 H0].
+ pose proof (CRealLt_aboveSig (inject_Q 0) x x0 H).
+ pose proof (CRealLt_aboveSig (inject_Q 0) y x1 H0).
+ destruct x as [xn limx], y as [yn limy].
+ simpl in H, H1, H2. simpl.
+ destruct (QCauchySeq_bounded xn Pos.to_nat limx) as [Ax majx].
+ destruct (QCauchySeq_bounded yn Pos.to_nat limy) as [Ay majy].
+ destruct (Qarchimedean (/ (xn (Pos.to_nat x0) - 0 - (2 # x0)))).
+ destruct (Qarchimedean (/ (yn (Pos.to_nat x1) - 0 - (2 # x1)))).
+ exists (Pos.max x0 x~0 * Pos.max x1 x2~0)%positive.
+ simpl. unfold Qminus. rewrite Qplus_0_r.
+ rewrite <- Pos2Nat.inj_mul.
+ unfold Qminus in H1, H2.
+ specialize (H1 ((Pos.max Ax Ay)~0 * (Pos.max x0 x~0 * Pos.max x1 x2~0))%positive).
+ assert (Pos.max x1 x2~0 <= (Pos.max Ax Ay)~0 * (Pos.max x0 x~0 * Pos.max x1 x2~0))%positive.
+ { apply Pos2Nat.inj_le.
+ rewrite Pos.mul_assoc. rewrite Pos2Nat.inj_mul.
+ rewrite <- (mult_1_l (Pos.to_nat (Pos.max x1 x2~0))).
+ rewrite mult_assoc. apply Nat.mul_le_mono_nonneg. auto.
+ rewrite mult_1_r. apply Pos2Nat.is_pos. apply le_0_n.
+ apply le_refl. }
+ specialize (H2 ((Pos.max Ax Ay)~0 * (Pos.max x0 x~0 * Pos.max x1 x2~0))%positive H3).
+ rewrite Qplus_0_r in H1, H2.
+ apply (Qlt_trans _ ((2 # Pos.max x0 x~0) * (2 # Pos.max x1 x2~0))).
+ unfold Qlt; simpl. assert (forall p : positive, (Z.pos p < Z.pos p~0)%Z).
+ intro p. rewrite <- (Z.mul_1_l (Z.pos p)).
+ replace (Z.pos p~0) with (2 * Z.pos p)%Z. apply Z.mul_lt_mono_pos_r.
+ apply Pos2Z.is_pos. reflexivity. reflexivity.
+ apply H4.
+ apply (Qlt_trans _ ((2 # Pos.max x0 x~0) * (yn (Pos.to_nat ((Pos.max Ax Ay)~0 * (Pos.max x0 x~0 * Pos.max x1 x2~0)))))).
+ apply Qmult_lt_l. reflexivity. apply H2. apply Qmult_lt_r.
+ apply (Qlt_trans 0 (2 # Pos.max x1 x2~0)). reflexivity. apply H2.
+ apply H1. rewrite Pos.mul_comm. apply Pos2Nat.inj_le.
+ rewrite <- Pos.mul_assoc. rewrite Pos2Nat.inj_mul.
+ rewrite <- (mult_1_r (Pos.to_nat (Pos.max x0 x~0))).
+ rewrite <- mult_assoc. apply Nat.mul_le_mono_nonneg.
+ apply le_0_n. apply le_refl. auto.
+ rewrite mult_1_l. apply Pos2Nat.is_pos.
+Qed.
+
+Lemma CReal_mult_plus_distr_l : forall r1 r2 r3 : CReal,
+ r1 * (r2 + r3) == (r1 * r2) + (r1 * r3).
+Proof.
+ intros x y z. apply CRealEq_diff. apply CRealEq_modindep.
+ apply (QSeqEquivEx_trans _ (fun n => proj1_sig x n
+ * (proj1_sig (CReal_plus y z) n))%Q).
+ apply CReal_mult_unfold.
+ apply (QSeqEquivEx_trans _ (fun n => proj1_sig (CReal_mult x y) n
+ + proj1_sig (CReal_mult x z) n))%Q.
+ 2: apply QSeqEquivEx_sym; exists (fun p => Pos.to_nat (2 * p))
+ ; apply CReal_plus_unfold.
+ apply (QSeqEquivEx_trans _ (fun n => proj1_sig x n
+ * (proj1_sig y n + proj1_sig z n))%Q).
+ - pose proof (CReal_plus_unfold y z).
+ destruct x as [xn limx], y as [yn limy], z as [zn limz]; simpl; simpl in H.
+ destruct (QCauchySeq_bounded xn Pos.to_nat limx) as [Ax majx].
+ destruct (QCauchySeq_bounded yn Pos.to_nat limy) as [Ay majy].
+ destruct (QCauchySeq_bounded zn Pos.to_nat limz) as [Az majz].
+ pose proof (CReal_mult_cauchy (fun n => yn (n + (n + 0))%nat + zn (n + (n + 0))%nat)%Q
+ (fun n => yn n + zn n)%Q
+ xn (Ay + Az) Ax
+ (fun p => Pos.to_nat (2 * p)) H limx).
+ exists (fun p : positive => (Pos.to_nat (2 * (2 * Pos.max (Ay + Az) Ax * p)))).
+ intros p n k H1 H2.
+ setoid_replace (xn n * (yn (n + (n + 0))%nat + zn (n + (n + 0))%nat) - xn k * (yn k + zn k))%Q
+ with ((yn (n + (n + 0))%nat + zn (n + (n + 0))%nat) * xn n - (yn k + zn k) * xn k)%Q.
+ 2: ring.
+ assert (Pos.to_nat (2 * Pos.max (Ay + Az) Ax * p) <=
+ Pos.to_nat 2 * Pos.to_nat (2 * Pos.max (Ay + Az) Ax * p))%nat.
+ { rewrite (Pos2Nat.inj_mul 2).
+ rewrite <- (mult_1_l (Pos.to_nat (2 * Pos.max (Ay + Az) Ax * p))).
+ rewrite mult_assoc. apply Nat.mul_le_mono_nonneg. auto.
+ simpl. auto. apply le_0_n. apply le_refl. }
+ apply H0. intro n0. apply (Qle_lt_trans _ (Qabs (yn n0) + Qabs (zn n0))).
+ apply Qabs_triangle. rewrite Pos2Z.inj_add.
+ rewrite <- Qinv_plus_distr. apply Qplus_lt_le_compat.
+ apply majy. apply Qlt_le_weak. apply majz.
+ apply majx. rewrite max_l.
+ apply H1. rewrite (Pos2Nat.inj_mul 2). apply H3.
+ rewrite max_l. apply H2. rewrite (Pos2Nat.inj_mul 2).
+ apply H3.
+ - destruct x as [xn limx], y as [yn limy], z as [zn limz]; simpl.
+ destruct (QCauchySeq_bounded xn Pos.to_nat limx) as [Ax majx].
+ destruct (QCauchySeq_bounded yn Pos.to_nat limy) as [Ay majy].
+ destruct (QCauchySeq_bounded zn Pos.to_nat limz) as [Az majz].
+ simpl.
+ exists (fun p : positive => (Pos.to_nat (2 * (Pos.max (Pos.max Ax Ay) Az) * (2 * p)))).
+ intros p n k H H0.
+ setoid_replace (xn n * (yn n + zn n) -
+ (xn (Pos.to_nat (Pos.max Ax Ay)~0 * k)%nat *
+ yn (Pos.to_nat (Pos.max Ax Ay)~0 * k)%nat +
+ xn (Pos.to_nat (Pos.max Ax Az)~0 * k)%nat *
+ zn (Pos.to_nat (Pos.max Ax Az)~0 * k)%nat))%Q
+ with (xn n * yn n - (xn (Pos.to_nat (Pos.max Ax Ay)~0 * k)%nat *
+ yn (Pos.to_nat (Pos.max Ax Ay)~0 * k)%nat)
+ + (xn n * zn n - xn (Pos.to_nat (Pos.max Ax Az)~0 * k)%nat *
+ zn (Pos.to_nat (Pos.max Ax Az)~0 * k)%nat))%Q.
+ 2: ring.
+ apply (Qle_lt_trans _ (Qabs (xn n * yn n - (xn (Pos.to_nat (Pos.max Ax Ay)~0 * k)%nat *
+ yn (Pos.to_nat (Pos.max Ax Ay)~0 * k)%nat))
+ + Qabs (xn n * zn n - xn (Pos.to_nat (Pos.max Ax Az)~0 * k)%nat *
+ zn (Pos.to_nat (Pos.max Ax Az)~0 * k)%nat))).
+ apply Qabs_triangle.
+ setoid_replace (1#p)%Q with ((1#2*p) + (1#2*p))%Q.
+ apply Qplus_lt_le_compat.
+ + pose proof (CReal_mult_cauchy xn xn yn Ax Ay Pos.to_nat limx limy).
+ apply H1. apply majx. apply majy. rewrite max_l.
+ apply (le_trans _ (Pos.to_nat (2 * Pos.max (Pos.max Ax Ay) Az * (2 * p)))).
+ rewrite (Pos.mul_comm 2). rewrite <- Pos.mul_assoc.
+ rewrite <- (Pos.mul_comm (Pos.max (Pos.max Ax Ay) Az)).
+ rewrite <- Pos.mul_assoc.
+ rewrite Pos2Nat.inj_mul.
+ rewrite (Pos2Nat.inj_mul (Pos.max (Pos.max Ax Ay) Az)).
+ apply Nat.mul_le_mono_nonneg. apply le_0_n.
+ apply Pos2Nat.inj_le. apply Pos.le_max_l.
+ apply le_0_n. apply le_refl. apply H. apply le_refl.
+ rewrite max_l. apply (le_trans _ k).
+ apply (le_trans _ (Pos.to_nat (2 * Pos.max (Pos.max Ax Ay) Az * (2 * p)))).
+ rewrite (Pos.mul_comm 2). rewrite <- Pos.mul_assoc.
+ rewrite <- (Pos.mul_comm (Pos.max (Pos.max Ax Ay) Az)).
+ rewrite <- Pos.mul_assoc.
+ rewrite Pos2Nat.inj_mul.
+ rewrite (Pos2Nat.inj_mul (Pos.max (Pos.max Ax Ay) Az)).
+ apply Nat.mul_le_mono_nonneg. apply le_0_n.
+ apply Pos2Nat.inj_le. apply Pos.le_max_l.
+ apply le_0_n. apply le_refl. apply H0.
+ rewrite <- (mult_1_l k). rewrite mult_assoc.
+ apply Nat.mul_le_mono_nonneg. auto.
+ rewrite mult_1_r. apply Pos2Nat.is_pos. apply le_0_n.
+ apply le_refl. apply le_refl.
+ + apply Qlt_le_weak.
+ pose proof (CReal_mult_cauchy xn xn zn Ax Az Pos.to_nat limx limz).
+ apply H1. apply majx. apply majz. rewrite max_l. 2: apply le_refl.
+ apply (le_trans _ (Pos.to_nat (2 * Pos.max (Pos.max Ax Ay) Az * (2 * p)))).
+ rewrite (Pos.mul_comm 2). rewrite <- Pos.mul_assoc.
+ rewrite <- (Pos.mul_comm (Pos.max (Pos.max Ax Ay) Az)).
+ rewrite <- Pos.mul_assoc.
+ rewrite Pos2Nat.inj_mul.
+ rewrite (Pos2Nat.inj_mul (Pos.max (Pos.max Ax Ay) Az)).
+ apply Nat.mul_le_mono_nonneg. apply le_0_n.
+ rewrite <- Pos.max_assoc. rewrite (Pos.max_comm Ay Az).
+ rewrite Pos.max_assoc. apply Pos2Nat.inj_le. apply Pos.le_max_l.
+ apply le_0_n. apply le_refl. apply H.
+ rewrite max_l. apply (le_trans _ k).
+ apply (le_trans _ (Pos.to_nat (2 * Pos.max (Pos.max Ax Ay) Az * (2 * p)))).
+ rewrite (Pos.mul_comm 2). rewrite <- Pos.mul_assoc.
+ rewrite <- (Pos.mul_comm (Pos.max (Pos.max Ax Ay) Az)).
+ rewrite <- Pos.mul_assoc.
+ rewrite Pos2Nat.inj_mul.
+ rewrite (Pos2Nat.inj_mul (Pos.max (Pos.max Ax Ay) Az)).
+ apply Nat.mul_le_mono_nonneg. apply le_0_n.
+ rewrite <- Pos.max_assoc. rewrite (Pos.max_comm Ay Az).
+ rewrite Pos.max_assoc. apply Pos2Nat.inj_le. apply Pos.le_max_l.
+ apply le_0_n. apply le_refl. apply H0.
+ rewrite <- (mult_1_l k). rewrite mult_assoc.
+ apply Nat.mul_le_mono_nonneg. auto.
+ rewrite mult_1_r. apply Pos2Nat.is_pos. apply le_0_n.
+ apply le_refl. apply le_refl.
+ + rewrite Qinv_plus_distr. unfold Qeq. reflexivity.
+Qed.
+
+Lemma CReal_mult_plus_distr_r : forall r1 r2 r3 : CReal,
+ (r2 + r3) * r1 == (r2 * r1) + (r3 * r1).
+Proof.
+ intros.
+ rewrite CReal_mult_comm, CReal_mult_plus_distr_l,
+ <- (CReal_mult_comm r1), <- (CReal_mult_comm r1).
+ reflexivity.
+Qed.
+
+Lemma CReal_mult_1_l : forall r: CReal, 1 * r == r.
+Proof.
+ intros [rn limr]. split.
+ - intros [m maj]. simpl in maj.
+ destruct (QCauchySeq_bounded (fun _ : nat => 1%Q) Pos.to_nat (ConstCauchy 1)).
+ destruct (QCauchySeq_bounded rn Pos.to_nat limr).
+ simpl in maj. rewrite Qmult_1_l in maj.
+ specialize (limr m).
+ apply (Qlt_not_le (2 # m) (1 # m)).
+ apply (Qlt_trans _ (rn (Pos.to_nat m) - rn (Pos.to_nat (Pos.max x x0)~0 * Pos.to_nat m)%nat)).
+ apply maj.
+ apply (Qle_lt_trans _ (Qabs (rn (Pos.to_nat m) - rn (Pos.to_nat (Pos.max x x0)~0 * Pos.to_nat m)%nat))).
+ apply Qle_Qabs. apply limr. apply le_refl.
+ rewrite <- (mult_1_l (Pos.to_nat m)). rewrite mult_assoc.
+ apply Nat.mul_le_mono_nonneg. auto. rewrite mult_1_r.
+ apply Pos2Nat.is_pos. apply le_0_n. apply le_refl.
+ apply Z.mul_le_mono_nonneg. discriminate. discriminate.
+ discriminate. apply Z.le_refl.
+ - intros [m maj]. simpl in maj.
+ destruct (QCauchySeq_bounded (fun _ : nat => 1%Q) Pos.to_nat (ConstCauchy 1)).
+ destruct (QCauchySeq_bounded rn Pos.to_nat limr).
+ simpl in maj. rewrite Qmult_1_l in maj.
+ specialize (limr m).
+ apply (Qlt_not_le (2 # m) (1 # m)).
+ apply (Qlt_trans _ (rn (Pos.to_nat (Pos.max x x0)~0 * Pos.to_nat m)%nat - rn (Pos.to_nat m))).
+ apply maj.
+ apply (Qle_lt_trans _ (Qabs (rn (Pos.to_nat (Pos.max x x0)~0 * Pos.to_nat m)%nat - rn (Pos.to_nat m)))).
+ apply Qle_Qabs. apply limr.
+ rewrite <- (mult_1_l (Pos.to_nat m)). rewrite mult_assoc.
+ apply Nat.mul_le_mono_nonneg. auto. rewrite mult_1_r.
+ apply Pos2Nat.is_pos. apply le_0_n. apply le_refl.
+ apply le_refl. apply Z.mul_le_mono_nonneg. discriminate. discriminate.
+ discriminate. apply Z.le_refl.
+Qed.
+
+Lemma CReal_isRingExt : ring_eq_ext CReal_plus CReal_mult CReal_opp CRealEq.
+Proof.
+ split.
+ - intros x y H z t H0. apply CReal_plus_morph; assumption.
+ - intros x y H z t H0. apply (CRealEq_trans _ (CReal_mult x t)).
+ apply CReal_mult_proper_l. apply H0.
+ apply (CRealEq_trans _ (CReal_mult t x)). apply CReal_mult_comm.
+ apply (CRealEq_trans _ (CReal_mult t y)).
+ apply CReal_mult_proper_l. apply H. apply CReal_mult_comm.
+ - intros x y H. apply (CReal_plus_eq_reg_l x).
+ apply (CRealEq_trans _ (inject_Q 0)). apply CReal_plus_opp_r.
+ apply (CRealEq_trans _ (CReal_plus y (CReal_opp y))).
+ apply CRealEq_sym. apply CReal_plus_opp_r.
+ apply CReal_plus_proper_r. apply CRealEq_sym. apply H.
+Qed.
+
+Lemma CReal_isRing : ring_theory (inject_Q 0) (inject_Q 1)
+ CReal_plus CReal_mult
+ CReal_minus CReal_opp
+ CRealEq.
+Proof.
+ intros. split.
+ - apply CReal_plus_0_l.
+ - apply CReal_plus_comm.
+ - intros x y z. symmetry. apply CReal_plus_assoc.
+ - apply CReal_mult_1_l.
+ - apply CReal_mult_comm.
+ - intros x y z. symmetry. apply CReal_mult_assoc.
+ - intros x y z. rewrite <- (CReal_mult_comm z).
+ rewrite CReal_mult_plus_distr_l.
+ apply (CRealEq_trans _ (CReal_plus (CReal_mult x z) (CReal_mult z y))).
+ apply CReal_plus_proper_r. apply CReal_mult_comm.
+ apply CReal_plus_proper_l. apply CReal_mult_comm.
+ - intros x y. apply CRealEq_refl.
+ - apply CReal_plus_opp_r.
+Qed.
+
+Add Parametric Morphism : CReal_mult
+ with signature CRealEq ==> CRealEq ==> CRealEq
+ as CReal_mult_morph.
+Proof.
+ apply CReal_isRingExt.
+Qed.
+
+Instance CReal_mult_morph_T
+ : CMorphisms.Proper
+ (CMorphisms.respectful CRealEq (CMorphisms.respectful CRealEq CRealEq)) CReal_mult.
+Proof.
+ apply CReal_isRingExt.
+Qed.
+
+Add Parametric Morphism : CReal_opp
+ with signature CRealEq ==> CRealEq
+ as CReal_opp_morph.
+Proof.
+ apply (Ropp_ext CReal_isRingExt).
+Qed.
+
+Instance CReal_opp_morph_T
+ : CMorphisms.Proper
+ (CMorphisms.respectful CRealEq CRealEq) CReal_opp.
+Proof.
+ apply CReal_isRingExt.
+Qed.
+
+Add Parametric Morphism : CReal_minus
+ with signature CRealEq ==> CRealEq ==> CRealEq
+ as CReal_minus_morph.
+Proof.
+ intros. unfold CReal_minus. rewrite H,H0. reflexivity.
+Qed.
+
+Instance CReal_minus_morph_T
+ : CMorphisms.Proper
+ (CMorphisms.respectful CRealEq (CMorphisms.respectful CRealEq CRealEq)) CReal_minus.
+Proof.
+ intros x y exy z t ezt. unfold CReal_minus. rewrite exy,ezt. reflexivity.
+Qed.
+
+Add Ring CRealRing : CReal_isRing.
+
+(**********)
+Lemma CReal_mult_0_l : forall r, 0 * r == 0.
+Proof.
+ intro; ring.
+Qed.
+
+Lemma CReal_mult_0_r : forall r, r * 0 == 0.
+Proof.
+ intro; ring.
+Qed.
+
+(**********)
+Lemma CReal_mult_1_r : forall r, r * 1 == r.
+Proof.
+ intro; ring.
+Qed.
+
+Lemma CReal_opp_mult_distr_l
+ : forall r1 r2 : CReal, - (r1 * r2) == (- r1) * r2.
+Proof.
+ intros. ring.
+Qed.
+
+Lemma CReal_opp_mult_distr_r
+ : forall r1 r2 : CReal, - (r1 * r2) == r1 * (- r2).
+Proof.
+ intros. ring.
+Qed.
+
+Lemma CReal_mult_lt_compat_l : forall x y z : CReal,
+ 0 < x -> y < z -> x*y < x*z.
+Proof.
+ intros. apply (CReal_plus_lt_reg_l
+ (CReal_opp (CReal_mult x y))).
+ rewrite CReal_plus_comm. pose proof CReal_plus_opp_r.
+ unfold CReal_minus in H1. rewrite H1.
+ rewrite CReal_mult_comm, CReal_opp_mult_distr_l, CReal_mult_comm.
+ rewrite <- CReal_mult_plus_distr_l.
+ apply CReal_mult_lt_0_compat. exact H.
+ apply (CReal_plus_lt_reg_l y).
+ rewrite CReal_plus_comm, CReal_plus_0_l.
+ rewrite <- CReal_plus_assoc, H1, CReal_plus_0_l. exact H0.
+Qed.
+
+Lemma CReal_mult_lt_compat_r : forall x y z : CReal,
+ 0 < x -> y < z -> y*x < z*x.
+Proof.
+ intros. rewrite <- (CReal_mult_comm x), <- (CReal_mult_comm x).
+ apply (CReal_mult_lt_compat_l x); assumption.
+Qed.
+
+Lemma CReal_mult_eq_reg_l : forall (r r1 r2 : CReal),
+ r # 0
+ -> CRealEq (CReal_mult r r1) (CReal_mult r r2)
+ -> CRealEq r1 r2.
+Proof.
+ intros. destruct H; split.
+ - intro abs. apply (CReal_mult_lt_compat_l (-r)) in abs.
+ rewrite <- CReal_opp_mult_distr_l, <- CReal_opp_mult_distr_l, H0 in abs.
+ exact (CRealLt_irrefl _ abs). apply (CReal_plus_lt_reg_l r).
+ rewrite CReal_plus_opp_r, CReal_plus_comm, CReal_plus_0_l. exact c.
+ - intro abs. apply (CReal_mult_lt_compat_l (-r)) in abs.
+ rewrite <- CReal_opp_mult_distr_l, <- CReal_opp_mult_distr_l, H0 in abs.
+ exact (CRealLt_irrefl _ abs). apply (CReal_plus_lt_reg_l r).
+ rewrite CReal_plus_opp_r, CReal_plus_comm, CReal_plus_0_l. exact c.
+ - intro abs. apply (CReal_mult_lt_compat_l r) in abs. rewrite H0 in abs.
+ exact (CRealLt_irrefl _ abs). exact c.
+ - intro abs. apply (CReal_mult_lt_compat_l r) in abs. rewrite H0 in abs.
+ exact (CRealLt_irrefl _ abs). exact c.
+Qed.
+
+Lemma CReal_abs_appart_zero : forall (x : CReal) (n : positive),
+ Qlt (2#n) (Qabs (proj1_sig x (Pos.to_nat n)))
+ -> 0 # x.
+Proof.
+ intros. destruct x as [xn xcau]. simpl in H.
+ destruct (Qlt_le_dec 0 (xn (Pos.to_nat n))).
+ - left. exists n; simpl. rewrite Qabs_pos in H.
+ ring_simplify. exact H. apply Qlt_le_weak. exact q.
+ - right. exists n; simpl. rewrite Qabs_neg in H.
+ unfold Qminus. rewrite Qplus_0_l. exact H. exact q.
+Qed.
+
+
+(*********************************************************)
+(** * Field *)
+(*********************************************************)
+
+Lemma CRealArchimedean
+ : forall x:CReal, { n:Z & x < inject_Q (n#1) < x+2 }.
+Proof.
+ (* Locate x within 1/4 and pick the first integer above this interval. *)
+ intros [xn limx].
+ pose proof (Qlt_floor (xn 4%nat + (1#4))). unfold inject_Z in H.
+ pose proof (Qfloor_le (xn 4%nat + (1#4))). unfold inject_Z in H0.
+ remember (Qfloor (xn 4%nat + (1#4)))%Z as n.
+ exists (n+1)%Z. split.
+ - assert (Qlt 0 ((n + 1 # 1) - (xn 4%nat + (1 # 4)))) as epsPos.
+ { unfold Qminus. rewrite <- Qlt_minus_iff. exact H. }
+ destruct (Qarchimedean (/((1#2)*((n + 1 # 1) - (xn 4%nat + (1 # 4)))))) as [k kmaj].
+ exists (Pos.max 4 k). simpl.
+ apply (Qlt_trans _ ((n + 1 # 1) - (xn 4%nat + (1 # 4)))).
+ + setoid_replace (Z.pos k # 1)%Q with (/(1#k))%Q in kmaj. 2: reflexivity.
+ rewrite <- Qinv_lt_contravar in kmaj. 2: reflexivity.
+ apply (Qle_lt_trans _ (2#k)).
+ rewrite <- (Qmult_le_l _ _ (1#2)).
+ setoid_replace ((1 # 2) * (2 # k))%Q with (1#k)%Q. 2: reflexivity.
+ setoid_replace ((1 # 2) * (2 # Pos.max 4 k))%Q with (1#Pos.max 4 k)%Q. 2: reflexivity.
+ unfold Qle; simpl. apply Pos2Z.pos_le_pos. apply Pos.le_max_r.
+ reflexivity.
+ rewrite <- (Qmult_lt_l _ _ (1#2)).
+ setoid_replace ((1 # 2) * (2 # k))%Q with (1#k)%Q. exact kmaj.
+ reflexivity. reflexivity. rewrite <- (Qmult_0_r (1#2)).
+ rewrite Qmult_lt_l. exact epsPos. reflexivity.
+ + rewrite <- (Qplus_lt_r _ _ (xn (Pos.to_nat (Pos.max 4 k)) - (n + 1 # 1) + (1#4))).
+ ring_simplify.
+ apply (Qle_lt_trans _ (Qabs (xn (Pos.to_nat (Pos.max 4 k)) - xn 4%nat))).
+ apply Qle_Qabs. apply limx.
+ rewrite Pos2Nat.inj_max. apply Nat.le_max_l. apply le_refl.
+ - apply (CReal_plus_lt_reg_l (-(2))). ring_simplify.
+ exists 4%positive. simpl.
+ rewrite <- Qinv_plus_distr.
+ rewrite <- (Qplus_lt_r _ _ ((n#1) - (1#2))). ring_simplify.
+ apply (Qle_lt_trans _ (xn 4%nat + (1 # 4)) _ H0).
+ unfold Pos.to_nat; simpl.
+ rewrite <- (Qplus_lt_r _ _ (-xn 4%nat)). ring_simplify.
+ reflexivity.
+Defined.
+
+Definition Rup_pos (x : CReal)
+ : { n : positive & x < inject_Q (Z.pos n # 1) }.
+Proof.
+ intros. destruct (CRealArchimedean x) as [p [maj _]].
+ destruct p.
+ - exists 1%positive. apply (CReal_lt_trans _ 0 _ maj). apply CRealLt_0_1.
+ - exists p. exact maj.
+ - exists 1%positive. apply (CReal_lt_trans _ (inject_Q (Z.neg p # 1)) _ maj).
+ apply (CReal_lt_trans _ 0). apply inject_Q_lt. reflexivity.
+ apply CRealLt_0_1.
+Qed.
+
+Lemma CRealLtDisjunctEpsilon : forall a b c d : CReal,
+ (CRealLtProp a b \/ CRealLtProp c d) -> CRealLt a b + CRealLt c d.
+Proof.
+ intros.
+ assert (exists n : nat, n <> O /\
+ (Qlt (2 # Pos.of_nat n) (proj1_sig b n - proj1_sig a n)
+ \/ Qlt (2 # Pos.of_nat n) (proj1_sig d n - proj1_sig c n))).
+ { destruct H. destruct H as [n maj]. exists (Pos.to_nat n). split.
+ intro abs. destruct (Pos2Nat.is_succ n). rewrite H in abs.
+ inversion abs. left. rewrite Pos2Nat.id. apply maj.
+ destruct H as [n maj]. exists (Pos.to_nat n). split.
+ intro abs. destruct (Pos2Nat.is_succ n). rewrite H in abs.
+ inversion abs. right. rewrite Pos2Nat.id. apply maj. }
+ apply constructive_indefinite_ground_description_nat in H0.
+ - destruct H0 as [n [nPos maj]].
+ destruct (Qlt_le_dec (2 # Pos.of_nat n)
+ (proj1_sig b n - proj1_sig a n)).
+ left. exists (Pos.of_nat n). rewrite Nat2Pos.id. apply q. apply nPos.
+ assert (2 # Pos.of_nat n < proj1_sig d n - proj1_sig c n)%Q.
+ destruct maj. exfalso.
+ apply (Qlt_not_le (2 # Pos.of_nat n) (proj1_sig b n - proj1_sig a n)); assumption.
+ assumption. clear maj. right. exists (Pos.of_nat n). rewrite Nat2Pos.id.
+ apply H0. apply nPos.
+ - clear H0. clear H. intro n. destruct n. right.
+ intros [abs _]. exact (abs (eq_refl O)).
+ destruct (Qlt_le_dec (2 # Pos.of_nat (S n)) (proj1_sig b (S n) - proj1_sig a (S n))).
+ left. split. discriminate. left. apply q.
+ destruct (Qlt_le_dec (2 # Pos.of_nat (S n)) (proj1_sig d (S n) - proj1_sig c (S n))).
+ left. split. discriminate. right. apply q0.
+ right. intros [_ [abs|abs]].
+ apply (Qlt_not_le (2 # Pos.of_nat (S n))
+ (proj1_sig b (S n) - proj1_sig a (S n))); assumption.
+ apply (Qlt_not_le (2 # Pos.of_nat (S n))
+ (proj1_sig d (S n) - proj1_sig c (S n))); assumption.
+Qed.
+
+Lemma CRealShiftReal : forall (x : CReal) (k : nat),
+ QCauchySeq (fun n => proj1_sig x (plus n k)) Pos.to_nat.
+Proof.
+ intros x k n p q H H0.
+ destruct x as [xn cau]; unfold proj1_sig.
+ destruct k. rewrite plus_0_r. rewrite plus_0_r. apply cau; assumption.
+ specialize (cau (n + Pos.of_nat (S k))%positive (p + S k)%nat (q + S k)%nat).
+ apply (Qlt_trans _ (1 # n + Pos.of_nat (S k))).
+ apply cau. rewrite Pos2Nat.inj_add. rewrite Nat2Pos.id.
+ apply Nat.add_le_mono_r. apply H. discriminate.
+ rewrite Pos2Nat.inj_add. rewrite Nat2Pos.id.
+ apply Nat.add_le_mono_r. apply H0. discriminate.
+ apply Pos2Nat.inj_lt; simpl. rewrite Pos2Nat.inj_add.
+ rewrite <- (plus_0_r (Pos.to_nat n)). rewrite <- plus_assoc.
+ apply Nat.add_lt_mono_l. apply Pos2Nat.is_pos.
+Qed.
+
+Lemma CRealShiftEqual : forall (x : CReal) (k : nat),
+ CRealEq x (exist _ (fun n => proj1_sig x (plus n k)) (CRealShiftReal x k)).
+Proof.
+ intros. split.
+ - intros [n maj]. destruct x as [xn cau]; simpl in maj.
+ specialize (cau n (Pos.to_nat n + k)%nat (Pos.to_nat n)).
+ apply Qlt_not_le in maj. apply maj. clear maj.
+ apply (Qle_trans _ (Qabs (xn (Pos.to_nat n + k)%nat - xn (Pos.to_nat n)))).
+ apply Qle_Qabs. apply (Qle_trans _ (1#n)). apply Zlt_le_weak.
+ apply cau. rewrite <- (plus_0_r (Pos.to_nat n)).
+ rewrite <- plus_assoc. apply Nat.add_le_mono_l. apply le_0_n.
+ apply le_refl. apply Z.mul_le_mono_pos_r. apply Pos2Z.is_pos.
+ discriminate.
+ - intros [n maj]. destruct x as [xn cau]; simpl in maj.
+ specialize (cau n (Pos.to_nat n) (Pos.to_nat n + k)%nat).
+ apply Qlt_not_le in maj. apply maj. clear maj.
+ apply (Qle_trans _ (Qabs (xn (Pos.to_nat n) - xn (Pos.to_nat n + k)%nat))).
+ apply Qle_Qabs. apply (Qle_trans _ (1#n)). apply Zlt_le_weak.
+ apply cau. apply le_refl. rewrite <- (plus_0_r (Pos.to_nat n)).
+ rewrite <- plus_assoc. apply Nat.add_le_mono_l. apply le_0_n.
+ apply Z.mul_le_mono_pos_r. apply Pos2Z.is_pos. discriminate.
+Qed.
+
+(* Find an equal negative real number, which rational sequence
+ stays below 0, so that it can be inversed. *)
+Definition CRealNegShift (x : CReal)
+ : CRealLt x (inject_Q 0)
+ -> { y : prod positive CReal | CRealEq x (snd y)
+ /\ forall n:nat, Qlt (proj1_sig (snd y) n) (-1 # fst y) }.
+Proof.
+ intro xNeg.
+ pose proof (CRealLt_aboveSig x (inject_Q 0)).
+ pose proof (CRealShiftReal x).
+ pose proof (CRealShiftEqual x).
+ destruct xNeg as [n maj], x as [xn cau]; simpl in maj.
+ specialize (H n maj); simpl in H.
+ destruct (Qarchimedean (/ (0 - xn (Pos.to_nat n) - (2 # n)))) as [a _].
+ remember (Pos.max n a~0) as k.
+ clear Heqk. clear maj. clear n.
+ exists (pair k
+ (exist _ (fun n => xn (plus n (Pos.to_nat k))) (H0 (Pos.to_nat k)))).
+ split. apply H1. intro n. simpl. apply Qlt_minus_iff.
+ destruct n.
+ - specialize (H k).
+ unfold Qminus in H. rewrite Qplus_0_l in H. apply Qlt_minus_iff in H.
+ unfold Qminus. rewrite Qplus_comm.
+ apply (Qlt_trans _ (- xn (Pos.to_nat k)%nat - (2 #k))). apply H.
+ unfold Qminus. simpl. apply Qplus_lt_r.
+ apply Z.mul_lt_mono_pos_r. simpl. apply Pos2Z.is_pos.
+ reflexivity. apply Pos.le_refl.
+ - apply (Qlt_trans _ (-(2 # k) - xn (S n + Pos.to_nat k)%nat)).
+ rewrite <- (Nat2Pos.id (S n)). rewrite <- Pos2Nat.inj_add.
+ specialize (H (Pos.of_nat (S n) + k)%positive).
+ unfold Qminus in H. rewrite Qplus_0_l in H. apply Qlt_minus_iff in H.
+ unfold Qminus. rewrite Qplus_comm. apply H. apply Pos2Nat.inj_le.
+ rewrite <- (plus_0_l (Pos.to_nat k)). rewrite Pos2Nat.inj_add.
+ apply Nat.add_le_mono_r. apply le_0_n. discriminate.
+ apply Qplus_lt_l.
+ apply Z.mul_lt_mono_pos_r. simpl. apply Pos2Z.is_pos.
+ reflexivity.
+Qed.
+
+Definition CRealPosShift (x : CReal)
+ : inject_Q 0 < x
+ -> { y : prod positive CReal | CRealEq x (snd y)
+ /\ forall n:nat, Qlt (1 # fst y) (proj1_sig (snd y) n) }.
+Proof.
+ intro xPos.
+ pose proof (CRealLt_aboveSig (inject_Q 0) x).
+ pose proof (CRealShiftReal x).
+ pose proof (CRealShiftEqual x).
+ destruct xPos as [n maj], x as [xn cau]; simpl in maj.
+ simpl in H. specialize (H n).
+ destruct (Qarchimedean (/ (xn (Pos.to_nat n) - 0 - (2 # n)))) as [a _].
+ specialize (H maj); simpl in H.
+ remember (Pos.max n a~0) as k.
+ clear Heqk. clear maj. clear n.
+ exists (pair k
+ (exist _ (fun n => xn (plus n (Pos.to_nat k))) (H0 (Pos.to_nat k)))).
+ split. apply H1. intro n. simpl. apply Qlt_minus_iff.
+ destruct n.
+ - specialize (H k).
+ unfold Qminus in H. rewrite Qplus_0_r in H.
+ simpl. rewrite <- Qlt_minus_iff.
+ apply (Qlt_trans _ (2 #k)).
+ apply Z.mul_lt_mono_pos_r. simpl. apply Pos2Z.is_pos.
+ reflexivity. apply H. apply Pos.le_refl.
+ - rewrite <- Qlt_minus_iff. apply (Qlt_trans _ (2 # k)).
+ apply Z.mul_lt_mono_pos_r. simpl. apply Pos2Z.is_pos.
+ reflexivity. specialize (H (Pos.of_nat (S n) + k)%positive).
+ unfold Qminus in H. rewrite Qplus_0_r in H.
+ rewrite Pos2Nat.inj_add in H. rewrite Nat2Pos.id in H.
+ apply H. apply Pos2Nat.inj_le.
+ rewrite <- (plus_0_l (Pos.to_nat k)). rewrite Pos2Nat.inj_add.
+ apply Nat.add_le_mono_r. apply le_0_n. discriminate.
+Qed.
+
+Lemma CReal_inv_neg : forall (yn : nat -> Q) (k : positive),
+ (QCauchySeq yn Pos.to_nat)
+ -> (forall n : nat, yn n < -1 # k)%Q
+ -> QCauchySeq (fun n : nat => / yn (Pos.to_nat k ^ 2 * n)%nat) Pos.to_nat.
+Proof.
+ (* Prove the inverse sequence is Cauchy *)
+ intros yn k cau maj n p q H0 H1.
+ setoid_replace (/ yn (Pos.to_nat k ^ 2 * p)%nat -
+ / yn (Pos.to_nat k ^ 2 * q)%nat)%Q
+ with ((yn (Pos.to_nat k ^ 2 * q)%nat -
+ yn (Pos.to_nat k ^ 2 * p)%nat)
+ / (yn (Pos.to_nat k ^ 2 * q)%nat *
+ yn (Pos.to_nat k ^ 2 * p)%nat)).
+ + apply (Qle_lt_trans _ (Qabs (yn (Pos.to_nat k ^ 2 * q)%nat
+ - yn (Pos.to_nat k ^ 2 * p)%nat)
+ / (1 # (k^2)))).
+ assert (1 # k ^ 2
+ < Qabs (yn (Pos.to_nat k ^ 2 * q)%nat * yn (Pos.to_nat k ^ 2 * p)%nat))%Q.
+ { rewrite Qabs_Qmult. unfold "^"%positive; simpl.
+ rewrite factorDenom. rewrite Pos.mul_1_r.
+ apply (Qlt_trans _ ((1#k) * Qabs (yn (Pos.to_nat k * (Pos.to_nat k * 1) * p)%nat))).
+ apply Qmult_lt_l. reflexivity. rewrite Qabs_neg.
+ specialize (maj (Pos.to_nat k * (Pos.to_nat k * 1) * p)%nat).
+ apply Qlt_minus_iff in maj. apply Qlt_minus_iff.
+ rewrite Qplus_comm. setoid_replace (-(1#k))%Q with (-1 # k)%Q. apply maj.
+ reflexivity. apply (Qle_trans _ (-1 # k)). apply Zlt_le_weak.
+ apply maj. discriminate.
+ apply Qmult_lt_r. apply (Qlt_trans 0 (1#k)). reflexivity.
+ rewrite Qabs_neg.
+ specialize (maj (Pos.to_nat k * (Pos.to_nat k * 1) * p)%nat).
+ apply Qlt_minus_iff in maj. apply Qlt_minus_iff.
+ rewrite Qplus_comm. setoid_replace (-(1#k))%Q with (-1 # k)%Q. apply maj.
+ reflexivity. apply (Qle_trans _ (-1 # k)). apply Zlt_le_weak.
+ apply maj. discriminate.
+ rewrite Qabs_neg.
+ specialize (maj (Pos.to_nat k * (Pos.to_nat k * 1) * q)%nat).
+ apply Qlt_minus_iff in maj. apply Qlt_minus_iff.
+ rewrite Qplus_comm. setoid_replace (-(1#k))%Q with (-1 # k)%Q. apply maj.
+ reflexivity. apply (Qle_trans _ (-1 # k)). apply Zlt_le_weak.
+ apply maj. discriminate. }
+ unfold Qdiv. rewrite Qabs_Qmult. rewrite Qabs_Qinv.
+ rewrite Qmult_comm. rewrite <- (Qmult_comm (/ (1 # k ^ 2))).
+ apply Qmult_le_compat_r. apply Qlt_le_weak.
+ rewrite <- Qmult_1_l. apply Qlt_shift_div_r.
+ apply (Qlt_trans 0 (1 # k ^ 2)). reflexivity. apply H.
+ rewrite Qmult_comm. apply Qlt_shift_div_l.
+ reflexivity. rewrite Qmult_1_l. apply H.
+ apply Qabs_nonneg. simpl in maj.
+ specialize (cau (n * (k^2))%positive
+ (Pos.to_nat k ^ 2 * q)%nat
+ (Pos.to_nat k ^ 2 * p)%nat).
+ apply Qlt_shift_div_r. reflexivity.
+ apply (Qlt_le_trans _ (1 # n * k ^ 2)). apply cau.
+ rewrite Pos2Nat.inj_mul. rewrite mult_comm.
+ unfold "^"%positive. simpl. rewrite Pos2Nat.inj_mul.
+ rewrite <- mult_assoc. rewrite <- mult_assoc.
+ apply Nat.mul_le_mono_nonneg_l. apply le_0_n.
+ rewrite (mult_1_r). rewrite Pos.mul_1_r.
+ apply Nat.mul_le_mono_nonneg_l. apply le_0_n.
+ apply (le_trans _ (q+0)). rewrite plus_0_r. assumption.
+ rewrite plus_0_r. apply le_refl.
+ rewrite Pos2Nat.inj_mul. rewrite mult_comm.
+ unfold "^"%positive; simpl. rewrite Pos2Nat.inj_mul.
+ rewrite <- mult_assoc. rewrite <- mult_assoc.
+ apply Nat.mul_le_mono_nonneg_l. apply le_0_n.
+ rewrite (mult_1_r). rewrite Pos.mul_1_r.
+ apply Nat.mul_le_mono_nonneg_l. apply le_0_n.
+ apply (le_trans _ (p+0)). rewrite plus_0_r. assumption.
+ rewrite plus_0_r. apply le_refl.
+ rewrite factorDenom. apply Qle_refl.
+ + field. split. intro abs.
+ specialize (maj (Pos.to_nat k ^ 2 * p)%nat).
+ rewrite abs in maj. inversion maj.
+ intro abs.
+ specialize (maj (Pos.to_nat k ^ 2 * q)%nat).
+ rewrite abs in maj. inversion maj.
+Qed.
+
+Lemma CReal_inv_pos : forall (yn : nat -> Q) (k : positive),
+ (QCauchySeq yn Pos.to_nat)
+ -> (forall n : nat, 1 # k < yn n)%Q
+ -> QCauchySeq (fun n : nat => / yn (Pos.to_nat k ^ 2 * n)%nat) Pos.to_nat.
+Proof.
+ intros yn k cau maj n p q H0 H1.
+ setoid_replace (/ yn (Pos.to_nat k ^ 2 * p)%nat -
+ / yn (Pos.to_nat k ^ 2 * q)%nat)%Q
+ with ((yn (Pos.to_nat k ^ 2 * q)%nat -
+ yn (Pos.to_nat k ^ 2 * p)%nat)
+ / (yn (Pos.to_nat k ^ 2 * q)%nat *
+ yn (Pos.to_nat k ^ 2 * p)%nat)).
+ + apply (Qle_lt_trans _ (Qabs (yn (Pos.to_nat k ^ 2 * q)%nat
+ - yn (Pos.to_nat k ^ 2 * p)%nat)
+ / (1 # (k^2)))).
+ assert (1 # k ^ 2
+ < Qabs (yn (Pos.to_nat k ^ 2 * q)%nat * yn (Pos.to_nat k ^ 2 * p)%nat))%Q.
+ { rewrite Qabs_Qmult. unfold "^"%positive; simpl.
+ rewrite factorDenom. rewrite Pos.mul_1_r.
+ apply (Qlt_trans _ ((1#k) * Qabs (yn (Pos.to_nat k * (Pos.to_nat k * 1) * p)%nat))).
+ apply Qmult_lt_l. reflexivity. rewrite Qabs_pos.
+ specialize (maj (Pos.to_nat k * (Pos.to_nat k * 1) * p)%nat).
+ apply maj. apply (Qle_trans _ (1 # k)).
+ discriminate. apply Zlt_le_weak. apply maj.
+ apply Qmult_lt_r. apply (Qlt_trans 0 (1#k)). reflexivity.
+ rewrite Qabs_pos.
+ specialize (maj (Pos.to_nat k * (Pos.to_nat k * 1) * p)%nat).
+ apply maj. apply (Qle_trans _ (1 # k)). discriminate.
+ apply Zlt_le_weak. apply maj.
+ rewrite Qabs_pos.
+ specialize (maj (Pos.to_nat k * (Pos.to_nat k * 1) * q)%nat).
+ apply maj. apply (Qle_trans _ (1 # k)). discriminate.
+ apply Zlt_le_weak. apply maj. }
+ unfold Qdiv. rewrite Qabs_Qmult. rewrite Qabs_Qinv.
+ rewrite Qmult_comm. rewrite <- (Qmult_comm (/ (1 # k ^ 2))).
+ apply Qmult_le_compat_r. apply Qlt_le_weak.
+ rewrite <- Qmult_1_l. apply Qlt_shift_div_r.
+ apply (Qlt_trans 0 (1 # k ^ 2)). reflexivity. apply H.
+ rewrite Qmult_comm. apply Qlt_shift_div_l.
+ reflexivity. rewrite Qmult_1_l. apply H.
+ apply Qabs_nonneg. simpl in maj.
+ specialize (cau (n * (k^2))%positive
+ (Pos.to_nat k ^ 2 * q)%nat
+ (Pos.to_nat k ^ 2 * p)%nat).
+ apply Qlt_shift_div_r. reflexivity.
+ apply (Qlt_le_trans _ (1 # n * k ^ 2)). apply cau.
+ rewrite Pos2Nat.inj_mul. rewrite mult_comm.
+ unfold "^"%positive. simpl. rewrite Pos2Nat.inj_mul.
+ rewrite <- mult_assoc. rewrite <- mult_assoc.
+ apply Nat.mul_le_mono_nonneg_l. apply le_0_n.
+ rewrite (mult_1_r). rewrite Pos.mul_1_r.
+ apply Nat.mul_le_mono_nonneg_l. apply le_0_n.
+ apply (le_trans _ (q+0)). rewrite plus_0_r. assumption.
+ rewrite plus_0_r. apply le_refl.
+ rewrite Pos2Nat.inj_mul. rewrite mult_comm.
+ unfold "^"%positive; simpl. rewrite Pos2Nat.inj_mul.
+ rewrite <- mult_assoc. rewrite <- mult_assoc.
+ apply Nat.mul_le_mono_nonneg_l. apply le_0_n.
+ rewrite (mult_1_r). rewrite Pos.mul_1_r.
+ apply Nat.mul_le_mono_nonneg_l. apply le_0_n.
+ apply (le_trans _ (p+0)). rewrite plus_0_r. assumption.
+ rewrite plus_0_r. apply le_refl.
+ rewrite factorDenom. apply Qle_refl.
+ + field. split. intro abs.
+ specialize (maj (Pos.to_nat k ^ 2 * p)%nat).
+ rewrite abs in maj. inversion maj.
+ intro abs.
+ specialize (maj (Pos.to_nat k ^ 2 * q)%nat).
+ rewrite abs in maj. inversion maj.
+Qed.
+
+Definition CReal_inv (x : CReal) (xnz : x # 0) : CReal.
+Proof.
+ destruct xnz as [xNeg | xPos].
+ - destruct (CRealNegShift x xNeg) as [[k y] [_ maj]].
+ destruct y as [yn cau]; unfold proj1_sig, snd, fst in maj.
+ exists (fun n => Qinv (yn (mult (Pos.to_nat k^2) n))).
+ apply (CReal_inv_neg yn). apply cau. apply maj.
+ - destruct (CRealPosShift x xPos) as [[k y] [_ maj]].
+ destruct y as [yn cau]; unfold proj1_sig, snd, fst in maj.
+ exists (fun n => Qinv (yn (mult (Pos.to_nat k^2) n))).
+ apply (CReal_inv_pos yn). apply cau. apply maj.
+Defined.
+
+Notation "/ x" := (CReal_inv x) (at level 35, right associativity) : CReal_scope.
+
+Lemma CReal_inv_0_lt_compat
+ : forall (r : CReal) (rnz : r # 0),
+ 0 < r -> 0 < ((/ r) rnz).
+Proof.
+ intros. unfold CReal_inv. simpl.
+ destruct rnz.
+ - exfalso. apply CRealLt_asym in H. contradiction.
+ - destruct (CRealPosShift r c) as [[k rpos] [req maj]].
+ clear req. destruct rpos as [rn cau]; simpl in maj.
+ unfold CRealLt; simpl.
+ destruct (Qarchimedean (rn 1%nat)) as [A majA].
+ exists (2 * (A + 1))%positive. unfold Qminus. rewrite Qplus_0_r.
+ rewrite <- (Qmult_1_l (Qinv (rn (Pos.to_nat k * (Pos.to_nat k * 1) * Pos.to_nat (2 * (A + 1)))%nat))).
+ apply Qlt_shift_div_l. apply (Qlt_trans 0 (1#k)). reflexivity.
+ apply maj. rewrite <- (Qmult_inv_r (Z.pos A + 1 # 1)).
+ setoid_replace (2 # 2 * (A + 1))%Q with (Qinv (Z.pos A + 1 # 1)).
+ 2: reflexivity.
+ rewrite Qmult_comm. apply Qmult_lt_r. reflexivity.
+ rewrite mult_1_r. rewrite <- Pos2Nat.inj_mul. rewrite <- Pos2Nat.inj_mul.
+ rewrite <- (Qplus_lt_l _ _ (- rn 1%nat)).
+ apply (Qle_lt_trans _ (Qabs (rn (Pos.to_nat (k * k * (2 * (A + 1)))) + - rn 1%nat))).
+ apply Qle_Qabs. apply (Qlt_le_trans _ 1). apply cau.
+ apply Pos2Nat.is_pos. apply le_refl.
+ rewrite <- Qinv_plus_distr. rewrite <- (Qplus_comm 1).
+ rewrite <- Qplus_0_r. rewrite <- Qplus_assoc. rewrite <- Qplus_assoc.
+ rewrite Qplus_le_r. rewrite Qplus_0_l. apply Qlt_le_weak.
+ apply Qlt_minus_iff in majA. apply majA.
+ intro abs. inversion abs.
+Qed.
+
+Lemma CReal_linear_shift : forall (x : CReal) (k : nat),
+ le 1 k -> QCauchySeq (fun n => proj1_sig x (k * n)%nat) Pos.to_nat.
+Proof.
+ intros [xn limx] k lek p n m H H0. unfold proj1_sig.
+ apply limx. apply (le_trans _ n). apply H.
+ rewrite <- (mult_1_l n). rewrite mult_assoc.
+ apply Nat.mul_le_mono_nonneg_r. apply le_0_n.
+ rewrite mult_1_r. apply lek. apply (le_trans _ m). apply H0.
+ rewrite <- (mult_1_l m). rewrite mult_assoc.
+ apply Nat.mul_le_mono_nonneg_r. apply le_0_n.
+ rewrite mult_1_r. apply lek.
+Qed.
+
+Lemma CReal_linear_shift_eq : forall (x : CReal) (k : nat) (kPos : le 1 k),
+ CRealEq x
+ (exist (fun n : nat -> Q => QCauchySeq n Pos.to_nat)
+ (fun n : nat => proj1_sig x (k * n)%nat) (CReal_linear_shift x k kPos)).
+Proof.
+ intros. apply CRealEq_diff. intro n.
+ destruct x as [xn limx]; unfold proj1_sig.
+ specialize (limx n (Pos.to_nat n) (k * Pos.to_nat n)%nat).
+ apply (Qle_trans _ (1 # n)). apply Qlt_le_weak. apply limx.
+ apply le_refl. rewrite <- (mult_1_l (Pos.to_nat n)).
+ rewrite mult_assoc. apply Nat.mul_le_mono_nonneg_r. apply le_0_n.
+ rewrite mult_1_r. apply kPos. apply Z.mul_le_mono_nonneg_r.
+ discriminate. discriminate.
+Qed.
+
+Lemma CReal_inv_l : forall (r:CReal) (rnz : r # 0),
+ ((/ r) rnz) * r == 1.
+Proof.
+ intros. unfold CReal_inv; simpl.
+ destruct rnz.
+ - (* r < 0 *) destruct (CRealNegShift r c) as [[k rneg] [req maj]].
+ simpl in req. apply CRealEq_diff. apply CRealEq_modindep.
+ apply (QSeqEquivEx_trans _
+ (proj1_sig (CReal_mult ((let
+ (yn, cau) as s
+ return ((forall n : nat, proj1_sig s n < -1 # k) -> CReal) := rneg in
+ fun maj0 : forall n : nat, yn n < -1 # k =>
+ exist (fun x : nat -> Q => QCauchySeq x Pos.to_nat)
+ (fun n : nat => Qinv (yn (Pos.to_nat k * (Pos.to_nat k * 1) * n))%nat)
+ (CReal_inv_neg yn k cau maj0)) maj) rneg)))%Q.
+ + apply CRealEq_modindep. apply CRealEq_diff.
+ apply CReal_mult_proper_l. apply req.
+ + assert (le 1 (Pos.to_nat k * (Pos.to_nat k * 1))%nat). rewrite mult_1_r.
+ rewrite <- Pos2Nat.inj_mul. apply Pos2Nat.is_pos.
+ apply (QSeqEquivEx_trans _
+ (proj1_sig (CReal_mult ((let
+ (yn, cau) as s
+ return ((forall n : nat, proj1_sig s n < -1 # k) -> CReal) := rneg in
+ fun maj0 : forall n : nat, yn n < -1 # k =>
+ exist (fun x : nat -> Q => QCauchySeq x Pos.to_nat)
+ (fun n : nat => Qinv (yn (Pos.to_nat k * (Pos.to_nat k * 1) * n)%nat))
+ (CReal_inv_neg yn k cau maj0)) maj)
+ (exist _ (fun n => proj1_sig rneg (Pos.to_nat k * (Pos.to_nat k * 1) * n)%nat) (CReal_linear_shift rneg _ H)))))%Q.
+ apply CRealEq_modindep. apply CRealEq_diff.
+ apply CReal_mult_proper_l. apply CReal_linear_shift_eq.
+ destruct r as [rn limr], rneg as [rnn limneg]; simpl.
+ destruct (QCauchySeq_bounded
+ (fun n : nat => Qinv (rnn (Pos.to_nat k * (Pos.to_nat k * 1) * n)%nat))
+ Pos.to_nat (CReal_inv_neg rnn k limneg maj)).
+ destruct (QCauchySeq_bounded
+ (fun n : nat => rnn (Pos.to_nat k * (Pos.to_nat k * 1) * n)%nat)
+ Pos.to_nat
+ (CReal_linear_shift
+ (exist (fun x0 : nat -> Q => QCauchySeq x0 Pos.to_nat) rnn limneg)
+ (Pos.to_nat k * (Pos.to_nat k * 1)) H)) ; simpl.
+ exists (fun n => 1%nat). intros p n m H0 H1. rewrite Qmult_comm.
+ rewrite Qmult_inv_r. unfold Qminus. rewrite Qplus_opp_r.
+ reflexivity. intro abs.
+ specialize (maj (Pos.to_nat k * (Pos.to_nat k * 1)
+ * (Pos.to_nat (Pos.max x x0)~0 * n))%nat).
+ simpl in maj. rewrite abs in maj. inversion maj.
+ - (* r > 0 *) destruct (CRealPosShift r c) as [[k rneg] [req maj]].
+ simpl in req. apply CRealEq_diff. apply CRealEq_modindep.
+ apply (QSeqEquivEx_trans _
+ (proj1_sig (CReal_mult ((let
+ (yn, cau) as s
+ return ((forall n : nat, 1 # k < proj1_sig s n) -> CReal) := rneg in
+ fun maj0 : forall n : nat, 1 # k < yn n =>
+ exist (fun x : nat -> Q => QCauchySeq x Pos.to_nat)
+ (fun n : nat => Qinv (yn (Pos.to_nat k * (Pos.to_nat k * 1) * n)%nat))
+ (CReal_inv_pos yn k cau maj0)) maj) rneg)))%Q.
+ + apply CRealEq_modindep. apply CRealEq_diff.
+ apply CReal_mult_proper_l. apply req.
+ + assert (le 1 (Pos.to_nat k * (Pos.to_nat k * 1))%nat). rewrite mult_1_r.
+ rewrite <- Pos2Nat.inj_mul. apply Pos2Nat.is_pos.
+ apply (QSeqEquivEx_trans _
+ (proj1_sig (CReal_mult ((let
+ (yn, cau) as s
+ return ((forall n : nat, 1 # k < proj1_sig s n) -> CReal) := rneg in
+ fun maj0 : forall n : nat, 1 # k < yn n =>
+ exist (fun x : nat -> Q => QCauchySeq x Pos.to_nat)
+ (fun n : nat => Qinv (yn (Pos.to_nat k * (Pos.to_nat k * 1) * n)%nat))
+ (CReal_inv_pos yn k cau maj0)) maj)
+ (exist _ (fun n => proj1_sig rneg (Pos.to_nat k * (Pos.to_nat k * 1) * n)%nat) (CReal_linear_shift rneg _ H)))))%Q.
+ apply CRealEq_modindep. apply CRealEq_diff.
+ apply CReal_mult_proper_l. apply CReal_linear_shift_eq.
+ destruct r as [rn limr], rneg as [rnn limneg]; simpl.
+ destruct (QCauchySeq_bounded
+ (fun n : nat => Qinv (rnn (Pos.to_nat k * (Pos.to_nat k * 1) * n)%nat))
+ Pos.to_nat (CReal_inv_pos rnn k limneg maj)).
+ destruct (QCauchySeq_bounded
+ (fun n : nat => rnn (Pos.to_nat k * (Pos.to_nat k * 1) * n)%nat)
+ Pos.to_nat
+ (CReal_linear_shift
+ (exist (fun x0 : nat -> Q => QCauchySeq x0 Pos.to_nat) rnn limneg)
+ (Pos.to_nat k * (Pos.to_nat k * 1)) H)) ; simpl.
+ exists (fun n => 1%nat). intros p n m H0 H1. rewrite Qmult_comm.
+ rewrite Qmult_inv_r. unfold Qminus. rewrite Qplus_opp_r.
+ reflexivity. intro abs.
+ specialize (maj (Pos.to_nat k * (Pos.to_nat k * 1)
+ * (Pos.to_nat (Pos.max x x0)~0 * n))%nat).
+ simpl in maj. rewrite abs in maj. inversion maj.
+Qed.
+
+Lemma CReal_inv_r : forall (r:CReal) (rnz : r # 0),
+ r * ((/ r) rnz) == 1.
+Proof.
+ intros. rewrite CReal_mult_comm, CReal_inv_l.
+ reflexivity.
+Qed.
+
+Lemma CReal_inv_1 : forall nz : 1 # 0, (/ 1) nz == 1.
+Proof.
+ intros. rewrite <- (CReal_mult_1_l ((/1) nz)). rewrite CReal_inv_r.
+ reflexivity.
+Qed.
+
+Lemma CReal_inv_mult_distr :
+ forall r1 r2 (r1nz : r1 # 0) (r2nz : r2 # 0) (rmnz : (r1*r2) # 0),
+ (/ (r1 * r2)) rmnz == (/ r1) r1nz * (/ r2) r2nz.
+Proof.
+ intros. apply (CReal_mult_eq_reg_l r1). exact r1nz.
+ rewrite <- CReal_mult_assoc. rewrite CReal_inv_r. rewrite CReal_mult_1_l.
+ apply (CReal_mult_eq_reg_l r2). exact r2nz.
+ rewrite CReal_inv_r. rewrite <- CReal_mult_assoc.
+ rewrite (CReal_mult_comm r2 r1). rewrite CReal_inv_r.
+ reflexivity.
+Qed.
+
+Lemma Rinv_eq_compat : forall x y (rxnz : x # 0) (rynz : y # 0),
+ x == y
+ -> (/ x) rxnz == (/ y) rynz.
+Proof.
+ intros. apply (CReal_mult_eq_reg_l x). exact rxnz.
+ rewrite CReal_inv_r, H, CReal_inv_r. reflexivity.
+Qed.
+
+Lemma CReal_mult_lt_reg_l : forall r r1 r2, 0 < r -> r * r1 < r * r2 -> r1 < r2.
+Proof.
+ intros z x y H H0.
+ apply (CReal_mult_lt_compat_l ((/z) (inr H))) in H0.
+ repeat rewrite <- CReal_mult_assoc in H0. rewrite CReal_inv_l in H0.
+ repeat rewrite CReal_mult_1_l in H0. apply H0.
+ apply CReal_inv_0_lt_compat. exact H.
+Qed.
+
+Lemma CReal_mult_lt_reg_r : forall r r1 r2, 0 < r -> r1 * r < r2 * r -> r1 < r2.
+Proof.
+ intros.
+ apply CReal_mult_lt_reg_l with r.
+ exact H.
+ now rewrite 2!(CReal_mult_comm r).
+Qed.
+
+Lemma CReal_mult_eq_reg_r : forall r r1 r2, r1 * r == r2 * r -> r # 0 -> r1 == r2.
+Proof.
+ intros. apply (CReal_mult_eq_reg_l r). exact H0.
+ now rewrite 2!(CReal_mult_comm r).
+Qed.
+
+Lemma CReal_mult_eq_compat_l : forall r r1 r2, r1 == r2 -> r * r1 == r * r2.
+Proof.
+ intros. rewrite H. reflexivity.
+Qed.
+
+Lemma CReal_mult_eq_compat_r : forall r r1 r2, r1 == r2 -> r1 * r == r2 * r.
+Proof.
+ intros. rewrite H. reflexivity.
+Qed.
+
+(* In particular x * y == 1 implies that 0 # x, 0 # y and
+ that x and y are inverses of each other. *)
+Lemma CReal_mult_pos_appart_zero : forall x y : CReal, 0 < x * y -> 0 # x.
+Proof.
+ intros. destruct (linear_order_T 0 x 1 (CRealLt_0_1)).
+ left. exact c. destruct (linear_order_T (CReal_opp 1) x 0).
+ rewrite <- CReal_opp_0. apply CReal_opp_gt_lt_contravar, CRealLt_0_1.
+ 2: right; exact c0.
+ pose proof (CRealLt_above _ _ H). destruct H0 as [k kmaj].
+ simpl in kmaj.
+ apply CRealLt_above in c. destruct c as [i imaj]. simpl in imaj.
+ apply CRealLt_above in c0. destruct c0 as [j jmaj]. simpl in jmaj.
+ pose proof (CReal_abs_appart_zero y).
+ destruct x as [xn xcau], y as [yn ycau]. simpl in kmaj.
+ destruct (QCauchySeq_bounded xn Pos.to_nat xcau) as [a amaj],
+ (QCauchySeq_bounded yn Pos.to_nat ycau) as [b bmaj]; simpl in kmaj.
+ clear amaj bmaj. simpl in imaj, jmaj. simpl in H0.
+ specialize (kmaj (Pos.max k (Pos.max i j)) (Pos.le_max_l _ _)).
+ destruct (H0 ((Pos.max a b)~0 * (Pos.max k (Pos.max i j)))%positive).
+ - apply (Qlt_trans _ (2#k)).
+ + unfold Qlt. rewrite <- Z.mul_lt_mono_pos_l. 2: reflexivity.
+ unfold Qden. apply Pos2Z.pos_lt_pos.
+ apply (Pos.le_lt_trans _ (1 * Pos.max k (Pos.max i j))).
+ rewrite Pos.mul_1_l. apply Pos.le_max_l.
+ apply Pos2Nat.inj_lt. do 2 rewrite Pos2Nat.inj_mul.
+ rewrite <- Nat.mul_lt_mono_pos_r. 2: apply Pos2Nat.is_pos.
+ fold (2*Pos.max a b)%positive. rewrite Pos2Nat.inj_mul.
+ apply Nat.lt_1_mul_pos. auto. apply Pos2Nat.is_pos.
+ + apply (Qlt_le_trans _ _ _ kmaj). unfold Qminus. rewrite Qplus_0_r.
+ rewrite <- (Qmult_1_l (Qabs (yn (Pos.to_nat ((Pos.max a b)~0 * Pos.max k (Pos.max i j)))))).
+ apply (Qle_trans _ _ _ (Qle_Qabs _)). rewrite Qabs_Qmult.
+ replace (Pos.to_nat (Pos.max a b)~0 * Pos.to_nat (Pos.max k (Pos.max i j)))%nat
+ with (Pos.to_nat ((Pos.max a b)~0 * Pos.max k (Pos.max i j))).
+ 2: apply Pos2Nat.inj_mul.
+ apply Qmult_le_compat_r. 2: apply Qabs_nonneg.
+ apply Qabs_Qle_condition. split.
+ apply Qlt_le_weak. apply Qlt_minus_iff, (Qlt_trans _ (2#j)).
+ reflexivity. apply jmaj.
+ apply (Pos.le_trans _ (1 * Pos.max k (Pos.max i j))).
+ rewrite Pos.mul_1_l.
+ apply (Pos.le_trans _ (Pos.max i j) _ (Pos.le_max_r _ _)).
+ apply Pos.le_max_r.
+ apply Pos2Nat.inj_le. do 2 rewrite Pos2Nat.inj_mul.
+ rewrite <- Nat.mul_le_mono_pos_r. 2: apply Pos2Nat.is_pos.
+ apply Pos2Nat.is_pos.
+ apply Qlt_le_weak. apply Qlt_minus_iff, (Qlt_trans _ (2#i)).
+ reflexivity. apply imaj.
+ apply (Pos.le_trans _ (1 * Pos.max k (Pos.max i j))).
+ rewrite Pos.mul_1_l.
+ apply (Pos.le_trans _ (Pos.max i j) _ (Pos.le_max_l _ _)).
+ apply Pos.le_max_r.
+ apply Pos2Nat.inj_le. do 2 rewrite Pos2Nat.inj_mul.
+ rewrite <- Nat.mul_le_mono_pos_r. 2: apply Pos2Nat.is_pos.
+ apply Pos2Nat.is_pos.
+ - left. apply (CReal_mult_lt_reg_r (exist _ yn ycau) _ _ c).
+ rewrite CReal_mult_0_l. exact H.
+ - right. apply (CReal_mult_lt_reg_r (CReal_opp (exist _ yn ycau))).
+ rewrite <- CReal_opp_0. apply CReal_opp_gt_lt_contravar. exact c.
+ rewrite CReal_mult_0_l, <- CReal_opp_0, <- CReal_opp_mult_distr_r.
+ apply CReal_opp_gt_lt_contravar. exact H.
+Qed.
+
+Fixpoint pow (r:CReal) (n:nat) : CReal :=
+ match n with
+ | O => 1
+ | S n => r * (pow r n)
+ end.
+
+
+Lemma CReal_mult_le_compat_l_half : forall r r1 r2,
+ 0 < r -> r1 <= r2 -> r * r1 <= r * r2.
+Proof.
+ intros. intro abs. apply (CReal_mult_lt_reg_l) in abs.
+ contradiction. apply H.
+Qed.
+
+Lemma CReal_invQ : forall (b : positive) (pos : Qlt 0 (Z.pos b # 1)),
+ CRealEq (CReal_inv (inject_Q (Z.pos b # 1)) (inr (CReal_injectQPos (Z.pos b # 1) pos)))
+ (inject_Q (1 # b)).
+Proof.
+ intros.
+ apply (CReal_mult_eq_reg_l (inject_Q (Z.pos b # 1))).
+ - right. apply CReal_injectQPos. exact pos.
+ - rewrite CReal_mult_comm, CReal_inv_l.
+ apply CRealEq_diff. intro n. simpl;
+ destruct (QCauchySeq_bounded (fun _ : nat => 1 # b)%Q Pos.to_nat (ConstCauchy (1 # b))),
+ (QCauchySeq_bounded (fun _ : nat => Z.pos b # 1)%Q Pos.to_nat (ConstCauchy (Z.pos b # 1))); simpl.
+ do 2 rewrite Pos.mul_1_r. rewrite Z.pos_sub_diag. discriminate.
+Qed.
+
+Definition CRealQ_dense (a b : CReal)
+ : a < b -> { q : Q & a < inject_Q q < b }.
+Proof.
+ (* Locate a and b at the index given by a<b,
+ and pick the middle rational number. *)
+ intros [p pmaj].
+ exists ((proj1_sig a (Pos.to_nat p) + proj1_sig b (Pos.to_nat p)) * (1#2))%Q.
+ split.
+ - apply (CReal_le_lt_trans _ _ _ (inject_Q_compare a p)). apply inject_Q_lt.
+ apply (Qmult_lt_l _ _ 2). reflexivity.
+ apply (Qplus_lt_l _ _ (-2*proj1_sig a (Pos.to_nat p))).
+ field_simplify. field_simplify in pmaj.
+ setoid_replace (-2#2)%Q with (-1)%Q. 2: reflexivity.
+ setoid_replace (2*(1#p))%Q with (2#p)%Q. 2: reflexivity.
+ rewrite Qplus_comm. exact pmaj.
+ - apply (CReal_plus_lt_reg_l (-b)).
+ rewrite CReal_plus_opp_l.
+ apply (CReal_plus_lt_reg_r
+ (-inject_Q ((proj1_sig a (Pos.to_nat p) + proj1_sig b (Pos.to_nat p)) * (1 # 2)))).
+ rewrite CReal_plus_assoc, CReal_plus_opp_r, CReal_plus_0_r, CReal_plus_0_l.
+ rewrite <- opp_inject_Q.
+ apply (CReal_le_lt_trans _ _ _ (inject_Q_compare (-b) p)). apply inject_Q_lt.
+ apply (Qmult_lt_l _ _ 2). reflexivity.
+ apply (Qplus_lt_l _ _ (2*proj1_sig b (Pos.to_nat p))).
+ destruct b as [bn bcau]; simpl. simpl in pmaj.
+ field_simplify. field_simplify in pmaj.
+ setoid_replace (-2#2)%Q with (-1)%Q. 2: reflexivity.
+ setoid_replace (2*(1#p))%Q with (2#p)%Q. 2: reflexivity. exact pmaj.
+Qed.
+
+Lemma inject_Q_mult : forall q r : Q,
+ inject_Q (q * r) == inject_Q q * inject_Q r.
+Proof.
+ split.
+ - intros [n maj]. simpl in maj.
+ destruct (QCauchySeq_bounded (fun _ : nat => q) Pos.to_nat (ConstCauchy q)).
+ destruct (QCauchySeq_bounded (fun _ : nat => r) Pos.to_nat (ConstCauchy r)).
+ simpl in maj. ring_simplify in maj. discriminate maj.
+ - intros [n maj]. simpl in maj.
+ destruct (QCauchySeq_bounded (fun _ : nat => q) Pos.to_nat (ConstCauchy q)).
+ destruct (QCauchySeq_bounded (fun _ : nat => r) Pos.to_nat (ConstCauchy r)).
+ simpl in maj. ring_simplify in maj. discriminate maj.
+Qed.
diff --git a/theories/Reals/ConstructiveRIneq.v b/theories/Reals/ConstructiveRIneq.v
index b53436be55..e0f08d2fbe 100644
--- a/theories/Reals/ConstructiveRIneq.v
+++ b/theories/Reals/ConstructiveRIneq.v
@@ -22,9 +22,8 @@
constructive reals, do not use ConstructiveCauchyReals
directly. *)
-Require Import ConstructiveCauchyReals.
+Require Import ConstructiveCauchyRealsMult.
Require Import ConstructiveRcomplete.
-Require Import ConstructiveRealsLUB.
Require Export ConstructiveReals.
Require Import Zpower.
Require Export ZArithRing.
@@ -37,11 +36,11 @@ Declare Scope R_scope_constr.
Local Open Scope Z_scope.
Local Open Scope R_scope_constr.
-Definition CR : ConstructiveReals.
+Definition CRealImplem : ConstructiveReals.
Proof.
assert (isLinearOrder CReal CRealLt) as lin.
{ repeat split. exact CRealLt_asym.
- exact CRealLt_trans.
+ exact CReal_lt_trans.
intros. destruct (CRealLt_dec x z y H).
left. exact c. right. exact c. }
apply (Build_ConstructiveReals
@@ -53,30 +52,25 @@ Proof.
CReal_plus_lt_compat_l CReal_plus_lt_reg_l
CReal_mult_lt_0_compat
CReal_inv CReal_inv_l CReal_inv_0_lt_compat
- CRealArchimedean).
+ inject_Q inject_Q_plus inject_Q_mult
+ inject_Q_one inject_Q_lt lt_inject_Q
+ CRealQ_dense Rup_pos).
- intros. destruct (Rcauchy_complete xn) as [l cv].
- intro n. apply (H (IQR (1#n))). apply IQR_pos. reflexivity.
- exists l. intros eps epsPos.
- destruct (Rup_nat ((/eps) (inr epsPos))) as [n nmaj].
- specialize (cv (Pos.of_nat (S n))) as [p pmaj].
- exists p. intros. specialize (pmaj i H0). unfold absSmall in pmaj.
- apply (CReal_mult_lt_compat_l eps) in nmaj.
- rewrite CReal_inv_r, CReal_mult_comm in nmaj.
- 2: apply epsPos. split.
- + apply (CRealLt_trans _ (-IQR (1 # Pos.of_nat (S n)))).
- 2: apply pmaj. clear pmaj.
- apply CReal_opp_gt_lt_contravar. unfold CRealGt, IQR.
- rewrite CReal_mult_1_l. apply (CReal_mult_lt_reg_l (IPR (Pos.of_nat (S n)))).
- apply IPR_pos. rewrite CReal_inv_r, <- INR_IPR, Nat2Pos.id.
- 2: discriminate. apply (CRealLt_trans _ (INR n * eps) _ nmaj).
- apply CReal_mult_lt_compat_r. exact epsPos. apply lt_INR, le_refl.
- + apply (CRealLt_trans _ (IQR (1 # Pos.of_nat (S n)))).
- apply pmaj. unfold IQR. rewrite CReal_mult_1_l.
- apply (CReal_mult_lt_reg_l (IPR (Pos.of_nat (S n)))).
- apply IPR_pos. rewrite CReal_inv_r, <- INR_IPR, Nat2Pos.id.
- 2: discriminate. apply (CRealLt_trans _ (INR n * eps) _ nmaj).
- apply CReal_mult_lt_compat_r. exact epsPos. apply lt_INR, le_refl.
- - exact sig_lub.
+ intro n. destruct (H n). exists x. intros.
+ specialize (a i j H0 H1) as [a b]. split. 2: exact b.
+ rewrite <- opp_inject_Q.
+ setoid_replace (-(1#n))%Q with (-1#n). exact a. reflexivity.
+ exists l. intros p. destruct (cv p).
+ exists x. intros. specialize (a i H0). split. 2: apply a.
+ unfold orderLe.
+ intro abs. setoid_replace (-1#p) with (-(1#p))%Q in abs.
+ rewrite opp_inject_Q in abs. destruct a. contradiction.
+ reflexivity.
+Defined.
+
+Definition CR : ConstructiveReals.
+Proof.
+ exact CRealImplem.
Qed. (* Keep it opaque to possibly change the implementation later *)
Definition R := CRcarrier CR.
@@ -1673,6 +1667,19 @@ Proof.
intro; destruct n. rewrite Rplus_0_l. reflexivity. reflexivity.
Qed.
+(**********)
+Lemma IZN : forall n:Z, (0 <= n)%Z -> { m : nat | n = Z.of_nat m }.
+Proof.
+ intros. exists (Z.to_nat n). rewrite Z2Nat.id. reflexivity. assumption.
+Qed.
+
+Lemma le_succ_r_T : forall n m : nat, (n <= S m)%nat -> {(n <= m)%nat} + {n = S m}.
+Proof.
+ intros. destruct (le_lt_dec n m). left. exact l.
+ right. apply Nat.le_succ_r in H. destruct H.
+ exfalso. apply (le_not_lt n m); assumption. exact H.
+Qed.
+
Lemma lt_INR : forall n m:nat, (n < m)%nat -> INR n < INR m.
Proof.
induction m.
@@ -2174,35 +2181,29 @@ Proof.
contradiction. apply H.
Qed.
-Lemma INR_gen_phiZ : forall (n : nat),
- gen_phiZ 0 1 Rplus Rmult Ropp (Z.of_nat n) == INR n.
+Lemma INR_CR_of_Q : forall (n : nat),
+ CR_of_Q CR (Z.of_nat n # 1) == INR n.
Proof.
induction n.
- - apply Req_refl.
- - replace (Z.of_nat (S n)) with (1 + Z.of_nat n)%Z.
- rewrite (gen_phiZ_add Req_rel (CRisRingExt CR) RisRing).
- rewrite IHn. clear IHn. simpl. rewrite (Rplus_comm 1).
- destruct n. rewrite Rplus_0_l. reflexivity. reflexivity.
+ - apply CR_of_Q_zero.
+ - transitivity (CR_of_Q CR (1 + (Z.of_nat n # 1))).
replace (S n) with (1 + n)%nat. 2: reflexivity.
- rewrite (Nat2Z.inj_add 1 n). reflexivity.
+ rewrite (Nat2Z.inj_add 1 n).
+ apply CR_of_Q_proper.
+ rewrite <- (Qinv_plus_distr (Z.of_nat 1) (Z.of_nat n) 1). reflexivity.
+ rewrite CR_of_Q_plus. rewrite IHn. clear IHn.
+ setoid_replace (INR (S n)) with (1 + INR n).
+ rewrite CR_of_Q_one. reflexivity.
+ simpl. destruct n. rewrite Rplus_0_r. reflexivity.
+ rewrite Rplus_comm. reflexivity.
Qed.
Definition Rup_nat (x : R)
: { n : nat & x < INR n }.
Proof.
- intros. destruct (CRarchimedean CR x) as [p maj].
- destruct p.
- - exists O. apply maj.
- - exists (Pos.to_nat p).
- rewrite <- positive_nat_Z, (INR_gen_phiZ (Pos.to_nat p)) in maj. exact maj.
- - exists O. apply (Rlt_trans _ _ _ maj). simpl.
- rewrite <- Ropp_0. apply Ropp_gt_lt_contravar.
- fold (gen_phiZ 0 1 Rplus Rmult Ropp (Z.pos p)).
- replace (gen_phiPOS 1 (CRplus CR) (CRmult CR) p)
- with (gen_phiZ 0 1 Rplus Rmult Ropp (Z.pos p)).
- 2: reflexivity.
- rewrite <- positive_nat_Z, (INR_gen_phiZ (Pos.to_nat p)).
- apply (lt_INR 0). apply Pos2Nat.is_pos.
+ intros. destruct (CR_archimedean CR x) as [p maj].
+ exists (Pos.to_nat p).
+ rewrite <- INR_CR_of_Q, positive_nat_Z. exact maj.
Qed.
Fixpoint Rarchimedean_ind (x:R) (n : Z) (p:nat) { struct p }
diff --git a/theories/Reals/ConstructiveRcomplete.v b/theories/Reals/ConstructiveRcomplete.v
index ce45bcd567..0a515672f2 100644
--- a/theories/Reals/ConstructiveRcomplete.v
+++ b/theories/Reals/ConstructiveRcomplete.v
@@ -11,227 +11,145 @@
Require Import QArith_base.
Require Import Qabs.
-Require Import ConstructiveCauchyReals.
+Require Import ConstructiveCauchyRealsMult.
Require Import Logic.ConstructiveEpsilon.
Local Open Scope CReal_scope.
+Definition absLe (a b : CReal) : Prop
+ := -b <= a <= b.
+
Lemma CReal_absSmall : forall (x y : CReal) (n : positive),
(Qlt (2 # n)
(proj1_sig x (Pos.to_nat n) - Qabs (proj1_sig y (Pos.to_nat n))))
- -> (CRealLt (CReal_opp x) y * CRealLt y x).
+ -> absLe y x.
Proof.
intros x y n maj. split.
- - exists n. destruct x as [xn caux], y as [yn cauy]; simpl.
+ - apply CRealLt_asym. exists n. destruct x as [xn caux], y as [yn cauy]; simpl.
simpl in maj. unfold Qminus. rewrite Qopp_involutive.
rewrite Qplus_comm.
apply (Qlt_le_trans _ (xn (Pos.to_nat n) - Qabs (yn (Pos.to_nat n)))).
apply maj. apply Qplus_le_r.
rewrite <- (Qopp_involutive (yn (Pos.to_nat n))).
apply Qopp_le_compat. rewrite Qabs_opp. apply Qle_Qabs.
- - exists n. destruct x as [xn caux], y as [yn cauy]; simpl.
+ - apply CRealLt_asym. exists n. destruct x as [xn caux], y as [yn cauy]; simpl.
simpl in maj.
apply (Qlt_le_trans _ (xn (Pos.to_nat n) - Qabs (yn (Pos.to_nat n)))).
apply maj. apply Qplus_le_r. apply Qopp_le_compat. apply Qle_Qabs.
Qed.
-Definition absSmall (a b : CReal) : Set
- := -b < a < b.
-
+(* We use absLe in sort Prop rather than Set,
+ to extract smaller programs. *)
Definition Un_cv_mod (un : nat -> CReal) (l : CReal) : Set
- := forall n : positive,
- { p : nat & forall i:nat, le p i -> absSmall (un i - l) (IQR (1#n)) }.
+ := forall p : positive,
+ { n : nat | forall i:nat, le n i -> absLe (un i - l) (inject_Q (1#p)) }.
Lemma Un_cv_mod_eq : forall (v u : nat -> CReal) (s : CReal),
(forall n:nat, u n == v n)
- -> Un_cv_mod u s -> Un_cv_mod v s.
+ -> Un_cv_mod u s
+ -> Un_cv_mod v s.
Proof.
intros v u s seq H1 p. specialize (H1 p) as [N H0].
- exists N. intros. unfold absSmall. split.
+ exists N. intros. split.
rewrite <- seq. apply H0. apply H.
rewrite <- seq. apply H0. apply H.
Qed.
Definition Un_cauchy_mod (un : nat -> CReal) : Set
- := forall n : positive,
- { p : nat & forall i j:nat, le p i
- -> le p j
- -> -IQR (1#n) < un i - un j < IQR (1#n) }.
+ := forall p : positive,
+ { n : nat | forall i j:nat, le n i -> le n j
+ -> absLe (un i - un j) (inject_Q (1#p)) }.
(* Sharpen the archimedean property : constructive versions of
- the usual floor and ceiling functions.
-
- n is a temporary parameter used for the recursion,
- look at Ffloor below. *)
-Fixpoint Rfloor_pos (a : CReal) (n : nat) { struct n }
- : 0 < a
- -> a < INR n
- -> { p : nat & INR p < a < INR p + 2 }.
-Proof.
- (* Decreasing loop on n, until it is the first integer above a. *)
- intros H H0. destruct n.
- - exfalso. apply (CRealLt_asym 0 a); assumption.
- - destruct n as [|p] eqn:des.
- + (* n = 1 *) exists O. split.
- apply H. rewrite CReal_plus_0_l. apply (CRealLt_trans a (1+0)).
- rewrite CReal_plus_comm, CReal_plus_0_l. apply H0.
- apply CReal_plus_le_lt_compat.
- apply CRealLe_refl. apply CRealLt_0_1.
- + (* n > 1 *)
- destruct (linear_order_T (INR p) a (INR (S p))).
- * rewrite <- CReal_plus_0_l, S_INR, CReal_plus_comm. apply CReal_plus_lt_compat_l.
- apply CRealLt_0_1.
- * exists p. split. exact c.
- rewrite S_INR, S_INR, CReal_plus_assoc in H0. exact H0.
- * apply (Rfloor_pos a n H). rewrite des. apply c.
-Qed.
-
+ the usual floor and ceiling functions. *)
Definition Rfloor (a : CReal)
- : { p : Z & IZR p < a < IZR p + 2 }.
+ : { p : Z & inject_Q (p#1) < a < inject_Q (p#1) + 2 }.
Proof.
- assert (forall x:CReal, 0 < x -> { n : nat & x < INR n }).
- { intros. pose proof (Rarchimedean x) as [n [maj _]].
- destruct n.
- + exfalso. apply (CRealLt_asym 0 x); assumption.
- + exists (Pos.to_nat p). rewrite INR_IPR. apply maj.
- + exfalso. apply (CRealLt_asym 0 x). apply H.
- apply (CRealLt_trans x (IZR (Z.neg p))). apply maj.
- apply (CReal_plus_lt_reg_l (-IZR (Z.neg p))).
- rewrite CReal_plus_comm, CReal_plus_opp_r. rewrite <- opp_IZR.
- rewrite CReal_plus_comm, CReal_plus_0_l.
- apply (IZR_lt 0). reflexivity. }
- destruct (linear_order_T 0 a 1 CRealLt_0_1).
- - destruct (H a c). destruct (Rfloor_pos a x c c0).
- exists (Z.of_nat x0). split; rewrite <- INR_IZR_INZ; apply p.
- - apply (CReal_plus_lt_compat_l (-a)) in c.
- rewrite CReal_plus_comm, CReal_plus_opp_r, CReal_plus_comm in c.
- destruct (H (1-a) c).
- destruct (Rfloor_pos (1-a) x c c0).
- exists (-(Z.of_nat x0 + 1))%Z. split; rewrite opp_IZR, plus_IZR.
- + rewrite <- (CReal_opp_involutive a). apply CReal_opp_gt_lt_contravar.
- destruct p as [_ a0]. apply (CReal_plus_lt_reg_r 1).
- rewrite CReal_plus_comm, CReal_plus_assoc. rewrite <- INR_IZR_INZ. apply a0.
- + destruct p as [a0 _]. apply (CReal_plus_lt_compat_l a) in a0.
- unfold CReal_minus in a0.
- rewrite <- (CReal_plus_comm (1+-a)), CReal_plus_assoc, CReal_plus_opp_l, CReal_plus_0_r in a0.
- rewrite <- INR_IZR_INZ.
- apply (CReal_plus_lt_reg_r (INR x0)). unfold IZR, IPR, IPR_2.
- ring_simplify. exact a0.
-Qed.
+ destruct (CRealArchimedean a) as [n [H H0]].
+ exists (n-2)%Z. split.
+ - setoid_replace (n - 2 # 1)%Q with ((n#1) + - 2)%Q.
+ rewrite inject_Q_plus, (opp_inject_Q 2).
+ apply (CReal_plus_lt_reg_r 2). ring_simplify.
+ rewrite CReal_plus_comm. exact H0.
+ rewrite Qinv_plus_distr. reflexivity.
+ - setoid_replace (n - 2 # 1)%Q with ((n#1) + - 2)%Q.
+ rewrite inject_Q_plus, (opp_inject_Q 2).
+ ring_simplify. exact H.
+ rewrite Qinv_plus_distr. reflexivity.
+Defined.
-Definition Rup_nat (x : CReal)
- : { n : nat & x < INR n }.
-Proof.
- intros. destruct (Rarchimedean x) as [p [maj _]].
- destruct p.
- - exists O. apply maj.
- - exists (Pos.to_nat p). rewrite INR_IPR. apply maj.
- - exists O. apply (CRealLt_trans _ (IZR (Z.neg p)) _ maj).
- apply (IZR_lt _ 0). reflexivity.
-Qed.
(* A point in an archimedean field is the limit of a
sequence of rational numbers (n maps to the q between
a and a+1/n). This will yield a maximum
archimedean field, which is the field of real numbers. *)
-Definition FQ_dense_pos (a b : CReal)
- : 0 < b
- -> a < b -> { q : Q & a < IQR q < b }.
-Proof.
- intros H H0.
- assert (0 < b - a) as epsPos.
- { apply (CReal_plus_lt_compat_l (-a)) in H0.
- rewrite CReal_plus_opp_l, CReal_plus_comm in H0.
- apply H0. }
- pose proof (Rup_nat ((/(b-a)) (inr epsPos)))
- as [n maj].
- destruct n as [|k].
- - exfalso.
- apply (CReal_mult_lt_compat_l (b-a)) in maj. 2: apply epsPos.
- rewrite CReal_mult_0_r in maj. rewrite CReal_inv_r in maj.
- apply (CRealLt_asym 0 1). apply CRealLt_0_1. apply maj.
- - (* 0 < n *)
- pose (Pos.of_nat (S k)) as n.
- destruct (Rfloor (IZR (2 * Z.pos n) * b)) as [p maj2].
- exists (p # (2*n))%Q. split.
- + apply (CRealLt_trans a (b - IQR (1 # n))).
- apply (CReal_plus_lt_reg_r (IQR (1#n))).
- unfold CReal_minus. rewrite CReal_plus_assoc. rewrite CReal_plus_opp_l.
- rewrite CReal_plus_0_r. apply (CReal_plus_lt_reg_l (-a)).
- rewrite <- CReal_plus_assoc, CReal_plus_opp_l, CReal_plus_0_l.
- rewrite CReal_plus_comm. unfold IQR.
- rewrite CReal_mult_1_l. apply (CReal_mult_lt_reg_l (IPR n)).
- apply IPR_pos. rewrite CReal_inv_r.
- apply (CReal_mult_lt_compat_l (b-a)) in maj.
- rewrite CReal_inv_r, CReal_mult_comm in maj.
- rewrite <- INR_IPR. unfold n. rewrite Nat2Pos.id.
- apply maj. discriminate. exact epsPos.
- apply (CReal_plus_lt_reg_r (IQR (1 # n))).
- unfold CReal_minus. rewrite CReal_plus_assoc, CReal_plus_opp_l.
- rewrite CReal_plus_0_r. rewrite <- plus_IQR.
- destruct maj2 as [_ maj2].
- setoid_replace ((p # 2 * n) + (1 # n))%Q
- with ((p + 2 # 2 * n))%Q. unfold IQR.
- apply (CReal_mult_lt_reg_r (IZR (Z.pos (2 * n)))).
- apply (IZR_lt 0). reflexivity. rewrite CReal_mult_assoc.
- rewrite CReal_inv_l. rewrite CReal_mult_1_r. rewrite CReal_mult_comm.
- rewrite plus_IZR. apply maj2.
- setoid_replace (1#n)%Q with (2#2*n)%Q. 2: reflexivity.
- apply Qinv_plus_distr.
- + destruct maj2 as [maj2 _]. unfold IQR.
- apply (CReal_mult_lt_reg_r (IZR (Z.pos (2 * n)))).
- apply (IZR_lt 0). apply Pos2Z.is_pos. rewrite CReal_mult_assoc, CReal_inv_l.
- rewrite CReal_mult_1_r, CReal_mult_comm. apply maj2.
-Qed.
-
Definition FQ_dense (a b : CReal)
- : a < b
- -> { q : Q & a < IQR q < b }.
+ : a < b -> { q : Q & a < inject_Q q < b }.
Proof.
- intros H. destruct (linear_order_T a 0 b). apply H.
- - destruct (FQ_dense_pos (-b) (-a)) as [q maj].
- apply (CReal_plus_lt_compat_l (-a)) in c. rewrite CReal_plus_opp_l in c.
- rewrite CReal_plus_0_r in c. apply c.
- apply (CReal_plus_lt_compat_l (-a)) in H.
+ intros H. assert (0 < b - a) as epsPos.
+ { apply (CReal_plus_lt_compat_l (-a)) in H.
rewrite CReal_plus_opp_l, CReal_plus_comm in H.
- apply (CReal_plus_lt_compat_l (-b)) in H. rewrite <- CReal_plus_assoc in H.
- rewrite CReal_plus_opp_l in H. rewrite CReal_plus_0_l in H.
- rewrite CReal_plus_0_r in H. apply H.
- exists (-q)%Q. split.
- + destruct maj as [_ maj].
- apply (CReal_plus_lt_compat_l (-IQR q)) in maj.
- rewrite CReal_plus_opp_l, <- opp_IQR, CReal_plus_comm in maj.
- apply (CReal_plus_lt_compat_l a) in maj. rewrite <- CReal_plus_assoc in maj.
- rewrite CReal_plus_opp_r, CReal_plus_0_l in maj.
- rewrite CReal_plus_0_r in maj. apply maj.
- + destruct maj as [maj _].
- apply (CReal_plus_lt_compat_l (-IQR q)) in maj.
- rewrite CReal_plus_opp_l, <- opp_IQR, CReal_plus_comm in maj.
- apply (CReal_plus_lt_compat_l b) in maj. rewrite <- CReal_plus_assoc in maj.
- rewrite CReal_plus_opp_r in maj. rewrite CReal_plus_0_l in maj.
- rewrite CReal_plus_0_r in maj. apply maj.
- - apply FQ_dense_pos. apply c. apply H.
+ apply H. }
+ pose proof (Rup_pos ((/(b-a)) (inr epsPos)))
+ as [n maj].
+ destruct (Rfloor (inject_Q (2 * Z.pos n # 1) * b)) as [p maj2].
+ exists (p # (2*n))%Q. split.
+ - apply (CReal_lt_trans a (b - inject_Q (1 # n))).
+ apply (CReal_plus_lt_reg_r (inject_Q (1#n))).
+ unfold CReal_minus. rewrite CReal_plus_assoc. rewrite CReal_plus_opp_l.
+ rewrite CReal_plus_0_r. apply (CReal_plus_lt_reg_l (-a)).
+ rewrite <- CReal_plus_assoc, CReal_plus_opp_l, CReal_plus_0_l.
+ rewrite CReal_plus_comm.
+ apply (CReal_mult_lt_reg_l (inject_Q (Z.pos n # 1))).
+ apply inject_Q_lt. reflexivity. rewrite <- inject_Q_mult.
+ setoid_replace ((Z.pos n # 1) * (1 # n))%Q with 1%Q.
+ apply (CReal_mult_lt_compat_l (b-a)) in maj.
+ rewrite CReal_inv_r, CReal_mult_comm in maj. exact maj.
+ exact epsPos. unfold Qeq; simpl. do 2 rewrite Pos.mul_1_r. reflexivity.
+ apply (CReal_plus_lt_reg_r (inject_Q (1 # n))).
+ unfold CReal_minus. rewrite CReal_plus_assoc, CReal_plus_opp_l.
+ rewrite CReal_plus_0_r. rewrite <- inject_Q_plus.
+ destruct maj2 as [_ maj2].
+ setoid_replace ((p # 2 * n) + (1 # n))%Q
+ with ((p + 2 # 2 * n))%Q.
+ apply (CReal_mult_lt_reg_r (inject_Q (Z.pos (2 * n) # 1))).
+ apply inject_Q_lt. reflexivity. rewrite <- inject_Q_mult.
+ setoid_replace ((p + 2 # 2 * n) * (Z.pos (2 * n) # 1))%Q
+ with ((p#1) + 2)%Q.
+ rewrite inject_Q_plus. rewrite Pos2Z.inj_mul.
+ rewrite CReal_mult_comm. exact maj2.
+ unfold Qeq; simpl. rewrite Pos.mul_1_r, Z.mul_1_r. ring.
+ setoid_replace (1#n)%Q with (2#2*n)%Q. 2: reflexivity.
+ apply Qinv_plus_distr.
+ - destruct maj2 as [maj2 _].
+ apply (CReal_mult_lt_reg_r (inject_Q (Z.pos (2 * n) # 1))).
+ apply inject_Q_lt. reflexivity.
+ rewrite <- inject_Q_mult.
+ setoid_replace ((p # 2 * n) * (Z.pos (2 * n) # 1))%Q
+ with ((p#1))%Q.
+ rewrite CReal_mult_comm. exact maj2.
+ unfold Qeq; simpl. rewrite Pos.mul_1_r, Z.mul_1_r. reflexivity.
Qed.
Definition RQ_limit : forall (x : CReal) (n:nat),
- { q:Q & x < IQR q < x + IQR (1 # Pos.of_nat n) }.
+ { q:Q & x < inject_Q q < x + inject_Q (1 # Pos.of_nat n) }.
Proof.
- intros x n. apply (FQ_dense x (x + IQR (1 # Pos.of_nat n))).
+ intros x n. apply (FQ_dense x (x + inject_Q (1 # Pos.of_nat n))).
rewrite <- (CReal_plus_0_r x). rewrite CReal_plus_assoc.
- apply CReal_plus_lt_compat_l. rewrite CReal_plus_0_l. apply IQR_pos.
+ apply CReal_plus_lt_compat_l. rewrite CReal_plus_0_l. apply inject_Q_lt.
reflexivity.
Qed.
Definition Un_cauchy_Q (xn : nat -> Q) : Set
:= forall n : positive,
{ k : nat | forall p q : nat, le k p -> le k q
- -> Qlt (-(1#n)) (xn p - xn q)
- /\ Qlt (xn p - xn q) (1#n) }.
+ -> Qle (-(1#n)) (xn p - xn q)
+ /\ Qle (xn p - xn q) (1#n) }.
Lemma Rdiag_cauchy_sequence : forall (xn : nat -> CReal),
Un_cauchy_mod xn
- -> Un_cauchy_Q (fun n => let (l,_) := RQ_limit (xn n) n in l).
+ -> Un_cauchy_Q (fun n:nat => let (l,_) := RQ_limit (xn n) n in l).
Proof.
intros xn H p. specialize (H (2 * p)%positive) as [k cv].
exists (max k (2 * Pos.to_nat p)). intros.
@@ -241,67 +159,69 @@ Proof.
apply (le_trans _ (Init.Nat.max k (2 * Pos.to_nat p))).
apply Nat.le_max_l. apply H0.
split.
- - apply lt_IQR. unfold Qminus.
- apply (CRealLt_trans _ (xn p0 - (xn q + IQR (1 # 2 * p)))).
- + unfold CReal_minus. rewrite CReal_opp_plus_distr. unfold CReal_minus.
+ - apply le_inject_Q. unfold Qminus.
+ apply (CReal_le_trans _ (xn p0 - (xn q + inject_Q (1 # 2 * p)))).
+ + unfold CReal_minus. rewrite CReal_opp_plus_distr.
rewrite <- CReal_plus_assoc.
- apply (CReal_plus_lt_reg_r (IQR (1 # 2 * p))).
+ apply (CReal_plus_le_reg_r (inject_Q (1 # 2 * p))).
rewrite CReal_plus_assoc. rewrite CReal_plus_opp_l. rewrite CReal_plus_0_r.
- rewrite <- plus_IQR.
+ rewrite <- inject_Q_plus.
setoid_replace (- (1 # p) + (1 # 2 * p))%Q with (- (1 # 2 * p))%Q.
- rewrite opp_IQR. exact c.
+ rewrite opp_inject_Q. exact H1.
rewrite Qplus_comm.
setoid_replace (1#p)%Q with (2 # 2 *p)%Q. rewrite Qinv_minus_distr.
reflexivity. reflexivity.
- + rewrite plus_IQR. apply CReal_plus_le_lt_compat.
+ + rewrite inject_Q_plus. apply CReal_plus_le_compat.
apply CRealLt_asym.
destruct (RQ_limit (xn p0) p0); simpl. apply p1.
+ apply CRealLt_asym.
destruct (RQ_limit (xn q) q); unfold proj1_sig.
- rewrite opp_IQR. apply CReal_opp_gt_lt_contravar.
- apply (CRealLt_Le_trans _ (xn q + IQR (1 # Pos.of_nat q))).
- apply p1. apply CReal_plus_le_compat_l. apply IQR_le.
+ rewrite opp_inject_Q. apply CReal_opp_gt_lt_contravar.
+ apply (CReal_lt_le_trans _ (xn q + inject_Q (1 # Pos.of_nat q))).
+ apply p1. apply CReal_plus_le_compat_l. apply inject_Q_le.
apply Z2Nat.inj_le. discriminate. discriminate.
simpl. assert ((Pos.to_nat p~0 <= q)%nat).
{ apply (le_trans _ (Init.Nat.max k (2 * Pos.to_nat p))).
2: apply H0. replace (p~0)%positive with (2*p)%positive.
2: reflexivity. rewrite Pos2Nat.inj_mul.
apply Nat.le_max_r. }
- rewrite Nat2Pos.id. apply H1. intro abs. subst q.
- inversion H1. pose proof (Pos2Nat.is_pos (p~0)).
- rewrite H3 in H2. inversion H2.
- - apply lt_IQR. unfold Qminus.
- apply (CRealLt_trans _ (xn p0 + IQR (1 # 2 * p) - xn q)).
- + rewrite plus_IQR. apply CReal_plus_le_lt_compat.
+ rewrite Nat2Pos.id. apply H3. intro abs. subst q.
+ inversion H3. pose proof (Pos2Nat.is_pos (p~0)).
+ rewrite H5 in H4. inversion H4.
+ - apply le_inject_Q. unfold Qminus.
+ apply (CReal_le_trans _ (xn p0 + inject_Q (1 # 2 * p) - xn q)).
+ + rewrite inject_Q_plus. apply CReal_plus_le_compat.
apply CRealLt_asym.
destruct (RQ_limit (xn p0) p0); unfold proj1_sig.
- apply (CRealLt_Le_trans _ (xn p0 + IQR (1 # Pos.of_nat p0))).
- apply p1. apply CReal_plus_le_compat_l. apply IQR_le.
+ apply (CReal_lt_le_trans _ (xn p0 + inject_Q (1 # Pos.of_nat p0))).
+ apply p1. apply CReal_plus_le_compat_l. apply inject_Q_le.
apply Z2Nat.inj_le. discriminate. discriminate.
simpl. assert ((Pos.to_nat p~0 <= p0)%nat).
{ apply (le_trans _ (Init.Nat.max k (2 * Pos.to_nat p))).
2: apply H. replace (p~0)%positive with (2*p)%positive.
2: reflexivity. rewrite Pos2Nat.inj_mul.
apply Nat.le_max_r. }
- rewrite Nat2Pos.id. apply H1. intro abs. subst p0.
- inversion H1. pose proof (Pos2Nat.is_pos (p~0)).
- rewrite H3 in H2. inversion H2.
- rewrite opp_IQR. apply CReal_opp_gt_lt_contravar.
+ rewrite Nat2Pos.id. apply H3. intro abs. subst p0.
+ inversion H3. pose proof (Pos2Nat.is_pos (p~0)).
+ rewrite H5 in H4. inversion H4.
+ apply CRealLt_asym.
+ rewrite opp_inject_Q. apply CReal_opp_gt_lt_contravar.
destruct (RQ_limit (xn q) q); simpl. apply p1.
+ unfold CReal_minus. rewrite (CReal_plus_comm (xn p0)).
rewrite CReal_plus_assoc.
- apply (CReal_plus_lt_reg_l (- IQR (1 # 2 * p))).
+ apply (CReal_plus_le_reg_l (- inject_Q (1 # 2 * p))).
rewrite <- CReal_plus_assoc. rewrite CReal_plus_opp_l. rewrite CReal_plus_0_l.
- rewrite <- opp_IQR. rewrite <- plus_IQR.
+ rewrite <- opp_inject_Q. rewrite <- inject_Q_plus.
setoid_replace (- (1 # 2 * p) + (1 # p))%Q with (1 # 2 * p)%Q.
- exact c0. rewrite Qplus_comm.
+ exact H2. rewrite Qplus_comm.
setoid_replace (1#p)%Q with (2 # 2*p)%Q. rewrite Qinv_minus_distr.
reflexivity. reflexivity.
Qed.
-Lemma doubleLtCovariant : forall a b c d e f : CReal,
+Lemma doubleLeCovariant : forall a b c d e f : CReal,
a == b -> c == d -> e == f
- -> (a < c < e)
- -> (b < d < f).
+ -> (a <= c <= e)
+ -> (b <= d <= f).
Proof.
split. rewrite <- H. rewrite <- H0. apply H2.
rewrite <- H0. rewrite <- H1. apply H2.
@@ -311,15 +231,13 @@ Qed.
show that it converges to itself in CReal. *)
Lemma CReal_cv_self : forall (qn : nat -> Q) (x : CReal) (cvmod : positive -> nat),
QSeqEquiv qn (fun n => proj1_sig x n) cvmod
- -> Un_cv_mod (fun n => IQR (qn n)) x.
+ -> Un_cv_mod (fun n => inject_Q (qn n)) x.
Proof.
intros qn x cvmod H p.
specialize (H (2*p)%positive). exists (cvmod (2*p)%positive).
- intros p0 H0. unfold absSmall, CReal_minus.
- apply (doubleLtCovariant (-inject_Q (1#p)) _ (inject_Q (qn p0) - x) _ (inject_Q (1#p))).
- rewrite FinjectQ_CReal. reflexivity.
- rewrite FinjectQ_CReal. reflexivity.
- rewrite FinjectQ_CReal. reflexivity.
+ intros p0 H0. unfold absLe, CReal_minus.
+ apply (doubleLeCovariant (-inject_Q (1#p)) _ (inject_Q (qn p0) - x) _ (inject_Q (1#p))).
+ reflexivity. reflexivity. reflexivity.
apply (CReal_absSmall _ _ (Pos.max (4 * p)%positive (Pos.of_nat (cvmod (2 * p)%positive)))).
setoid_replace (proj1_sig (inject_Q (1 # p)) (Pos.to_nat (Pos.max (4 * p) (Pos.of_nat (cvmod (2 * p)%positive)))))
with (1 # p)%Q.
@@ -353,7 +271,7 @@ Lemma Un_cv_extens : forall (xn yn : nat -> CReal) (l : CReal),
-> Un_cv_mod yn l.
Proof.
intros. intro p. destruct (H p) as [n cv]. exists n.
- intros. unfold absSmall, CReal_minus.
+ intros. unfold absLe, CReal_minus.
split; rewrite <- (H0 i); apply cv; apply H1.
Qed.
@@ -362,29 +280,28 @@ Qed.
The biggest computable such field has all rational limits. *)
Lemma R_has_all_rational_limits : forall qn : nat -> Q,
Un_cauchy_Q qn
- -> { r : CReal & Un_cv_mod (fun n => IQR (qn n)) r }.
+ -> { r : CReal & Un_cv_mod (fun n:nat => inject_Q (qn n)) r }.
Proof.
- (* qn is an element of CReal. Show that IQR qn
+ (* qn is an element of CReal. Show that inject_Q qn
converges to it in CReal. *)
intros.
- destruct (standard_modulus qn (fun p => proj1_sig (H p))).
- - intros p n k H0 H1. destruct (H p); simpl in H0,H1.
- specialize (a n k H0 H1). apply Qabs_case.
- intros _. apply a. intros _.
- apply (Qplus_lt_r _ _ (qn n -qn k-(1#p))). ring_simplify.
- destruct a. ring_simplify in H2. exact H2.
+ destruct (standard_modulus qn (fun p => proj1_sig (H (Pos.succ p)))).
+ - intros p n k H0 H1. destruct (H (Pos.succ p)%positive) as [x a]; simpl in H0,H1.
+ specialize (a n k H0 H1).
+ apply (Qle_lt_trans _ (1#Pos.succ p)).
+ apply Qabs_Qle_condition. exact a.
+ apply Pos2Z.pos_lt_pos. simpl. apply Pos.lt_succ_diag_r.
- exists (exist _ (fun n : nat =>
- qn (increasing_modulus (fun p : positive => proj1_sig (H p)) n)) H0).
- apply (Un_cv_extens (fun n : nat => IQR (qn n))).
+ qn (increasing_modulus (fun p : positive => proj1_sig (H (Pos.succ p))) n)) H0).
apply (CReal_cv_self qn (exist _ (fun n : nat =>
- qn (increasing_modulus (fun p : positive => proj1_sig (H p)) n)) H0)
- (fun p : positive => Init.Nat.max (proj1_sig (H p)) (Pos.to_nat p))).
- apply H1. intro n. reflexivity.
+ qn (increasing_modulus (fun p : positive => proj1_sig (H (Pos.succ p))) n)) H0)
+ (fun p : positive => Init.Nat.max (proj1_sig (H (Pos.succ p))) (Pos.to_nat p))).
+ apply H1.
Qed.
Lemma Rcauchy_complete : forall (xn : nat -> CReal),
Un_cauchy_mod xn
- -> { l : CReal & Un_cv_mod xn l }.
+ -> { l : CReal & Un_cv_mod xn l }.
Proof.
intros xn cau.
destruct (R_has_all_rational_limits (fun n => let (l,_) := RQ_limit (xn n) n in l)
@@ -396,21 +313,21 @@ Proof.
apply Nat.le_max_l. apply H.
destruct (RQ_limit (xn p0) p0) as [q maj]; unfold proj1_sig in H0,H1.
split.
- - apply (CRealLt_trans _ (IQR q - IQR (1 # 2 * p) - l)).
- + unfold CReal_minus. rewrite (CReal_plus_comm (IQR q)).
- apply (CReal_plus_lt_reg_l (IQR (1 # 2 * p))).
- ring_simplify. unfold CReal_minus. rewrite <- opp_IQR. rewrite <- plus_IQR.
+ - apply (CReal_le_trans _ (inject_Q q - inject_Q (1 # 2 * p) - l)).
+ + unfold CReal_minus. rewrite (CReal_plus_comm (inject_Q q)).
+ apply (CReal_plus_le_reg_l (inject_Q (1 # 2 * p))).
+ ring_simplify. unfold CReal_minus. rewrite <- opp_inject_Q. rewrite <- inject_Q_plus.
setoid_replace ((1 # 2 * p) + - (1 # p))%Q with (-(1#2*p))%Q.
- rewrite opp_IQR. apply H0.
+ rewrite opp_inject_Q. apply H0.
setoid_replace (1#p)%Q with (2 # 2*p)%Q.
rewrite Qinv_minus_distr. reflexivity. reflexivity.
+ unfold CReal_minus.
- do 2 rewrite <- (CReal_plus_comm (-l)). apply CReal_plus_lt_compat_l.
- apply (CReal_plus_lt_reg_r (IQR (1 # 2 * p))).
+ do 2 rewrite <- (CReal_plus_comm (-l)). apply CReal_plus_le_compat_l.
+ apply (CReal_plus_le_reg_r (inject_Q (1 # 2 * p))).
ring_simplify. rewrite CReal_plus_comm.
- apply (CRealLt_Le_trans _ (xn p0 + IQR (1 # Pos.of_nat p0))).
- apply maj. apply CReal_plus_le_compat_l.
- apply IQR_le.
+ apply (CReal_le_trans _ (xn p0 + inject_Q (1 # Pos.of_nat p0))).
+ apply CRealLt_asym, maj. apply CReal_plus_le_compat_l.
+ apply inject_Q_le.
apply Z2Nat.inj_le. discriminate. discriminate.
simpl. assert ((Pos.to_nat p~0 <= p0)%nat).
{ apply (le_trans _ (Init.Nat.max k (2 * Pos.to_nat p))).
@@ -420,13 +337,13 @@ Proof.
rewrite Nat2Pos.id. apply H2. intro abs. subst p0.
inversion H2. pose proof (Pos2Nat.is_pos (p~0)).
rewrite H4 in H3. inversion H3.
- - apply (CRealLt_trans _ (IQR q - l)).
+ - apply (CReal_le_trans _ (inject_Q q - l)).
+ unfold CReal_minus. do 2 rewrite <- (CReal_plus_comm (-l)).
- apply CReal_plus_lt_compat_l. apply maj.
- + apply (CRealLt_trans _ (IQR (1 # 2 * p))).
- apply H1. apply IQR_lt.
+ apply CReal_plus_le_compat_l. apply CRealLt_asym, maj.
+ + apply (CReal_le_trans _ (inject_Q (1 # 2 * p))).
+ apply H1. apply inject_Q_le.
rewrite <- Qplus_0_r.
setoid_replace (1#p)%Q with ((1#2*p)+(1#2*p))%Q.
- apply Qplus_lt_r. reflexivity.
+ apply Qplus_le_r. discriminate.
rewrite Qinv_plus_distr. reflexivity.
Qed.
diff --git a/theories/Reals/ConstructiveReals.v b/theories/Reals/ConstructiveReals.v
index fc3d6afe15..25242f5ea9 100644
--- a/theories/Reals/ConstructiveReals.v
+++ b/theories/Reals/ConstructiveReals.v
@@ -9,10 +9,10 @@
(************************************************************************)
(************************************************************************)
-(* An interface for constructive and computable real numbers.
- All of its instances are isomorphic, for example it contains
- the Cauchy reals implemented in file ConstructivecauchyReals
- and the sumbool-based Dedekind reals defined by
+(** An interface for constructive and computable real numbers.
+ All of its instances are isomorphic (see file ConstructiveRealsMorphisms).
+ For example it contains the Cauchy reals implemented in file
+ ConstructivecauchyReals and the sumbool-based Dedekind reals defined by
Structure R := {
(* The cuts are represented as propositional functions, rather than subsets,
@@ -41,7 +41,22 @@ Structure R := {
see github.com/andrejbauer/dedekind-reals for the Prop-based
version of those Dedekind reals (although Prop fails to make
- them an instance of ConstructiveReals). *)
+ them an instance of ConstructiveReals).
+
+ Any computation about constructive reals, can be worked
+ in the fastest instance for it; we then transport the results
+ to all other instances by the isomorphisms. This way of working
+ is different from the usual interfaces, where we would rather
+ prove things abstractly, by quantifying universally on the instance.
+
+ The functions of ConstructiveReals do not have a direct impact
+ on performance, because algorithms will be extracted from instances,
+ and because fast ConstructiveReals morphisms should be coded
+ manually. However, since instances are forced to implement
+ those functions, it is probable that they will also use them
+ in their algorithms. So those functions hint at what we think
+ will yield fast and small extracted programs. *)
+
Require Import QArith.
@@ -56,6 +71,9 @@ Definition orderEq (X : Set) (Xlt : X -> X -> Set) (x y : X) : Prop
Definition orderAppart (X : Set) (Xlt : X -> X -> Set) (x y : X) : Set
:= Xlt x y + Xlt y x.
+Definition orderLe (X : Set) (Xlt : X -> X -> Set) (x y : X) : Prop
+ := Xlt y x -> False.
+
Definition sig_forall_dec_T : Type
:= forall (P : nat -> Prop), (forall n, {P n} + {~P n})
-> {n | ~P n} + {forall n, P n}.
@@ -65,9 +83,17 @@ Definition sig_not_dec_T : Type := forall P : Prop, { ~~P } + { ~P }.
Record ConstructiveReals : Type :=
{
CRcarrier : Set;
+
+ (* Put this order relation in sort Set rather than Prop,
+ to allow the definition of fast ConstructiveReals morphisms.
+ For example, the Cauchy reals do store information in
+ the proofs of CRlt, which is used in algorithms in sort Set. *)
CRlt : CRcarrier -> CRcarrier -> Set;
CRltLinear : isLinearOrder CRcarrier CRlt;
+ (* The propositional truncation of CRlt. It facilitates proofs
+ when computations are not considered important, for example in
+ classical reals with extra logical axioms. *)
CRltProp : CRcarrier -> CRcarrier -> Prop;
(* This choice algorithm can be slow, keep it for the classical
quotient of the reals, where computations are blocked by
@@ -114,36 +140,696 @@ Record ConstructiveReals : Type :=
CRinv_0_lt_compat : forall (r : CRcarrier) (rnz : orderAppart _ CRlt r CRzero),
CRlt CRzero r -> CRlt CRzero (CRinv r rnz);
- CRarchimedean : forall x : CRcarrier,
- { k : Z & CRlt x (gen_phiZ CRzero CRone CRplus CRmult CRopp k) };
+ (* The initial field morphism (in characteristic zero).
+ The abstract definition by iteration of addition is
+ probably the slowest. Let each instance implement
+ a faster (and often simpler) version. *)
+ CR_of_Q : Q -> CRcarrier;
+ CR_of_Q_plus : forall q r : Q, orderEq _ CRlt (CR_of_Q (q+r))
+ (CRplus (CR_of_Q q) (CR_of_Q r));
+ CR_of_Q_mult : forall q r : Q, orderEq _ CRlt (CR_of_Q (q*r))
+ (CRmult (CR_of_Q q) (CR_of_Q r));
+ CR_of_Q_one : orderEq _ CRlt (CR_of_Q 1) CRone;
+ CR_of_Q_lt : forall q r : Q,
+ Qlt q r -> CRlt (CR_of_Q q) (CR_of_Q r);
+ lt_CR_of_Q : forall q r : Q,
+ CRlt (CR_of_Q q) (CR_of_Q r) -> Qlt q r;
+
+ (* This function is very fast in both the Cauchy and Dedekind
+ instances, because this rational number q is almost what
+ the proof of CRlt x y contains.
+ This function is also the heart of the computation of
+ constructive real numbers : it approximates x to any
+ requested precision y. *)
+ CR_Q_dense : forall x y : CRcarrier, CRlt x y ->
+ { q : Q & prod (CRlt x (CR_of_Q q))
+ (CRlt (CR_of_Q q) y) };
+ CR_archimedean : forall x : CRcarrier,
+ { n : positive & CRlt x (CR_of_Q (Z.pos n # 1)) };
CRminus (x y : CRcarrier) : CRcarrier
:= CRplus x (CRopp y);
+
+ (* Definitions of convergence and Cauchy-ness. The formulas
+ with orderLe or CRlt are logically equivalent, the choice of
+ orderLe in sort Prop is a question of performance.
+ It is very rare to turn back to the strict order to
+ define functions in sort Set, so we prefer to discard
+ those proofs during extraction. And even in those rare cases,
+ it is easy to divide epsilon by 2 for example. *)
CR_cv (un : nat -> CRcarrier) (l : CRcarrier) : Set
- := forall eps:CRcarrier,
- CRlt CRzero eps
- -> { p : nat & forall i:nat, le p i -> CRlt (CRopp eps) (CRminus (un i) l)
- * CRlt (CRminus (un i) l) eps };
+ := forall p:positive,
+ { n : nat | forall i:nat, le n i
+ -> orderLe _ CRlt (CR_of_Q (-1#p)) (CRminus (un i) l)
+ /\ orderLe _ CRlt (CRminus (un i) l) (CR_of_Q (1#p)) };
CR_cauchy (un : nat -> CRcarrier) : Set
- := forall eps:CRcarrier,
- CRlt CRzero eps
- -> { p : nat & forall i j:nat, le p i -> le p j ->
- CRlt (CRopp eps) (CRminus (un i) (un j))
- * CRlt (CRminus (un i) (un j)) eps };
+ := forall p : positive,
+ { n : nat | forall i j:nat, le n i -> le n j
+ -> orderLe _ CRlt (CR_of_Q (-1#p)) (CRminus (un i) (un j))
+ /\ orderLe _ CRlt (CRminus (un i) (un j)) (CR_of_Q (1#p)) };
+ (* For the Cauchy reals, this algorithm consists in building
+ a Cauchy sequence of rationals un : nat -> Q that has
+ the same limit as xn. For each n:nat, un n is a 1/n
+ rational approximation of a point of xn that has converged
+ within 1/n. *)
CR_complete :
- forall xn : nat -> CRcarrier, CR_cauchy xn -> { l : CRcarrier & CR_cv xn l };
-
- (* Those are redundant, they could be proved from the previous hypotheses *)
- CRis_upper_bound (E:CRcarrier -> Prop) (m:CRcarrier)
- := forall x:CRcarrier, E x -> CRlt m x -> False;
-
- CR_sig_lub :
- forall (E:CRcarrier -> Prop),
- sig_forall_dec_T
- -> sig_not_dec_T
- -> (exists x : CRcarrier, E x)
- -> (exists x : CRcarrier, CRis_upper_bound E x)
- -> { u : CRcarrier | CRis_upper_bound E u /\
- forall y:CRcarrier, CRis_upper_bound E y -> CRlt y u -> False };
+ forall xn : (nat -> CRcarrier),
+ CR_cauchy xn -> { l : CRcarrier & CR_cv xn l };
}.
+
+Lemma CRlt_asym : forall (R : ConstructiveReals) (x y : CRcarrier R),
+ CRlt R x y -> CRlt R y x -> False.
+Proof.
+ intros. destruct (CRltLinear R), p.
+ apply (f x y); assumption.
+Qed.
+
+Lemma CRlt_proper
+ : forall R : ConstructiveReals,
+ CMorphisms.Proper
+ (CMorphisms.respectful (orderEq _ (CRlt R))
+ (CMorphisms.respectful (orderEq _ (CRlt R)) CRelationClasses.iffT)) (CRlt R).
+Proof.
+ intros R x y H x0 y0 H0. destruct H, H0.
+ destruct (CRltLinear R). split.
+ - intro. destruct (s x y x0). assumption.
+ contradiction. destruct (s y y0 x0).
+ assumption. assumption. contradiction.
+ - intro. destruct (s y x y0). assumption.
+ contradiction. destruct (s x x0 y0).
+ assumption. assumption. contradiction.
+Qed.
+
+Lemma CRle_refl : forall (R : ConstructiveReals) (x : CRcarrier R),
+ CRlt R x x -> False.
+Proof.
+ intros. destruct (CRltLinear R), p.
+ exact (f x x H H).
+Qed.
+
+Lemma CRle_lt_trans : forall (R : ConstructiveReals) (r1 r2 r3 : CRcarrier R),
+ (CRlt R r2 r1 -> False) -> CRlt R r2 r3 -> CRlt R r1 r3.
+Proof.
+ intros. destruct (CRltLinear R).
+ destruct (s r2 r1 r3 H0). contradiction. apply c.
+Qed.
+
+Lemma CRlt_le_trans : forall (R : ConstructiveReals) (r1 r2 r3 : CRcarrier R),
+ CRlt R r1 r2 -> (CRlt R r3 r2 -> False) -> CRlt R r1 r3.
+Proof.
+ intros. destruct (CRltLinear R).
+ destruct (s r1 r3 r2 H). apply c. contradiction.
+Qed.
+
+Lemma CRle_trans : forall (R : ConstructiveReals) (x y z : CRcarrier R),
+ orderLe _ (CRlt R) x y -> orderLe _ (CRlt R) y z -> orderLe _ (CRlt R) x z.
+Proof.
+ intros. intro abs. apply H0.
+ apply (CRlt_le_trans _ _ x); assumption.
+Qed.
+
+Lemma CRlt_trans : forall (R : ConstructiveReals) (x y z : CRcarrier R),
+ CRlt R x y -> CRlt R y z -> CRlt R x z.
+Proof.
+ intros. apply (CRlt_le_trans R _ y _ H).
+ apply CRlt_asym. exact H0.
+Defined.
+
+Lemma CRlt_trans_flip : forall (R : ConstructiveReals) (x y z : CRcarrier R),
+ CRlt R y z -> CRlt R x y -> CRlt R x z.
+Proof.
+ intros. apply (CRlt_le_trans R _ y). exact H0.
+ apply CRlt_asym. exact H.
+Defined.
+
+Lemma CReq_refl : forall (R : ConstructiveReals) (x : CRcarrier R),
+ orderEq _ (CRlt R) x x.
+Proof.
+ split; apply CRle_refl.
+Qed.
+
+Lemma CReq_sym : forall (R : ConstructiveReals) (x y : CRcarrier R),
+ orderEq _ (CRlt R) x y
+ -> orderEq _ (CRlt R) y x.
+Proof.
+ intros. destruct H. split; intro abs; contradiction.
+Qed.
+
+Lemma CReq_trans : forall (R : ConstructiveReals) (x y z : CRcarrier R),
+ orderEq _ (CRlt R) x y
+ -> orderEq _ (CRlt R) y z
+ -> orderEq _ (CRlt R) x z.
+Proof.
+ intros. destruct H,H0. destruct (CRltLinear R), p. split.
+ - intro abs. destruct (s _ y _ abs); contradiction.
+ - intro abs. destruct (s _ y _ abs); contradiction.
+Qed.
+
+Lemma CR_setoid : forall R : ConstructiveReals,
+ Setoid_Theory (CRcarrier R) (orderEq _ (CRlt R)).
+Proof.
+ split. intro x. apply CReq_refl.
+ intros x y. apply CReq_sym.
+ intros x y z. apply CReq_trans.
+Qed.
+
+Lemma CRplus_0_r : forall (R : ConstructiveReals) (x : CRcarrier R),
+ orderEq _ (CRlt R) (CRplus R x (CRzero R)) x.
+Proof.
+ intros. destruct (CRisRing R).
+ apply (CReq_trans R _ (CRplus R (CRzero R) x)).
+ apply Radd_comm. apply Radd_0_l.
+Qed.
+
+Lemma CRmult_1_r : forall (R : ConstructiveReals) (x : CRcarrier R),
+ orderEq _ (CRlt R) (CRmult R x (CRone R)) x.
+Proof.
+ intros. destruct (CRisRing R).
+ apply (CReq_trans R _ (CRmult R (CRone R) x)).
+ apply Rmul_comm. apply Rmul_1_l.
+Qed.
+
+Lemma CRplus_opp_l : forall (R : ConstructiveReals) (x : CRcarrier R),
+ orderEq _ (CRlt R) (CRplus R (CRopp R x) x) (CRzero R).
+Proof.
+ intros. destruct (CRisRing R).
+ apply (CReq_trans R _ (CRplus R x (CRopp R x))).
+ apply Radd_comm. apply Ropp_def.
+Qed.
+
+Lemma CRplus_lt_compat_r : forall (R : ConstructiveReals) (r r1 r2 : CRcarrier R),
+ CRlt R r1 r2 -> CRlt R (CRplus R r1 r) (CRplus R r2 r).
+Proof.
+ intros. destruct (CRisRing R).
+ apply (CRlt_proper R (CRplus R r r1) (CRplus R r1 r) (Radd_comm _ _)
+ (CRplus R r2 r) (CRplus R r2 r)).
+ apply CReq_refl.
+ apply (CRlt_proper R _ _ (CReq_refl _ _) _ (CRplus R r r2)).
+ apply Radd_comm. apply CRplus_lt_compat_l. exact H.
+Qed.
+
+Lemma CRplus_lt_reg_r : forall (R : ConstructiveReals) (r r1 r2 : CRcarrier R),
+ CRlt R (CRplus R r1 r) (CRplus R r2 r) -> CRlt R r1 r2.
+Proof.
+ intros. destruct (CRisRing R).
+ apply (CRlt_proper R (CRplus R r r1) (CRplus R r1 r) (Radd_comm _ _)
+ (CRplus R r2 r) (CRplus R r2 r)) in H.
+ 2: apply CReq_refl.
+ apply (CRlt_proper R _ _ (CReq_refl _ _) _ (CRplus R r r2)) in H.
+ apply CRplus_lt_reg_l in H. exact H.
+ apply Radd_comm.
+Qed.
+
+Lemma CRplus_le_compat_l : forall (R : ConstructiveReals) (r r1 r2 : CRcarrier R),
+ orderLe _ (CRlt R) r1 r2
+ -> orderLe _ (CRlt R) (CRplus R r r1) (CRplus R r r2).
+Proof.
+ intros. intros abs. apply CRplus_lt_reg_l in abs. apply H. exact abs.
+Qed.
+
+Lemma CRplus_le_compat_r : forall (R : ConstructiveReals) (r r1 r2 : CRcarrier R),
+ orderLe _ (CRlt R) r1 r2
+ -> orderLe _ (CRlt R) (CRplus R r1 r) (CRplus R r2 r).
+Proof.
+ intros. intros abs. apply CRplus_lt_reg_r in abs. apply H. exact abs.
+Qed.
+
+Lemma CRplus_le_reg_l : forall (R : ConstructiveReals) (r r1 r2 : CRcarrier R),
+ orderLe _ (CRlt R) (CRplus R r r1) (CRplus R r r2)
+ -> orderLe _ (CRlt R) r1 r2.
+Proof.
+ intros. intro abs. apply H. clear H.
+ apply CRplus_lt_compat_l. exact abs.
+Qed.
+
+Lemma CRplus_le_reg_r : forall (R : ConstructiveReals) (r r1 r2 : CRcarrier R),
+ orderLe _ (CRlt R) (CRplus R r1 r) (CRplus R r2 r)
+ -> orderLe _ (CRlt R) r1 r2.
+Proof.
+ intros. intro abs. apply H. clear H.
+ apply CRplus_lt_compat_r. exact abs.
+Qed.
+
+Lemma CRplus_lt_le_compat :
+ forall (R : ConstructiveReals) (r1 r2 r3 r4 : CRcarrier R),
+ CRlt R r1 r2
+ -> (CRlt R r4 r3 -> False)
+ -> CRlt R (CRplus R r1 r3) (CRplus R r2 r4).
+Proof.
+ intros. apply (CRlt_le_trans R _ (CRplus R r2 r3)).
+ apply CRplus_lt_compat_r. exact H. intro abs.
+ apply CRplus_lt_reg_l in abs. contradiction.
+Qed.
+
+Lemma CRplus_eq_reg_l : forall (R : ConstructiveReals) (r r1 r2 : CRcarrier R),
+ orderEq _ (CRlt R) (CRplus R r r1) (CRplus R r r2)
+ -> orderEq _ (CRlt R) r1 r2.
+Proof.
+ intros.
+ destruct (CRisRingExt R). clear Rmul_ext Ropp_ext.
+ pose proof (Radd_ext
+ (CRopp R r) (CRopp R r) (CReq_refl _ _)
+ _ _ H).
+ destruct (CRisRing R).
+ apply (CReq_trans _ r1) in H0.
+ apply (CReq_trans R _ _ _ H0).
+ apply (CReq_trans R _ (CRplus R (CRplus R (CRopp R r) r) r2)).
+ apply Radd_assoc.
+ apply (CReq_trans R _ (CRplus R (CRzero R) r2)).
+ apply Radd_ext. apply CRplus_opp_l. apply CReq_refl.
+ apply Radd_0_l. apply CReq_sym.
+ apply (CReq_trans R _ (CRplus R (CRplus R (CRopp R r) r) r1)).
+ apply Radd_assoc.
+ apply (CReq_trans R _ (CRplus R (CRzero R) r1)).
+ apply Radd_ext. apply CRplus_opp_l. apply CReq_refl.
+ apply Radd_0_l.
+Qed.
+
+Lemma CRplus_eq_reg_r : forall (R : ConstructiveReals) (r r1 r2 : CRcarrier R),
+ orderEq _ (CRlt R) (CRplus R r1 r) (CRplus R r2 r)
+ -> orderEq _ (CRlt R) r1 r2.
+Proof.
+ intros. apply (CRplus_eq_reg_l R r).
+ apply (CReq_trans R _ (CRplus R r1 r)). apply (Radd_comm (CRisRing R)).
+ apply (CReq_trans R _ (CRplus R r2 r)).
+ exact H. apply (Radd_comm (CRisRing R)).
+Qed.
+
+Lemma CRopp_involutive : forall (R : ConstructiveReals) (r : CRcarrier R),
+ orderEq _ (CRlt R) (CRopp R (CRopp R r)) r.
+Proof.
+ intros. apply (CRplus_eq_reg_l R (CRopp R r)).
+ apply (CReq_trans R _ (CRzero R)). apply CRisRing.
+ apply CReq_sym, (CReq_trans R _ (CRplus R r (CRopp R r))).
+ apply CRisRing. apply CRisRing.
+Qed.
+
+Lemma CRopp_gt_lt_contravar
+ : forall (R : ConstructiveReals) (r1 r2 : CRcarrier R),
+ CRlt R r2 r1 -> CRlt R (CRopp R r1) (CRopp R r2).
+Proof.
+ intros. apply (CRplus_lt_reg_l R r1).
+ destruct (CRisRing R).
+ apply (CRle_lt_trans R _ (CRzero R)). apply Ropp_def.
+ apply (CRplus_lt_compat_l R (CRopp R r2)) in H.
+ apply (CRle_lt_trans R _ (CRplus R (CRopp R r2) r2)).
+ apply (CRle_trans R _ (CRplus R r2 (CRopp R r2))).
+ destruct (Ropp_def r2). exact H0.
+ destruct (Radd_comm r2 (CRopp R r2)). exact H1.
+ apply (CRlt_le_trans R _ _ _ H).
+ destruct (Radd_comm r1 (CRopp R r2)). exact H0.
+Qed.
+
+Lemma CRopp_lt_cancel : forall (R : ConstructiveReals) (r1 r2 : CRcarrier R),
+ CRlt R (CRopp R r2) (CRopp R r1) -> CRlt R r1 r2.
+Proof.
+ intros. apply (CRplus_lt_compat_r R r1) in H.
+ destruct (CRplus_opp_l R r1) as [_ H1].
+ apply (CRlt_le_trans R _ _ _ H) in H1. clear H.
+ apply (CRplus_lt_compat_l R r2) in H1.
+ destruct (CRplus_0_r R r2) as [_ H0].
+ apply (CRlt_le_trans R _ _ _ H1) in H0. clear H1.
+ destruct (Radd_assoc (CRisRing R) r2 (CRopp R r2) r1) as [H _].
+ apply (CRle_lt_trans R _ _ _ H) in H0. clear H.
+ apply (CRle_lt_trans R _ (CRplus R (CRzero R) r1)).
+ apply (Radd_0_l (CRisRing R)).
+ apply (CRle_lt_trans R _ (CRplus R (CRplus R r2 (CRopp R r2)) r1)).
+ 2: exact H0. apply CRplus_le_compat_r.
+ destruct (Ropp_def (CRisRing R) r2). exact H.
+Qed.
+
+Lemma CRopp_plus_distr : forall (R : ConstructiveReals) (r1 r2 : CRcarrier R),
+ orderEq _ (CRlt R) (CRopp R (CRplus R r1 r2)) (CRplus R (CRopp R r1) (CRopp R r2)).
+Proof.
+ intros. destruct (CRisRing R), (CRisRingExt R).
+ apply (CRplus_eq_reg_l R (CRplus R r1 r2)).
+ apply (CReq_trans R _ (CRzero R)). apply Ropp_def.
+ apply (CReq_trans R _ (CRplus R (CRplus R r2 r1) (CRplus R (CRopp R r1) (CRopp R r2)))).
+ apply (CReq_trans R _ (CRplus R r2 (CRplus R r1 (CRplus R (CRopp R r1) (CRopp R r2))))).
+ apply (CReq_trans R _ (CRplus R r2 (CRopp R r2))).
+ apply CReq_sym. apply Ropp_def. apply Radd_ext.
+ apply CReq_refl.
+ apply (CReq_trans R _ (CRplus R (CRzero R) (CRopp R r2))).
+ apply CReq_sym, Radd_0_l.
+ apply (CReq_trans R _ (CRplus R (CRplus R r1 (CRopp R r1)) (CRopp R r2))).
+ apply Radd_ext. 2: apply CReq_refl. apply CReq_sym, Ropp_def.
+ apply CReq_sym, Radd_assoc. apply Radd_assoc.
+ apply Radd_ext. 2: apply CReq_refl. apply Radd_comm.
+Qed.
+
+Lemma CRmult_plus_distr_l : forall (R : ConstructiveReals) (r1 r2 r3 : CRcarrier R),
+ orderEq _ (CRlt R) (CRmult R r1 (CRplus R r2 r3))
+ (CRplus R (CRmult R r1 r2) (CRmult R r1 r3)).
+Proof.
+ intros. destruct (CRisRing R).
+ apply (CReq_trans R _ (CRmult R (CRplus R r2 r3) r1)).
+ apply Rmul_comm.
+ apply (CReq_trans R _ (CRplus R (CRmult R r2 r1) (CRmult R r3 r1))).
+ apply Rdistr_l.
+ apply (CReq_trans R _ (CRplus R (CRmult R r1 r2) (CRmult R r3 r1))).
+ destruct (CRisRingExt R). apply Radd_ext.
+ apply Rmul_comm. apply CReq_refl.
+ destruct (CRisRingExt R). apply Radd_ext.
+ apply CReq_refl. apply Rmul_comm.
+Qed.
+
+(* x == x+x -> x == 0 *)
+Lemma CRzero_double : forall (R : ConstructiveReals) (x : CRcarrier R),
+ orderEq _ (CRlt R) x (CRplus R x x)
+ -> orderEq _ (CRlt R) x (CRzero R).
+Proof.
+ intros.
+ apply (CRplus_eq_reg_l R x), CReq_sym, (CReq_trans R _ x).
+ apply CRplus_0_r. exact H.
+Qed.
+
+Lemma CRmult_0_r : forall (R : ConstructiveReals) (x : CRcarrier R),
+ orderEq _ (CRlt R) (CRmult R x (CRzero R)) (CRzero R).
+Proof.
+ intros. apply CRzero_double.
+ apply (CReq_trans R _ (CRmult R x (CRplus R (CRzero R) (CRzero R)))).
+ destruct (CRisRingExt R). apply Rmul_ext. apply CReq_refl.
+ apply CReq_sym, CRplus_0_r.
+ destruct (CRisRing R). apply CRmult_plus_distr_l.
+Qed.
+
+Lemma CRopp_mult_distr_r : forall (R : ConstructiveReals) (r1 r2 : CRcarrier R),
+ orderEq _ (CRlt R) (CRopp R (CRmult R r1 r2))
+ (CRmult R r1 (CRopp R r2)).
+Proof.
+ intros. apply (CRplus_eq_reg_l R (CRmult R r1 r2)).
+ destruct (CRisRing R).
+ apply (CReq_trans R _ (CRzero R)). apply Ropp_def.
+ apply (CReq_trans R _ (CRmult R r1 (CRplus R r2 (CRopp R r2)))).
+ 2: apply CRmult_plus_distr_l.
+ apply (CReq_trans R _ (CRmult R r1 (CRzero R))).
+ apply CReq_sym, CRmult_0_r.
+ destruct (CRisRingExt R). apply Rmul_ext. apply CReq_refl.
+ apply CReq_sym, Ropp_def.
+Qed.
+
+Lemma CRopp_mult_distr_l : forall (R : ConstructiveReals) (r1 r2 : CRcarrier R),
+ orderEq _ (CRlt R) (CRopp R (CRmult R r1 r2))
+ (CRmult R (CRopp R r1) r2).
+Proof.
+ intros. apply (CReq_trans R _ (CRmult R r2 (CRopp R r1))).
+ apply (CReq_trans R _ (CRopp R (CRmult R r2 r1))).
+ apply (Ropp_ext (CRisRingExt R)).
+ apply CReq_sym, (Rmul_comm (CRisRing R)).
+ apply CRopp_mult_distr_r.
+ apply CReq_sym, (Rmul_comm (CRisRing R)).
+Qed.
+
+Lemma CRmult_lt_compat_r : forall (R : ConstructiveReals) (r r1 r2 : CRcarrier R),
+ CRlt R (CRzero R) r
+ -> CRlt R r1 r2
+ -> CRlt R (CRmult R r1 r) (CRmult R r2 r).
+Proof.
+ intros. apply (CRplus_lt_reg_r R (CRopp R (CRmult R r1 r))).
+ apply (CRle_lt_trans R _ (CRzero R)).
+ apply (Ropp_def (CRisRing R)).
+ apply (CRlt_le_trans R _ (CRplus R (CRmult R r2 r) (CRmult R (CRopp R r1) r))).
+ apply (CRlt_le_trans R _ (CRmult R (CRplus R r2 (CRopp R r1)) r)).
+ apply CRmult_lt_0_compat. 2: exact H.
+ apply (CRplus_lt_reg_r R r1).
+ apply (CRle_lt_trans R _ r1). apply (Radd_0_l (CRisRing R)).
+ apply (CRlt_le_trans R _ r2 _ H0).
+ apply (CRle_trans R _ (CRplus R r2 (CRplus R (CRopp R r1) r1))).
+ apply (CRle_trans R _ (CRplus R r2 (CRzero R))).
+ destruct (CRplus_0_r R r2). exact H1.
+ apply CRplus_le_compat_l. destruct (CRplus_opp_l R r1). exact H1.
+ destruct (Radd_assoc (CRisRing R) r2 (CRopp R r1) r1). exact H2.
+ destruct (CRisRing R).
+ destruct (Rdistr_l r2 (CRopp R r1) r). exact H2.
+ apply CRplus_le_compat_l. destruct (CRopp_mult_distr_l R r1 r).
+ exact H1.
+Qed.
+
+Lemma CRinv_r : forall (R : ConstructiveReals) (r:CRcarrier R)
+ (rnz : orderAppart _ (CRlt R) r (CRzero R)),
+ orderEq _ (CRlt R) (CRmult R r (CRinv R r rnz)) (CRone R).
+Proof.
+ intros. apply (CReq_trans R _ (CRmult R (CRinv R r rnz) r)).
+ apply (CRisRing R). apply CRinv_l.
+Qed.
+
+Lemma CRmult_lt_reg_r : forall (R : ConstructiveReals) (r r1 r2 : CRcarrier R),
+ CRlt R (CRzero R) r
+ -> CRlt R (CRmult R r1 r) (CRmult R r2 r)
+ -> CRlt R r1 r2.
+Proof.
+ intros. apply (CRmult_lt_compat_r R (CRinv R r (inr H))) in H0.
+ 2: apply CRinv_0_lt_compat, H.
+ apply (CRle_lt_trans R _ (CRmult R (CRmult R r1 r) (CRinv R r (inr H)))).
+ - clear H0. apply (CRle_trans R _ (CRmult R r1 (CRone R))).
+ destruct (CRmult_1_r R r1). exact H0.
+ apply (CRle_trans R _ (CRmult R r1 (CRmult R r (CRinv R r (inr H))))).
+ destruct (Rmul_ext (CRisRingExt R) r1 r1 (CReq_refl R r1)
+ (CRmult R r (CRinv R r (inr H))) (CRone R)).
+ apply CRinv_r. exact H0.
+ destruct (Rmul_assoc (CRisRing R) r1 r (CRinv R r (inr H))). exact H1.
+ - apply (CRlt_le_trans R _ (CRmult R (CRmult R r2 r) (CRinv R r (inr H)))).
+ exact H0. clear H0.
+ apply (CRle_trans R _ (CRmult R r2 (CRone R))).
+ 2: destruct (CRmult_1_r R r2); exact H1.
+ apply (CRle_trans R _ (CRmult R r2 (CRmult R r (CRinv R r (inr H))))).
+ destruct (Rmul_assoc (CRisRing R) r2 r (CRinv R r (inr H))). exact H0.
+ destruct (Rmul_ext (CRisRingExt R) r2 r2 (CReq_refl R r2)
+ (CRmult R r (CRinv R r (inr H))) (CRone R)).
+ apply CRinv_r. exact H1.
+Qed.
+
+Lemma CRmult_lt_reg_l : forall (R : ConstructiveReals) (r r1 r2 : CRcarrier R),
+ CRlt R (CRzero R) r
+ -> CRlt R (CRmult R r r1) (CRmult R r r2)
+ -> CRlt R r1 r2.
+Proof.
+ intros.
+ destruct (Rmul_comm (CRisRing R) r r1) as [H1 _].
+ apply (CRle_lt_trans R _ _ _ H1) in H0. clear H1.
+ destruct (Rmul_comm (CRisRing R) r r2) as [_ H1].
+ apply (CRlt_le_trans R _ _ _ H0) in H1. clear H0.
+ apply CRmult_lt_reg_r in H1.
+ exact H1. exact H.
+Qed.
+
+Lemma CRmult_le_compat_l : forall (R : ConstructiveReals) (r r1 r2 : CRcarrier R),
+ CRlt R (CRzero R) r
+ -> orderLe _ (CRlt R) r1 r2
+ -> orderLe _ (CRlt R) (CRmult R r r1) (CRmult R r r2).
+Proof.
+ intros. intro abs. apply CRmult_lt_reg_l in abs.
+ contradiction. exact H.
+Qed.
+
+Lemma CRmult_le_compat_r : forall (R : ConstructiveReals) (r r1 r2 : CRcarrier R),
+ CRlt R (CRzero R) r
+ -> orderLe _ (CRlt R) r1 r2
+ -> orderLe _ (CRlt R) (CRmult R r1 r) (CRmult R r2 r).
+Proof.
+ intros. intro abs. apply CRmult_lt_reg_r in abs.
+ contradiction. exact H.
+Qed.
+
+Lemma CRmult_eq_reg_r : forall (R : ConstructiveReals) (r r1 r2 : CRcarrier R),
+ orderAppart _ (CRlt R) (CRzero R) r
+ -> orderEq _ (CRlt R) (CRmult R r1 r) (CRmult R r2 r)
+ -> orderEq _ (CRlt R) r1 r2.
+Proof.
+ intros. destruct H0,H.
+ - split.
+ + intro abs. apply H0. apply CRmult_lt_compat_r.
+ exact c. exact abs.
+ + intro abs. apply H1. apply CRmult_lt_compat_r.
+ exact c. exact abs.
+ - split.
+ + intro abs. apply H1. apply CRopp_lt_cancel.
+ apply (CRle_lt_trans R _ (CRmult R r1 (CRopp R r))).
+ apply CRopp_mult_distr_r.
+ apply (CRlt_le_trans R _ (CRmult R r2 (CRopp R r))).
+ 2: apply CRopp_mult_distr_r.
+ apply CRmult_lt_compat_r. 2: exact abs.
+ apply (CRplus_lt_reg_r R r). apply (CRle_lt_trans R _ r).
+ apply (Radd_0_l (CRisRing R)).
+ apply (CRlt_le_trans R _ (CRzero R) _ c).
+ apply CRplus_opp_l.
+ + intro abs. apply H0. apply CRopp_lt_cancel.
+ apply (CRle_lt_trans R _ (CRmult R r2 (CRopp R r))).
+ apply CRopp_mult_distr_r.
+ apply (CRlt_le_trans R _ (CRmult R r1 (CRopp R r))).
+ 2: apply CRopp_mult_distr_r.
+ apply CRmult_lt_compat_r. 2: exact abs.
+ apply (CRplus_lt_reg_r R r). apply (CRle_lt_trans R _ r).
+ apply (Radd_0_l (CRisRing R)).
+ apply (CRlt_le_trans R _ (CRzero R) _ c).
+ apply CRplus_opp_l.
+Qed.
+
+Lemma CR_of_Q_proper : forall (R : ConstructiveReals) (q r : Q),
+ q == r -> orderEq _ (CRlt R) (CR_of_Q R q) (CR_of_Q R r).
+Proof.
+ split.
+ - intro abs. apply lt_CR_of_Q in abs. rewrite H in abs.
+ exact (Qlt_not_le r r abs (Qle_refl r)).
+ - intro abs. apply lt_CR_of_Q in abs. rewrite H in abs.
+ exact (Qlt_not_le r r abs (Qle_refl r)).
+Qed.
+
+Lemma CR_of_Q_zero : forall (R : ConstructiveReals),
+ orderEq _ (CRlt R) (CR_of_Q R 0) (CRzero R).
+Proof.
+ intros. apply CRzero_double.
+ apply (CReq_trans R _ (CR_of_Q R (0+0))). apply CR_of_Q_proper.
+ reflexivity. apply CR_of_Q_plus.
+Qed.
+
+Lemma CR_of_Q_opp : forall (R : ConstructiveReals) (q : Q),
+ orderEq _ (CRlt R) (CR_of_Q R (-q)) (CRopp R (CR_of_Q R q)).
+Proof.
+ intros. apply (CRplus_eq_reg_l R (CR_of_Q R q)).
+ apply (CReq_trans R _ (CRzero R)).
+ apply (CReq_trans R _ (CR_of_Q R (q-q))).
+ apply CReq_sym, CR_of_Q_plus.
+ apply (CReq_trans R _ (CR_of_Q R 0)).
+ apply CR_of_Q_proper. ring. apply CR_of_Q_zero.
+ apply CReq_sym. apply (CRisRing R).
+Qed.
+
+Lemma CR_of_Q_le : forall (R : ConstructiveReals) (r q : Q),
+ Qle r q
+ -> orderLe _ (CRlt R) (CR_of_Q R r) (CR_of_Q R q).
+Proof.
+ intros. intro abs. apply lt_CR_of_Q in abs.
+ exact (Qlt_not_le _ _ abs H).
+Qed.
+
+Lemma CR_of_Q_pos : forall (R : ConstructiveReals) (q:Q),
+ Qlt 0 q -> CRlt R (CRzero R) (CR_of_Q R q).
+Proof.
+ intros. apply (CRle_lt_trans R _ (CR_of_Q R 0)).
+ apply CR_of_Q_zero. apply CR_of_Q_lt. exact H.
+Qed.
+
+Lemma CR_cv_above_rat
+ : forall (R : ConstructiveReals) (xn : nat -> Q) (x : CRcarrier R) (q : Q),
+ CR_cv R (fun n : nat => CR_of_Q R (xn n)) x
+ -> CRlt R (CR_of_Q R q) x
+ -> { n : nat | forall p:nat, le n p -> Qlt q (xn p) }.
+Proof.
+ intros.
+ destruct (CR_Q_dense R _ _ H0) as [r [H1 H2]].
+ apply lt_CR_of_Q in H1. clear H0.
+ destruct (Qarchimedean (/(r-q))) as [p pmaj].
+ destruct (H p) as [n nmaj].
+ exists n. intros k lenk. specialize (nmaj k lenk) as [H3 _].
+ apply (lt_CR_of_Q R), (CRlt_le_trans R _ (CRplus R x (CR_of_Q R (-1#p)))).
+ apply (CRlt_trans R _ (CRplus R (CR_of_Q R r) (CR_of_Q R (-1#p)))).
+ 2: apply CRplus_lt_compat_r, H2.
+ apply (CRlt_le_trans R _ (CR_of_Q R (r+(-1#p)))).
+ - apply CR_of_Q_lt.
+ apply (Qplus_lt_l _ _ (-(-1#p)-q)). field_simplify.
+ setoid_replace (-1*(-1#p)) with (1#p). 2: reflexivity.
+ apply (Qmult_lt_l _ _ (r-q)) in pmaj.
+ rewrite Qmult_inv_r in pmaj. apply Qlt_shift_div_r in pmaj.
+ 2: reflexivity. setoid_replace (-1*q + r) with (r-q). exact pmaj.
+ ring. intro abs. apply Qlt_minus_iff in H1.
+ rewrite abs in H1. inversion H1.
+ apply Qlt_minus_iff in H1. exact H1.
+ - apply CR_of_Q_plus.
+ - apply (CRplus_le_reg_r R (CRopp R x)).
+ apply (CRle_trans R _ (CR_of_Q R (-1#p))). 2: exact H3. clear H3.
+ apply (CRle_trans R _ (CRplus R (CRopp R x) (CRplus R x (CR_of_Q R (-1 # p))))).
+ exact (proj1 (Radd_comm (CRisRing R) _ _)).
+ apply (CRle_trans R _ (CRplus R (CRplus R (CRopp R x) x) (CR_of_Q R (-1 # p)))).
+ exact (proj2 (Radd_assoc (CRisRing R) _ _ _)).
+ apply (CRle_trans R _ (CRplus R (CRzero R) (CR_of_Q R (-1 # p)))).
+ apply CRplus_le_compat_r. exact (proj2 (CRplus_opp_l R _)).
+ exact (proj2 (Radd_0_l (CRisRing R) _)).
+Qed.
+
+Lemma CR_cv_below_rat
+ : forall (R : ConstructiveReals) (xn : nat -> Q) (x : CRcarrier R) (q : Q),
+ CR_cv R (fun n : nat => CR_of_Q R (xn n)) x
+ -> CRlt R x (CR_of_Q R q)
+ -> { n : nat | forall p:nat, le n p -> Qlt (xn p) q }.
+Proof.
+ intros.
+ destruct (CR_Q_dense R _ _ H0) as [r [H1 H2]].
+ apply lt_CR_of_Q in H2. clear H0.
+ destruct (Qarchimedean (/(q-r))) as [p pmaj].
+ destruct (H p) as [n nmaj].
+ exists n. intros k lenk. specialize (nmaj k lenk) as [_ H4].
+ apply (lt_CR_of_Q R), (CRle_lt_trans R _ (CRplus R x (CR_of_Q R (1#p)))).
+ - apply (CRplus_le_reg_r R (CRopp R x)).
+ apply (CRle_trans R _ (CR_of_Q R (1#p))). exact H4. clear H4.
+ apply (CRle_trans R _ (CRplus R (CRopp R x) (CRplus R x (CR_of_Q R (1 # p))))).
+ 2: exact (proj1 (Radd_comm (CRisRing R) _ _)).
+ apply (CRle_trans R _ (CRplus R (CRplus R (CRopp R x) x) (CR_of_Q R (1 # p)))).
+ 2: exact (proj1 (Radd_assoc (CRisRing R) _ _ _)).
+ apply (CRle_trans R _ (CRplus R (CRzero R) (CR_of_Q R (1 # p)))).
+ exact (proj1 (Radd_0_l (CRisRing R) _)).
+ apply CRplus_le_compat_r. exact (proj1 (CRplus_opp_l R _)).
+ - apply (CRlt_trans R _ (CRplus R (CR_of_Q R r) (CR_of_Q R (1 # p)))).
+ apply CRplus_lt_compat_r. exact H1.
+ apply (CRle_lt_trans R _ (CR_of_Q R (r + (1#p)))).
+ apply CR_of_Q_plus. apply CR_of_Q_lt.
+ apply (Qmult_lt_l _ _ (q-r)) in pmaj.
+ rewrite Qmult_inv_r in pmaj. apply Qlt_shift_div_r in pmaj.
+ apply (Qplus_lt_l _ _ (-r)). field_simplify.
+ setoid_replace (-1*r + q) with (q-r). exact pmaj.
+ ring. reflexivity. intro abs. apply Qlt_minus_iff in H2.
+ rewrite abs in H2. inversion H2.
+ apply Qlt_minus_iff in H2. exact H2.
+Qed.
+
+Lemma CR_cv_const : forall (R : ConstructiveReals) (x y : CRcarrier R),
+ CR_cv R (fun _ => x) y -> orderEq _ (CRlt R) x y.
+Proof.
+ intros. destruct (CRisRing R). split.
+ - intro abs.
+ destruct (CR_Q_dense R x y abs) as [q [H0 H1]].
+ destruct (CR_Q_dense R _ _ H1) as [r [H2 H3]].
+ apply lt_CR_of_Q in H2.
+ destruct (Qarchimedean (/(r-q))) as [p pmaj].
+ destruct (H p) as [n nmaj]. specialize (nmaj n (le_refl n)) as [nmaj _].
+ apply nmaj. clear nmaj.
+ apply (CRlt_trans R _ (CR_of_Q R (q-r))).
+ apply (CRlt_le_trans R _ (CRplus R (CR_of_Q R q) (CRopp R (CR_of_Q R r)))).
+ + apply CRplus_lt_le_compat. exact H0.
+ intro H4. apply CRopp_lt_cancel in H4. exact (CRlt_asym R _ _ H4 H3).
+ + apply (CRle_trans R _ (CRplus R (CR_of_Q R q) (CR_of_Q R (-r)))).
+ apply CRplus_le_compat_l. exact (proj1 (CR_of_Q_opp R r)).
+ exact (proj1 (CR_of_Q_plus R _ _)).
+ + apply CR_of_Q_lt.
+ apply (Qplus_lt_l _ _ (-(-1#p)+r-q)). field_simplify.
+ setoid_replace (-1*(-1#p)) with (1#p). 2: reflexivity.
+ apply (Qmult_lt_l _ _ (r-q)) in pmaj.
+ rewrite Qmult_inv_r in pmaj. apply Qlt_shift_div_r in pmaj.
+ 2: reflexivity. setoid_replace (-1*q + r) with (r-q). exact pmaj.
+ ring. intro H4. apply Qlt_minus_iff in H2.
+ rewrite H4 in H2. inversion H2.
+ apply Qlt_minus_iff in H2. exact H2.
+ - intro abs.
+ destruct (CR_Q_dense R _ _ abs) as [q [H0 H1]].
+ destruct (CR_Q_dense R _ _ H0) as [r [H2 H3]].
+ apply lt_CR_of_Q in H3.
+ destruct (Qarchimedean (/(q-r))) as [p pmaj].
+ destruct (H p) as [n nmaj]. specialize (nmaj n (le_refl n)) as [_ nmaj].
+ apply nmaj. clear nmaj.
+ apply (CRlt_trans R _ (CR_of_Q R (q-r))).
+ + apply CR_of_Q_lt.
+ apply (Qmult_lt_l _ _ (q-r)) in pmaj.
+ rewrite Qmult_inv_r in pmaj. apply Qlt_shift_div_r in pmaj.
+ exact pmaj. reflexivity.
+ intro H4. apply Qlt_minus_iff in H3.
+ rewrite H4 in H3. inversion H3.
+ apply Qlt_minus_iff in H3. exact H3.
+ + apply (CRle_lt_trans R _ (CRplus R (CR_of_Q R q) (CR_of_Q R (-r)))).
+ apply CR_of_Q_plus.
+ apply (CRle_lt_trans R _ (CRplus R (CR_of_Q R q) (CRopp R (CR_of_Q R r)))).
+ apply CRplus_le_compat_l. exact (proj2 (CR_of_Q_opp R r)).
+ apply CRplus_lt_le_compat. exact H1.
+ intro H4. apply CRopp_lt_cancel in H4.
+ exact (CRlt_asym R _ _ H4 H2).
+Qed.
diff --git a/theories/Reals/ConstructiveRealsLUB.v b/theories/Reals/ConstructiveRealsLUB.v
index f5c447f7db..3a26b8cefb 100644
--- a/theories/Reals/ConstructiveRealsLUB.v
+++ b/theories/Reals/ConstructiveRealsLUB.v
@@ -15,7 +15,9 @@
Require Import QArith_base.
Require Import Qabs.
-Require Import ConstructiveCauchyReals.
+Require Import ConstructiveReals.
+Require Import ConstructiveCauchyRealsMult.
+Require Import ConstructiveRealsMorphisms.
Require Import ConstructiveRcomplete.
Require Import Logic.ConstructiveEpsilon.
@@ -54,14 +56,15 @@ Lemma is_upper_bound_epsilon :
sig_forall_dec_T
-> sig_not_dec_T
-> (exists x:CReal, is_upper_bound E x)
- -> { n:nat | is_upper_bound E (INR n) }.
+ -> { n:nat | is_upper_bound E (inject_Q (Z.of_nat n # 1)) }.
Proof.
intros E lpo sig_not_dec Ebound.
apply constructive_indefinite_ground_description_nat.
- intro n. apply is_upper_bound_dec. exact lpo. exact sig_not_dec.
- - destruct Ebound as [x H]. destruct (Rup_nat x). exists x0.
+ - destruct Ebound as [x H]. destruct (Rup_pos x). exists (Pos.to_nat x0).
intros y ey. specialize (H y ey).
- apply CRealLt_asym. apply (CRealLe_Lt_trans _ x); assumption.
+ apply CRealLt_asym. apply (CReal_le_lt_trans _ x).
+ exact H. rewrite positive_nat_Z. exact c.
Qed.
Lemma is_upper_bound_not_epsilon :
@@ -69,15 +72,16 @@ Lemma is_upper_bound_not_epsilon :
sig_forall_dec_T
-> sig_not_dec_T
-> (exists x : CReal, E x)
- -> { m:nat | ~is_upper_bound E (-INR m) }.
+ -> { m:nat | ~is_upper_bound E (-inject_Q (Z.of_nat m # 1)) }.
Proof.
intros E lpo sig_not_dec H.
apply constructive_indefinite_ground_description_nat.
- - intro n. destruct (is_upper_bound_dec E (-INR n) lpo sig_not_dec).
+ - intro n. destruct (is_upper_bound_dec E (-inject_Q (Z.of_nat n # 1)) lpo sig_not_dec).
right. intro abs. contradiction. left. exact n0.
- - destruct H as [x H]. destruct (Rup_nat (-x)) as [n H0].
- exists n. intro abs. specialize (abs x H).
- apply abs. apply (CReal_plus_lt_reg_l (INR n-x)).
+ - destruct H as [x H]. destruct (Rup_pos (-x)) as [n H0].
+ exists (Pos.to_nat n). intro abs. specialize (abs x H).
+ apply abs. rewrite positive_nat_Z.
+ apply (CReal_plus_lt_reg_l (inject_Q (Z.pos n # 1)-x)).
ring_simplify. exact H0.
Qed.
@@ -140,8 +144,8 @@ Proof.
Qed.
Lemma glb_dec_Q : forall upcut : DedekindDecCut,
- { x : CReal | forall r:Q, (x < IQR r -> DDupcut upcut r)
- /\ (IQR r < x -> ~DDupcut upcut r) }.
+ { x : CReal | forall r:Q, (x < inject_Q r -> DDupcut upcut r)
+ /\ (inject_Q r < x -> ~DDupcut upcut r) }.
Proof.
intros.
assert (forall a b : Q, Qle a b -> Qle (-b) (-a)).
@@ -175,7 +179,7 @@ Proof.
pose (exist (fun qn => QSeqEquiv qn qn Pos.to_nat) _ H0) as l.
exists l. split.
- intros. (* find an upper point between the limit and r *)
- rewrite FinjectQ_CReal in H1. destruct H1 as [p pmaj].
+ destruct H1 as [p pmaj].
unfold l,proj1_sig in pmaj.
destruct (DDcut_limit upcut (1 # Pos.of_nat (Pos.to_nat p)) eq_refl) as [q qmaj]
; simpl in pmaj.
@@ -184,8 +188,7 @@ Proof.
apply (Qle_trans _ ((2#p) + q)).
apply (Qplus_le_l _ _ (-q)). ring_simplify. discriminate.
apply Qlt_le_weak. exact pmaj.
- - intros H1 abs.
- rewrite FinjectQ_CReal in H1. destruct H1 as [p pmaj].
+ - intros [p pmaj] abs.
unfold l,proj1_sig in pmaj.
destruct (DDcut_limit upcut (1 # Pos.of_nat (Pos.to_nat p)) eq_refl) as [q qmaj]
; simpl in pmaj.
@@ -205,26 +208,24 @@ Lemma is_upper_bound_glb :
-> sig_forall_dec_T
-> (exists x : CReal, E x)
-> (exists x : CReal, is_upper_bound E x)
- -> { x : CReal | forall r:Q, (x < IQR r -> is_upper_bound E (IQR r))
- /\ (IQR r < x -> ~is_upper_bound E (IQR r)) }.
+ -> { x : CReal | forall r:Q, (x < inject_Q r -> is_upper_bound E (inject_Q r))
+ /\ (inject_Q r < x -> ~is_upper_bound E (inject_Q r)) }.
Proof.
intros E sig_not_dec lpo Einhab Ebound.
destruct (is_upper_bound_epsilon E lpo sig_not_dec Ebound) as [a luba].
destruct (is_upper_bound_not_epsilon E lpo sig_not_dec Einhab) as [b glbb].
- pose (fun q => is_upper_bound E (IQR q)) as upcut.
+ pose (fun q => is_upper_bound E (inject_Q q)) as upcut.
assert (forall q:Q, { upcut q } + { ~upcut q } ).
{ intro q. apply is_upper_bound_dec. exact lpo. exact sig_not_dec. }
assert (forall q r : Q, (q <= r)%Q -> upcut q -> upcut r).
{ intros. intros x Ex. specialize (H1 x Ex). intro abs.
- apply H1. apply (CRealLe_Lt_trans _ (IQR r)). 2: exact abs.
- apply IQR_le. exact H0. }
+ apply H1. apply (CReal_le_lt_trans _ (inject_Q r)). 2: exact abs.
+ apply inject_Q_le. exact H0. }
assert (upcut (Z.of_nat a # 1)%Q).
- { intros x Ex. unfold IQR. rewrite CReal_inv_1, CReal_mult_1_r.
- specialize (luba x Ex). rewrite <- INR_IZR_INZ. exact luba. }
+ { intros x Ex. exact (luba x Ex). }
assert (~upcut (- Z.of_nat b # 1)%Q).
{ intros abs. apply glbb. intros x Ex.
- specialize (abs x Ex). unfold IQR in abs.
- rewrite CReal_inv_1, CReal_mult_1_r, opp_IZR, <- INR_IZR_INZ in abs.
+ specialize (abs x Ex). rewrite <- opp_inject_Q.
exact abs. }
assert (forall q r : Q, (q == r)%Q -> upcut q -> upcut r).
{ intros. intros x Ex. specialize (H4 x Ex). rewrite <- H3. exact H4. }
@@ -257,7 +258,7 @@ Proof.
intro abs. destruct (FQ_dense b x abs) as [q [qmaj H0]].
specialize (a q) as [_ a]. apply a. exact H0.
intros y Ey. specialize (H y Ey). intro abs2.
- apply H. exact (CRealLt_trans _ (IQR q) _ qmaj abs2).
+ apply H. exact (CReal_lt_trans _ (inject_Q q) _ qmaj abs2).
Qed.
Lemma sig_lub :
@@ -274,3 +275,44 @@ Proof.
E sig_not_dec sig_forall_dec Einhab Ebound); simpl in H.
exists x. exact H.
Qed.
+
+Definition CRis_upper_bound (R : ConstructiveReals) (E:CRcarrier R -> Prop) (m:CRcarrier R)
+ := forall x:CRcarrier R, E x -> CRlt R m x -> False.
+
+Lemma CR_sig_lub :
+ forall (R : ConstructiveReals) (E:CRcarrier R -> Prop),
+ (forall x y : CRcarrier R, orderEq _ (CRlt R) x y -> (E x <-> E y))
+ -> sig_forall_dec_T
+ -> sig_not_dec_T
+ -> (exists x : CRcarrier R, E x)
+ -> (exists x : CRcarrier R, CRis_upper_bound R E x)
+ -> { u : CRcarrier R | CRis_upper_bound R E u /\
+ forall y:CRcarrier R, CRis_upper_bound R E y -> CRlt R y u -> False }.
+Proof.
+ intros. destruct (sig_lub (fun x:CReal => E (CauchyMorph R x)) X X0) as [u ulub].
+ - destruct H0. exists (CauchyMorph_inv R x).
+ specialize (H (CauchyMorph R (CauchyMorph_inv R x)) x
+ (CauchyMorph_surject R x)) as [_ H].
+ exact (H H0).
+ - destruct H1. exists (CauchyMorph_inv R x).
+ intros y Ey. specialize (H1 (CauchyMorph R y) Ey).
+ intros abs. apply H1.
+ apply (CauchyMorph_increasing R) in abs.
+ apply (CRle_lt_trans R _ (CauchyMorph R (CauchyMorph_inv R x))).
+ 2: exact abs. apply (CauchyMorph_surject R x).
+ - exists (CauchyMorph R u). destruct ulub. split.
+ + intros y Ey abs. specialize (H2 (CauchyMorph_inv R y)).
+ simpl in H2.
+ specialize (H (CauchyMorph R (CauchyMorph_inv R y)) y
+ (CauchyMorph_surject R y)) as [_ H].
+ specialize (H2 (H Ey)). apply H2.
+ apply CauchyMorph_inv_increasing in abs.
+ rewrite CauchyMorph_inject in abs. exact abs.
+ + intros. apply (H3 (CauchyMorph_inv R y)).
+ intros z Ez abs. specialize (H4 (CauchyMorph R z)).
+ apply (H4 Ez). apply (CauchyMorph_increasing R) in abs.
+ apply (CRle_lt_trans R _ (CauchyMorph R (CauchyMorph_inv R y))).
+ 2: exact abs. apply (CauchyMorph_surject R y).
+ apply CauchyMorph_inv_increasing in H5.
+ rewrite CauchyMorph_inject in H5. exact H5.
+Qed.
diff --git a/theories/Reals/ConstructiveRealsMorphisms.v b/theories/Reals/ConstructiveRealsMorphisms.v
new file mode 100644
index 0000000000..0d3027d475
--- /dev/null
+++ b/theories/Reals/ConstructiveRealsMorphisms.v
@@ -0,0 +1,1158 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2019 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+(************************************************************************)
+
+(** Morphisms used to transport results from any instance of
+ ConstructiveReals to any other.
+ Between any two constructive reals structures R1 and R2,
+ all morphisms R1 -> R2 are extensionally equal. We will
+ further show that they exist, and so are isomorphisms.
+ The difference between two morphisms R1 -> R2 is therefore
+ the speed of computation.
+
+ The canonical isomorphisms we provide here are often very slow,
+ when a new implementation of constructive reals is added,
+ it should define its own ad hoc isomorphisms for better speed.
+
+ Apart from the speed, those unique isomorphisms also serve as
+ sanity checks of the interface ConstructiveReals :
+ it captures a concept with a strong notion of uniqueness. *)
+
+Require Import QArith.
+Require Import Qabs.
+Require Import ConstructiveReals.
+Require Import ConstructiveCauchyRealsMult.
+Require Import ConstructiveRIneq.
+
+
+Record ConstructiveRealsMorphism (R1 R2 : ConstructiveReals) : Set :=
+ {
+ CRmorph : CRcarrier R1 -> CRcarrier R2;
+ CRmorph_rat : forall q : Q,
+ orderEq _ (CRlt R2) (CRmorph (CR_of_Q R1 q)) (CR_of_Q R2 q);
+ CRmorph_increasing : forall x y : CRcarrier R1,
+ CRlt R1 x y -> CRlt R2 (CRmorph x) (CRmorph y);
+ }.
+
+
+Lemma CRmorph_increasing_inv
+ : forall (R1 R2 : ConstructiveReals)
+ (f : ConstructiveRealsMorphism R1 R2)
+ (x y : CRcarrier R1),
+ CRlt R2 (CRmorph _ _ f x) (CRmorph _ _ f y)
+ -> CRlt R1 x y.
+Proof.
+ intros. destruct (CR_Q_dense R2 _ _ H) as [q [H0 H1]].
+ destruct (CR_Q_dense R2 _ _ H0) as [r [H2 H3]].
+ apply lt_CR_of_Q, (CR_of_Q_lt R1) in H3.
+ destruct (CRltLinear R1).
+ destruct (s _ x _ H3).
+ - exfalso. apply (CRmorph_increasing _ _ f) in c.
+ destruct (CRmorph_rat _ _ f r) as [H4 _].
+ apply (CRle_lt_trans R2 _ _ _ H4) in c. clear H4.
+ exact (CRlt_asym R2 _ _ c H2).
+ - clear H2 H3 r. apply (CRlt_trans R1 _ _ _ c). clear c.
+ destruct (CR_Q_dense R2 _ _ H1) as [t [H2 H3]].
+ apply lt_CR_of_Q, (CR_of_Q_lt R1) in H2.
+ destruct (s _ y _ H2). exact c.
+ exfalso. apply (CRmorph_increasing _ _ f) in c.
+ destruct (CRmorph_rat _ _ f t) as [_ H4].
+ apply (CRlt_le_trans R2 _ _ _ c) in H4. clear c.
+ exact (CRlt_asym R2 _ _ H4 H3).
+Qed.
+
+Lemma CRmorph_unique : forall (R1 R2 : ConstructiveReals)
+ (f g : ConstructiveRealsMorphism R1 R2)
+ (x : CRcarrier R1),
+ orderEq _ (CRlt R2) (CRmorph _ _ f x) (CRmorph _ _ g x).
+Proof.
+ split.
+ - intro abs. destruct (CR_Q_dense R2 _ _ abs) as [q [H H0]].
+ destruct (CRmorph_rat _ _ f q) as [H1 _].
+ apply (CRlt_le_trans R2 _ _ _ H) in H1. clear H.
+ apply CRmorph_increasing_inv in H1.
+ destruct (CRmorph_rat _ _ g q) as [_ H2].
+ apply (CRle_lt_trans R2 _ _ _ H2) in H0. clear H2.
+ apply CRmorph_increasing_inv in H0.
+ exact (CRlt_asym R1 _ _ H0 H1).
+ - intro abs. destruct (CR_Q_dense R2 _ _ abs) as [q [H H0]].
+ destruct (CRmorph_rat _ _ f q) as [_ H1].
+ apply (CRle_lt_trans R2 _ _ _ H1) in H0. clear H1.
+ apply CRmorph_increasing_inv in H0.
+ destruct (CRmorph_rat _ _ g q) as [H2 _].
+ apply (CRlt_le_trans R2 _ _ _ H) in H2. clear H.
+ apply CRmorph_increasing_inv in H2.
+ exact (CRlt_asym R1 _ _ H0 H2).
+Qed.
+
+
+(* The identity is the only endomorphism of constructive reals.
+ For any ConstructiveReals R1, R2 and any morphisms
+ f : R1 -> R2 and g : R2 -> R1,
+ f and g are isomorphisms and are inverses of each other. *)
+Lemma Endomorph_id : forall (R : ConstructiveReals) (f : ConstructiveRealsMorphism R R)
+ (x : CRcarrier R),
+ orderEq _ (CRlt R) (CRmorph _ _ f x) x.
+Proof.
+ split.
+ - intro abs. destruct (CR_Q_dense R _ _ abs) as [q [H0 H1]].
+ destruct (CRmorph_rat _ _ f q) as [H _].
+ apply (CRlt_le_trans R _ _ _ H0) in H. clear H0.
+ apply CRmorph_increasing_inv in H.
+ exact (CRlt_asym R _ _ H1 H).
+ - intro abs. destruct (CR_Q_dense R _ _ abs) as [q [H0 H1]].
+ destruct (CRmorph_rat _ _ f q) as [_ H].
+ apply (CRle_lt_trans R _ _ _ H) in H1. clear H.
+ apply CRmorph_increasing_inv in H1.
+ exact (CRlt_asym R _ _ H1 H0).
+Qed.
+
+Lemma CRmorph_proper : forall (R1 R2 : ConstructiveReals)
+ (f : ConstructiveRealsMorphism R1 R2)
+ (x y : CRcarrier R1),
+ orderEq _ (CRlt R1) x y
+ -> orderEq _ (CRlt R2) (CRmorph _ _ f x) (CRmorph _ _ f y).
+Proof.
+ split.
+ - intro abs. apply CRmorph_increasing_inv in abs.
+ destruct H. contradiction.
+ - intro abs. apply CRmorph_increasing_inv in abs.
+ destruct H. contradiction.
+Qed.
+
+Definition CRmorph_compose (R1 R2 R3 : ConstructiveReals)
+ (f : ConstructiveRealsMorphism R1 R2)
+ (g : ConstructiveRealsMorphism R2 R3)
+ : ConstructiveRealsMorphism R1 R3.
+Proof.
+ apply (Build_ConstructiveRealsMorphism
+ R1 R3 (fun x:CRcarrier R1 => CRmorph _ _ g (CRmorph _ _ f x))).
+ - intro q. apply (CReq_trans R3 _ (CRmorph R2 R3 g (CR_of_Q R2 q))).
+ apply CRmorph_proper. apply CRmorph_rat. apply CRmorph_rat.
+ - intros. apply CRmorph_increasing. apply CRmorph_increasing. exact H.
+Defined.
+
+Lemma CRmorph_le : forall (R1 R2 : ConstructiveReals)
+ (f : ConstructiveRealsMorphism R1 R2)
+ (x y : CRcarrier R1),
+ orderLe _ (CRlt R1) x y
+ -> orderLe _ (CRlt R2) (CRmorph _ _ f x) (CRmorph _ _ f y).
+Proof.
+ intros. intro abs. apply CRmorph_increasing_inv in abs. contradiction.
+Qed.
+
+Lemma CRmorph_le_inv : forall (R1 R2 : ConstructiveReals)
+ (f : ConstructiveRealsMorphism R1 R2)
+ (x y : CRcarrier R1),
+ orderLe _ (CRlt R2) (CRmorph _ _ f x) (CRmorph _ _ f y)
+ -> orderLe _ (CRlt R1) x y.
+Proof.
+ intros. intro abs. apply (CRmorph_increasing _ _ f) in abs. contradiction.
+Qed.
+
+Lemma CRmorph_zero : forall (R1 R2 : ConstructiveReals)
+ (f : ConstructiveRealsMorphism R1 R2),
+ orderEq _ (CRlt R2) (CRmorph _ _ f (CRzero R1)) (CRzero R2).
+Proof.
+ intros. apply (CReq_trans R2 _ (CRmorph _ _ f (CR_of_Q R1 0))).
+ apply CRmorph_proper. apply CReq_sym, CR_of_Q_zero.
+ apply (CReq_trans R2 _ (CR_of_Q R2 0)).
+ apply CRmorph_rat. apply CR_of_Q_zero.
+Qed.
+
+Lemma CRmorph_one : forall (R1 R2 : ConstructiveReals)
+ (f : ConstructiveRealsMorphism R1 R2),
+ orderEq _ (CRlt R2) (CRmorph _ _ f (CRone R1)) (CRone R2).
+Proof.
+ intros. apply (CReq_trans R2 _ (CRmorph _ _ f (CR_of_Q R1 1))).
+ apply CRmorph_proper. apply CReq_sym, CR_of_Q_one.
+ apply (CReq_trans R2 _ (CR_of_Q R2 1)).
+ apply CRmorph_rat. apply CR_of_Q_one.
+Qed.
+
+Lemma CRmorph_opp : forall (R1 R2 : ConstructiveReals)
+ (f : ConstructiveRealsMorphism R1 R2)
+ (x : CRcarrier R1),
+ orderEq _ (CRlt R2) (CRmorph _ _ f (CRopp R1 x))
+ (CRopp R2 (CRmorph _ _ f x)).
+Proof.
+ split.
+ - intro abs.
+ destruct (CR_Q_dense R2 _ _ abs) as [q [H H0]]. clear abs.
+ destruct (CRmorph_rat R1 R2 f q) as [H1 _].
+ apply (CRlt_le_trans R2 _ _ _ H) in H1. clear H.
+ apply CRmorph_increasing_inv in H1.
+ apply CRopp_gt_lt_contravar in H0.
+ destruct (CR_of_Q_opp R2 q) as [H2 _].
+ apply (CRlt_le_trans R2 _ _ _ H0) in H2. clear H0.
+ pose proof (CRopp_involutive R2 (CRmorph R1 R2 f x)) as [H _].
+ apply (CRle_lt_trans R2 _ _ _ H) in H2. clear H.
+ destruct (CRmorph_rat R1 R2 f (-q)) as [H _].
+ apply (CRlt_le_trans R2 _ _ _ H2) in H. clear H2.
+ apply CRmorph_increasing_inv in H.
+ destruct (CR_of_Q_opp R1 q) as [_ H2].
+ apply (CRlt_le_trans R1 _ _ _ H) in H2. clear H.
+ apply CRopp_gt_lt_contravar in H2.
+ pose proof (CRopp_involutive R1 (CR_of_Q R1 q)) as [H _].
+ apply (CRle_lt_trans R1 _ _ _ H) in H2. clear H.
+ exact (CRlt_asym R1 _ _ H1 H2).
+ - intro abs.
+ destruct (CR_Q_dense R2 _ _ abs) as [q [H H0]]. clear abs.
+ destruct (CRmorph_rat R1 R2 f q) as [_ H1].
+ apply (CRle_lt_trans R2 _ _ _ H1) in H0. clear H1.
+ apply CRmorph_increasing_inv in H0.
+ apply CRopp_gt_lt_contravar in H.
+ pose proof (CRopp_involutive R2 (CRmorph R1 R2 f x)) as [_ H1].
+ apply (CRlt_le_trans R2 _ _ _ H) in H1. clear H.
+ destruct (CR_of_Q_opp R2 q) as [_ H2].
+ apply (CRle_lt_trans R2 _ _ _ H2) in H1. clear H2.
+ destruct (CRmorph_rat R1 R2 f (-q)) as [_ H].
+ apply (CRle_lt_trans R2 _ _ _ H) in H1. clear H.
+ apply CRmorph_increasing_inv in H1.
+ destruct (CR_of_Q_opp R1 q) as [H2 _].
+ apply (CRle_lt_trans R1 _ _ _ H2) in H1. clear H2.
+ apply CRopp_gt_lt_contravar in H1.
+ pose proof (CRopp_involutive R1 (CR_of_Q R1 q)) as [_ H].
+ apply (CRlt_le_trans R1 _ _ _ H1) in H. clear H1.
+ exact (CRlt_asym R1 _ _ H0 H).
+Qed.
+
+Lemma CRplus_pos_rat_lt : forall (R : ConstructiveReals) (x : CRcarrier R) (q : Q),
+ Qlt 0 q -> CRlt R x (CRplus R x (CR_of_Q R q)).
+Proof.
+ intros.
+ apply (CRle_lt_trans R _ (CRplus R x (CRzero R))). apply CRplus_0_r.
+ apply CRplus_lt_compat_l.
+ apply (CRle_lt_trans R _ (CR_of_Q R 0)). apply CR_of_Q_zero.
+ apply CR_of_Q_lt. exact H.
+Defined.
+
+Lemma CRplus_neg_rat_lt : forall (R : ConstructiveReals) (x : CRcarrier R) (q : Q),
+ Qlt q 0 -> CRlt R (CRplus R x (CR_of_Q R q)) x.
+Proof.
+ intros.
+ apply (CRlt_le_trans R _ (CRplus R x (CRzero R))). 2: apply CRplus_0_r.
+ apply CRplus_lt_compat_l.
+ apply (CRlt_le_trans R _ (CR_of_Q R 0)).
+ apply CR_of_Q_lt. exact H. apply CR_of_Q_zero.
+Qed.
+
+Lemma CRmorph_plus_rat : forall (R1 R2 : ConstructiveReals)
+ (f : ConstructiveRealsMorphism R1 R2)
+ (x : CRcarrier R1) (q : Q),
+ orderEq _ (CRlt R2) (CRmorph _ _ f (CRplus R1 x (CR_of_Q R1 q)))
+ (CRplus R2 (CRmorph _ _ f x) (CR_of_Q R2 q)).
+Proof.
+ split.
+ - intro abs.
+ destruct (CR_Q_dense R2 _ _ abs) as [r [H H0]]. clear abs.
+ destruct (CRmorph_rat _ _ f r) as [H1 _].
+ apply (CRlt_le_trans R2 _ _ _ H) in H1. clear H.
+ apply CRmorph_increasing_inv in H1.
+ apply (CRlt_asym R1 _ _ H1). clear H1.
+ apply (CRplus_lt_reg_r R1 (CRopp R1 (CR_of_Q R1 q))).
+ apply (CRlt_le_trans R1 _ x).
+ apply (CRle_lt_trans R1 _ (CR_of_Q R1 (r-q))).
+ apply (CRle_trans R1 _ (CRplus R1 (CR_of_Q R1 r) (CR_of_Q R1 (-q)))).
+ apply CRplus_le_compat_l. destruct (CR_of_Q_opp R1 q). exact H.
+ destruct (CR_of_Q_plus R1 r (-q)). exact H.
+ apply (CRmorph_increasing_inv _ _ f).
+ apply (CRle_lt_trans R2 _ (CR_of_Q R2 (r - q))).
+ apply CRmorph_rat.
+ apply (CRplus_lt_reg_r R2 (CR_of_Q R2 q)).
+ apply (CRle_lt_trans R2 _ (CR_of_Q R2 r)). 2: exact H0.
+ intro H.
+ destruct (CR_of_Q_plus R2 (r-q) q) as [H1 _].
+ apply (CRlt_le_trans R2 _ _ _ H) in H1. clear H.
+ apply lt_CR_of_Q in H1. ring_simplify in H1.
+ exact (Qlt_not_le _ _ H1 (Qle_refl _)).
+ destruct (CRisRing R1).
+ apply (CRle_trans R1 _ (CRplus R1 x (CRplus R1 (CR_of_Q R1 q) (CRopp R1 (CR_of_Q R1 q))))).
+ apply (CRle_trans R1 _ (CRplus R1 x (CRzero R1))).
+ destruct (CRplus_0_r R1 x). exact H.
+ apply CRplus_le_compat_l. destruct (Ropp_def (CR_of_Q R1 q)). exact H.
+ destruct (Radd_assoc x (CR_of_Q R1 q) (CRopp R1 (CR_of_Q R1 q))).
+ exact H1.
+ - intro abs.
+ destruct (CR_Q_dense R2 _ _ abs) as [r [H H0]]. clear abs.
+ destruct (CRmorph_rat _ _ f r) as [_ H1].
+ apply (CRle_lt_trans R2 _ _ _ H1) in H0. clear H1.
+ apply CRmorph_increasing_inv in H0.
+ apply (CRlt_asym R1 _ _ H0). clear H0.
+ apply (CRplus_lt_reg_r R1 (CRopp R1 (CR_of_Q R1 q))).
+ apply (CRle_lt_trans R1 _ x).
+ destruct (CRisRing R1).
+ apply (CRle_trans R1 _ (CRplus R1 x (CRplus R1 (CR_of_Q R1 q) (CRopp R1 (CR_of_Q R1 q))))).
+ destruct (Radd_assoc x (CR_of_Q R1 q) (CRopp R1 (CR_of_Q R1 q))).
+ exact H0.
+ apply (CRle_trans R1 _ (CRplus R1 x (CRzero R1))).
+ apply CRplus_le_compat_l. destruct (Ropp_def (CR_of_Q R1 q)). exact H1.
+ destruct (CRplus_0_r R1 x). exact H1.
+ apply (CRlt_le_trans R1 _ (CR_of_Q R1 (r-q))).
+ apply (CRmorph_increasing_inv _ _ f).
+ apply (CRlt_le_trans R2 _ (CR_of_Q R2 (r - q))).
+ apply (CRplus_lt_reg_r R2 (CR_of_Q R2 q)).
+ apply (CRlt_le_trans R2 _ _ _ H).
+ 2: apply CRmorph_rat.
+ apply (CRle_trans R2 _ (CR_of_Q R2 (r-q+q))).
+ intro abs. apply lt_CR_of_Q in abs. ring_simplify in abs.
+ exact (Qlt_not_le _ _ abs (Qle_refl _)).
+ destruct (CR_of_Q_plus R2 (r-q) q). exact H1.
+ apply (CRle_trans R1 _ (CRplus R1 (CR_of_Q R1 r) (CR_of_Q R1 (-q)))).
+ destruct (CR_of_Q_plus R1 r (-q)). exact H1.
+ apply CRplus_le_compat_l. destruct (CR_of_Q_opp R1 q). exact H1.
+Qed.
+
+Lemma CRmorph_plus : forall (R1 R2 : ConstructiveReals)
+ (f : ConstructiveRealsMorphism R1 R2)
+ (x y : CRcarrier R1),
+ orderEq _ (CRlt R2) (CRmorph _ _ f (CRplus R1 x y))
+ (CRplus R2 (CRmorph _ _ f x) (CRmorph _ _ f y)).
+Proof.
+ intros R1 R2 f.
+ assert (forall (x y : CRcarrier R1),
+ orderLe _ (CRlt R2) (CRplus R2 (CRmorph R1 R2 f x) (CRmorph R1 R2 f y))
+ (CRmorph R1 R2 f (CRplus R1 x y))).
+ { intros x y abs. destruct (CR_Q_dense R2 _ _ abs) as [r [H H0]]. clear abs.
+ destruct (CRmorph_rat _ _ f r) as [H1 _].
+ apply (CRlt_le_trans R2 _ _ _ H) in H1. clear H.
+ apply CRmorph_increasing_inv in H1.
+ apply (CRlt_asym R1 _ _ H1). clear H1.
+ destruct (CR_Q_dense R2 _ _ H0) as [q [H2 H3]].
+ apply lt_CR_of_Q in H2.
+ assert (Qlt (r-q) 0) as epsNeg.
+ { apply (Qplus_lt_r _ _ q). ring_simplify. exact H2. }
+ destruct (CR_Q_dense R1 _ _ (CRplus_neg_rat_lt R1 x (r-q) epsNeg))
+ as [s [H4 H5]].
+ apply (CRlt_trans R1 _ (CRplus R1 (CR_of_Q R1 s) y)).
+ 2: apply CRplus_lt_compat_r, H5.
+ apply (CRmorph_increasing_inv _ _ f).
+ apply (CRlt_le_trans R2 _ (CRplus R2 (CR_of_Q R2 s) (CRmorph _ _ f y))).
+ apply (CRmorph_increasing _ _ f) in H4.
+ destruct (CRmorph_plus_rat _ _ f x (r-q)) as [H _].
+ apply (CRle_lt_trans R2 _ _ _ H) in H4. clear H.
+ destruct (CRmorph_rat _ _ f s) as [_ H1].
+ apply (CRlt_le_trans R2 _ _ _ H4) in H1. clear H4.
+ apply (CRlt_trans R2 _ (CRplus R2 (CRplus R2 (CRmorph R1 R2 f x) (CR_of_Q R2 (r - q)))
+ (CRmorph R1 R2 f y))).
+ 2: apply CRplus_lt_compat_r, H1.
+ apply (CRlt_le_trans R2 _ (CRplus R2 (CRplus R2 (CR_of_Q R2 (r - q)) (CRmorph R1 R2 f x))
+ (CRmorph R1 R2 f y))).
+ apply (CRlt_le_trans R2 _ (CRplus R2 (CR_of_Q R2 (r - q))
+ (CRplus R2 (CRmorph R1 R2 f x) (CRmorph R1 R2 f y)))).
+ apply (CRle_lt_trans R2 _ (CRplus R2 (CR_of_Q R2 (r - q)) (CR_of_Q R2 q))).
+ 2: apply CRplus_lt_compat_l, H3.
+ intro abs.
+ destruct (CR_of_Q_plus R2 (r-q) q) as [_ H4].
+ apply (CRle_lt_trans R2 _ _ _ H4) in abs. clear H4.
+ destruct (CRmorph_rat _ _ f r) as [_ H4].
+ apply (CRlt_le_trans R2 _ _ _ abs) in H4. clear abs.
+ apply lt_CR_of_Q in H4. ring_simplify in H4.
+ exact (Qlt_not_le _ _ H4 (Qle_refl _)).
+ destruct (CRisRing R2); apply Radd_assoc.
+ apply CRplus_le_compat_r. destruct (CRisRing R2).
+ destruct (Radd_comm (CRmorph R1 R2 f x) (CR_of_Q R2 (r - q))).
+ exact H.
+ intro abs.
+ destruct (CRmorph_plus_rat _ _ f y s) as [H _]. apply H. clear H.
+ apply (CRlt_le_trans R2 _ (CRplus R2 (CR_of_Q R2 s) (CRmorph R1 R2 f y))).
+ apply (CRle_lt_trans R2 _ (CRmorph R1 R2 f (CRplus R1 (CR_of_Q R1 s) y))).
+ apply CRmorph_proper. destruct (CRisRing R1); apply Radd_comm.
+ exact abs. destruct (CRisRing R2); apply Radd_comm. }
+ split.
+ - apply H.
+ - specialize (H (CRplus R1 x y) (CRopp R1 y)).
+ intro abs. apply H. clear H.
+ apply (CRle_lt_trans R2 _ (CRmorph R1 R2 f x)).
+ apply CRmorph_proper. destruct (CRisRing R1).
+ apply (CReq_trans R1 _ (CRplus R1 x (CRplus R1 y (CRopp R1 y)))).
+ apply CReq_sym, Radd_assoc.
+ apply (CReq_trans R1 _ (CRplus R1 x (CRzero R1))). 2: apply CRplus_0_r.
+ destruct (CRisRingExt R1). apply Radd_ext.
+ apply CReq_refl. apply Ropp_def.
+ apply (CRplus_lt_reg_r R2 (CRmorph R1 R2 f y)).
+ apply (CRlt_le_trans R2 _ _ _ abs). clear abs.
+ apply (CRle_trans R2 _ (CRplus R2 (CRmorph R1 R2 f (CRplus R1 x y)) (CRzero R2))).
+ destruct (CRplus_0_r R2 (CRmorph R1 R2 f (CRplus R1 x y))). exact H.
+ apply (CRle_trans R2 _ (CRplus R2 (CRmorph R1 R2 f (CRplus R1 x y))
+ (CRplus R2 (CRmorph R1 R2 f (CRopp R1 y)) (CRmorph R1 R2 f y)))).
+ apply CRplus_le_compat_l.
+ apply (CRle_trans R2 _ (CRplus R2 (CRopp R2 (CRmorph R1 R2 f y)) (CRmorph R1 R2 f y))).
+ destruct (CRplus_opp_l R2 (CRmorph R1 R2 f y)). exact H.
+ apply CRplus_le_compat_r. destruct (CRmorph_opp _ _ f y). exact H.
+ destruct (CRisRing R2).
+ destruct (Radd_assoc (CRmorph R1 R2 f (CRplus R1 x y))
+ (CRmorph R1 R2 f (CRopp R1 y)) (CRmorph R1 R2 f y)).
+ exact H0.
+Qed.
+
+Lemma CRmorph_mult_pos : forall (R1 R2 : ConstructiveReals)
+ (f : ConstructiveRealsMorphism R1 R2)
+ (x : CRcarrier R1) (n : nat),
+ orderEq _ (CRlt R2) (CRmorph _ _ f (CRmult R1 x (CR_of_Q R1 (Z.of_nat n # 1))))
+ (CRmult R2 (CRmorph _ _ f x) (CR_of_Q R2 (Z.of_nat n # 1))).
+Proof.
+ induction n.
+ - simpl. destruct (CRisRingExt R1).
+ apply (CReq_trans R2 _ (CRzero R2)).
+ + apply (CReq_trans R2 _ (CRmorph R1 R2 f (CRzero R1))).
+ 2: apply CRmorph_zero. apply CRmorph_proper.
+ apply (CReq_trans R1 _ (CRmult R1 x (CRzero R1))).
+ 2: apply CRmult_0_r. apply Rmul_ext. apply CReq_refl. apply CR_of_Q_zero.
+ + apply (CReq_trans R2 _ (CRmult R2 (CRmorph R1 R2 f x) (CRzero R2))).
+ apply CReq_sym, CRmult_0_r. destruct (CRisRingExt R2).
+ apply Rmul_ext0. apply CReq_refl. apply CReq_sym, CR_of_Q_zero.
+ - destruct (CRisRingExt R1), (CRisRingExt R2).
+ apply (CReq_trans
+ R2 _ (CRmorph R1 R2 f (CRplus R1 x (CRmult R1 x (CR_of_Q R1 (Z.of_nat n # 1)))))).
+ apply CRmorph_proper.
+ apply (CReq_trans R1 _ (CRmult R1 x (CRplus R1 (CRone R1) (CR_of_Q R1 (Z.of_nat n # 1))))).
+ apply Rmul_ext. apply CReq_refl.
+ apply (CReq_trans R1 _ (CR_of_Q R1 (1 + (Z.of_nat n # 1)))).
+ apply CR_of_Q_proper. rewrite Nat2Z.inj_succ. unfold Z.succ.
+ rewrite Z.add_comm. rewrite Qinv_plus_distr. reflexivity.
+ apply (CReq_trans R1 _ (CRplus R1 (CR_of_Q R1 1) (CR_of_Q R1 (Z.of_nat n # 1)))).
+ apply CR_of_Q_plus. apply Radd_ext. apply CR_of_Q_one. apply CReq_refl.
+ apply (CReq_trans R1 _ (CRplus R1 (CRmult R1 x (CRone R1))
+ (CRmult R1 x (CR_of_Q R1 (Z.of_nat n # 1))))).
+ apply CRmult_plus_distr_l. apply Radd_ext. apply CRmult_1_r. apply CReq_refl.
+ apply (CReq_trans R2 _ (CRplus R2 (CRmorph R1 R2 f x)
+ (CRmorph R1 R2 f (CRmult R1 x (CR_of_Q R1 (Z.of_nat n # 1)))))).
+ apply CRmorph_plus.
+ apply (CReq_trans R2 _ (CRplus R2 (CRmorph R1 R2 f x)
+ (CRmult R2 (CRmorph R1 R2 f x) (CR_of_Q R2 (Z.of_nat n # 1))))).
+ apply Radd_ext0. apply CReq_refl. exact IHn.
+ apply (CReq_trans R2 _ (CRmult R2 (CRmorph R1 R2 f x) (CRplus R2 (CRone R2) (CR_of_Q R2 (Z.of_nat n # 1))))).
+ apply (CReq_trans R2 _ (CRplus R2 (CRmult R2 (CRmorph R1 R2 f x) (CRone R2))
+ (CRmult R2 (CRmorph _ _ f x) (CR_of_Q R2 (Z.of_nat n # 1))))).
+ apply Radd_ext0. 2: apply CReq_refl. apply CReq_sym, CRmult_1_r.
+ apply CReq_sym, CRmult_plus_distr_l.
+ apply Rmul_ext0. apply CReq_refl.
+ apply (CReq_trans R2 _ (CR_of_Q R2 (1 + (Z.of_nat n # 1)))).
+ apply (CReq_trans R2 _ (CRplus R2 (CR_of_Q R2 1) (CR_of_Q R2 (Z.of_nat n # 1)))).
+ apply Radd_ext0. apply CReq_sym, CR_of_Q_one. apply CReq_refl.
+ apply CReq_sym, CR_of_Q_plus.
+ apply CR_of_Q_proper. rewrite Nat2Z.inj_succ. unfold Z.succ.
+ rewrite Z.add_comm. rewrite Qinv_plus_distr. reflexivity.
+Qed.
+
+Lemma NatOfZ : forall n : Z, { p : nat | n = Z.of_nat p \/ n = Z.opp (Z.of_nat p) }.
+Proof.
+ intros [|p|n].
+ - exists O. left. reflexivity.
+ - exists (Pos.to_nat p). left. rewrite positive_nat_Z. reflexivity.
+ - exists (Pos.to_nat n). right. rewrite positive_nat_Z. reflexivity.
+Qed.
+
+Lemma CRmorph_mult_int : forall (R1 R2 : ConstructiveReals)
+ (f : ConstructiveRealsMorphism R1 R2)
+ (x : CRcarrier R1) (n : Z),
+ orderEq _ (CRlt R2) (CRmorph _ _ f (CRmult R1 x (CR_of_Q R1 (n # 1))))
+ (CRmult R2 (CRmorph _ _ f x) (CR_of_Q R2 (n # 1))).
+Proof.
+ intros. destruct (NatOfZ n) as [p [pos|neg]].
+ - subst n. apply CRmorph_mult_pos.
+ - subst n.
+ apply (CReq_trans R2 _ (CRopp R2 (CRmorph R1 R2 f (CRmult R1 x (CR_of_Q R1 (Z.of_nat p # 1)))))).
+ + apply (CReq_trans R2 _ (CRmorph R1 R2 f (CRopp R1 (CRmult R1 x (CR_of_Q R1 (Z.of_nat p # 1)))))).
+ 2: apply CRmorph_opp. apply CRmorph_proper.
+ apply (CReq_trans R1 _ (CRmult R1 x (CR_of_Q R1 (- (Z.of_nat p # 1))))).
+ destruct (CRisRingExt R1). apply Rmul_ext. apply CReq_refl.
+ apply CR_of_Q_proper. reflexivity.
+ apply (CReq_trans R1 _ (CRmult R1 x (CRopp R1 (CR_of_Q R1 (Z.of_nat p # 1))))).
+ destruct (CRisRingExt R1). apply Rmul_ext. apply CReq_refl.
+ apply CR_of_Q_opp. apply CReq_sym, CRopp_mult_distr_r.
+ + apply (CReq_trans R2 _ (CRopp R2 (CRmult R2 (CRmorph R1 R2 f x) (CR_of_Q R2 (Z.of_nat p # 1))))).
+ destruct (CRisRingExt R2). apply Ropp_ext. apply CRmorph_mult_pos.
+ apply (CReq_trans R2 _ (CRmult R2 (CRmorph R1 R2 f x) (CRopp R2 (CR_of_Q R2 (Z.of_nat p # 1))))).
+ apply CRopp_mult_distr_r. destruct (CRisRingExt R2).
+ apply Rmul_ext. apply CReq_refl.
+ apply (CReq_trans R2 _ (CR_of_Q R2 (- (Z.of_nat p # 1)))).
+ apply CReq_sym, CR_of_Q_opp. apply CR_of_Q_proper. reflexivity.
+Qed.
+
+Lemma CRmorph_mult_inv : forall (R1 R2 : ConstructiveReals)
+ (f : ConstructiveRealsMorphism R1 R2)
+ (x : CRcarrier R1) (p : positive),
+ orderEq _ (CRlt R2) (CRmorph _ _ f (CRmult R1 x (CR_of_Q R1 (1 # p))))
+ (CRmult R2 (CRmorph _ _ f x) (CR_of_Q R2 (1 # p))).
+Proof.
+ intros. apply (CRmult_eq_reg_r R2 (CR_of_Q R2 (Z.pos p # 1))).
+ left. apply (CRle_lt_trans R2 _ (CR_of_Q R2 0)).
+ apply CR_of_Q_zero. apply CR_of_Q_lt. reflexivity.
+ apply (CReq_trans R2 _ (CRmorph _ _ f x)).
+ - apply (CReq_trans
+ R2 _ (CRmorph R1 R2 f (CRmult R1 (CRmult R1 x (CR_of_Q R1 (1 # p)))
+ (CR_of_Q R1 (Z.pos p # 1))))).
+ apply CReq_sym, CRmorph_mult_int. apply CRmorph_proper.
+ apply (CReq_trans
+ R1 _ (CRmult R1 x (CRmult R1 (CR_of_Q R1 (1 # p))
+ (CR_of_Q R1 (Z.pos p # 1))))).
+ destruct (CRisRing R1). apply CReq_sym, Rmul_assoc.
+ apply (CReq_trans R1 _ (CRmult R1 x (CRone R1))).
+ apply (Rmul_ext (CRisRingExt R1)). apply CReq_refl.
+ apply (CReq_trans R1 _ (CR_of_Q R1 ((1#p) * (Z.pos p # 1)))).
+ apply CReq_sym, CR_of_Q_mult.
+ apply (CReq_trans R1 _ (CR_of_Q R1 1)).
+ apply CR_of_Q_proper. reflexivity. apply CR_of_Q_one.
+ apply CRmult_1_r.
+ - apply (CReq_trans R2 _ (CRmult R2 (CRmorph R1 R2 f x)
+ (CRmult R2 (CR_of_Q R2 (1 # p)) (CR_of_Q R2 (Z.pos p # 1))))).
+ 2: apply (Rmul_assoc (CRisRing R2)).
+ apply (CReq_trans R2 _ (CRmult R2 (CRmorph R1 R2 f x) (CRone R2))).
+ apply CReq_sym, CRmult_1_r.
+ apply (Rmul_ext (CRisRingExt R2)). apply CReq_refl.
+ apply (CReq_trans R2 _ (CR_of_Q R2 1)).
+ apply CReq_sym, CR_of_Q_one.
+ apply (CReq_trans R2 _ (CR_of_Q R2 ((1#p)*(Z.pos p # 1)))).
+ apply CR_of_Q_proper. reflexivity. apply CR_of_Q_mult.
+Qed.
+
+Lemma CRmorph_mult_rat : forall (R1 R2 : ConstructiveReals)
+ (f : ConstructiveRealsMorphism R1 R2)
+ (x : CRcarrier R1) (q : Q),
+ orderEq _ (CRlt R2) (CRmorph _ _ f (CRmult R1 x (CR_of_Q R1 q)))
+ (CRmult R2 (CRmorph _ _ f x) (CR_of_Q R2 q)).
+Proof.
+ intros. destruct q as [a b].
+ apply (CReq_trans R2 _ (CRmult R2 (CRmorph _ _ f (CRmult R1 x (CR_of_Q R1 (a # 1))))
+ (CR_of_Q R2 (1 # b)))).
+ - apply (CReq_trans
+ R2 _ (CRmorph R1 R2 f (CRmult R1 (CRmult R1 x (CR_of_Q R1 (a # 1)))
+ (CR_of_Q R1 (1 # b))))).
+ 2: apply CRmorph_mult_inv. apply CRmorph_proper.
+ apply (CReq_trans R1 _ (CRmult R1 x (CRmult R1 (CR_of_Q R1 (a # 1))
+ (CR_of_Q R1 (1 # b))))).
+ apply (Rmul_ext (CRisRingExt R1)). apply CReq_refl.
+ apply (CReq_trans R1 _ (CR_of_Q R1 ((a#1)*(1#b)))).
+ apply CR_of_Q_proper. unfold Qeq; simpl. rewrite Z.mul_1_r. reflexivity.
+ apply CR_of_Q_mult.
+ apply (Rmul_assoc (CRisRing R1)).
+ - apply (CReq_trans R2 _ (CRmult R2 (CRmult R2 (CRmorph _ _ f x) (CR_of_Q R2 (a # 1)))
+ (CR_of_Q R2 (1 # b)))).
+ apply (Rmul_ext (CRisRingExt R2)). apply CRmorph_mult_int.
+ apply CReq_refl.
+ apply (CReq_trans R2 _ (CRmult R2 (CRmorph R1 R2 f x)
+ (CRmult R2 (CR_of_Q R2 (a # 1)) (CR_of_Q R2 (1 # b))))).
+ apply CReq_sym, (Rmul_assoc (CRisRing R2)).
+ apply (Rmul_ext (CRisRingExt R2)). apply CReq_refl.
+ apply (CReq_trans R2 _ (CR_of_Q R2 ((a#1)*(1#b)))).
+ apply CReq_sym, CR_of_Q_mult.
+ apply CR_of_Q_proper. unfold Qeq; simpl. rewrite Z.mul_1_r. reflexivity.
+Qed.
+
+Lemma CRmorph_mult_pos_pos_le : forall (R1 R2 : ConstructiveReals)
+ (f : ConstructiveRealsMorphism R1 R2)
+ (x y : CRcarrier R1),
+ CRlt R1 (CRzero R1) y
+ -> orderLe _ (CRlt R2) (CRmult R2 (CRmorph _ _ f x) (CRmorph _ _ f y))
+ (CRmorph _ _ f (CRmult R1 x y)).
+Proof.
+ intros. intro abs. destruct (CR_Q_dense R2 _ _ abs) as [q [H1 H2]].
+ destruct (CRmorph_rat _ _ f q) as [H3 _].
+ apply (CRlt_le_trans R2 _ _ _ H1) in H3. clear H1.
+ apply CRmorph_increasing_inv in H3.
+ apply (CRlt_asym R1 _ _ H3). clear H3.
+ destruct (CR_Q_dense R2 _ _ H2) as [r [H1 H3]].
+ apply lt_CR_of_Q in H1.
+ destruct (CR_archimedean R1 y) as [A Amaj].
+ assert (/ ((r - q) * (1 # A)) * (q - r) == - (Z.pos A # 1)) as diveq.
+ { rewrite Qinv_mult_distr. setoid_replace (q-r) with (-1*(r-q)).
+ field_simplify. reflexivity. 2: field.
+ split. intro H4. inversion H4. intro H4.
+ apply Qlt_minus_iff in H1. rewrite H4 in H1. inversion H1. }
+ destruct (CR_Q_dense R1 (CRplus R1 x (CR_of_Q R1 ((q-r) * (1#A)))) x)
+ as [s [H4 H5]].
+ - apply (CRlt_le_trans R1 _ (CRplus R1 x (CRzero R1))).
+ 2: apply CRplus_0_r. apply CRplus_lt_compat_l.
+ apply (CRplus_lt_reg_l R1 (CR_of_Q R1 ((r-q) * (1#A)))).
+ apply (CRle_lt_trans R1 _ (CRzero R1)).
+ apply (CRle_trans R1 _ (CR_of_Q R1 ((r-q)*(1#A) + (q-r)*(1#A)))).
+ destruct (CR_of_Q_plus R1 ((r-q)*(1#A)) ((q-r)*(1#A))).
+ exact H0. apply (CRle_trans R1 _ (CR_of_Q R1 0)).
+ 2: destruct (CR_of_Q_zero R1); exact H4.
+ intro H4. apply lt_CR_of_Q in H4. ring_simplify in H4.
+ inversion H4.
+ apply (CRlt_le_trans R1 _ (CR_of_Q R1 ((r - q) * (1 # A)))).
+ 2: apply CRplus_0_r.
+ apply (CRle_lt_trans R1 _ (CR_of_Q R1 0)).
+ apply CR_of_Q_zero. apply CR_of_Q_lt.
+ rewrite <- (Qmult_0_r (r-q)). apply Qmult_lt_l.
+ apply Qlt_minus_iff in H1. exact H1. reflexivity.
+ - apply (CRmorph_increasing _ _ f) in H4.
+ destruct (CRmorph_plus _ _ f x (CR_of_Q R1 ((q-r) * (1#A)))) as [H6 _].
+ apply (CRle_lt_trans R2 _ _ _ H6) in H4. clear H6.
+ destruct (CRmorph_rat _ _ f s) as [_ H6].
+ apply (CRlt_le_trans R2 _ _ _ H4) in H6. clear H4.
+ apply (CRmult_lt_compat_r R2 (CRmorph _ _ f y)) in H6.
+ destruct (Rdistr_l (CRisRing R2) (CRmorph _ _ f x)
+ (CRmorph R1 R2 f (CR_of_Q R1 ((q-r) * (1#A))))
+ (CRmorph _ _ f y)) as [H4 _].
+ apply (CRle_lt_trans R2 _ _ _ H4) in H6. clear H4.
+ apply (CRle_lt_trans R1 _ (CRmult R1 (CR_of_Q R1 s) y)).
+ 2: apply CRmult_lt_compat_r. 2: exact H. 2: exact H5.
+ apply (CRmorph_le_inv _ _ f).
+ apply (CRle_trans R2 _ (CR_of_Q R2 q)).
+ destruct (CRmorph_rat _ _ f q). exact H4.
+ apply (CRle_trans R2 _ (CRmult R2 (CR_of_Q R2 s) (CRmorph _ _ f y))).
+ apply (CRle_trans R2 _ (CRplus R2 (CRmult R2 (CRmorph _ _ f x) (CRmorph _ _ f y))
+ (CR_of_Q R2 (q-r)))).
+ apply (CRle_trans R2 _ (CRplus R2 (CR_of_Q R2 r) (CR_of_Q R2 (q - r)))).
+ + apply (CRle_trans R2 _ (CR_of_Q R2 (r + (q-r)))).
+ intro H4. apply lt_CR_of_Q in H4. ring_simplify in H4.
+ exact (Qlt_not_le q q H4 (Qle_refl q)).
+ destruct (CR_of_Q_plus R2 r (q-r)). exact H4.
+ + apply CRplus_le_compat_r. intro H4.
+ apply (CRlt_asym R2 _ _ H3). exact H4.
+ + intro H4. apply (CRlt_asym R2 _ _ H4). clear H4.
+ apply (CRlt_trans_flip R2 _ _ _ H6). clear H6.
+ apply CRplus_lt_compat_l.
+ apply (CRlt_le_trans R2 _ (CRmult R2 (CR_of_Q R2 ((q - r) * (1 # A))) (CRmorph R1 R2 f y))).
+ apply (CRmult_lt_reg_l R2 (CR_of_Q R2 (/((r-q)*(1#A))))).
+ apply (CRle_lt_trans R2 _ (CR_of_Q R2 0)). apply CR_of_Q_zero.
+ apply CR_of_Q_lt, Qinv_lt_0_compat.
+ rewrite <- (Qmult_0_r (r-q)). apply Qmult_lt_l.
+ apply Qlt_minus_iff in H1. exact H1. reflexivity.
+ apply (CRle_lt_trans R2 _ (CRopp R2 (CR_of_Q R2 (Z.pos A # 1)))).
+ apply (CRle_trans R2 _ (CR_of_Q R2 (-(Z.pos A # 1)))).
+ apply (CRle_trans R2 _ (CR_of_Q R2 ((/ ((r - q) * (1 # A))) * (q - r)))).
+ destruct (CR_of_Q_mult R2 (/ ((r - q) * (1 # A))) (q - r)).
+ exact H0. destruct (CR_of_Q_proper R2 (/ ((r - q) * (1 # A)) * (q - r))
+ (-(Z.pos A # 1))).
+ exact diveq. intro H7. apply lt_CR_of_Q in H7.
+ rewrite diveq in H7. exact (Qlt_not_le _ _ H7 (Qle_refl _)).
+ destruct (CR_of_Q_opp R2 (Z.pos A # 1)). exact H4.
+ apply (CRlt_le_trans R2 _ (CRopp R2 (CRmorph _ _ f y))).
+ apply CRopp_gt_lt_contravar.
+ apply (CRlt_le_trans R2 _ (CRmorph _ _ f (CR_of_Q R1 (Z.pos A # 1)))).
+ apply CRmorph_increasing. exact Amaj.
+ destruct (CRmorph_rat _ _ f (Z.pos A # 1)). exact H4.
+ apply (CRle_trans R2 _ (CRmult R2 (CRopp R2 (CRone R2)) (CRmorph _ _ f y))).
+ apply (CRle_trans R2 _ (CRopp R2 (CRmult R2 (CRone R2) (CRmorph R1 R2 f y)))).
+ destruct (Ropp_ext (CRisRingExt R2) (CRmorph _ _ f y)
+ (CRmult R2 (CRone R2) (CRmorph R1 R2 f y))).
+ apply CReq_sym, (Rmul_1_l (CRisRing R2)). exact H4.
+ destruct (CRopp_mult_distr_l R2 (CRone R2) (CRmorph _ _ f y)). exact H4.
+ apply (CRle_trans R2 _ (CRmult R2 (CRmult R2 (CR_of_Q R2 (/ ((r - q) * (1 # A))))
+ (CR_of_Q R2 ((q - r) * (1 # A))))
+ (CRmorph R1 R2 f y))).
+ apply CRmult_le_compat_r.
+ apply (CRle_lt_trans R2 _ (CRmorph _ _ f (CRzero R1))).
+ apply CRmorph_zero. apply CRmorph_increasing. exact H.
+ apply (CRle_trans R2 _ (CR_of_Q R2 ((/ ((r - q) * (1 # A)))
+ * ((q - r) * (1 # A))))).
+ apply (CRle_trans R2 _ (CR_of_Q R2 (-1))).
+ apply (CRle_trans R2 _ (CRopp R2 (CR_of_Q R2 1))).
+ destruct (Ropp_ext (CRisRingExt R2) (CRone R2) (CR_of_Q R2 1)).
+ apply CReq_sym, CR_of_Q_one. exact H4.
+ destruct (CR_of_Q_opp R2 1). exact H0.
+ destruct (CR_of_Q_proper R2 (-1) (/ ((r - q) * (1 # A)) * ((q - r) * (1 # A)))).
+ field. split.
+ intro H4. inversion H4. intro H4. apply Qlt_minus_iff in H1.
+ rewrite H4 in H1. inversion H1. exact H4.
+ destruct (CR_of_Q_mult R2 (/ ((r - q) * (1 # A))) ((q - r) * (1 # A))).
+ exact H4.
+ destruct (Rmul_assoc (CRisRing R2) (CR_of_Q R2 (/ ((r - q) * (1 # A))))
+ (CR_of_Q R2 ((q - r) * (1 # A)))
+ (CRmorph R1 R2 f y)).
+ exact H0.
+ apply CRmult_le_compat_r.
+ apply (CRle_lt_trans R2 _ (CRmorph _ _ f (CRzero R1))).
+ apply CRmorph_zero. apply CRmorph_increasing. exact H.
+ destruct (CRmorph_rat _ _ f ((q - r) * (1 # A))). exact H0.
+ + apply (CRle_trans R2 _ (CRmorph _ _ f (CRmult R1 y (CR_of_Q R1 s)))).
+ apply (CRle_trans R2 _ (CRmult R2 (CRmorph R1 R2 f y) (CR_of_Q R2 s))).
+ destruct (Rmul_comm (CRisRing R2) (CRmorph R1 R2 f y) (CR_of_Q R2 s)).
+ exact H0.
+ destruct (CRmorph_mult_rat _ _ f y s). exact H0.
+ destruct (CRmorph_proper _ _ f (CRmult R1 y (CR_of_Q R1 s))
+ (CRmult R1 (CR_of_Q R1 s) y)).
+ apply (Rmul_comm (CRisRing R1)). exact H4.
+ + apply (CRle_lt_trans R2 _ (CRmorph _ _ f (CRzero R1))).
+ apply CRmorph_zero. apply CRmorph_increasing. exact H.
+Qed.
+
+Lemma CRmorph_mult_pos_pos : forall (R1 R2 : ConstructiveReals)
+ (f : ConstructiveRealsMorphism R1 R2)
+ (x y : CRcarrier R1),
+ CRlt R1 (CRzero R1) y
+ -> orderEq _ (CRlt R2) (CRmorph _ _ f (CRmult R1 x y))
+ (CRmult R2 (CRmorph _ _ f x) (CRmorph _ _ f y)).
+Proof.
+ split. apply CRmorph_mult_pos_pos_le. exact H.
+ intro abs. destruct (CR_Q_dense R2 _ _ abs) as [q [H1 H2]].
+ destruct (CRmorph_rat _ _ f q) as [_ H3].
+ apply (CRle_lt_trans R2 _ _ _ H3) in H2. clear H3.
+ apply CRmorph_increasing_inv in H2.
+ apply (CRlt_asym R1 _ _ H2). clear H2.
+ destruct (CR_Q_dense R2 _ _ H1) as [r [H2 H3]].
+ apply lt_CR_of_Q in H3.
+ destruct (CR_archimedean R1 y) as [A Amaj].
+ destruct (CR_Q_dense R1 x (CRplus R1 x (CR_of_Q R1 ((q-r) * (1#A)))))
+ as [s [H4 H5]].
+ - apply (CRle_lt_trans R1 _ (CRplus R1 x (CRzero R1))).
+ apply CRplus_0_r. apply CRplus_lt_compat_l.
+ apply (CRle_lt_trans R1 _ (CR_of_Q R1 0)).
+ apply CR_of_Q_zero. apply CR_of_Q_lt.
+ rewrite <- (Qmult_0_r (q-r)). apply Qmult_lt_l.
+ apply Qlt_minus_iff in H3. exact H3. reflexivity.
+ - apply (CRmorph_increasing _ _ f) in H5.
+ destruct (CRmorph_plus _ _ f x (CR_of_Q R1 ((q-r) * (1#A)))) as [_ H6].
+ apply (CRlt_le_trans R2 _ _ _ H5) in H6. clear H5.
+ destruct (CRmorph_rat _ _ f s) as [H5 _ ].
+ apply (CRle_lt_trans R2 _ _ _ H5) in H6. clear H5.
+ apply (CRmult_lt_compat_r R2 (CRmorph _ _ f y)) in H6.
+ apply (CRlt_le_trans R1 _ (CRmult R1 (CR_of_Q R1 s) y)).
+ apply CRmult_lt_compat_r. exact H. exact H4. clear H4.
+ apply (CRmorph_le_inv _ _ f).
+ apply (CRle_trans R2 _ (CR_of_Q R2 q)).
+ 2: destruct (CRmorph_rat _ _ f q); exact H0.
+ apply (CRle_trans R2 _ (CRmult R2 (CR_of_Q R2 s) (CRmorph R1 R2 f y))).
+ + apply (CRle_trans R2 _ (CRmorph _ _ f (CRmult R1 y (CR_of_Q R1 s)))).
+ destruct (CRmorph_proper _ _ f (CRmult R1 (CR_of_Q R1 s) y)
+ (CRmult R1 y (CR_of_Q R1 s))).
+ apply (Rmul_comm (CRisRing R1)). exact H4.
+ apply (CRle_trans R2 _ (CRmult R2 (CRmorph R1 R2 f y) (CR_of_Q R2 s))).
+ exact (proj2 (CRmorph_mult_rat _ _ f y s)).
+ destruct (Rmul_comm (CRisRing R2) (CR_of_Q R2 s) (CRmorph R1 R2 f y)).
+ exact H0.
+ + intro H5. apply (CRlt_asym R2 _ _ H5). clear H5.
+ apply (CRlt_trans R2 _ _ _ H6). clear H6.
+ apply (CRle_lt_trans
+ R2 _ (CRplus R2
+ (CRmult R2 (CRmorph _ _ f x) (CRmorph _ _ f y))
+ (CRmult R2 (CRmorph R1 R2 f (CR_of_Q R1 ((q - r) * (1 # A))))
+ (CRmorph R1 R2 f y)))).
+ apply (Rdistr_l (CRisRing R2)).
+ apply (CRle_lt_trans
+ R2 _ (CRplus R2 (CR_of_Q R2 r)
+ (CRmult R2 (CRmorph R1 R2 f (CR_of_Q R1 ((q - r) * (1 # A))))
+ (CRmorph R1 R2 f y)))).
+ apply CRplus_le_compat_r. intro H5. apply (CRlt_asym R2 _ _ H5 H2).
+ clear H2.
+ apply (CRle_lt_trans
+ R2 _ (CRplus R2 (CR_of_Q R2 r)
+ (CRmult R2 (CR_of_Q R2 ((q - r) * (1 # A)))
+ (CRmorph R1 R2 f y)))).
+ apply CRplus_le_compat_l, CRmult_le_compat_r.
+ apply (CRle_lt_trans R2 _ (CRmorph _ _ f (CRzero R1))).
+ apply CRmorph_zero. apply CRmorph_increasing. exact H.
+ destruct (CRmorph_rat _ _ f ((q - r) * (1 # A))). exact H2.
+ apply (CRlt_le_trans R2 _ (CRplus R2 (CR_of_Q R2 r)
+ (CR_of_Q R2 ((q - r))))).
+ apply CRplus_lt_compat_l.
+ * apply (CRmult_lt_reg_l R2 (CR_of_Q R2 (/((q - r) * (1 # A))))).
+ apply (CRle_lt_trans R2 _ (CR_of_Q R2 0)). apply CR_of_Q_zero.
+ apply CR_of_Q_lt, Qinv_lt_0_compat.
+ rewrite <- (Qmult_0_r (q-r)). apply Qmult_lt_l.
+ apply Qlt_minus_iff in H3. exact H3. reflexivity.
+ apply (CRle_lt_trans R2 _ (CRmorph _ _ f y)).
+ apply (CRle_trans R2 _ (CRmult R2 (CRmult R2 (CR_of_Q R2 (/ ((q - r) * (1 # A))))
+ (CR_of_Q R2 ((q - r) * (1 # A))))
+ (CRmorph R1 R2 f y))).
+ exact (proj2 (Rmul_assoc (CRisRing R2) (CR_of_Q R2 (/ ((q - r) * (1 # A))))
+ (CR_of_Q R2 ((q - r) * (1 # A)))
+ (CRmorph _ _ f y))).
+ apply (CRle_trans R2 _ (CRmult R2 (CRone R2) (CRmorph R1 R2 f y))).
+ apply CRmult_le_compat_r.
+ apply (CRle_lt_trans R2 _ (CRmorph _ _ f (CRzero R1))).
+ apply CRmorph_zero. apply CRmorph_increasing. exact H.
+ apply (CRle_trans R2 _ (CR_of_Q R2 ((/ ((q - r) * (1 # A))) * ((q - r) * (1 # A))))).
+ exact (proj1 (CR_of_Q_mult R2 (/ ((q - r) * (1 # A))) ((q - r) * (1 # A)))).
+ apply (CRle_trans R2 _ (CR_of_Q R2 1)).
+ destruct (CR_of_Q_proper R2 (/ ((q - r) * (1 # A)) * ((q - r) * (1 # A))) 1).
+ field_simplify. reflexivity. split.
+ intro H5. inversion H5. intro H5. apply Qlt_minus_iff in H3.
+ rewrite H5 in H3. inversion H3. exact H2.
+ destruct (CR_of_Q_one R2). exact H2.
+ destruct (Rmul_1_l (CRisRing R2) (CRmorph _ _ f y)).
+ intro H5. contradiction.
+ apply (CRlt_le_trans R2 _ (CR_of_Q R2 (Z.pos A # 1))).
+ apply (CRlt_le_trans R2 _ (CRmorph _ _ f (CR_of_Q R1 (Z.pos A # 1)))).
+ apply CRmorph_increasing. exact Amaj.
+ exact (proj2 (CRmorph_rat _ _ f (Z.pos A # 1))).
+ apply (CRle_trans R2 _ (CR_of_Q R2 ((/ ((q - r) * (1 # A))) * (q - r)))).
+ 2: exact (proj2 (CR_of_Q_mult R2 (/ ((q - r) * (1 # A))) (q - r))).
+ destruct (CR_of_Q_proper R2 (Z.pos A # 1) (/ ((q - r) * (1 # A)) * (q - r))).
+ field_simplify. reflexivity. split.
+ intro H5. inversion H5. intro H5. apply Qlt_minus_iff in H3.
+ rewrite H5 in H3. inversion H3. exact H2.
+ * apply (CRle_trans R2 _ (CR_of_Q R2 (r + (q-r)))).
+ exact (proj1 (CR_of_Q_plus R2 r (q-r))).
+ destruct (CR_of_Q_proper R2 (r + (q-r)) q). ring. exact H2.
+ + apply (CRle_lt_trans R2 _ (CRmorph _ _ f (CRzero R1))).
+ apply CRmorph_zero. apply CRmorph_increasing. exact H.
+Qed.
+
+Lemma CRmorph_mult : forall (R1 R2 : ConstructiveReals)
+ (f : ConstructiveRealsMorphism R1 R2)
+ (x y : CRcarrier R1),
+ orderEq _ (CRlt R2) (CRmorph _ _ f (CRmult R1 x y))
+ (CRmult R2 (CRmorph _ _ f x) (CRmorph _ _ f y)).
+Proof.
+ intros.
+ destruct (CR_archimedean R1 (CRopp R1 y)) as [p pmaj].
+ apply (CRplus_eq_reg_r R2 (CRmult R2 (CRmorph _ _ f x)
+ (CR_of_Q R2 (Z.pos p # 1)))).
+ apply (CReq_trans R2 _ (CRmorph _ _ f (CRmult R1 x (CRplus R1 y (CR_of_Q R1 (Z.pos p # 1)))))).
+ - apply (CReq_trans R2 _ (CRplus R2 (CRmorph R1 R2 f (CRmult R1 x y))
+ (CRmorph R1 R2 f (CRmult R1 x (CR_of_Q R1 (Z.pos p # 1)))))).
+ apply (Radd_ext (CRisRingExt R2)). apply CReq_refl.
+ apply CReq_sym, CRmorph_mult_int.
+ apply (CReq_trans R2 _ (CRmorph _ _ f (CRplus R1 (CRmult R1 x y)
+ (CRmult R1 x (CR_of_Q R1 (Z.pos p # 1)))))).
+ apply CReq_sym, CRmorph_plus. apply CRmorph_proper.
+ apply CReq_sym, CRmult_plus_distr_l.
+ - apply (CReq_trans R2 _ (CRmult R2 (CRmorph _ _ f x)
+ (CRmorph _ _ f (CRplus R1 y (CR_of_Q R1 (Z.pos p # 1)))))).
+ apply CRmorph_mult_pos_pos.
+ apply (CRplus_lt_compat_l R1 y) in pmaj.
+ apply (CRle_lt_trans R1 _ (CRplus R1 y (CRopp R1 y))).
+ 2: exact pmaj. apply (CRisRing R1).
+ apply (CReq_trans R2 _ (CRmult R2 (CRmorph R1 R2 f x)
+ (CRplus R2 (CRmorph R1 R2 f y) (CR_of_Q R2 (Z.pos p # 1))))).
+ apply (Rmul_ext (CRisRingExt R2)). apply CReq_refl.
+ apply (CReq_trans R2 _ (CRplus R2 (CRmorph R1 R2 f y)
+ (CRmorph _ _ f (CR_of_Q R1 (Z.pos p # 1))))).
+ apply CRmorph_plus.
+ apply (Radd_ext (CRisRingExt R2)). apply CReq_refl.
+ apply CRmorph_rat.
+ apply CRmult_plus_distr_l.
+Qed.
+
+Lemma CRmorph_appart : forall (R1 R2 : ConstructiveReals)
+ (f : ConstructiveRealsMorphism R1 R2)
+ (x y : CRcarrier R1)
+ (app : orderAppart _ (CRlt R1) x y),
+ orderAppart _ (CRlt R2) (CRmorph _ _ f x) (CRmorph _ _ f y).
+Proof.
+ intros. destruct app.
+ - left. apply CRmorph_increasing. exact c.
+ - right. apply CRmorph_increasing. exact c.
+Defined.
+
+Lemma CRmorph_appart_zero : forall (R1 R2 : ConstructiveReals)
+ (f : ConstructiveRealsMorphism R1 R2)
+ (x : CRcarrier R1)
+ (app : orderAppart _ (CRlt R1) x (CRzero R1)),
+ orderAppart _ (CRlt R2) (CRmorph _ _ f x) (CRzero R2).
+Proof.
+ intros. destruct app.
+ - left. apply (CRlt_le_trans R2 _ (CRmorph _ _ f (CRzero R1))).
+ apply CRmorph_increasing. exact c.
+ exact (proj2 (CRmorph_zero _ _ f)).
+ - right. apply (CRle_lt_trans R2 _ (CRmorph _ _ f (CRzero R1))).
+ exact (proj1 (CRmorph_zero _ _ f)).
+ apply CRmorph_increasing. exact c.
+Defined.
+
+Lemma CRmorph_inv : forall (R1 R2 : ConstructiveReals)
+ (f : ConstructiveRealsMorphism R1 R2)
+ (x : CRcarrier R1)
+ (xnz : orderAppart _ (CRlt R1) x (CRzero R1))
+ (fxnz : orderAppart _ (CRlt R2) (CRmorph _ _ f x) (CRzero R2)),
+ orderEq _ (CRlt R2) (CRmorph _ _ f (CRinv R1 x xnz))
+ (CRinv R2 (CRmorph _ _ f x) fxnz).
+Proof.
+ intros. apply (CRmult_eq_reg_r R2 (CRmorph _ _ f x)).
+ destruct fxnz. right. exact c. left. exact c.
+ apply (CReq_trans R2 _ (CRone R2)).
+ 2: apply CReq_sym, CRinv_l.
+ apply (CReq_trans R2 _ (CRmorph _ _ f (CRmult R1 (CRinv R1 x xnz) x))).
+ apply CReq_sym, CRmorph_mult.
+ apply (CReq_trans R2 _ (CRmorph _ _ f (CRone R1))).
+ apply CRmorph_proper. apply CRinv_l.
+ apply CRmorph_one.
+Qed.
+
+Definition CauchyMorph (R : ConstructiveReals)
+ : CReal -> CRcarrier R.
+Proof.
+ intros [xn xcau].
+ destruct (CR_complete R (fun n:nat => CR_of_Q R (xn n))).
+ - intros p. exists (Pos.to_nat p). intros.
+ specialize (xcau p i j H H0). apply Qlt_le_weak in xcau.
+ rewrite Qabs_Qle_condition in xcau. split.
+ + unfold CRminus.
+ apply (CRle_trans R _ (CRplus R (CR_of_Q R (xn i)) (CR_of_Q R (-xn j)))).
+ apply (CRle_trans R _ (CR_of_Q R (xn i-xn j))).
+ apply CR_of_Q_le. apply xcau. exact (proj2 (CR_of_Q_plus R _ _)).
+ apply CRplus_le_compat_l. exact (proj2 (CR_of_Q_opp R (xn j))).
+ + unfold CRminus.
+ apply (CRle_trans R _ (CRplus R (CR_of_Q R (xn i)) (CR_of_Q R (-xn j)))).
+ apply CRplus_le_compat_l. exact (proj1 (CR_of_Q_opp R (xn j))).
+ apply (CRle_trans R _ (CR_of_Q R (xn i-xn j))).
+ exact (proj1 (CR_of_Q_plus R _ _)).
+ apply CR_of_Q_le. apply xcau.
+ - exact x.
+Defined.
+
+Lemma CauchyMorph_rat : forall (R : ConstructiveReals) (q : Q),
+ orderEq _ (CRlt R) (CauchyMorph R (inject_Q q)) (CR_of_Q R q).
+Proof.
+ intros.
+ unfold CauchyMorph; simpl;
+ destruct (CRltLinear R), p, (CR_complete R (fun _ : nat => CR_of_Q R q)).
+ apply CR_cv_const in c0. apply CReq_sym. exact c0.
+Qed.
+
+Lemma CauchyMorph_increasing_Ql : forall (R : ConstructiveReals) (x : CReal) (q : Q),
+ CRealLt x (inject_Q q) -> CRlt R (CauchyMorph R x) (CR_of_Q R q).
+Proof.
+ intros.
+ unfold CauchyMorph; simpl;
+ destruct x as [xn xcau], (CRltLinear R), p, (CR_complete R (fun n : nat => CR_of_Q R (xn n))).
+ destruct (CRealQ_dense _ _ H) as [r [H0 H1]].
+ apply lt_inject_Q in H1.
+ destruct (s _ x _ (CR_of_Q_lt R _ _ H1)). 2: exact c1. exfalso.
+ clear H1 H q.
+ (* For an index high enough, xn should be both higher
+ and lower than r, which is absurd. *)
+ apply CRealLt_above in H0.
+ destruct H0 as [p pmaj]. simpl in pmaj.
+ destruct (CR_cv_above_rat R xn x r c0 c1).
+ assert (x0 <= Nat.max (Pos.to_nat p) (S x0))%nat.
+ { apply (le_trans _ (S x0)). apply le_S, le_refl. apply Nat.le_max_r. }
+ specialize (q (Nat.max (Pos.to_nat p) (S x0)) H). clear H.
+ specialize (pmaj (Pos.max p (Pos.of_nat (S x0))) (Pos.le_max_l _ _)).
+ rewrite Pos2Nat.inj_max, Nat2Pos.id in pmaj. 2: discriminate.
+ apply (Qlt_not_le _ _ q). apply Qlt_le_weak.
+ apply Qlt_minus_iff. apply (Qlt_trans _ (2#p)). reflexivity. exact pmaj.
+Qed.
+
+Lemma CauchyMorph_increasing_Qr : forall (R : ConstructiveReals) (x : CReal) (q : Q),
+ CRealLt (inject_Q q) x -> CRlt R (CR_of_Q R q) (CauchyMorph R x).
+Proof.
+ intros.
+ unfold CauchyMorph; simpl;
+ destruct x as [xn xcau], (CRltLinear R), p, (CR_complete R (fun n : nat => CR_of_Q R (xn n))).
+ destruct (CRealQ_dense _ _ H) as [r [H0 H1]].
+ apply lt_inject_Q in H0.
+ destruct (s _ x _ (CR_of_Q_lt R _ _ H0)). exact c1. exfalso.
+ clear H0 H q.
+ (* For an index high enough, xn should be both higher
+ and lower than r, which is absurd. *)
+ apply CRealLt_above in H1.
+ destruct H1 as [p pmaj]. simpl in pmaj.
+ destruct (CR_cv_below_rat R xn x r c0 c1).
+ assert (x0 <= Nat.max (Pos.to_nat p) (S x0))%nat.
+ { apply (le_trans _ (S x0)). apply le_S, le_refl. apply Nat.le_max_r. }
+ specialize (q (Nat.max (Pos.to_nat p) (S x0)) H). clear H.
+ specialize (pmaj (Pos.max p (Pos.of_nat (S x0))) (Pos.le_max_l _ _)).
+ rewrite Pos2Nat.inj_max, Nat2Pos.id in pmaj. 2: discriminate.
+ apply (Qlt_not_le _ _ q). apply Qlt_le_weak.
+ apply Qlt_minus_iff. apply (Qlt_trans _ (2#p)). reflexivity. exact pmaj.
+Qed.
+
+Lemma CauchyMorph_increasing : forall (R : ConstructiveReals) (x y : CReal),
+ CRealLt x y -> CRlt R (CauchyMorph R x) (CauchyMorph R y).
+Proof.
+ intros.
+ destruct (CRealQ_dense _ _ H) as [q [H0 H1]].
+ apply (CRlt_trans R _ (CR_of_Q R q)).
+ apply CauchyMorph_increasing_Ql. exact H0.
+ apply CauchyMorph_increasing_Qr. exact H1.
+Qed.
+
+Definition CauchyMorphism (R : ConstructiveReals) : ConstructiveRealsMorphism CRealImplem R.
+Proof.
+ apply (Build_ConstructiveRealsMorphism CRealImplem R (CauchyMorph R)).
+ exact (CauchyMorph_rat R).
+ exact (CauchyMorph_increasing R).
+Defined.
+
+Lemma RightBound : forall (R : ConstructiveReals) (x : CRcarrier R) (p q r : Q),
+ CRlt R x (CR_of_Q R q)
+ -> CRlt R x (CR_of_Q R r)
+ -> CRlt R (CR_of_Q R q) (CRplus R x (CR_of_Q R p))
+ -> CRlt R (CR_of_Q R r) (CRplus R x (CR_of_Q R p))
+ -> Qlt (Qabs (q - r)) p.
+Proof.
+ intros. apply Qabs_case.
+ - intros. apply (Qplus_lt_l _ _ r). ring_simplify.
+ apply (lt_CR_of_Q R), (CRlt_le_trans R _ _ _ H1).
+ apply (CRle_trans R _ (CRplus R (CR_of_Q R r) (CR_of_Q R p))).
+ intro abs. apply CRplus_lt_reg_r in abs.
+ exact (CRlt_asym R _ _ abs H0).
+ destruct (CR_of_Q_plus R r p). exact H4.
+ - intros. apply (Qplus_lt_l _ _ q). ring_simplify.
+ apply (lt_CR_of_Q R), (CRlt_le_trans R _ _ _ H2).
+ apply (CRle_trans R _ (CRplus R (CR_of_Q R q) (CR_of_Q R p))).
+ intro abs. apply CRplus_lt_reg_r in abs.
+ exact (CRlt_asym R _ _ abs H).
+ destruct (CR_of_Q_plus R q p). exact H4.
+Qed.
+
+Definition CauchyMorph_inv (R : ConstructiveReals)
+ : CRcarrier R -> CReal.
+Proof.
+ intro x.
+ exists (fun n:nat => let (q,_) := CR_Q_dense
+ R x _ (CRplus_pos_rat_lt R x (1 # Pos.of_nat (S n)) (eq_refl _))
+ in q).
+ intros n p q H0 H1.
+ destruct (CR_Q_dense R x (CRplus R x (CR_of_Q R (1 # Pos.of_nat (S p))))
+ (CRplus_pos_rat_lt R x (1 # Pos.of_nat (S p)) (eq_refl _)))
+ as [r [H2 H3]].
+ destruct (CR_Q_dense R x (CRplus R x (CR_of_Q R (1 # Pos.of_nat (S q))))
+ (CRplus_pos_rat_lt R x (1 # Pos.of_nat (S q)) (eq_refl _)))
+ as [s [H4 H5]].
+ apply (RightBound R x (1#n) r s). exact H2. exact H4.
+ apply (CRlt_trans R _ _ _ H3), CRplus_lt_compat_l, CR_of_Q_lt.
+ unfold Qlt. do 2 rewrite Z.mul_1_l. unfold Qden.
+ apply Pos2Z.pos_lt_pos, Pos2Nat.inj_lt. rewrite Nat2Pos.id.
+ 2: discriminate. apply le_n_S. exact H0.
+ apply (CRlt_trans R _ _ _ H5), CRplus_lt_compat_l, CR_of_Q_lt.
+ unfold Qlt. do 2 rewrite Z.mul_1_l. unfold Qden.
+ apply Pos2Z.pos_lt_pos, Pos2Nat.inj_lt. rewrite Nat2Pos.id.
+ 2: discriminate. apply le_n_S. exact H1.
+Defined.
+
+Lemma CauchyMorph_inv_rat : forall (R : ConstructiveReals) (q : Q),
+ CRealEq (CauchyMorph_inv R (CR_of_Q R q)) (inject_Q q).
+Proof.
+ split.
+ - intros [n nmaj]. unfold CauchyMorph_inv, proj1_sig, inject_Q in nmaj.
+ destruct (CR_Q_dense R (CR_of_Q R q)
+ (CRplus R (CR_of_Q R q) (CR_of_Q R (1 # Pos.of_nat (S (Pos.to_nat n)))))
+ (CRplus_pos_rat_lt R (CR_of_Q R q) (1 # Pos.of_nat (S (Pos.to_nat n)))
+ eq_refl))
+ as [r [H _]].
+ apply lt_CR_of_Q, Qlt_minus_iff in H.
+ apply (Qlt_not_le _ _ H), (Qplus_le_l _ _ (q-r)).
+ ring_simplify. apply (Qle_trans _ (2#n)). discriminate.
+ apply Qlt_le_weak. ring_simplify in nmaj. rewrite Qplus_comm. exact nmaj.
+ - intros [n nmaj]. unfold CauchyMorph_inv, proj1_sig, inject_Q in nmaj.
+ destruct (CR_Q_dense R (CR_of_Q R q)
+ (CRplus R (CR_of_Q R q) (CR_of_Q R (1 # Pos.of_nat (S (Pos.to_nat n)))))
+ (CRplus_pos_rat_lt R (CR_of_Q R q) (1 # Pos.of_nat (S (Pos.to_nat n)))
+ eq_refl))
+ as [r [_ H0]].
+ destruct (CR_of_Q_plus R q (1 # Pos.of_nat (S (Pos.to_nat n)))) as [H1 _].
+ apply (CRlt_le_trans R _ _ _ H0) in H1. clear H0.
+ apply lt_CR_of_Q, (Qplus_lt_l _ _ (-q)) in H1.
+ ring_simplify in H1. ring_simplify in nmaj.
+ apply (Qlt_trans _ _ _ nmaj) in H1. clear nmaj.
+ apply (Qlt_not_le _ _ H1). clear H1.
+ apply (Qle_trans _ (1#n)).
+ unfold Qle, Qnum, Qden. do 2 rewrite Z.mul_1_l.
+ apply Pos2Z.pos_le_pos. apply Pos2Nat.inj_le.
+ rewrite Nat2Pos.id. 2: discriminate. apply le_S, le_refl.
+ unfold Qle, Qnum, Qden. apply Z.mul_le_mono_nonneg_r.
+ 2: discriminate. apply Pos2Z.pos_is_nonneg.
+Qed.
+
+(* The easier side, because CauchyMorph_inv takes a limit from above. *)
+Lemma CauchyMorph_inv_increasing_Qr
+ : forall (R : ConstructiveReals) (x : CRcarrier R) (q : Q),
+ CRlt R (CR_of_Q R q) x -> CRealLt (inject_Q q) (CauchyMorph_inv R x).
+Proof.
+ intros.
+ destruct (CR_Q_dense R _ _ H) as [r [H2 H3]].
+ apply lt_CR_of_Q in H2.
+ destruct (Qarchimedean (/(r-q))) as [p pmaj].
+ exists (2*p)%positive. unfold CauchyMorph_inv, inject_Q, proj1_sig.
+ destruct (CR_Q_dense
+ R x (CRplus R x (CR_of_Q R (1 # Pos.of_nat (S (Pos.to_nat (2*p))))))
+ (CRplus_pos_rat_lt R x (1 # Pos.of_nat (S (Pos.to_nat (2*p)))) eq_refl))
+ as [t [H4 H5]].
+ setoid_replace (2#2*p) with (1#p). 2: reflexivity.
+ apply (Qlt_trans _ (r-q)).
+ apply (Qmult_lt_l _ _ (r-q)) in pmaj.
+ rewrite Qmult_inv_r in pmaj.
+ apply Qlt_shift_inv_r in pmaj. 2: reflexivity. exact pmaj.
+ intro abs. apply Qlt_minus_iff in H2.
+ rewrite abs in H2. inversion H2.
+ apply Qlt_minus_iff in H2. exact H2.
+ apply Qplus_lt_l, (lt_CR_of_Q R), (CRlt_trans R _ x _ H3 H4).
+Qed.
+
+Lemma CauchyMorph_inv_increasing : forall (R : ConstructiveReals) (x y : CRcarrier R),
+ CRlt R x y -> CRealLt (CauchyMorph_inv R x) (CauchyMorph_inv R y).
+Proof.
+ intros.
+ destruct (CR_Q_dense R _ _ H) as [q [H0 H1]].
+ apply (CReal_lt_trans _ (inject_Q q)).
+ - clear H1 H y.
+ destruct (CR_Q_dense R _ _ H0) as [r [H2 H3]].
+ apply lt_CR_of_Q in H3.
+ destruct (Qarchimedean (/(q-r))) as [p pmaj].
+ exists (4*p)%positive. unfold CauchyMorph_inv, inject_Q, proj1_sig.
+ destruct (CR_Q_dense
+ R x (CRplus R x (CR_of_Q R (1 # Pos.of_nat (S (Pos.to_nat (4*p))))))
+ (CRplus_pos_rat_lt R x (1 # Pos.of_nat (S (Pos.to_nat (4*p)))) eq_refl))
+ as [t [H4 H5]].
+ setoid_replace (2#4*p) with (1#2*p). 2: reflexivity.
+ assert (1 # 2 * p < (q - r) / 2) as H.
+ { apply Qlt_shift_div_l. reflexivity.
+ setoid_replace ((1#2*p)*2) with (1#p).
+ apply (Qmult_lt_l _ _ (q-r)) in pmaj.
+ rewrite Qmult_inv_r in pmaj.
+ apply Qlt_shift_inv_r in pmaj. 2: reflexivity. exact pmaj.
+ intro abs. apply Qlt_minus_iff in H3.
+ rewrite abs in H3. inversion H3.
+ apply Qlt_minus_iff in H3. exact H3.
+ rewrite Qmult_comm. reflexivity. }
+ apply (Qlt_trans _ ((q-r)/2)). exact H.
+ apply (Qplus_lt_l _ _ (t + (r-q)/2)). field_simplify.
+ setoid_replace (2*t/2) with t. 2: field.
+ apply (lt_CR_of_Q R). apply (CRlt_trans R _ _ _ H5).
+ apply (CRlt_trans
+ R _ (CRplus R (CR_of_Q R r) (CR_of_Q R (1 # Pos.of_nat (S (Pos.to_nat (4 * p))))))).
+ apply CRplus_lt_compat_r. exact H2.
+ apply (CRle_lt_trans
+ R _ (CR_of_Q R (r + (1 # Pos.of_nat (S (Pos.to_nat (4 * p))))))).
+ apply CR_of_Q_plus. apply CR_of_Q_lt.
+ apply (Qlt_le_trans _ (r + (q-r)/2)).
+ 2: field_simplify; apply Qle_refl.
+ apply Qplus_lt_r.
+ apply (Qlt_trans _ (1#2*p)). 2: exact H.
+ unfold Qlt. do 2 rewrite Z.mul_1_l. unfold Qden.
+ apply Pos2Z.pos_lt_pos.
+ rewrite Nat2Pos.inj_succ, Pos2Nat.id.
+ apply (Pos.lt_trans _ (4*p)). apply Pos2Nat.inj_lt.
+ do 2 rewrite Pos2Nat.inj_mul.
+ apply Nat.mul_lt_mono_pos_r. apply Pos2Nat.is_pos.
+ unfold Pos.to_nat. simpl. auto.
+ apply Pos.lt_succ_diag_r.
+ intro abs. pose proof (Pos2Nat.is_pos (4*p)).
+ rewrite abs in H1. inversion H1.
+ - apply CauchyMorph_inv_increasing_Qr. exact H1.
+Qed.
+
+Definition CauchyMorphismInv (R : ConstructiveReals)
+ : ConstructiveRealsMorphism R CRealImplem.
+Proof.
+ apply (Build_ConstructiveRealsMorphism R CRealImplem (CauchyMorph_inv R)).
+ - apply CauchyMorph_inv_rat.
+ - apply CauchyMorph_inv_increasing.
+Defined.
+
+Lemma CauchyMorph_surject : forall (R : ConstructiveReals) (x : CRcarrier R),
+ orderEq _ (CRlt R) (CauchyMorph R (CauchyMorph_inv R x)) x.
+Proof.
+ intros.
+ apply (Endomorph_id
+ R (CRmorph_compose _ _ _ (CauchyMorphismInv R) (CauchyMorphism R)) x).
+Qed.
+
+Lemma CauchyMorph_inject : forall (R : ConstructiveReals) (x : CReal),
+ CRealEq (CauchyMorph_inv R (CauchyMorph R x)) x.
+Proof.
+ intros.
+ apply (Endomorph_id CRealImplem (CRmorph_compose _ _ _ (CauchyMorphism R) (CauchyMorphismInv R)) x).
+Qed.
+
+(* We call this morphism slow to remind that it should only be used
+ for proofs, not for computations. *)
+Definition SlowConstructiveRealsMorphism (R1 R2 : ConstructiveReals)
+ : ConstructiveRealsMorphism R1 R2
+ := CRmorph_compose R1 CRealImplem R2
+ (CauchyMorphismInv R1) (CauchyMorphism R2).
diff --git a/theories/Reals/Raxioms.v b/theories/Reals/Raxioms.v
index f03b0ccea3..d856d1c7fe 100644
--- a/theories/Reals/Raxioms.v
+++ b/theories/Reals/Raxioms.v
@@ -21,6 +21,7 @@
Require Export ZArith_base.
Require Import ConstructiveRIneq.
+Require Import ConstructiveRealsLUB.
Require Export Rdefinitions.
Declare Scope R_scope.
Local Open Scope R_scope.
@@ -408,6 +409,10 @@ Lemma completeness :
bound E -> (exists x : R, E x) -> { m:R | is_lub E m }.
Proof.
intros. pose (fun x:ConstructiveRIneq.R => E (Rabst x)) as Er.
+ assert (forall x y : CRcarrier CR, orderEq (CRcarrier CR) (CRlt CR) x y -> Er x <-> Er y)
+ as Erproper.
+ { intros. unfold Er. replace (Rabst x) with (Rabst y). reflexivity.
+ apply Rquot1. do 2 rewrite Rquot2. split; apply H1. }
assert (exists x : ConstructiveRIneq.R, Er x) as Einhab.
{ destruct H0. exists (Rrepr x). unfold Er.
replace (Rabst (Rrepr x)) with x. exact H0.
@@ -418,7 +423,7 @@ Proof.
{ destruct H. exists (Rrepr x). intros y Ey. rewrite <- (Rquot2 y).
apply Rrepr_le. apply H. exact Ey. }
destruct (CR_sig_lub CR
- Er sig_forall_dec sig_not_dec Einhab Ebound).
+ Er Erproper sig_forall_dec sig_not_dec Einhab Ebound).
exists (Rabst x). split.
intros y Ey. apply Rrepr_le. rewrite Rquot2.
unfold ConstructiveRIneq.Rle. apply a.
diff --git a/theories/Structures/OrderedType.v b/theories/Structures/OrderedType.v
index 566dd31a9e..a411c5e54e 100644
--- a/theories/Structures/OrderedType.v
+++ b/theories/Structures/OrderedType.v
@@ -26,6 +26,8 @@ Arguments LT [X lt eq x y] _.
Arguments EQ [X lt eq x y] _.
Arguments GT [X lt eq x y] _.
+Create HintDb ordered_type.
+
Module Type MiniOrderedType.
Parameter Inline t : Type.
@@ -42,8 +44,8 @@ Module Type MiniOrderedType.
Parameter compare : forall x y : t, Compare lt eq x y.
- Hint Immediate eq_sym : core.
- Hint Resolve eq_refl eq_trans lt_not_eq lt_trans : core.
+ Hint Immediate eq_sym : ordered_type.
+ Hint Resolve eq_refl eq_trans lt_not_eq lt_trans : ordered_type.
End MiniOrderedType.
@@ -60,9 +62,9 @@ Module MOT_to_OT (Import O : MiniOrderedType) <: OrderedType.
Include O.
Definition eq_dec : forall x y : t, {eq x y} + {~ eq x y}.
- Proof.
- intros; elim (compare x y); intro H; [ right | left | right ]; auto.
- assert (~ eq y x); auto.
+ Proof with auto with ordered_type.
+ intros; elim (compare x y); intro H; [ right | left | right ]...
+ assert (~ eq y x)...
Defined.
End MOT_to_OT.
@@ -79,31 +81,30 @@ Module OrderedTypeFacts (Import O: OrderedType).
Lemma lt_antirefl : forall x, ~ lt x x.
Proof.
- intros; intro; absurd (eq x x); auto.
+ intros; intro; absurd (eq x x); auto with ordered_type.
Qed.
Instance lt_strorder : StrictOrder lt.
Proof. split; [ exact lt_antirefl | exact lt_trans]. Qed.
Lemma lt_eq : forall x y z, lt x y -> eq y z -> lt x z.
- Proof.
+ Proof with auto with ordered_type.
intros; destruct (compare x z) as [Hlt|Heq|Hlt]; auto.
- elim (lt_not_eq H); apply eq_trans with z; auto.
- elim (lt_not_eq (lt_trans Hlt H)); auto.
+ elim (lt_not_eq H); apply eq_trans with z...
+ elim (lt_not_eq (lt_trans Hlt H))...
Qed.
Lemma eq_lt : forall x y z, eq x y -> lt y z -> lt x z.
- Proof.
+ Proof with auto with ordered_type.
intros; destruct (compare x z) as [Hlt|Heq|Hlt]; auto.
- elim (lt_not_eq H0); apply eq_trans with x; auto.
- elim (lt_not_eq (lt_trans H0 Hlt)); auto.
+ elim (lt_not_eq H0); apply eq_trans with x...
+ elim (lt_not_eq (lt_trans H0 Hlt))...
Qed.
Instance lt_compat : Proper (eq==>eq==>iff) lt.
- Proof.
apply proper_sym_impl_iff_2; auto with *.
intros x x' Hx y y' Hy H.
- apply eq_lt with x; auto.
+ apply eq_lt with x; auto with ordered_type.
apply lt_eq with y; auto.
Qed.
@@ -143,9 +144,9 @@ Module OrderedTypeFacts (Import O: OrderedType).
Lemma eq_not_gt x y : eq x y -> ~ lt y x. Proof. order. Qed.
Lemma lt_not_gt x y : lt x y -> ~ lt y x. Proof. order. Qed.
- Hint Resolve gt_not_eq eq_not_lt : core.
- Hint Immediate eq_lt lt_eq le_eq eq_le neq_eq eq_neq : core.
- Hint Resolve eq_not_gt lt_antirefl lt_not_gt : core.
+ Hint Resolve gt_not_eq eq_not_lt : ordered_type.
+ Hint Immediate eq_lt lt_eq le_eq eq_le neq_eq eq_neq : ordered_type.
+ Hint Resolve eq_not_gt lt_antirefl lt_not_gt : ordered_type.
Lemma elim_compare_eq :
forall x y : t,
@@ -197,7 +198,7 @@ Module OrderedTypeFacts (Import O: OrderedType).
Lemma lt_dec : forall x y : t, {lt x y} + {~ lt x y}.
Proof.
- intros; elim (compare x y); [ left | right | right ]; auto.
+ intros; elim (compare x y); [ left | right | right ]; auto with ordered_type.
Defined.
Definition eqb x y : bool := if eq_dec x y then true else false.
@@ -247,8 +248,8 @@ Proof. exact (SortA_NoDupA eq_equiv lt_strorder lt_compat). Qed.
End ForNotations.
-Hint Resolve ListIn_In Sort_NoDup Inf_lt : core.
-Hint Immediate In_eq Inf_lt : core.
+Hint Resolve ListIn_In Sort_NoDup Inf_lt : ordered_type.
+Hint Immediate In_eq Inf_lt : ordered_type.
End OrderedTypeFacts.
@@ -266,8 +267,8 @@ Module KeyOrderedType(O:OrderedType).
eq (fst p) (fst p') /\ (snd p) = (snd p').
Definition ltk (p p':key*elt) := lt (fst p) (fst p').
- Hint Unfold eqk eqke ltk : core.
- Hint Extern 2 (eqke ?a ?b) => split : core.
+ Hint Unfold eqk eqke ltk : ordered_type.
+ Hint Extern 2 (eqke ?a ?b) => split : ordered_type.
(* eqke is stricter than eqk *)
@@ -283,35 +284,35 @@ Module KeyOrderedType(O:OrderedType).
Lemma ltk_right_l : forall x k e e', ltk (k,e) x -> ltk (k,e') x.
Proof. auto. Qed.
- Hint Immediate ltk_right_r ltk_right_l : core.
+ Hint Immediate ltk_right_r ltk_right_l : ordered_type.
(* eqk, eqke are equalities, ltk is a strict order *)
Lemma eqk_refl : forall e, eqk e e.
- Proof. auto. Qed.
+ Proof. auto with ordered_type. Qed.
Lemma eqke_refl : forall e, eqke e e.
- Proof. auto. Qed.
+ Proof. auto with ordered_type. Qed.
Lemma eqk_sym : forall e e', eqk e e' -> eqk e' e.
- Proof. auto. Qed.
+ Proof. auto with ordered_type. Qed.
Lemma eqke_sym : forall e e', eqke e e' -> eqke e' e.
Proof. unfold eqke; intuition. Qed.
Lemma eqk_trans : forall e e' e'', eqk e e' -> eqk e' e'' -> eqk e e''.
- Proof. eauto. Qed.
+ Proof. eauto with ordered_type. Qed.
Lemma eqke_trans : forall e e' e'', eqke e e' -> eqke e' e'' -> eqke e e''.
Proof.
- unfold eqke; intuition; [ eauto | congruence ].
+ unfold eqke; intuition; [ eauto with ordered_type | congruence ].
Qed.
Lemma ltk_trans : forall e e' e'', ltk e e' -> ltk e' e'' -> ltk e e''.
- Proof. eauto. Qed.
+ Proof. eauto with ordered_type. Qed.
Lemma ltk_not_eqk : forall e e', ltk e e' -> ~ eqk e e'.
- Proof. unfold eqk, ltk; auto. Qed.
+ Proof. unfold eqk, ltk; auto with ordered_type. Qed.
Lemma ltk_not_eqke : forall e e', ltk e e' -> ~eqke e e'.
Proof.
@@ -319,18 +320,18 @@ Module KeyOrderedType(O:OrderedType).
exact (lt_not_eq H H1).
Qed.
- Hint Resolve eqk_trans eqke_trans eqk_refl eqke_refl : core.
- Hint Resolve ltk_trans ltk_not_eqk ltk_not_eqke : core.
- Hint Immediate eqk_sym eqke_sym : core.
+ Hint Resolve eqk_trans eqke_trans eqk_refl eqke_refl : ordered_type.
+ Hint Resolve ltk_trans ltk_not_eqk ltk_not_eqke : ordered_type.
+ Hint Immediate eqk_sym eqke_sym : ordered_type.
Global Instance eqk_equiv : Equivalence eqk.
- Proof. constructor; eauto. Qed.
+ Proof. constructor; eauto with ordered_type. Qed.
Global Instance eqke_equiv : Equivalence eqke.
- Proof. split; eauto. Qed.
+ Proof. split; eauto with ordered_type. Qed.
Global Instance ltk_strorder : StrictOrder ltk.
- Proof. constructor; eauto. intros x; apply (irreflexivity (x:=fst x)). Qed.
+ Proof. constructor; eauto with ordered_type. intros x; apply (irreflexivity (x:=fst x)). Qed.
Global Instance ltk_compat : Proper (eqk==>eqk==>iff) ltk.
Proof.
@@ -348,45 +349,45 @@ Module KeyOrderedType(O:OrderedType).
Lemma eqk_not_ltk : forall x x', eqk x x' -> ~ltk x x'.
Proof.
- unfold eqk, ltk; simpl; auto.
+ unfold eqk, ltk; simpl; auto with ordered_type.
Qed.
Lemma ltk_eqk : forall e e' e'', ltk e e' -> eqk e' e'' -> ltk e e''.
- Proof. eauto. Qed.
+ Proof. eauto with ordered_type. Qed.
Lemma eqk_ltk : forall e e' e'', eqk e e' -> ltk e' e'' -> ltk e e''.
Proof.
intros (k,e) (k',e') (k'',e'').
- unfold ltk, eqk; simpl; eauto.
+ unfold ltk, eqk; simpl; eauto with ordered_type.
Qed.
- Hint Resolve eqk_not_ltk : core.
- Hint Immediate ltk_eqk eqk_ltk : core.
+ Hint Resolve eqk_not_ltk : ordered_type.
+ Hint Immediate ltk_eqk eqk_ltk : ordered_type.
Lemma InA_eqke_eqk :
forall x m, InA eqke x m -> InA eqk x m.
Proof.
unfold eqke; induction 1; intuition.
Qed.
- Hint Resolve InA_eqke_eqk : core.
+ Hint Resolve InA_eqke_eqk : ordered_type.
Definition MapsTo (k:key)(e:elt):= InA eqke (k,e).
Definition In k m := exists e:elt, MapsTo k e m.
Notation Sort := (sort ltk).
Notation Inf := (lelistA ltk).
- Hint Unfold MapsTo In : core.
+ Hint Unfold MapsTo In : ordered_type.
(* An alternative formulation for [In k l] is [exists e, InA eqk (k,e) l] *)
Lemma In_alt : forall k l, In k l <-> exists e, InA eqk (k,e) l.
- Proof.
+ Proof with auto with ordered_type.
firstorder.
- exists x; auto.
+ exists x...
induction H.
- destruct y.
- exists e; auto.
+ destruct y.
+ exists e...
destruct IHInA as [e H0].
- exists e; auto.
+ exists e...
Qed.
Lemma MapsTo_eq : forall l x y e, eq x y -> MapsTo x e l -> MapsTo y e l.
@@ -405,8 +406,8 @@ Module KeyOrderedType(O:OrderedType).
Lemma Inf_lt : forall l x x', ltk x x' -> Inf x' l -> Inf x l.
Proof. exact (InfA_ltA ltk_strorder). Qed.
- Hint Immediate Inf_eq : core.
- Hint Resolve Inf_lt : core.
+ Hint Immediate Inf_eq : ordered_type.
+ Hint Resolve Inf_lt : ordered_type.
Lemma Sort_Inf_In :
forall l p q, Sort l -> Inf q l -> InA eqk p l -> ltk q p.
@@ -420,8 +421,8 @@ Module KeyOrderedType(O:OrderedType).
intros; red; intros.
destruct H1 as [e' H2].
elim (@ltk_not_eqk (k,e) (k,e')).
- eapply Sort_Inf_In; eauto.
- red; simpl; auto.
+ eapply Sort_Inf_In; eauto with ordered_type.
+ red; simpl; auto with ordered_type.
Qed.
Lemma Sort_NoDupA: forall l, Sort l -> NoDupA eqk l.
@@ -437,7 +438,7 @@ Module KeyOrderedType(O:OrderedType).
Lemma Sort_In_cons_2 : forall l e e', Sort (e::l) -> InA eqk e' (e::l) ->
ltk e e' \/ eqk e e'.
Proof.
- inversion_clear 2; auto.
+ inversion_clear 2; auto with ordered_type.
left; apply Sort_In_cons_1 with l; auto.
Qed.
@@ -451,7 +452,7 @@ Module KeyOrderedType(O:OrderedType).
Lemma In_inv : forall k k' e l, In k ((k',e) :: l) -> eq k k' \/ In k l.
Proof.
inversion 1.
- inversion_clear H0; eauto.
+ inversion_clear H0; eauto with ordered_type.
destruct H1; simpl in *; intuition.
Qed.
@@ -469,19 +470,19 @@ Module KeyOrderedType(O:OrderedType).
End Elt.
- Hint Unfold eqk eqke ltk : core.
- Hint Extern 2 (eqke ?a ?b) => split : core.
- Hint Resolve eqk_trans eqke_trans eqk_refl eqke_refl : core.
- Hint Resolve ltk_trans ltk_not_eqk ltk_not_eqke : core.
- Hint Immediate eqk_sym eqke_sym : core.
- Hint Resolve eqk_not_ltk : core.
- Hint Immediate ltk_eqk eqk_ltk : core.
- Hint Resolve InA_eqke_eqk : core.
- Hint Unfold MapsTo In : core.
- Hint Immediate Inf_eq : core.
- Hint Resolve Inf_lt : core.
- Hint Resolve Sort_Inf_NotIn : core.
- Hint Resolve In_inv_2 In_inv_3 : core.
+ Hint Unfold eqk eqke ltk : ordered_type.
+ Hint Extern 2 (eqke ?a ?b) => split : ordered_type.
+ Hint Resolve eqk_trans eqke_trans eqk_refl eqke_refl : ordered_type.
+ Hint Resolve ltk_trans ltk_not_eqk ltk_not_eqke : ordered_type.
+ Hint Immediate eqk_sym eqke_sym : ordered_type.
+ Hint Resolve eqk_not_ltk : ordered_type.
+ Hint Immediate ltk_eqk eqk_ltk : ordered_type.
+ Hint Resolve InA_eqke_eqk : ordered_type.
+ Hint Unfold MapsTo In : ordered_type.
+ Hint Immediate Inf_eq : ordered_type.
+ Hint Resolve Inf_lt : ordered_type.
+ Hint Resolve Sort_Inf_NotIn : ordered_type.
+ Hint Resolve In_inv_2 In_inv_3 : ordered_type.
End KeyOrderedType.
diff --git a/theories/Structures/OrderedTypeEx.v b/theories/Structures/OrderedTypeEx.v
index 9b99fa5de4..a8e6993a63 100644
--- a/theories/Structures/OrderedTypeEx.v
+++ b/theories/Structures/OrderedTypeEx.v
@@ -178,7 +178,7 @@ Module PairOrderedType(O1 O2:OrderedType) <: OrderedType.
Lemma eq_refl : forall x : t, eq x x.
Proof.
- intros (x1,x2); red; simpl; auto.
+ intros (x1,x2); red; simpl; auto with ordered_type.
Qed.
Lemma eq_sym : forall x y : t, eq x y -> eq y x.
@@ -188,16 +188,16 @@ Module PairOrderedType(O1 O2:OrderedType) <: OrderedType.
Lemma eq_trans : forall x y z : t, eq x y -> eq y z -> eq x z.
Proof.
- intros (x1,x2) (y1,y2) (z1,z2); unfold eq; simpl; intuition eauto.
+ intros (x1,x2) (y1,y2) (z1,z2); unfold eq; simpl; intuition eauto with ordered_type.
Qed.
Lemma lt_trans : forall x y z : t, lt x y -> lt y z -> lt x z.
Proof.
intros (x1,x2) (y1,y2) (z1,z2); unfold eq, lt; simpl; intuition.
- left; eauto.
+ left; eauto with ordered_type.
left; eapply MO1.lt_eq; eauto.
left; eapply MO1.eq_lt; eauto.
- right; split; eauto.
+ right; split; eauto with ordered_type.
Qed.
Lemma lt_not_eq : forall x y : t, lt x y -> ~ eq x y.
@@ -214,7 +214,7 @@ Module PairOrderedType(O1 O2:OrderedType) <: OrderedType.
destruct (O2.compare x2 y2).
apply LT; unfold lt; auto.
apply EQ; unfold eq; auto.
- apply GT; unfold lt; auto.
+ apply GT; unfold lt; auto with ordered_type.
apply GT; unfold lt; auto.
Defined.
diff --git a/tools/CoqMakefile.in b/tools/CoqMakefile.in
index d37d2bea94..08253e5a8f 100644
--- a/tools/CoqMakefile.in
+++ b/tools/CoqMakefile.in
@@ -266,7 +266,7 @@ CMIFILES = \
$(CMOFILES:.cmo=.cmi) \
$(MLIFILES:.mli=.cmi)
# the /if/ is because old _CoqProject did not list a .ml(pack|lib) but just
-# a .ml4 file
+# a .mlg file
CMXSFILES = \
$(MLPACKFILES:.mlpack=.cmxs) \
$(CMXAFILES:.cmxa=.cmxs) \
diff --git a/tools/coq_dune.ml b/tools/coq_dune.ml
index adb416e3ce..ab180769b6 100644
--- a/tools/coq_dune.ml
+++ b/tools/coq_dune.ml
@@ -127,7 +127,6 @@ module Options = struct
let all_opts =
[ { enabled = false; cmd = "-debug"; }
; { enabled = false; cmd = "-native_compiler"; }
- ; { enabled = true; cmd = "-allow-sprop"; }
; { enabled = true; cmd = "-w +default"; }
]
diff --git a/toplevel/coqargs.ml b/toplevel/coqargs.ml
index 113b1fb5d7..1529959cc6 100644
--- a/toplevel/coqargs.ml
+++ b/toplevel/coqargs.ml
@@ -113,7 +113,7 @@ let default_logic_config = {
impredicative_set = Declarations.PredicativeSet;
indices_matter = false;
toplevel_name = Stm.TopLogical default_toplevel;
- allow_sprop = false;
+ allow_sprop = true;
cumulative_sprop = false;
}
@@ -178,7 +178,8 @@ let add_compat_require opts v =
match v with
| Flags.V8_8 -> add_vo_require opts "Coq.Compat.Coq88" None (Some false)
| Flags.V8_9 -> add_vo_require opts "Coq.Compat.Coq89" None (Some false)
- | Flags.Current -> add_vo_require opts "Coq.Compat.Coq810" None (Some false)
+ | Flags.V8_10 -> add_vo_require opts "Coq.Compat.Coq810" None (Some false)
+ | Flags.Current -> add_vo_require opts "Coq.Compat.Coq811" None (Some false)
let add_load_vernacular opts verb s =
{ opts with pre = { opts.pre with load_vernacular_list = (CUnix.make_suffix s ".v",verb) :: opts.pre.load_vernacular_list }}
@@ -497,7 +498,7 @@ let parse_args ~help ~init arglist : t * string list =
{ oval with config = { oval.config with stm_flags = { oval.config.stm_flags with
Stm.AsyncOpts.async_proofs_never_reopen_branch = true
}}}
- |"-test-mode" -> Vernacentries.test_mode := true; oval
+ |"-test-mode" -> Vernacinterp.test_mode := true; oval
|"-beautify" -> Flags.beautify := true; oval
|"-bt" -> Backtrace.record_backtrace true; oval
|"-color" -> set_color oval (next ())
diff --git a/toplevel/coqc.ml b/toplevel/coqc.ml
index 7658ad68a5..642dc94ab2 100644
--- a/toplevel/coqc.ml
+++ b/toplevel/coqc.ml
@@ -54,7 +54,10 @@ let coqc_main copts ~opts =
if opts.Coqargs.post.Coqargs.output_context then begin
let sigma, env = let e = Global.env () in Evd.from_env e, e in
let library_accessor = Library.indirect_accessor in
- Feedback.msg_notice Pp.(Flags.(with_option raw_print (Prettyp.print_full_pure_context ~library_accessor env) sigma) ++ fnl ())
+ let mod_ops = { Printmod.import_module = Declaremods.import_module
+ ; process_module_binding = Declaremods.process_module_binding
+ } in
+ Feedback.msg_notice Pp.(Flags.(with_option raw_print (Prettyp.print_full_pure_context ~mod_ops ~library_accessor env) sigma) ++ fnl ())
end;
CProfile.print_profile ()
diff --git a/toplevel/coqloop.ml b/toplevel/coqloop.ml
index 07466d641e..1f319d2bfd 100644
--- a/toplevel/coqloop.ml
+++ b/toplevel/coqloop.ml
@@ -405,7 +405,17 @@ let rec vernac_loop ~state =
| Some (VernacShowGoal {gid; sid}) ->
let proof = Stm.get_proof ~doc:state.doc (Stateid.of_int sid) in
- Feedback.msg_notice (Printer.pr_goal_emacs ~proof gid sid);
+ let goal = Printer.pr_goal_emacs ~proof gid sid in
+ let evars =
+ match proof with
+ | None -> mt()
+ | Some p ->
+ let gl = (Evar.unsafe_of_int gid) in
+ let { Proof.sigma } = Proof.data p in
+ try Printer.print_dependent_evars (Some gl) sigma [ gl ]
+ with Not_found -> mt()
+ in
+ Feedback.msg_notice (v 0 (goal ++ evars));
vernac_loop ~state
| None ->
diff --git a/toplevel/usage.ml b/toplevel/usage.ml
index 8555d78156..b17ca71f4c 100644
--- a/toplevel/usage.ml
+++ b/toplevel/usage.ml
@@ -79,6 +79,7 @@ let print_usage_common co command =
\n -dump-glob f dump globalizations in file f (to be used by coqdoc)\
\n -impredicative-set set sort Set impredicative\
\n -allow-sprop allow using the proof irrelevant SProp sort\
+\n -disallow-sprop forbid using the proof irrelevant SProp sort\
\n -sprop-cumulative make sort SProp cumulative with the rest of the hierarchy\
\n -indices-matter levels of indices (and nonuniform parameters) contribute to the level of inductives\
\n -type-in-type disable universe consistency checking\
diff --git a/user-contrib/Ltac2/Bool.v b/user-contrib/Ltac2/Bool.v
index d808436e13..d808436e13 100755..100644
--- a/user-contrib/Ltac2/Bool.v
+++ b/user-contrib/Ltac2/Bool.v
diff --git a/user-contrib/Ltac2/Constr.v b/user-contrib/Ltac2/Constr.v
index 34299f3cf9..1e330b06d7 100644
--- a/user-contrib/Ltac2/Constr.v
+++ b/user-contrib/Ltac2/Constr.v
@@ -16,6 +16,10 @@ Ltac2 @ external type : constr -> constr := "ltac2" "constr_type".
Ltac2 @ external equal : constr -> constr -> bool := "ltac2" "constr_equal".
(** Strict syntactic equality: only up to α-conversion and evar expansion *)
+Ltac2 Type relevance := [ Relevant | Irrelevant ].
+
+Ltac2 Type 'a binder_annot := { binder_name : 'a; binder_relevance : relevance }.
+
Module Unsafe.
(** Low-level access to kernel terms. Use with care! *)
@@ -29,16 +33,16 @@ Ltac2 Type kind := [
| Evar (evar, constr array)
| Sort (sort)
| Cast (constr, cast, constr)
-| Prod (ident option, constr, constr)
-| Lambda (ident option, constr, constr)
-| LetIn (ident option, constr, constr, constr)
+| Prod (ident option binder_annot, constr, constr)
+| Lambda (ident option binder_annot, constr, constr)
+| LetIn (ident option binder_annot, constr, constr, constr)
| App (constr, constr array)
| Constant (constant, instance)
| Ind (inductive, instance)
| Constructor (constructor, instance)
| Case (case, constr, constr, constr array)
-| Fix (int array, int, ident option array, constr array, constr array)
-| CoFix (int, ident option array, constr array, constr array)
+| Fix (int array, int, ident option binder_annot array, constr array, constr array)
+| CoFix (int, ident option binder_annot array, constr array, constr array)
| Proj (projection, constr)
| Uint63 (uint63)
].
diff --git a/user-contrib/Ltac2/Init.v b/user-contrib/Ltac2/Init.v
index 88454ff2fb..88454ff2fb 100755..100644
--- a/user-contrib/Ltac2/Init.v
+++ b/user-contrib/Ltac2/Init.v
diff --git a/vernac/classes.ml b/vernac/classes.ml
index d5f5656e1d..0a8c4e6b0f 100644
--- a/vernac/classes.ml
+++ b/vernac/classes.ml
@@ -371,10 +371,9 @@ let declare_instance_open sigma ?hook ~tac ~global ~poly id pri imps udecl ids t
the refinement manually.*)
let gls = List.rev (Evd.future_goals sigma) in
let sigma = Evd.reset_future_goals sigma in
- let scope = DeclareDef.Global Declare.ImportDefaultBehavior in
let kind = Decls.(IsDefinition Instance) in
let hook = DeclareDef.Hook.(make (fun { S.dref ; _ } -> instance_hook pri global imps ?hook dref)) in
- let info = Lemmas.Info.make ~hook ~scope ~kind () in
+ let info = Lemmas.Info.make ~hook ~kind () in
let lemma = Lemmas.start_lemma ~name:id ~poly ~udecl ~info sigma (EConstr.of_constr termtype) in
(* spiwack: I don't know what to do with the status here. *)
let lemma =
diff --git a/vernac/comAssumption.ml b/vernac/comAssumption.ml
index e3f90ab98c..5ba8b0ab3c 100644
--- a/vernac/comAssumption.ml
+++ b/vernac/comAssumption.ml
@@ -11,7 +11,6 @@
open CErrors
open Util
open Vars
-open Declare
open Names
open Context
open Constrexpr_ops
@@ -41,27 +40,24 @@ let should_axiom_into_instance = let open Decls in function
true
| Definitional | Logical | Conjectural -> !axiom_into_instance
-let declare_assumption is_coe ~poly ~scope ~kind typ univs pl imps impl nl {CAst.v=name} =
-let open DeclareDef in
-match scope with
-| Discharge ->
- let univs = match univs with
- | Monomorphic_entry univs -> univs
- | Polymorphic_entry (_, univs) -> Univ.ContextSet.of_context univs
- in
+let declare_variable is_coe ~kind typ imps impl {CAst.v=name} =
let kind = Decls.IsAssumption kind in
- let decl = SectionLocalAssum {typ; univs; poly; impl} in
- let () = declare_variable ~name ~kind decl in
- let () = assumption_message name in
+ let decl = Declare.SectionLocalAssum {typ; impl} in
+ let () = Declare.declare_variable ~name ~kind decl in
+ let () = Declare.assumption_message name in
let r = GlobRef.VarRef name in
let () = maybe_declare_manual_implicits true r imps in
let env = Global.env () in
let sigma = Evd.from_env env in
let () = Classes.declare_instance env sigma None true r in
let () = if is_coe then Class.try_add_new_coercion r ~local:true ~poly:false in
- (r,Univ.Instance.empty)
+ ()
-| Global local ->
+let instance_of_univ_entry = function
+ | Polymorphic_entry (_, univs) -> Univ.UContext.instance univs
+ | Monomorphic_entry _ -> Univ.Instance.empty
+
+let declare_axiom is_coe ~poly ~local ~kind typ (univs, pl) imps nl {CAst.v=name} =
let do_instance = should_axiom_into_instance kind in
let inl = let open Declaremods in match nl with
| NoInline -> None
@@ -70,42 +66,65 @@ match scope with
in
let kind = Decls.IsAssumption kind in
let decl = Declare.ParameterEntry (None,(typ,univs),inl) in
- let kn = declare_constant ~name ~local ~kind decl in
+ let kn = Declare.declare_constant ~name ~local ~kind decl in
let gr = GlobRef.ConstRef kn in
let () = maybe_declare_manual_implicits false gr imps in
let () = Declare.declare_univ_binders gr pl in
- let () = assumption_message name in
+ let () = Declare.assumption_message name in
let env = Global.env () in
let sigma = Evd.from_env env in
let () = if do_instance then Classes.declare_instance env sigma None false gr in
- let local = match local with ImportNeedQualified -> true | ImportDefaultBehavior -> false in
- let () = if is_coe then Class.try_add_new_coercion gr ~local ~poly in
- let inst = match univs with
- | Polymorphic_entry (_, univs) -> Univ.UContext.instance univs
- | Monomorphic_entry _ -> Univ.Instance.empty
+ let local = match local with
+ | Declare.ImportNeedQualified -> true
+ | Declare.ImportDefaultBehavior -> false
in
+ let () = if is_coe then Class.try_add_new_coercion gr ~local ~poly in
+ let inst = instance_of_univ_entry univs in
(gr,inst)
let interp_assumption ~program_mode sigma env impls c =
let sigma, (ty, impls) = interp_type_evars_impls ~program_mode env sigma ~impls c in
sigma, (ty, impls)
-(* When monomorphic the universe constraints are declared with the first declaration only. *)
-let next_uctx =
- let empty_uctx = Monomorphic_entry Univ.ContextSet.empty in
+(* When monomorphic the universe constraints and universe names are
+ declared with the first declaration only. *)
+let next_univs =
+ let empty_univs = Monomorphic_entry Univ.ContextSet.empty, UnivNames.empty_binders in
function
- | Polymorphic_entry _ as uctx -> uctx
- | Monomorphic_entry _ -> empty_uctx
+ | Polymorphic_entry _, _ as univs -> univs
+ | Monomorphic_entry _, _ -> empty_univs
-let declare_assumptions idl is_coe ~scope ~poly ~kind typ uctx pl imps nl =
- let refs, _ =
- List.fold_left (fun (refs,uctx) id ->
- let ref = declare_assumption is_coe ~scope ~poly ~kind typ uctx pl imps Glob_term.Explicit nl id in
- ref::refs, next_uctx uctx)
- ([],uctx) idl
- in
- List.rev refs
+let context_set_of_entry = function
+ | Polymorphic_entry (_,uctx) -> Univ.ContextSet.of_context uctx
+ | Monomorphic_entry uctx -> uctx
+let declare_assumptions ~poly ~scope ~kind univs nl l =
+ let open DeclareDef in
+ let () = match scope with
+ | Discharge ->
+ (* declare universes separately for variables *)
+ Declare.declare_universe_context ~poly (context_set_of_entry (fst univs))
+ | Global _ -> ()
+ in
+ let _, _ = List.fold_left (fun (subst,univs) ((is_coe,idl),typ,imps) ->
+ (* NB: here univs are ignored when scope=Discharge *)
+ let typ = replace_vars subst typ in
+ let univs,subst' =
+ List.fold_left_map (fun univs id ->
+ let refu = match scope with
+ | Discharge ->
+ declare_variable is_coe ~kind typ imps Glob_term.Explicit id;
+ GlobRef.VarRef id.CAst.v, Univ.Instance.empty
+ | Global local ->
+ declare_axiom is_coe ~local ~poly ~kind typ univs imps nl id
+ in
+ next_univs univs, (id.CAst.v, Constr.mkRef refu))
+ univs idl
+ in
+ subst'@subst, next_univs univs)
+ ([], univs) l
+ in
+ ()
let maybe_error_many_udecls = function
| ({CAst.loc;v=id}, Some _) ->
@@ -175,139 +194,114 @@ let do_assumptions ~program_mode ~poly ~scope ~kind nl l =
IMO, thus I think we should adapt `prepare_parameter` to handle
this case too. *)
let sigma = Evd.restrict_universe_context sigma uvars in
- let uctx = Evd.check_univ_decl ~poly sigma udecl in
+ let univs = Evd.check_univ_decl ~poly sigma udecl in
let ubinders = Evd.universe_binders sigma in
- let _, _ = List.fold_left (fun (subst,uctx) ((is_coe,idl),typ,imps) ->
- let typ = replace_vars subst typ in
- let refs = declare_assumptions idl is_coe ~poly ~scope ~kind typ uctx ubinders imps nl in
- let subst' = List.map2
- (fun {CAst.v=id} (c,u) -> (id, Constr.mkRef (c,u)))
- idl refs
- in
- subst'@subst, next_uctx uctx)
- ([], uctx) l
+ declare_assumptions ~poly ~scope ~kind (univs,ubinders) nl l
+
+let context_subst subst (name,b,t,impl) =
+ name, Option.map (Vars.substl subst) b, Vars.substl subst t, impl
+
+let context_insection sigma ~poly ctx =
+ let uctx = Evd.universe_context_set sigma in
+ let () = Declare.declare_universe_context ~poly uctx in
+ let fn subst (name,_,_,_ as d) =
+ let d = context_subst subst d in
+ let () = match d with
+ | name, None, t, impl ->
+ let kind = Decls.Context in
+ declare_variable false ~kind t [] impl (CAst.make name)
+ | name, Some b, t, impl ->
+ (* We need to get poly right for check_same_poly *)
+ let univs = if poly then Polymorphic_entry ([| |], Univ.UContext.empty)
+ else Monomorphic_entry Univ.ContextSet.empty
+ in
+ let entry = Declare.definition_entry ~univs ~types:t b in
+ let _ : GlobRef.t = DeclareDef.declare_definition ~name ~scope:DeclareDef.Discharge
+ ~kind:Decls.Definition UnivNames.empty_binders entry []
+ in
+ ()
+ in
+ Constr.mkVar name :: subst
in
+ let _ : Vars.substl = List.fold_left fn [] ctx in
()
-let do_primitive id prim typopt =
- if Lib.sections_are_opened () then
- CErrors.user_err Pp.(str "Declaring a primitive is not allowed in sections.");
- if Dumpglob.dump () then Dumpglob.dump_definition id false "ax";
- let env = Global.env () in
- let evd = Evd.from_env env in
- let evd, typopt = Option.fold_left_map
- (interp_type_evars_impls ~impls:empty_internalization_env env)
- evd typopt
- in
- let evd = Evd.minimize_universes evd in
- let uvars, impls, typopt = match typopt with
- | None -> Univ.LSet.empty, [], None
- | Some (ty,impls) ->
- EConstr.universes_of_constr evd ty, impls, Some (EConstr.to_constr evd ty)
+let context_nosection sigma ~poly ctx =
+ let univs =
+ match ctx, poly with
+ | [_], _ | _, true -> Evd.univ_entry ~poly sigma
+ | _, false ->
+ (* Multiple monomorphic axioms: declare universes separately to
+ avoid redeclaring them. *)
+ let uctx = Evd.universe_context_set sigma in
+ let () = Declare.declare_universe_context ~poly uctx in
+ Monomorphic_entry Univ.ContextSet.empty
in
- let evd = Evd.restrict_universe_context evd uvars in
- let uctx = UState.check_mono_univ_decl (Evd.evar_universe_context evd) UState.default_univ_decl in
- let entry = { prim_entry_type = typopt;
- prim_entry_univs = uctx;
- prim_entry_content = prim;
- }
+ let fn subst d =
+ let (name,b,t,_impl) = context_subst subst d in
+ let kind = Decls.(IsAssumption Logical) in
+ let decl = match b with
+ | None ->
+ Declare.ParameterEntry (None,(t,univs),None)
+ | Some b ->
+ let entry = Declare.definition_entry ~univs ~types:t b in
+ Declare.DefinitionEntry entry
+ in
+ let local = if Lib.is_modtype () then Declare.ImportDefaultBehavior
+ else Declare.ImportNeedQualified
+ in
+ let cst = Declare.declare_constant ~name ~kind ~local decl in
+ let () = Declare.assumption_message name in
+ let env = Global.env () in
+ (* why local when is_modtype? *)
+ let () = if Lib.is_modtype() || Option.is_empty b then
+ Classes.declare_instance env sigma None (Lib.is_modtype()) (GlobRef.ConstRef cst)
+ in
+ Constr.mkConstU (cst,instance_of_univ_entry univs) :: subst
in
- let _kn : Names.Constant.t =
- declare_constant ~name:id.CAst.v ~kind:Decls.IsPrimitive (PrimitiveEntry entry) in
- Flags.if_verbose Feedback.msg_info Pp.(Id.print id.CAst.v ++ str " is declared")
-
-let named_of_rel_context l =
- let open EConstr.Vars in
- let open RelDecl in
- let acc, ctx =
- List.fold_right
- (fun decl (subst, ctx) ->
- let id = match get_name decl with Anonymous -> invalid_arg "named_of_rel_context" | Name id -> id in
- let d = match decl with
- | LocalAssum (_,t) -> id, None, substl subst t
- | LocalDef (_,b,t) -> id, Some (substl subst b), substl subst t in
- (EConstr.mkVar id :: subst, d :: ctx))
- l ([], [])
- in ctx
+ let _ : Vars.substl = List.fold_left fn [] ctx in
+ ()
let context ~poly l =
let env = Global.env() in
let sigma = Evd.from_env env in
- let sigma, (_, ((env', fullctx), impls)) = interp_context_evars ~program_mode:false env sigma l in
+ let sigma, (_, ((_env, ctx), impls)) = interp_context_evars ~program_mode:false env sigma l in
(* Note, we must use the normalized evar from now on! *)
let sigma = Evd.minimize_universes sigma in
let ce t = Pretyping.check_evars env (Evd.from_env env) sigma t in
- let () = List.iter (fun decl -> Context.Rel.Declaration.iter_constr ce decl) fullctx in
- let ctx =
- try named_of_rel_context fullctx
- with e when CErrors.noncritical e ->
- user_err Pp.(str "Anonymous variables not allowed in contexts.")
- in
- let univs =
- match ctx with
- | [] -> assert false
- | [_] -> Evd.univ_entry ~poly sigma
- | _::_::_ ->
- if Lib.sections_are_opened ()
- then
- (* More than 1 variable in a section: we can't associate
- universes to any specific variable so we declare them
- separately. *)
- begin
- let uctx = Evd.universe_context_set sigma in
- Declare.declare_universe_context ~poly uctx;
- if poly then Polymorphic_entry ([||], Univ.UContext.empty)
- else Monomorphic_entry Univ.ContextSet.empty
- end
- else if poly then
- (* Multiple polymorphic axioms: they are all polymorphic the same way. *)
- Evd.univ_entry ~poly sigma
- else
- (* Multiple monomorphic axioms: declare universes separately
- to avoid redeclaring them. *)
- begin
- let uctx = Evd.universe_context_set sigma in
- Declare.declare_universe_context ~poly uctx;
- Monomorphic_entry Univ.ContextSet.empty
- end
- in
- let fn (name, b, t) =
- let b, t = Option.map (EConstr.to_constr sigma) b, EConstr.to_constr sigma t in
- if Lib.is_modtype () && not (Lib.sections_are_opened ()) then
- (* Declare the universe context once *)
- let kind = Decls.(IsAssumption Logical) in
- let decl = match b with
- | None ->
- Declare.ParameterEntry (None,(t,univs),None)
- | Some b ->
- let entry = Declare.definition_entry ~univs ~types:t b in
- Declare.DefinitionEntry entry
+ let () = List.iter (fun decl -> Context.Rel.Declaration.iter_constr ce decl) ctx in
+ (* reorder, evar-normalize and add implicit status *)
+ let ctx = List.rev_map (fun d ->
+ let {binder_name=name}, b, t = RelDecl.to_tuple d in
+ let name = match name with
+ | Anonymous -> user_err Pp.(str "Anonymous variables not allowed in contexts.")
+ | Name id -> id
in
- let cst = Declare.declare_constant ~name ~kind decl in
- let env = Global.env () in
- Classes.declare_instance env sigma (Some Hints.empty_hint_info) true (GlobRef.ConstRef cst);
- ()
- else
+ let b = Option.map (EConstr.to_constr sigma) b in
+ let t = EConstr.to_constr sigma t in
let test x = match x.CAst.v with
| Some (Name id',_) -> Id.equal name id'
| _ -> false
in
- let impl = if List.exists test impls then Glob_term.Implicit else Glob_term.Explicit in
- let scope =
- if Lib.sections_are_opened () then DeclareDef.Discharge else DeclareDef.Global ImportDefaultBehavior in
- match b with
- | None ->
- let _, _ =
- declare_assumption false ~scope ~poly ~kind:Decls.Context t
- univs UnivNames.empty_binders [] impl
- Declaremods.NoInline (CAst.make name)
- in
- ()
- | Some b ->
- let entry = Declare.definition_entry ~univs ~types:t b in
- let _gr = DeclareDef.declare_definition
- ~name ~scope:DeclareDef.Discharge
- ~kind:Decls.Definition UnivNames.empty_binders entry [] in
- ()
+ let impl = Glob_term.(if List.exists test impls then Implicit else Explicit) in
+ name,b,t,impl)
+ ctx
in
- List.iter fn (List.rev ctx)
+ if Lib.sections_are_opened ()
+ then context_insection sigma ~poly ctx
+ else context_nosection sigma ~poly ctx
+
+(* Deprecated *)
+let declare_assumption is_coe ~poly ~scope ~kind typ univs pl imps impl nl name =
+let open DeclareDef in
+match scope with
+| Discharge ->
+ let univs = match univs with
+ | Monomorphic_entry univs -> univs
+ | Polymorphic_entry (_, univs) -> Univ.ContextSet.of_context univs
+ in
+ let () = Declare.declare_universe_context ~poly univs in
+ declare_variable is_coe ~kind typ imps impl name;
+ GlobRef.VarRef name.CAst.v, Univ.Instance.empty
+| Global local ->
+ declare_axiom is_coe ~poly ~local ~kind typ (univs, pl) imps nl name
diff --git a/vernac/comAssumption.mli b/vernac/comAssumption.mli
index 2715bd8305..ae9edefcac 100644
--- a/vernac/comAssumption.mli
+++ b/vernac/comAssumption.mli
@@ -23,29 +23,46 @@ val do_assumptions
-> (ident_decl list * constr_expr) with_coercion list
-> unit
-(** returns [false] if the assumption is neither local to a section,
- nor in a module type and meant to be instantiated. *)
-val declare_assumption
+val declare_variable
: coercion_flag
- -> poly:bool
- -> scope:DeclareDef.locality
-> kind:Decls.assumption_object_kind
-> Constr.types
- -> Entries.universes_entry
- -> UnivNames.universe_binders
-> Impargs.manual_implicits
-> Glob_term.binding_kind
+ -> variable CAst.t
+ -> unit
+
+val declare_axiom
+ : coercion_flag
+ -> poly:bool
+ -> local:Declare.import_status
+ -> kind:Decls.assumption_object_kind
+ -> Constr.types
+ -> Entries.universes_entry * UnivNames.universe_binders
+ -> Impargs.manual_implicits
-> Declaremods.inline
-> variable CAst.t
-> GlobRef.t * Univ.Instance.t
(** Context command *)
-(** returns [false] if, for lack of section, it declares an assumption
- (unless in a module type). *)
val context
: poly:bool
-> local_binder_expr list
-> unit
-val do_primitive : lident -> CPrimitives.op_or_type -> constr_expr option -> unit
+(** Deprecated *)
+val declare_assumption
+ : coercion_flag
+ -> poly:bool
+ -> scope:DeclareDef.locality
+ -> kind:Decls.assumption_object_kind
+ -> Constr.types
+ -> Entries.universes_entry
+ -> UnivNames.universe_binders
+ -> Impargs.manual_implicits
+ -> Glob_term.binding_kind
+ -> Declaremods.inline
+ -> variable CAst.t
+ -> GlobRef.t * Univ.Instance.t
+[@@ocaml.deprecated "Use declare_variable or declare_axiom instead."]
diff --git a/vernac/comPrimitive.ml b/vernac/comPrimitive.ml
new file mode 100644
index 0000000000..06fafddafb
--- /dev/null
+++ b/vernac/comPrimitive.ml
@@ -0,0 +1,37 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2019 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+let do_primitive id prim typopt =
+ if Lib.sections_are_opened () then
+ CErrors.user_err Pp.(str "Declaring a primitive is not allowed in sections.");
+ if Dumpglob.dump () then Dumpglob.dump_definition id false "ax";
+ let env = Global.env () in
+ let evd = Evd.from_env env in
+ let evd, typopt = Option.fold_left_map
+ Constrintern.(interp_type_evars_impls ~impls:empty_internalization_env env)
+ evd typopt
+ in
+ let evd = Evd.minimize_universes evd in
+ let uvars, impls, typopt = match typopt with
+ | None -> Univ.LSet.empty, [], None
+ | Some (ty,impls) ->
+ EConstr.universes_of_constr evd ty, impls, Some (EConstr.to_constr evd ty)
+ in
+ let evd = Evd.restrict_universe_context evd uvars in
+ let uctx = UState.check_mono_univ_decl (Evd.evar_universe_context evd) UState.default_univ_decl in
+ let entry = Entries.{
+ prim_entry_type = typopt;
+ prim_entry_univs = uctx;
+ prim_entry_content = prim;
+ }
+ in
+ let _kn : Names.Constant.t =
+ Declare.declare_constant ~name:id.CAst.v ~kind:Decls.IsPrimitive (Declare.PrimitiveEntry entry) in
+ Flags.if_verbose Feedback.msg_info Pp.(Names.Id.print id.CAst.v ++ str " is declared")
diff --git a/vernac/comPrimitive.mli b/vernac/comPrimitive.mli
new file mode 100644
index 0000000000..c0db1cc464
--- /dev/null
+++ b/vernac/comPrimitive.mli
@@ -0,0 +1,11 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2019 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+val do_primitive : Names.lident -> CPrimitives.op_or_type -> Constrexpr.constr_expr option -> unit
diff --git a/vernac/comProgramFixpoint.ml b/vernac/comProgramFixpoint.ml
index 3497e6369f..0e17f2b274 100644
--- a/vernac/comProgramFixpoint.ml
+++ b/vernac/comProgramFixpoint.ml
@@ -44,41 +44,68 @@ let mkSubset sigma name typ prop =
let make_qref s = qualid_of_string s
let lt_ref = make_qref "Init.Peano.lt"
+type family = SPropF | PropF | TypeF
+let family_of_sort_family = let open Sorts in function
+ | InSProp -> SPropF
+ | InProp -> PropF
+ | InSet | InType -> TypeF
+
+let get_sigmatypes sigma ~sort ~predsort =
+ let open EConstr in
+ let which, sigsort = match predsort, sort with
+ | SPropF, _ | _, SPropF ->
+ user_err Pp.(str "SProp arguments not supported by Program Fixpoint yet.")
+ | PropF, PropF -> "ex", PropF
+ | PropF, TypeF -> "sig", TypeF
+ | TypeF, (PropF|TypeF) -> "sigT", TypeF
+ in
+ let sigma, ty = Evarutil.new_global sigma (lib_ref ("core."^which^".type")) in
+ let uinstance = snd (destRef sigma ty) in
+ let intro = mkRef (lib_ref ("core."^which^".intro"), uinstance) in
+ let p1 = mkRef (lib_ref ("core."^which^".proj1"), uinstance) in
+ let p2 = mkRef (lib_ref ("core."^which^".proj2"), uinstance) in
+ sigma, ty, intro, p1, p2, sigsort
+
let rec telescope sigma l =
let open EConstr in
let open Vars in
match l with
| [] -> assert false
- | [LocalAssum (n, t)] ->
+ | [LocalAssum (n, t), _] ->
sigma, t, [LocalDef (n, mkRel 1, t)], mkRel 1
- | LocalAssum (n, t) :: tl ->
- let sigma, ty, tys, (k, constr) =
+ | (LocalAssum (n, t), tsort) :: tl ->
+ let sigma, ty, _tysort, tys, (k, constr) =
List.fold_left
- (fun (sigma, ty, tys, (k, constr)) decl ->
+ (fun (sigma, ty, tysort, tys, (k, constr)) (decl,sort) ->
let t = RelDecl.get_type decl in
let pred = mkLambda (RelDecl.get_annot decl, t, ty) in
- let sigma, ty = Evarutil.new_global sigma (lib_ref "core.sigT.type") in
- let sigma, intro = Evarutil.new_global sigma (lib_ref "core.sigT.intro") in
+ let sigma, ty, intro, p1, p2, sigsort = get_sigmatypes sigma ~predsort:tysort ~sort in
let sigty = mkApp (ty, [|t; pred|]) in
let intro = mkApp (intro, [|lift k t; lift k pred; mkRel k; constr|]) in
- (sigma, sigty, pred :: tys, (succ k, intro)))
- (sigma, t, [], (2, mkRel 1)) tl
+ (sigma, sigty, sigsort, (pred, p1, p2) :: tys, (succ k, intro)))
+ (sigma, t, tsort, [], (2, mkRel 1)) tl
in
let sigma, last, subst = List.fold_right2
- (fun pred decl (sigma, prev, subst) ->
+ (fun (pred,p1,p2) (decl,_) (sigma, prev, subst) ->
let t = RelDecl.get_type decl in
- let sigma, p1 = Evarutil.new_global sigma (lib_ref "core.sigT.proj1") in
- let sigma, p2 = Evarutil.new_global sigma (lib_ref "core.sigT.proj2") in
let proj1 = applist (p1, [t; pred; prev]) in
let proj2 = applist (p2, [t; pred; prev]) in
(sigma, lift 1 proj2, LocalDef (get_annot decl, proj1, t) :: subst))
(List.rev tys) tl (sigma, mkRel 1, [])
in sigma, ty, (LocalDef (n, last, t) :: subst), constr
- | LocalDef (n, b, t) :: tl ->
+ | (LocalDef (n, b, t), _) :: tl ->
let sigma, ty, subst, term = telescope sigma tl in
sigma, ty, (LocalDef (n, b, t) :: subst), lift 1 term
+let telescope env sigma l =
+ let l, _ = List.fold_right_map (fun d env ->
+ let s = Retyping.get_sort_family_of env sigma (RelDecl.get_type d) in
+ let env = EConstr.push_rel d env in
+ (d, family_of_sort_family s), env) l env
+ in
+ telescope sigma l
+
let nf_evar_context sigma ctx =
List.map (map_constr (fun c -> Evarutil.nf_evar sigma c)) ctx
@@ -94,7 +121,7 @@ let build_wellfounded (recname,pl,bl,arityc,body) poly r measure notation =
let top_env = push_rel_context binders_rel env in
let sigma, top_arity = interp_type_evars ~program_mode:true top_env sigma arityc in
let full_arity = it_mkProd_or_LetIn top_arity binders_rel in
- let sigma, argtyp, letbinders, make = telescope sigma binders_rel in
+ let sigma, argtyp, letbinders, make = telescope env sigma binders_rel in
let argname = Id.of_string "recarg" in
let arg = LocalAssum (make_annot (Name argname) Sorts.Relevant, argtyp) in
let binders = letbinders @ [arg] in
diff --git a/library/declaremods.ml b/vernac/declaremods.ml
index b4dc42bdfe..58a7dff5fd 100644
--- a/library/declaremods.ml
+++ b/vernac/declaremods.ml
@@ -35,8 +35,6 @@ type inline =
| DefaultInline
| InlineAt of int
-type module_kind = Module | ModType | ModAny
-
let default_inline () = Some (Flags.get_inline_level ())
let inl2intopt = function
@@ -457,15 +455,15 @@ let rec compute_subst env mbids sign mp_l inl =
| _,[] -> mbids,empty_subst
| [],r -> user_err Pp.(str "Application of a functor with too few arguments.")
| mbid::mbids,mp::mp_l ->
- let farg_id, farg_b, fbody_b = Modops.destr_functor sign in
- let mb = Environ.lookup_module mp env in
- let mbid_left,subst = compute_subst env mbids fbody_b mp_l inl in
- let resolver =
+ let farg_id, farg_b, fbody_b = Modops.destr_functor sign in
+ let mb = Environ.lookup_module mp env in
+ let mbid_left,subst = compute_subst env mbids fbody_b mp_l inl in
+ let resolver =
if Modops.is_functor mb.mod_type then empty_delta_resolver
else
Modops.inline_delta_resolver env inl mp farg_id farg_b mb.mod_delta
- in
- mbid_left,join (map_mbid mbid mp resolver) subst
+ in
+ mbid_left,join (map_mbid mbid mp resolver) subst
(** Create the objects of a "with Module" structure. *)
@@ -547,11 +545,11 @@ let process_module_binding mbid me =
Objects in these parameters are also loaded.
Output is accumulated on top of [acc] (in reverse order). *)
-let intern_arg interp_modast (acc, cst) (idl,(typ,ann)) =
+let intern_arg (acc, cst) (idl,(typ,ann)) =
let inl = inl2intopt ann in
let lib_dir = Lib.library_dp() in
let env = Global.env() in
- let (mty, _, cst') = interp_modast env ModType typ in
+ let (mty, _, cst') = Modintern.interp_module_ast env Modintern.ModType typ in
let () = Global.push_context_set true cst' in
let env = Global.env () in
let sobjs = get_module_sobjs false env inl mty in
@@ -579,8 +577,8 @@ let intern_arg interp_modast (acc, cst) (idl,(typ,ann)) =
be more efficient and independent of [List.map] eval order.
*)
-let intern_args interp_modast params =
- List.fold_left (intern_arg interp_modast) ([], Univ.ContextSet.empty) params
+let intern_args params =
+ List.fold_left intern_arg ([], Univ.ContextSet.empty) params
(** {6 Auxiliary functions concerning subtyping checks} *)
@@ -588,10 +586,10 @@ let intern_args interp_modast params =
let check_sub mtb sub_mtb_l =
(* The constraints are checked and forgot immediately : *)
ignore (List.fold_right
- (fun sub_mtb env ->
- Environ.add_constraints
- (Subtyping.check_subtypes env mtb sub_mtb) env)
- sub_mtb_l (Global.env()))
+ (fun sub_mtb env ->
+ Environ.add_constraints
+ (Subtyping.check_subtypes env mtb sub_mtb) env)
+ sub_mtb_l (Global.env()))
(** This function checks if the type calculated for the module [mp] is
a subtype of all signatures in [sub_mtb_l]. Uses only the global
@@ -631,11 +629,11 @@ let mk_funct_type env args seb0 =
(** Prepare the module type list for check of subtypes *)
-let build_subtypes interp_modast env mp args mtys =
+let build_subtypes env mp args mtys =
let (cst, ans) = List.fold_left_map
(fun cst (m,ann) ->
let inl = inl2intopt ann in
- let mte, _, cst' = interp_modast env ModType m in
+ let mte, _, cst' = Modintern.interp_module_ast env Modintern.ModType m in
let env = Environ.push_context_set ~strict:true cst' env in
let cst = Univ.ContextSet.union cst cst' in
let mtb = Mod_typing.translate_modtype env mp inl ([],mte) in
@@ -673,22 +671,22 @@ let openmodtype_info =
module RawModOps = struct
-let start_module interp_modast export id args res fs =
+let start_module export id args res fs =
let mp = Global.start_module id in
- let arg_entries_r, cst = intern_args interp_modast args in
+ let arg_entries_r, cst = intern_args args in
let () = Global.push_context_set true cst in
let env = Global.env () in
let res_entry_o, subtyps, cst = match res with
| Enforce (res,ann) ->
let inl = inl2intopt ann in
- let (mte, _, cst) = interp_modast env ModType res in
+ let (mte, _, cst) = Modintern.interp_module_ast env Modintern.ModType res in
let env = Environ.push_context_set ~strict:true cst env in
(* We check immediately that mte is well-formed *)
let _, _, _, cst' = Mod_typing.translate_mse env None inl mte in
let cst = Univ.ContextSet.union cst cst' in
Some (mte, inl), [], cst
| Check resl ->
- let typs, cst = build_subtypes interp_modast env mp arg_entries_r resl in
+ let typs, cst = build_subtypes env mp arg_entries_r resl in
None, typs, cst
in
let () = Global.push_context_set true cst in
@@ -735,25 +733,25 @@ let end_module () =
mp
-let declare_module interp_modast id args res mexpr_o fs =
+let declare_module id args res mexpr_o fs =
(* We simulate the beginning of an interactive module,
then we adds the module parameters to the global env. *)
let mp = Global.start_module id in
- let arg_entries_r, cst = intern_args interp_modast args in
+ let arg_entries_r, cst = intern_args args in
let params = mk_params_entry arg_entries_r in
let env = Global.env () in
let env = Environ.push_context_set ~strict:true cst env in
let mty_entry_o, subs, inl_res, cst' = match res with
| Enforce (mty,ann) ->
let inl = inl2intopt ann in
- let (mte, _, cst) = interp_modast env ModType mty in
+ let (mte, _, cst) = Modintern.interp_module_ast env Modintern.ModType mty in
let env = Environ.push_context_set ~strict:true cst env in
(* We check immediately that mte is well-formed *)
let _, _, _, cst' = Mod_typing.translate_mse env None inl mte in
let cst = Univ.ContextSet.union cst cst' in
Some mte, [], inl, cst
| Check mtys ->
- let typs, cst = build_subtypes interp_modast env mp arg_entries_r mtys in
+ let typs, cst = build_subtypes env mp arg_entries_r mtys in
None, typs, default_inline (), cst
in
let env = Environ.push_context_set ~strict:true cst' env in
@@ -761,7 +759,7 @@ let declare_module interp_modast id args res mexpr_o fs =
let mexpr_entry_o, inl_expr, cst' = match mexpr_o with
| None -> None, default_inline (), Univ.ContextSet.empty
| Some (mexpr,ann) ->
- let (mte, _, cst) = interp_modast env Module mexpr in
+ let (mte, _, cst) = Modintern.interp_module_ast env Modintern.Module mexpr in
Some mte, inl2intopt ann, cst
in
let env = Environ.push_context_set ~strict:true cst' env in
@@ -803,12 +801,12 @@ end
module RawModTypeOps = struct
-let start_modtype interp_modast id args mtys fs =
+let start_modtype id args mtys fs =
let mp = Global.start_modtype id in
- let arg_entries_r, cst = intern_args interp_modast args in
+ let arg_entries_r, cst = intern_args args in
let () = Global.push_context_set true cst in
let env = Global.env () in
- let sub_mty_l, cst = build_subtypes interp_modast env mp arg_entries_r mtys in
+ let sub_mty_l, cst = build_subtypes env mp arg_entries_r mtys in
let () = Global.push_context_set true cst in
openmodtype_info := sub_mty_l;
let prefix = Lib.start_modtype id mp fs in
@@ -831,16 +829,16 @@ let end_modtype () =
mp
-let declare_modtype interp_modast id args mtys (mty,ann) fs =
+let declare_modtype id args mtys (mty,ann) fs =
let inl = inl2intopt ann in
(* We simulate the beginning of an interactive module,
then we adds the module parameters to the global env. *)
let mp = Global.start_modtype id in
- let arg_entries_r, cst = intern_args interp_modast args in
+ let arg_entries_r, cst = intern_args args in
let () = Global.push_context_set true cst in
let params = mk_params_entry arg_entries_r in
let env = Global.env () in
- let mte, _, cst = interp_modast env ModType mty in
+ let mte, _, cst = Modintern.interp_module_ast env Modintern.ModType mty in
let () = Global.push_context_set true cst in
let env = Global.env () in
(* We check immediately that mte is well-formed *)
@@ -848,7 +846,7 @@ let declare_modtype interp_modast id args mtys (mty,ann) fs =
let () = Global.push_context_set true cst in
let env = Global.env () in
let entry = params, mte in
- let sub_mty_l, cst = build_subtypes interp_modast env mp arg_entries_r mtys in
+ let sub_mty_l, cst = build_subtypes env mp arg_entries_r mtys in
let () = Global.push_context_set true cst in
let env = Global.env () in
let sobjs = get_functor_sobjs false env inl entry in
@@ -902,12 +900,12 @@ let type_of_incl env is_mod = function
decompose_functor mp_l (type_of_mod mp0 env is_mod)
|MEwith _ -> raise NoIncludeSelf
-let declare_one_include interp_modast (me_ast,annot) =
+let declare_one_include (me_ast,annot) =
let env = Global.env() in
- let me, kind, cst = interp_modast env ModAny me_ast in
+ let me, kind, cst = Modintern.interp_module_ast env Modintern.ModAny me_ast in
let () = Global.push_context_set true cst in
let env = Global.env () in
- let is_mod = (kind == Module) in
+ let is_mod = (kind == Modintern.Module) in
let cur_mp = Lib.current_mp () in
let inl = inl2intopt annot in
let mbids,aobjs = get_module_sobjs is_mod env inl me in
@@ -925,8 +923,7 @@ let declare_one_include interp_modast (me_ast,annot) =
let aobjs = subst_aobjs subst aobjs in
ignore (add_leaf (Lib.current_mod_id ()) (IncludeObject aobjs))
-let declare_include interp me_asts =
- List.iter (declare_one_include interp) me_asts
+let declare_include me_asts = List.iter declare_one_include me_asts
end
@@ -942,40 +939,40 @@ let protect_summaries f =
let () = Summary.unfreeze_summaries fs in
iraise reraise
-let start_module interp export id args res =
- protect_summaries (RawModOps.start_module interp export id args res)
+let start_module export id args res =
+ protect_summaries (RawModOps.start_module export id args res)
let end_module = RawModOps.end_module
-let declare_module interp id args mtys me_l =
+let declare_module id args mtys me_l =
let declare_me fs = match me_l with
- | [] -> RawModOps.declare_module interp id args mtys None fs
- | [me] -> RawModOps.declare_module interp id args mtys (Some me) fs
+ | [] -> RawModOps.declare_module id args mtys None fs
+ | [me] -> RawModOps.declare_module id args mtys (Some me) fs
| me_l ->
- ignore (RawModOps.start_module interp None id args mtys fs);
- RawIncludeOps.declare_include interp me_l;
- RawModOps.end_module ()
+ ignore (RawModOps.start_module None id args mtys fs);
+ RawIncludeOps.declare_include me_l;
+ RawModOps.end_module ()
in
protect_summaries declare_me
-let start_modtype interp id args mtys =
- protect_summaries (RawModTypeOps.start_modtype interp id args mtys)
+let start_modtype id args mtys =
+ protect_summaries (RawModTypeOps.start_modtype id args mtys)
let end_modtype = RawModTypeOps.end_modtype
-let declare_modtype interp id args mtys mty_l =
+let declare_modtype id args mtys mty_l =
let declare_mt fs = match mty_l with
| [] -> assert false
- | [mty] -> RawModTypeOps.declare_modtype interp id args mtys mty fs
+ | [mty] -> RawModTypeOps.declare_modtype id args mtys mty fs
| mty_l ->
- ignore (RawModTypeOps.start_modtype interp id args mtys fs);
- RawIncludeOps.declare_include interp mty_l;
- RawModTypeOps.end_modtype ()
+ ignore (RawModTypeOps.start_modtype id args mtys fs);
+ RawIncludeOps.declare_include mty_l;
+ RawModTypeOps.end_modtype ()
in
protect_summaries declare_mt
-let declare_include interp me_asts =
- protect_summaries (fun _ -> RawIncludeOps.declare_include interp me_asts)
+let declare_include me_asts =
+ protect_summaries (fun _ -> RawIncludeOps.declare_include me_asts)
(** {6 Libraries} *)
@@ -1055,12 +1052,7 @@ let iter_all_segments f =
(** {6 Some types used to shorten declaremods.mli} *)
-type 'modast module_interpretor =
- Environ.env -> module_kind -> 'modast ->
- Entries.module_struct_entry * module_kind * Univ.ContextSet.t
-
-type 'modast module_params =
- (lident list * ('modast * inline)) list
+type module_params = (lident list * (Constrexpr.module_ast * inline)) list
(** {6 Debug} *)
diff --git a/library/declaremods.mli b/vernac/declaremods.mli
index b7c7cd1dba..ae84704656 100644
--- a/library/declaremods.mli
+++ b/vernac/declaremods.mli
@@ -29,34 +29,24 @@ type inline =
(** Kinds of modules *)
-type module_kind = Module | ModType | ModAny
+type module_params = (lident list * (Constrexpr.module_ast * inline)) list
-type 'modast module_interpretor =
- Environ.env -> module_kind -> 'modast ->
- Entries.module_struct_entry * module_kind * Univ.ContextSet.t
-
-type 'modast module_params =
- (lident list * ('modast * inline)) list
-
-(** [declare_module interp_modast id fargs typ exprs]
- declares module [id], with structure constructed by [interp_modast]
- from functor arguments [fargs], with final type [typ].
- [exprs] is usually of length 1 (Module definition with a concrete
- body), but it could also be empty ("Declare Module", with non-empty [typ]),
- or multiple (body of the shape M <+ N <+ ...). *)
+(** [declare_module id fargs typ exprs] declares module [id], from
+ functor arguments [fargs], with final type [typ]. [exprs] is
+ usually of length 1 (Module definition with a concrete body), but
+ it could also be empty ("Declare Module", with non-empty [typ]), or
+ multiple (body of the shape M <+ N <+ ...). *)
val declare_module :
- 'modast module_interpretor ->
Id.t ->
- 'modast module_params ->
- ('modast * inline) module_signature ->
- ('modast * inline) list -> ModPath.t
+ module_params ->
+ (Constrexpr.module_ast * inline) module_signature ->
+ (Constrexpr.module_ast * inline) list -> ModPath.t
val start_module :
- 'modast module_interpretor ->
bool option -> Id.t ->
- 'modast module_params ->
- ('modast * inline) module_signature -> ModPath.t
+ module_params ->
+ (Constrexpr.module_ast * inline) module_signature -> ModPath.t
val end_module : unit -> ModPath.t
@@ -68,18 +58,16 @@ val end_module : unit -> ModPath.t
Similar to [declare_module], except that the types could be multiple *)
val declare_modtype :
- 'modast module_interpretor ->
Id.t ->
- 'modast module_params ->
- ('modast * inline) list ->
- ('modast * inline) list ->
+ module_params ->
+ (Constrexpr.module_ast * inline) list ->
+ (Constrexpr.module_ast * inline) list ->
ModPath.t
val start_modtype :
- 'modast module_interpretor ->
Id.t ->
- 'modast module_params ->
- ('modast * inline) list -> ModPath.t
+ module_params ->
+ (Constrexpr.module_ast * inline) list -> ModPath.t
val end_modtype : unit -> ModPath.t
@@ -117,8 +105,7 @@ val import_modules : export:bool -> ModPath.t list -> unit
(** Include *)
-val declare_include :
- 'modast module_interpretor -> ('modast * inline) list -> unit
+val declare_include : (Constrexpr.module_ast * inline) list -> unit
(** {6 ... } *)
(** [iter_all_segments] iterate over all segments, the modules'
diff --git a/vernac/g_vernac.mlg b/vernac/g_vernac.mlg
index 8a94a010a0..efcb2635be 100644
--- a/vernac/g_vernac.mlg
+++ b/vernac/g_vernac.mlg
@@ -62,7 +62,8 @@ let make_bullet s =
| _ -> assert false
let parse_compat_version = let open Flags in function
- | "8.10" -> Current
+ | "8.11" -> Current
+ | "8.10" -> V8_10
| "8.9" -> V8_9
| "8.8" -> V8_8
| ("8.7" | "8.6" | "8.5" | "8.4" | "8.3" | "8.2" | "8.1" | "8.0") as s ->
diff --git a/vernac/himsg.ml b/vernac/himsg.ml
index ea34b601e8..c335d3ad55 100644
--- a/vernac/himsg.ml
+++ b/vernac/himsg.ml
@@ -1079,9 +1079,7 @@ let explain_incorrect_with_in_module () =
let explain_incorrect_module_application () =
str "Illegal application to a module type."
-open Modintern
-
-let explain_module_internalization_error = function
+let explain_module_internalization_error = let open Modintern in function
| NotAModuleNorModtype s -> explain_not_module_nor_modtype s
| IncorrectWithInModule -> explain_incorrect_with_in_module ()
| IncorrectModuleApplication -> explain_incorrect_module_application ()
diff --git a/vernac/lemmas.ml b/vernac/lemmas.ml
index 42d1a1f3fc..e49277c51b 100644
--- a/vernac/lemmas.ml
+++ b/vernac/lemmas.ml
@@ -265,7 +265,8 @@ let save_remaining_recthms env sigma ~poly ~scope ~udecl uctx body opaq i { Rect
Univ.ContextSet.of_context univs
| Monomorphic_entry univs -> univs
in
- let c = Declare.SectionLocalAssum {typ=t_i; univs; poly; impl} in
+ let () = Declare.declare_universe_context ~poly univs in
+ let c = Declare.SectionLocalAssum {typ=t_i; impl} in
let () = Declare.declare_variable ~name ~kind c in
GlobRef.VarRef name, impargs
| Global local ->
@@ -359,7 +360,7 @@ let save_lemma_admitted ~(lemma : t) : unit =
let env = Global.env () in
let ids_typ = Environ.global_vars_set env typ in
let ids_def = Environ.global_vars_set env pproof in
- Some (Environ.keep_hyps env (Id.Set.union ids_typ ids_def))
+ Some (Environ.really_needed env (Id.Set.union ids_typ ids_def))
| _ -> None in
let universes = Proof_global.get_initial_euctx lemma.proof in
let ctx = UState.check_univ_decl ~poly universes udecl in
diff --git a/vernac/obligations.ml b/vernac/obligations.ml
index da14b6e979..c8cede1f84 100644
--- a/vernac/obligations.ml
+++ b/vernac/obligations.ml
@@ -397,8 +397,8 @@ let deps_remaining obls deps =
deps []
-let goal_kind = DeclareDef.(Global Declare.ImportNeedQualified, Decls.(IsDefinition Definition))
-let goal_proof_kind = DeclareDef.(Global Declare.ImportNeedQualified, Decls.(IsProof Lemma))
+let goal_kind = Decls.(IsDefinition Definition)
+let goal_proof_kind = Decls.(IsProof Lemma)
let kind_of_obligation o =
match o with
@@ -487,7 +487,8 @@ let rec solve_obligation prg num tac =
++ str (string_of_list ", " (fun x -> string_of_int (succ x)) remaining));
in
let obl = subst_deps_obl obls obl in
- let scope, kind = kind_of_obligation (snd obl.obl_status) in
+ let scope = DeclareDef.(Global Declare.ImportNeedQualified) in
+ let kind = kind_of_obligation (snd obl.obl_status) in
let evd = Evd.from_ctx prg.prg_ctx in
let evd = Evd.update_sigma_env evd (Global.env ()) in
let auto n oblset tac = auto_solve_obligations n ~oblset tac in
diff --git a/vernac/vernac.mllib b/vernac/vernac.mllib
index cd13f83e96..afc701edbc 100644
--- a/vernac/vernac.mllib
+++ b/vernac/vernac.mllib
@@ -1,6 +1,7 @@
Vernacexpr
Attributes
Pvernac
+Declaremods
G_vernac
G_proofs
Vernacprop
@@ -25,16 +26,16 @@ Indschemes
Obligations
ComDefinition
Classes
+ComPrimitive
ComAssumption
ComInductive
ComFixpoint
ComProgramFixpoint
Record
Assumptions
-Vernacstate
Mltop
Topfmt
Loadpath
Vernacentries
-
-Misctypes
+Vernacstate
+Vernacinterp
diff --git a/vernac/vernacentries.ml b/vernac/vernacentries.ml
index 43b58d6d4b..4734ce1fb9 100644
--- a/vernac/vernacentries.ml
+++ b/vernac/vernacentries.ml
@@ -35,12 +35,6 @@ module NamedDecl = Context.Named.Declaration
(** TODO: make this function independent of Ltac *)
let (f_interp_redexp, interp_redexp_hook) = Hook.make ()
-let debug = false
-
-(* XXX Should move to a common library *)
-let vernac_pperr_endline pp =
- if debug then Format.eprintf "@[%a@]@\n%!" Pp.pp_with (pp ()) else ()
-
(* Utility functions, at some point they should all disappear and
instead enviroment/state selection should be done at the Vernac DSL
level. *)
@@ -468,28 +462,6 @@ let vernac_notation ~atts =
let vernac_custom_entry ~module_local s =
Metasyntax.declare_custom_entry module_local s
-(* Default proof mode, to be set at the beginning of proofs for
- programs that cannot be statically classified. *)
-let default_proof_mode = ref (Pvernac.register_proof_mode "Noedit" Pvernac.Vernac_.noedit_mode)
-let get_default_proof_mode () = !default_proof_mode
-
-let get_default_proof_mode_opt () = Pvernac.proof_mode_to_string !default_proof_mode
-let set_default_proof_mode_opt name =
- default_proof_mode :=
- match Pvernac.lookup_proof_mode name with
- | Some pm -> pm
- | None -> CErrors.user_err Pp.(str (Format.sprintf "No proof mode named \"%s\"." name))
-
-let proof_mode_opt_name = ["Default";"Proof";"Mode"]
-let () =
- Goptions.declare_string_option Goptions.{
- optdepr = false;
- optname = "default proof mode" ;
- optkey = proof_mode_opt_name;
- optread = get_default_proof_mode_opt;
- optwrite = set_default_proof_mode_opt;
- }
-
(***********)
(* Gallina *)
@@ -872,10 +844,7 @@ let vernac_declare_module export {loc;v=id} binders_ast mty_ast =
if not (Option.is_empty export) then
user_err Pp.(str "Arguments of a functor declaration cannot be exported. Remove the \"Export\" and \"Import\" keywords from every functor argument.")
else (idl,ty)) binders_ast in
- let mp =
- Declaremods.declare_module Modintern.interp_module_ast
- id binders_ast (Declaremods.Enforce mty_ast) []
- in
+ let mp = Declaremods.declare_module id binders_ast (Declaremods.Enforce mty_ast) [] in
Dumpglob.dump_moddef ?loc mp "mod";
Flags.if_verbose Feedback.msg_info (str "Module " ++ Id.print id ++ str " is declared");
Option.iter (fun export -> vernac_import export [qualid_of_ident id]) export
@@ -892,10 +861,7 @@ let vernac_define_module export {loc;v=id} (binders_ast : module_binder list) mt
(fun (export,idl,ty) (args,argsexport) ->
(idl,ty)::args, (List.map (fun {v=i} -> export,i)idl)@argsexport) binders_ast
([],[]) in
- let mp =
- Declaremods.start_module Modintern.interp_module_ast
- export id binders_ast mty_ast_o
- in
+ let mp = Declaremods.start_module export id binders_ast mty_ast_o in
Dumpglob.dump_moddef ?loc mp "mod";
Flags.if_verbose Feedback.msg_info
(str "Interactive Module " ++ Id.print id ++ str " started");
@@ -911,7 +877,7 @@ let vernac_define_module export {loc;v=id} (binders_ast : module_binder list) mt
user_err Pp.(str "Arguments of a functor definition can be imported only if the definition is interactive. Remove the \"Export\" and \"Import\" keywords from every functor argument.")
else (idl,ty)) binders_ast in
let mp =
- Declaremods.declare_module Modintern.interp_module_ast
+ Declaremods.declare_module
id binders_ast mty_ast_o mexpr_ast_l
in
Dumpglob.dump_moddef ?loc mp "mod";
@@ -938,10 +904,7 @@ let vernac_declare_module_type {loc;v=id} binders_ast mty_sign mty_ast_l =
(idl,ty)::args, (List.map (fun {v=i} -> export,i)idl)@argsexport) binders_ast
([],[]) in
- let mp =
- Declaremods.start_modtype Modintern.interp_module_ast
- id binders_ast mty_sign
- in
+ let mp = Declaremods.start_modtype id binders_ast mty_sign in
Dumpglob.dump_moddef ?loc mp "modtype";
Flags.if_verbose Feedback.msg_info
(str "Interactive Module Type " ++ Id.print id ++ str " started");
@@ -957,10 +920,7 @@ let vernac_declare_module_type {loc;v=id} binders_ast mty_sign mty_ast_l =
if not (Option.is_empty export) then
user_err Pp.(str "Arguments of a functor definition can be imported only if the definition is interactive. Remove the \"Export\" and \"Import\" keywords from every functor argument.")
else (idl,ty)) binders_ast in
- let mp =
- Declaremods.declare_modtype Modintern.interp_module_ast
- id binders_ast mty_sign mty_ast_l
- in
+ let mp = Declaremods.declare_modtype id binders_ast mty_sign mty_ast_l in
Dumpglob.dump_moddef ?loc mp "modtype";
Flags.if_verbose Feedback.msg_info
(str "Module Type " ++ Id.print id ++ str " is defined")
@@ -970,8 +930,7 @@ let vernac_end_modtype {loc;v=id} =
Dumpglob.dump_modref ?loc mp "modtype";
Flags.if_verbose Feedback.msg_info (str "Module Type " ++ Id.print id ++ str " is defined")
-let vernac_include l =
- Declaremods.declare_include Modintern.interp_module_ast l
+let vernac_include l = Declaremods.declare_include l
(**********************)
(* Gallina extensions *)
@@ -980,7 +939,9 @@ let vernac_include l =
let vernac_begin_section ~poly ({v=id} as lid) =
Dumpglob.dump_definition lid true "sec";
- Lib.open_section ~poly id;
+ Lib.open_section id;
+ (* If there was no polymorphism attribute this just sets the option
+ to its current value ie noop. *)
set_bool_option_value_gen ~locality:OptLocal ["Universe"; "Polymorphism"] poly
let vernac_end_section {CAst.loc} =
@@ -1966,26 +1927,29 @@ let print_about_hyp_globs ~pstate ?loc ref_or_by_not udecl glopt =
print_about env sigma ref_or_by_not udecl
let vernac_print ~pstate ~atts =
+ let mod_ops = { Printmod.import_module = Declaremods.import_module
+ ; process_module_binding = Declaremods.process_module_binding
+ } in
let sigma, env = get_current_or_global_context ~pstate in
function
| PrintTypingFlags -> pr_typing_flags (Environ.typing_flags (Global.env ()))
| PrintTables -> print_tables ()
- | PrintFullContext-> print_full_context_typ Library.indirect_accessor env sigma
- | PrintSectionContext qid -> print_sec_context_typ Library.indirect_accessor env sigma qid
- | PrintInspect n -> inspect Library.indirect_accessor env sigma n
+ | PrintFullContext-> print_full_context_typ ~mod_ops Library.indirect_accessor env sigma
+ | PrintSectionContext qid -> print_sec_context_typ ~mod_ops Library.indirect_accessor env sigma qid
+ | PrintInspect n -> inspect ~mod_ops Library.indirect_accessor env sigma n
| PrintGrammar ent -> Metasyntax.pr_grammar ent
| PrintCustomGrammar ent -> Metasyntax.pr_custom_grammar ent
| PrintLoadPath dir -> (* For compatibility ? *) print_loadpath dir
| PrintModules -> print_modules ()
- | PrintModule qid -> print_module qid
- | PrintModuleType qid -> print_modtype qid
+ | PrintModule qid -> print_module ~mod_ops qid
+ | PrintModuleType qid -> print_modtype ~mod_ops qid
| PrintNamespace ns -> print_namespace ~pstate ns
| PrintMLLoadPath -> Mltop.print_ml_path ()
| PrintMLModules -> Mltop.print_ml_modules ()
| PrintDebugGC -> Mltop.print_gc ()
| PrintName (qid,udecl) ->
dump_global qid;
- print_name Library.indirect_accessor env sigma qid udecl
+ print_name ~mod_ops Library.indirect_accessor env sigma qid udecl
| PrintGraph -> Prettyp.print_graph ()
| PrintClasses -> Prettyp.print_classes()
| PrintTypeClasses -> Prettyp.print_typeclasses()
@@ -2245,115 +2209,9 @@ let vernac_check_guard ~pstate =
(str ("Condition violated: ") ++s)
in message
-(** A global default timeout, controlled by option "Set Default Timeout n".
- Use "Unset Default Timeout" to deactivate it (or set it to 0). *)
-
-let default_timeout = ref None
-
-(* Timeout *)
-let vernac_timeout ?timeout (f : 'a -> 'b) (x : 'a) : 'b =
- match !default_timeout, timeout with
- | _, Some n
- | Some n, None ->
- Control.timeout n f x Timeout
- | None, None ->
- f x
-
-(* Fail *)
-let test_mode = ref false
-
-(* Restoring the state is the caller's responsibility *)
-let with_fail f : (Pp.t, unit) result =
- try
- let _ = f () in
- Error ()
- with
- (* Fail Timeout is a common pattern so we need to support it. *)
- | e when CErrors.noncritical e || e = Timeout ->
- (* The error has to be printed in the failing state *)
- Ok CErrors.(iprint (push e))
-
-(* We restore the state always *)
-let with_fail ~st f =
- let res = with_fail f in
- Vernacstate.invalidate_cache ();
- Vernacstate.unfreeze_interp_state st;
- match res with
- | Error () ->
- user_err ~hdr:"Fail" (str "The command has not failed!")
- | Ok msg ->
- if not !Flags.quiet || !test_mode
- then Feedback.msg_notice (str "The command has indeed failed with message:" ++ fnl () ++ msg)
-
-let locate_if_not_already ?loc (e, info) =
- match Loc.get_loc info with
- | None -> (e, Option.cata (Loc.add_loc info) info loc)
- | Some l -> (e, info)
-
-let mk_time_header =
- (* Drop the time header to print the command, we should indeed use a
- different mechanism to `-time` commands than the current hack of
- adding a time control to the AST. *)
- let pr_time_header vernac =
- let vernac = match vernac with
- | { v = { control = ControlTime _ :: control; attrs; expr }; loc } ->
- CAst.make ?loc { control; attrs; expr }
- | _ -> vernac
- in
- Topfmt.pr_cmd_header vernac
- in
- fun vernac -> Lazy.from_fun (fun () -> pr_time_header vernac)
-
-let interp_control_flag ~time_header (f : control_flag) ~st
- (fn : st:Vernacstate.t -> Vernacstate.LemmaStack.t option) =
- match f with
- | ControlFail ->
- with_fail ~st (fun () -> fn ~st);
- st.Vernacstate.lemmas
- | ControlTimeout timeout ->
- vernac_timeout ~timeout (fun () -> fn ~st) ()
- | ControlTime batch ->
- let header = if batch then Lazy.force time_header else Pp.mt () in
- System.with_time ~batch ~header (fun () -> fn ~st) ()
- | ControlRedirect s ->
- Topfmt.with_output_to_file s (fun () -> fn ~st) ()
-
-(* EJGA: We may remove this, only used twice below *)
-let vernac_require_open_lemma ~stack f =
- match stack with
- | Some stack -> f stack
- | None -> user_err Pp.(str "Command not supported (No proof-editing in progress)")
-
-let interp_typed_vernac c ~stack =
- let open Vernacextend in
- match c with
- | VtDefault f -> f (); stack
- | VtNoProof f ->
- if Option.has_some stack then
- user_err Pp.(str "Command not supported (Open proofs remain)");
- let () = f () in
- stack
- | VtCloseProof f ->
- vernac_require_open_lemma ~stack (fun stack ->
- let lemma, stack = Vernacstate.LemmaStack.pop stack in
- f ~lemma;
- stack)
- | VtOpenProof f ->
- Some (Vernacstate.LemmaStack.push stack (f ()))
- | VtModifyProof f ->
- Option.map (Vernacstate.LemmaStack.map_top_pstate ~f:(fun pstate -> f ~pstate)) stack
- | VtReadProofOpt f ->
- let pstate = Option.map (Vernacstate.LemmaStack.with_top_pstate ~f:(fun x -> x)) stack in
- f ~pstate;
- stack
- | VtReadProof f ->
- vernac_require_open_lemma ~stack
- (Vernacstate.LemmaStack.with_top_pstate ~f:(fun pstate -> f ~pstate));
- stack
-
(* We interpret vernacular commands to a DSL that specifies their
allowed actions on proof states *)
-let rec translate_vernac ~atts v = let open Vernacextend in match v with
+let translate_vernac ~atts v = let open Vernacextend in match v with
| VernacAbortAll
| VernacRestart
| VernacUndo _
@@ -2363,6 +2221,9 @@ let rec translate_vernac ~atts v = let open Vernacextend in match v with
| VernacBack _
| VernacAbort _ ->
anomaly (str "type_vernac")
+ | VernacLoad _ ->
+ anomaly (str "Load is not supported recursively")
+
(* Syntax *)
| VernacSyntaxExtension (infix, sl) ->
VtDefault(fun () -> with_module_locality ~atts vernac_syntax_extension infix sl)
@@ -2615,7 +2476,7 @@ let rec translate_vernac ~atts v = let open Vernacextend in match v with
| VernacPrimitive (id, prim, typopt) ->
VtDefault(fun () ->
unsupported_attributes atts;
- ComAssumption.do_primitive id prim typopt)
+ ComPrimitive.do_primitive id prim typopt)
| VernacComments l ->
VtDefault(fun () ->
unsupported_attributes atts;
@@ -2664,141 +2525,6 @@ let rec translate_vernac ~atts v = let open Vernacextend in match v with
| VernacEndProof pe ->
VtCloseProof (vernac_end_proof pe)
- | VernacLoad (verbosely,fname) ->
- VtNoProof(fun () ->
- unsupported_attributes atts;
- vernac_load ~verbosely fname)
-
(* Extensions *)
| VernacExtend (opn,args) ->
Vernacextend.type_vernac ~atts opn args
-
-(* "locality" is the prefix "Local" attribute, while the "local" component
- * is the outdated/deprecated "Local" attribute of some vernacular commands
- * still parsed as the obsolete_locality grammar entry for retrocompatibility.
- * loc is the Loc.t of the vernacular command being interpreted. *)
-and interp_expr ~atts ~st c =
- let stack = st.Vernacstate.lemmas in
- vernac_pperr_endline (fun () -> str "interpreting: " ++ Ppvernac.pr_vernac_expr c);
- match c with
-
- (* The STM should handle that, but LOAD bypasses the STM... *)
- | VernacAbortAll -> CErrors.user_err (str "AbortAll cannot be used through the Load command")
- | VernacRestart -> CErrors.user_err (str "Restart cannot be used through the Load command")
- | VernacUndo _ -> CErrors.user_err (str "Undo cannot be used through the Load command")
- | VernacUndoTo _ -> CErrors.user_err (str "UndoTo cannot be used through the Load command")
-
- (* Resetting *)
- | VernacResetName _ -> anomaly (str "VernacResetName not handled by Stm.")
- | VernacResetInitial -> anomaly (str "VernacResetInitial not handled by Stm.")
- | VernacBack _ -> anomaly (str "VernacBack not handled by Stm.")
-
- (* This one is possible to handle here *)
- | VernacAbort id -> CErrors.user_err (str "Abort cannot be used through the Load command")
-
- | v ->
- let fv = translate_vernac ~atts v in
- interp_typed_vernac ~stack fv
-
-(* XXX: This won't properly set the proof mode, as of today, it is
- controlled by the STM. Thus, we would need access information from
- the classifier. The proper fix is to move it to the STM, however,
- the way the proof mode is set there makes the task non trivial
- without a considerable amount of refactoring.
-*)
-and vernac_load ~verbosely fname =
- let exception End_of_input in
-
- (* Note that no proof should be open here, so the state here is just token for now *)
- let st = Vernacstate.freeze_interp_state ~marshallable:false in
- let fname =
- Envars.expand_path_macros ~warn:(fun x -> Feedback.msg_warning (str x)) fname in
- let fname = CUnix.make_suffix fname ".v" in
- let input =
- let longfname = Loadpath.locate_file fname in
- let in_chan = open_utf8_file_in longfname in
- Pcoq.Parsable.make ~loc:(Loc.initial (Loc.InFile longfname)) (Stream.of_channel in_chan) in
- (* Parsing loop *)
- let v_mod = if verbosely then Flags.verbosely else Flags.silently in
- let parse_sentence proof_mode = Flags.with_option Flags.we_are_parsing
- (fun po ->
- match Pcoq.Entry.parse (Pvernac.main_entry proof_mode) po with
- | Some x -> x
- | None -> raise End_of_input) in
- let rec load_loop ~stack =
- try
- let proof_mode = Option.map (fun _ -> get_default_proof_mode ()) stack in
- let stack =
- v_mod (interp_control ~st:{ st with Vernacstate.lemmas = stack })
- (parse_sentence proof_mode input) in
- load_loop ~stack
- with
- End_of_input ->
- stack
- in
- let stack = load_loop ~stack:st.Vernacstate.lemmas in
- (* If Load left a proof open, we fail too. *)
- if Option.has_some stack then
- CErrors.user_err Pp.(str "Files processed by Load cannot leave open proofs.");
- ()
-
-and interp_control ~st ({ v = cmd } as vernac) =
- let time_header = mk_time_header vernac in
- List.fold_right (fun flag fn -> interp_control_flag ~time_header flag fn)
- cmd.control
- (fun ~st ->
- let before_univs = Global.universes () in
- let pstack = interp_expr ~atts:cmd.attrs ~st cmd.expr in
- if before_univs == Global.universes () then pstack
- else Option.map (Vernacstate.LemmaStack.map_top_pstate ~f:Proof_global.update_global_env) pstack)
- ~st
-
-(* Interpreting a possibly delayed proof *)
-let interp_qed_delayed ~proof ~info ~st pe : Vernacstate.LemmaStack.t option =
- let stack = st.Vernacstate.lemmas in
- let stack = Option.cata (fun stack -> snd @@ Vernacstate.LemmaStack.pop stack) None stack in
- let () = match pe with
- | Admitted ->
- save_lemma_admitted_delayed ~proof ~info
- | Proved (_,idopt) ->
- save_lemma_proved_delayed ~proof ~info ~idopt in
- stack
-
-let interp_qed_delayed_control ~proof ~info ~st ~control { loc; v=pe } =
- let time_header = mk_time_header (CAst.make ?loc { control; attrs = []; expr = VernacEndProof pe }) in
- List.fold_right (fun flag fn -> interp_control_flag ~time_header flag fn)
- control
- (fun ~st -> interp_qed_delayed ~proof ~info ~st pe)
- ~st
-
-(* General interp with management of state *)
-let () =
- declare_int_option
- { optdepr = false;
- optname = "the default timeout";
- optkey = ["Default";"Timeout"];
- optread = (fun () -> !default_timeout);
- optwrite = ((:=) default_timeout) }
-
-(* Be careful with the cache here in case of an exception. *)
-let interp_gen ~verbosely ~st ~interp_fn cmd =
- Vernacstate.unfreeze_interp_state st;
- try vernac_timeout (fun st ->
- let v_mod = if verbosely then Flags.verbosely else Flags.silently in
- let ontop = v_mod (interp_fn ~st) cmd in
- Vernacstate.Proof_global.set ontop [@ocaml.warning "-3"];
- Vernacstate.freeze_interp_state ~marshallable:false
- ) st
- with exn ->
- let exn = CErrors.push exn in
- let exn = locate_if_not_already ?loc:cmd.CAst.loc exn in
- Vernacstate.invalidate_cache ();
- iraise exn
-
-(* Regular interp *)
-let interp ?(verbosely=true) ~st cmd =
- interp_gen ~verbosely ~st ~interp_fn:interp_control cmd
-
-let interp_qed_delayed_proof ~proof ~info ~st ~control pe : Vernacstate.t =
- interp_gen ~verbosely:false ~st
- ~interp_fn:(interp_qed_delayed_control ~proof ~info ~control) pe
diff --git a/vernac/vernacentries.mli b/vernac/vernacentries.mli
index e65f9d3cfe..6368ebeed8 100644
--- a/vernac/vernacentries.mli
+++ b/vernac/vernacentries.mli
@@ -8,25 +8,11 @@
(* * (see LICENSE file for the text of the license) *)
(************************************************************************)
-(** The main interpretation function of vernacular expressions *)
-val interp : ?verbosely:bool -> st:Vernacstate.t -> Vernacexpr.vernac_control -> Vernacstate.t
-
-(** Execute a Qed but with a proof_object which may contain a delayed
- proof and won't be forced *)
-val interp_qed_delayed_proof
- : proof:Proof_global.proof_object
- -> info:Lemmas.Info.t
- -> st:Vernacstate.t
- -> control:Vernacexpr.control_flag list
- -> Vernacexpr.proof_end CAst.t
- -> Vernacstate.t
-
-(** [with_fail ~st f] runs [f ()] and expects it to fail, otherwise it fails. *)
-val with_fail : st:Vernacstate.t -> (unit -> 'a) -> unit
-
-(** Flag set when the test-suite is called. Its only effect to display
- verbose information for [Fail] *)
-val test_mode : bool ref
+(** Vernac Translation into the Vernac DSL *)
+val translate_vernac
+ : atts:Attributes.vernac_flags
+ -> Vernacexpr.vernac_expr
+ -> Vernacextend.typed_vernac
(** Vernacular require command *)
val vernac_require :
@@ -38,8 +24,3 @@ val interp_redexp_hook : (Environ.env -> Evd.evar_map -> Genredexpr.raw_red_expr
(** Miscellaneous stuff *)
val command_focus : unit Proof.focus_kind
-
-(** Default proof mode set by `start_proof` *)
-val get_default_proof_mode : unit -> Pvernac.proof_mode
-
-val proof_mode_opt_name : string list
diff --git a/vernac/vernacextend.ml b/vernac/vernacextend.ml
index 2725516a76..e29086d726 100644
--- a/vernac/vernacextend.ml
+++ b/vernac/vernacextend.ml
@@ -54,7 +54,6 @@ and proof_block_name = string (** open type of delimiters *)
type typed_vernac =
| VtDefault of (unit -> unit)
-
| VtNoProof of (unit -> unit)
| VtCloseProof of (lemma:Lemmas.t -> unit)
| VtOpenProof of (unit -> Lemmas.t)
diff --git a/vernac/vernacinterp.ml b/vernac/vernacinterp.ml
new file mode 100644
index 0000000000..c14fc78462
--- /dev/null
+++ b/vernac/vernacinterp.ml
@@ -0,0 +1,278 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2019 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+open Vernacexpr
+
+(* XXX Should move to a common library *)
+let debug = false
+let vernac_pperr_endline pp =
+ if debug then Format.eprintf "@[%a@]@\n%!" Pp.pp_with (pp ()) else ()
+
+(* EJGA: We may remove this, only used twice below *)
+let vernac_require_open_lemma ~stack f =
+ match stack with
+ | Some stack -> f stack
+ | None ->
+ CErrors.user_err (Pp.str "Command not supported (No proof-editing in progress)")
+
+let interp_typed_vernac c ~stack =
+ let open Vernacextend in
+ match c with
+ | VtDefault f -> f (); stack
+ | VtNoProof f ->
+ if Option.has_some stack then
+ CErrors.user_err (Pp.str "Command not supported (Open proofs remain)");
+ let () = f () in
+ stack
+ | VtCloseProof f ->
+ vernac_require_open_lemma ~stack (fun stack ->
+ let lemma, stack = Vernacstate.LemmaStack.pop stack in
+ f ~lemma;
+ stack)
+ | VtOpenProof f ->
+ Some (Vernacstate.LemmaStack.push stack (f ()))
+ | VtModifyProof f ->
+ Option.map (Vernacstate.LemmaStack.map_top_pstate ~f:(fun pstate -> f ~pstate)) stack
+ | VtReadProofOpt f ->
+ let pstate = Option.map (Vernacstate.LemmaStack.with_top_pstate ~f:(fun x -> x)) stack in
+ f ~pstate;
+ stack
+ | VtReadProof f ->
+ vernac_require_open_lemma ~stack
+ (Vernacstate.LemmaStack.with_top_pstate ~f:(fun pstate -> f ~pstate));
+ stack
+
+(* Default proof mode, to be set at the beginning of proofs for
+ programs that cannot be statically classified. *)
+let default_proof_mode = ref (Pvernac.register_proof_mode "Noedit" Pvernac.Vernac_.noedit_mode)
+let get_default_proof_mode () = !default_proof_mode
+
+let get_default_proof_mode_opt () = Pvernac.proof_mode_to_string !default_proof_mode
+let set_default_proof_mode_opt name =
+ default_proof_mode :=
+ match Pvernac.lookup_proof_mode name with
+ | Some pm -> pm
+ | None -> CErrors.user_err Pp.(str (Format.sprintf "No proof mode named \"%s\"." name))
+
+let proof_mode_opt_name = ["Default";"Proof";"Mode"]
+let () =
+ Goptions.declare_string_option Goptions.{
+ optdepr = false;
+ optname = "default proof mode" ;
+ optkey = proof_mode_opt_name;
+ optread = get_default_proof_mode_opt;
+ optwrite = set_default_proof_mode_opt;
+ }
+
+(** A global default timeout, controlled by option "Set Default Timeout n".
+ Use "Unset Default Timeout" to deactivate it (or set it to 0). *)
+
+let default_timeout = ref None
+
+(* Timeout *)
+let vernac_timeout ?timeout (f : 'a -> 'b) (x : 'a) : 'b =
+ match !default_timeout, timeout with
+ | _, Some n
+ | Some n, None ->
+ Control.timeout n f x CErrors.Timeout
+ | None, None ->
+ f x
+
+(* Fail *)
+let test_mode = ref false
+
+(* Restoring the state is the caller's responsibility *)
+let with_fail f : (Pp.t, unit) result =
+ try
+ let _ = f () in
+ Error ()
+ with
+ (* Fail Timeout is a common pattern so we need to support it. *)
+ | e when CErrors.noncritical e || e = CErrors.Timeout ->
+ (* The error has to be printed in the failing state *)
+ Ok CErrors.(iprint (push e))
+
+(* We restore the state always *)
+let with_fail ~st f =
+ let res = with_fail f in
+ Vernacstate.invalidate_cache ();
+ Vernacstate.unfreeze_interp_state st;
+ match res with
+ | Error () ->
+ CErrors.user_err ~hdr:"Fail" (Pp.str "The command has not failed!")
+ | Ok msg ->
+ if not !Flags.quiet || !test_mode
+ then Feedback.msg_notice Pp.(str "The command has indeed failed with message:" ++ fnl () ++ msg)
+
+let locate_if_not_already ?loc (e, info) =
+ match Loc.get_loc info with
+ | None -> (e, Option.cata (Loc.add_loc info) info loc)
+ | Some l -> (e, info)
+
+let mk_time_header =
+ (* Drop the time header to print the command, we should indeed use a
+ different mechanism to `-time` commands than the current hack of
+ adding a time control to the AST. *)
+ let pr_time_header vernac =
+ let vernac = match vernac with
+ | { CAst.v = { control = ControlTime _ :: control; attrs; expr }; loc } ->
+ CAst.make ?loc { control; attrs; expr }
+ | _ -> vernac
+ in
+ Topfmt.pr_cmd_header vernac
+ in
+ fun vernac -> Lazy.from_fun (fun () -> pr_time_header vernac)
+
+let interp_control_flag ~time_header (f : control_flag) ~st
+ (fn : st:Vernacstate.t -> Vernacstate.LemmaStack.t option) =
+ match f with
+ | ControlFail ->
+ with_fail ~st (fun () -> fn ~st);
+ st.Vernacstate.lemmas
+ | ControlTimeout timeout ->
+ vernac_timeout ~timeout (fun () -> fn ~st) ()
+ | ControlTime batch ->
+ let header = if batch then Lazy.force time_header else Pp.mt () in
+ System.with_time ~batch ~header (fun () -> fn ~st) ()
+ | ControlRedirect s ->
+ Topfmt.with_output_to_file s (fun () -> fn ~st) ()
+
+(* "locality" is the prefix "Local" attribute, while the "local" component
+ * is the outdated/deprecated "Local" attribute of some vernacular commands
+ * still parsed as the obsolete_locality grammar entry for retrocompatibility.
+ * loc is the Loc.t of the vernacular command being interpreted. *)
+let rec interp_expr ~atts ~st c =
+ let stack = st.Vernacstate.lemmas in
+ vernac_pperr_endline Pp.(fun () -> str "interpreting: " ++ Ppvernac.pr_vernac_expr c);
+ match c with
+
+ (* The STM should handle that, but LOAD bypasses the STM... *)
+ | VernacAbortAll -> CErrors.user_err (Pp.str "AbortAll cannot be used through the Load command")
+ | VernacRestart -> CErrors.user_err (Pp.str "Restart cannot be used through the Load command")
+ | VernacUndo _ -> CErrors.user_err (Pp.str "Undo cannot be used through the Load command")
+ | VernacUndoTo _ -> CErrors.user_err (Pp.str "UndoTo cannot be used through the Load command")
+
+ (* Resetting *)
+ | VernacResetName _ -> CErrors.anomaly (Pp.str "VernacResetName not handled by Stm.")
+ | VernacResetInitial -> CErrors.anomaly (Pp.str "VernacResetInitial not handled by Stm.")
+ | VernacBack _ -> CErrors.anomaly (Pp.str "VernacBack not handled by Stm.")
+
+ (* This one is possible to handle here *)
+ | VernacAbort id -> CErrors.user_err (Pp.str "Abort cannot be used through the Load command")
+ | VernacLoad (verbosely, fname) ->
+ Attributes.unsupported_attributes atts;
+ vernac_load ~verbosely fname
+ | v ->
+ let fv = Vernacentries.translate_vernac ~atts v in
+ interp_typed_vernac ~stack fv
+
+and vernac_load ~verbosely fname =
+ let exception End_of_input in
+
+ (* Note that no proof should be open here, so the state here is just token for now *)
+ let st = Vernacstate.freeze_interp_state ~marshallable:false in
+ let fname =
+ Envars.expand_path_macros ~warn:(fun x -> Feedback.msg_warning (Pp.str x)) fname in
+ let fname = CUnix.make_suffix fname ".v" in
+ let input =
+ let longfname = Loadpath.locate_file fname in
+ let in_chan = Util.open_utf8_file_in longfname in
+ Pcoq.Parsable.make ~loc:(Loc.initial (Loc.InFile longfname)) (Stream.of_channel in_chan) in
+ (* Parsing loop *)
+ let v_mod = if verbosely then Flags.verbosely else Flags.silently in
+ let parse_sentence proof_mode = Flags.with_option Flags.we_are_parsing
+ (fun po ->
+ match Pcoq.Entry.parse (Pvernac.main_entry proof_mode) po with
+ | Some x -> x
+ | None -> raise End_of_input) in
+ let rec load_loop ~stack =
+ try
+ let proof_mode = Option.map (fun _ -> get_default_proof_mode ()) stack in
+ let stack =
+ v_mod (interp_control ~st:{ st with Vernacstate.lemmas = stack })
+ (parse_sentence proof_mode input) in
+ load_loop ~stack
+ with
+ End_of_input ->
+ stack
+ in
+ let stack = load_loop ~stack:st.Vernacstate.lemmas in
+ (* If Load left a proof open, we fail too. *)
+ if Option.has_some stack then
+ CErrors.user_err Pp.(str "Files processed by Load cannot leave open proofs.");
+ stack
+
+and interp_control ~st ({ CAst.v = cmd } as vernac) =
+ let time_header = mk_time_header vernac in
+ List.fold_right (fun flag fn -> interp_control_flag ~time_header flag fn)
+ cmd.control
+ (fun ~st ->
+ let before_univs = Global.universes () in
+ let pstack = interp_expr ~atts:cmd.attrs ~st cmd.expr in
+ if before_univs == Global.universes () then pstack
+ else Option.map (Vernacstate.LemmaStack.map_top_pstate ~f:Proof_global.update_global_env) pstack)
+ ~st
+
+(* XXX: This won't properly set the proof mode, as of today, it is
+ controlled by the STM. Thus, we would need access information from
+ the classifier. The proper fix is to move it to the STM, however,
+ the way the proof mode is set there makes the task non trivial
+ without a considerable amount of refactoring.
+*)
+
+(* Interpreting a possibly delayed proof *)
+let interp_qed_delayed ~proof ~info ~st pe : Vernacstate.LemmaStack.t option =
+ let stack = st.Vernacstate.lemmas in
+ let stack = Option.cata (fun stack -> snd @@ Vernacstate.LemmaStack.pop stack) None stack in
+ let () = match pe with
+ | Admitted ->
+ Lemmas.save_lemma_admitted_delayed ~proof ~info
+ | Proved (_,idopt) ->
+ Lemmas.save_lemma_proved_delayed ~proof ~info ~idopt in
+ stack
+
+let interp_qed_delayed_control ~proof ~info ~st ~control { CAst.loc; v=pe } =
+ let time_header = mk_time_header (CAst.make ?loc { control; attrs = []; expr = VernacEndProof pe }) in
+ List.fold_right (fun flag fn -> interp_control_flag ~time_header flag fn)
+ control
+ (fun ~st -> interp_qed_delayed ~proof ~info ~st pe)
+ ~st
+
+(* General interp with management of state *)
+let () = let open Goptions in
+ declare_int_option
+ { optdepr = false;
+ optname = "the default timeout";
+ optkey = ["Default";"Timeout"];
+ optread = (fun () -> !default_timeout);
+ optwrite = ((:=) default_timeout) }
+
+(* Be careful with the cache here in case of an exception. *)
+let interp_gen ~verbosely ~st ~interp_fn cmd =
+ Vernacstate.unfreeze_interp_state st;
+ try vernac_timeout (fun st ->
+ let v_mod = if verbosely then Flags.verbosely else Flags.silently in
+ let ontop = v_mod (interp_fn ~st) cmd in
+ Vernacstate.Proof_global.set ontop [@ocaml.warning "-3"];
+ Vernacstate.freeze_interp_state ~marshallable:false
+ ) st
+ with exn ->
+ let exn = CErrors.push exn in
+ let exn = locate_if_not_already ?loc:cmd.CAst.loc exn in
+ Vernacstate.invalidate_cache ();
+ Util.iraise exn
+
+(* Regular interp *)
+let interp ?(verbosely=true) ~st cmd =
+ interp_gen ~verbosely ~st ~interp_fn:interp_control cmd
+
+let interp_qed_delayed_proof ~proof ~info ~st ~control pe : Vernacstate.t =
+ interp_gen ~verbosely:false ~st
+ ~interp_fn:(interp_qed_delayed_control ~proof ~info ~control) pe
diff --git a/vernac/vernacinterp.mli b/vernac/vernacinterp.mli
new file mode 100644
index 0000000000..16849686da
--- /dev/null
+++ b/vernac/vernacinterp.mli
@@ -0,0 +1,33 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2019 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+(** The main interpretation function of vernacular expressions *)
+val interp : ?verbosely:bool -> st:Vernacstate.t -> Vernacexpr.vernac_control -> Vernacstate.t
+
+(** Execute a Qed but with a proof_object which may contain a delayed
+ proof and won't be forced *)
+val interp_qed_delayed_proof
+ : proof:Proof_global.proof_object
+ -> info:Lemmas.Info.t
+ -> st:Vernacstate.t
+ -> control:Vernacexpr.control_flag list
+ -> Vernacexpr.proof_end CAst.t
+ -> Vernacstate.t
+
+(** [with_fail ~st f] runs [f ()] and expects it to fail, otherwise it fails. *)
+val with_fail : st:Vernacstate.t -> (unit -> 'a) -> unit
+
+(** Flag set when the test-suite is called. Its only effect to display
+ verbose information for [Fail] *)
+val test_mode : bool ref
+
+(** Default proof mode set by `start_proof` *)
+val get_default_proof_mode : unit -> Pvernac.proof_mode
+val proof_mode_opt_name : string list