aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/ci.yml15
-rw-r--r--.gitlab-ci.yml2
-rw-r--r--Makefile.build16
-rw-r--r--Makefile.checker3
-rw-r--r--Makefile.ide77
-rw-r--r--Makefile.make2
-rw-r--r--configure.ml34
-rwxr-xr-xdev/build/osx/make-macos-dmg.sh37
-rw-r--r--dev/ci/docker/bionic_coq/Dockerfile4
-rw-r--r--dev/ci/user-overlays/14111-gares-update-elpi.sh2
-rw-r--r--doc/changelog/04-tactics/14089-ltac2_unify.rst5
-rw-r--r--doc/changelog/05-tactic-language/13939-ltac2-open-constr-scope.rst5
-rw-r--r--doc/sphinx/_static/notations.css5
-rw-r--r--doc/sphinx/addendum/micromega.rst5
-rw-r--r--doc/sphinx/language/core/conversion.rst102
-rw-r--r--doc/sphinx/proof-engine/ltac2.rst5
-rw-r--r--doc/sphinx/proof-engine/ssreflect-proof-language.rst13
-rw-r--r--doc/sphinx/proof-engine/tactics.rst7
-rw-r--r--doc/sphinx/refman-preamble.rst2
-rw-r--r--doc/tools/coqrst/coqdoc/main.py17
-rw-r--r--doc/tools/coqrst/coqdomain.py29
-rw-r--r--ide/coqide/MacOS/Info.plist.template89
-rw-r--r--ide/coqide/configwin_ihm.ml7
-rw-r--r--ide/coqide/preferences.ml15
-rw-r--r--plugins/micromega/zify.ml25
-rw-r--r--tactics/hipattern.ml53
-rw-r--r--test-suite/bugs/closed/bug_12806.v9
-rw-r--r--test-suite/ltac2/std_tactics.v29
-rw-r--r--test-suite/micromega/bug_11089.v13
-rw-r--r--test-suite/micromega/zify.v7
-rw-r--r--theories/micromega/ZifyClasses.v9
-rw-r--r--user-contrib/Ltac2/Notations.v2
-rw-r--r--user-contrib/Ltac2/Std.v2
-rw-r--r--user-contrib/Ltac2/tac2core.ml11
-rw-r--r--user-contrib/Ltac2/tac2quote.ml18
-rw-r--r--user-contrib/Ltac2/tac2quote.mli2
-rw-r--r--user-contrib/Ltac2/tac2stdlib.ml4
-rw-r--r--user-contrib/Ltac2/tac2tactics.ml2
-rw-r--r--user-contrib/Ltac2/tac2tactics.mli2
-rw-r--r--vernac/record.ml4
40 files changed, 341 insertions, 349 deletions
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 7ec3ba1bd7..744fe1c743 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -74,18 +74,3 @@ jobs:
make -j "$NJOBS" test-suite PRINT_LOGS=1
env:
NJOBS: "2"
-
- - name: Create the dmg bundle
- run: |
- eval $(opam env)
- export PKG_CONFIG_PATH=/usr/local/opt/libffi/lib/pkgconfig
- export OUTDIR="$(pwd)/_install_ci"
- ./dev/build/osx/make-macos-dmg.sh
- env:
- MACOSX_DEPLOYMENT_TARGET: "10.11"
- NJOBS: "2"
-
- - uses: actions/upload-artifact@v2
- with:
- name: coq-macOS-installer
- path: _build/*.dmg
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index ce6be777f3..52b03e455b 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -20,7 +20,7 @@ variables:
# Format: $IMAGE-V$DATE-$hash
# The $hash is the first 10 characters of the md5 of the Dockerfile. e.g.
# echo $(md5sum dev/ci/docker/bionic_coq/Dockerfile | head -c 10)
- CACHEKEY: "bionic_coq-V2021-02-11-b601de5a7b"
+ CACHEKEY: "bionic_coq-V2021-04-14-802aebab96"
IMAGE: "$CI_REGISTRY_IMAGE:$CACHEKEY"
# By default, jobs run in the base switch; override to select another switch
OPAM_SWITCH: "base"
diff --git a/Makefile.build b/Makefile.build
index cbd4f4efbe..2b626506a3 100644
--- a/Makefile.build
+++ b/Makefile.build
@@ -256,17 +256,6 @@ BYTEFLAGS=$(CAMLDEBUG) $(USERFLAGS)
OPTFLAGS=$(CAMLDEBUGOPT) $(CAMLTIMEPROF) $(USERFLAGS) $(FLAMBDA_FLAGS)
DEPFLAGS=$(LOCALINCLUDES) -map gramlib/.pack/gramlib.ml $(if $(filter plugins/% user-contrib/%,$@),, -I ide/coqide -I ide/coqide/protocol)
-# On MacOS, the binaries are signed, except our private ones
-ifeq ($(shell which codesign > /dev/null 2>&1 && echo $(ARCH)),Darwin)
-LINKMETADATA=$(if $(filter $(PRIVATEBINARIES),$@),,-ccopt "-sectcreate __TEXT __info_plist config/Info-$(notdir $@).plist")
-CODESIGN=$(if $(filter $(PRIVATEBINARIES),$@),true,codesign -s -)
-CODESIGN_HIDE=$(CODESIGN)
-else
-LINKMETADATA=
-CODESIGN=true
-CODESIGN_HIDE=$(HIDE)true
-endif
-
ifeq ($(STRIP),true)
STRIP_HIDE=$(HIDE)true
else
@@ -293,7 +282,7 @@ endef
define bestocaml
$(if $(OPT),\
-$(OCAMLOPT) $(MLINCLUDES) $(OPTFLAGS) $(LINKMETADATA) -o $@ -linkpkg $(1) $^ && $(STRIP) $@ && $(CODESIGN) $@,\
+$(OCAMLOPT) $(MLINCLUDES) $(OPTFLAGS) -o $@ -linkpkg $(1) $^ && $(STRIP) $@,\
$(OCAMLC) $(MLINCLUDES) $(BYTEFLAGS) $(CUSTOM) -o $@ -linkpkg $(1) $^)
endef
@@ -431,9 +420,8 @@ bin/%.opt$(EXE): topbin/%_bin.ml $(LINKCMX) $(LIBCOQRUN)
$(SHOW)'COQMKTOP -o $@'
$(HIDE)$(OCAMLOPT) -linkall -linkpkg $(MLINCLUDES) \
$(SYSMOD) \
- $(LINKCMX) $(OPTFLAGS) $(LINKMETADATA) $< -o $@
+ $(LINKCMX) $(OPTFLAGS) $< -o $@
$(STRIP_HIDE) $@
- $(CODESIGN_HIDE) $@
bin/%.byte$(EXE): topbin/%_bin.ml $(LINKCMO) $(LIBCOQRUN)
$(SHOW)'COQMKTOP -o $@'
diff --git a/Makefile.checker b/Makefile.checker
index ad296e0e88..320b03fea7 100644
--- a/Makefile.checker
+++ b/Makefile.checker
@@ -38,9 +38,8 @@ ifeq ($(BEST),opt)
$(CHICKEN): config/config.cmxa clib/clib.cmxa lib/lib.cmxa kernel/kernel.cmxa \
checker/check.cmxa $(LIBCOQRUN) checker/coqchk.mli checker/coqchk.ml
$(SHOW)'OCAMLOPT -o $@'
- $(HIDE)$(OCAMLOPT) -linkpkg $(SYSMOD) $(CHKLIBS) $(OPTFLAGS) $(LINKMETADATA) -o $@ $^
+ $(HIDE)$(OCAMLOPT) -linkpkg $(SYSMOD) $(CHKLIBS) $(OPTFLAGS) -o $@ $^
$(STRIP_HIDE) $@
- $(CODESIGN_HIDE) $@
else
$(CHICKEN): $(CHICKENBYTE)
rm -f $@ && cp $< $@
diff --git a/Makefile.ide b/Makefile.ide
index 6e3713c7bf..e721e90628 100644
--- a/Makefile.ide
+++ b/Makefile.ide
@@ -28,8 +28,6 @@
COQIDEBYTE:=bin/coqide.byte$(EXE)
COQIDE:=bin/coqide$(EXE)
-COQIDEAPP:=bin/CoqIDE_$(VERSION).app
-COQIDEINAPP:=$(COQIDEAPP)/Contents/MacOS/coqide
## CoqIDE source directory and files
@@ -154,9 +152,8 @@ $(IDETOP): ide/coqide/idetop.ml $(LINKCMX) $(LIBCOQRUN) $(IDETOPCMX)
$(SHOW)'COQMKTOP -o $@'
$(HIDE)$(OCAMLOPT) -linkall -linkpkg $(MLINCLUDES) -I ide/coqide -I ide/coqide/protocol/ \
$(SYSMOD) \
- $(LINKCMX) $(IDETOPCMX) $(OPTFLAGS) $(LINKMETADATA) $< -o $@
+ $(LINKCMX) $(IDETOPCMX) $(OPTFLAGS) $< -o $@
$(STRIP_HIDE) $@
- $(CODESIGN_HIDE) $@
$(IDETOPBYTE): ide/coqide/idetop.ml $(LINKCMO) $(LIBCOQRUN) $(IDETOPCMA)
$(SHOW)'COQMKTOP -o $@'
@@ -217,7 +214,7 @@ ifeq ($(BEST),opt)
$(INSTALLSH) $(FULLCOQLIB) $(IDECMA:.cma=.cmxa) $(IDECMA:.cma=.a)
endif
-install-ide-files: #Please update $(COQIDEAPP)/Contents/Resources/ at the same time
+install-ide-files:
$(MKDIR) $(FULLDATADIR)
$(INSTALLLIB) ide/coqide/coq.png ide/coqide/*.lang ide/coqide/coq_style.xml $(IDEBINDINGS) $(FULLDATADIR)
$(MKDIR) $(FULLCONFIGDIR)
@@ -227,76 +224,6 @@ install-ide-info:
$(INSTALLLIB) ide/coqide/FAQ $(FULLDOCDIR)/FAQ-CoqIde
###########################################################################
-# CoqIde MacOS special targets
-###########################################################################
-
-.PHONY: $(COQIDEAPP)/Contents
-
-$(COQIDEAPP)/Contents:
- $(MKDIR) $@
- sed -e "s/VERSION/$(VERSION4MACOS)/g" ide/coqide/MacOS/Info.plist.template > $@/Info.plist
- $(MKDIR) "$@/MacOS"
-
-$(COQIDEINAPP): ide/coqide/macos_prehook.cmx $(LINKIDEOPT) | $(COQIDEAPP)/Contents
- $(SHOW)'OCAMLOPT -o $@'
- $(HIDE)$(OCAMLOPT) $(COQIDEFLAGS) $(OPTFLAGS) -o $@ \
- -linkpkg -package str,unix,threads,lablgtk3-sourceview3 $(IDEFLAGS:.cma=.cmxa) $^
- $(STRIP_HIDE) $@
-
-$(COQIDEAPP)/Contents/Resources/share: $(COQIDEAPP)/Contents
- $(MKDIR) $@/coq/
- $(INSTALLLIB) ide/coqide/coq.png ide/coqide/*.lang ide/coqide/coq_style.xml $(IDEBINDINGS) $@/coq/
- $(MKDIR) $@/gtksourceview-3.0/{language-specs,styles}
- $(INSTALLLIB) "$(SOURCEVIEWSHARE)/"gtksourceview-3.0/language-specs/{def.lang,language2.rng} $@/gtksourceview-3.0/language-specs/
- $(INSTALLLIB) "$(SOURCEVIEWSHARE)/"gtksourceview-3.0/styles/{styles.rng,classic.xml} $@/gtksourceview-3.0/styles/
- cp -R "$(GTKSHARE)/"locale $@
- cp -R "$(GTKSHARE)/"themes $@
- $(MKDIR) $@/glib-2.0/schemas
- glib-compile-schemas --targetdir=$@/glib-2.0/schemas "$(GTKSHARE)/"glib-2.0/schemas/
- cp -R "$(ADWAITASHARE)/"icons $@
-
-$(COQIDEAPP)/Contents/Resources/loaders: $(COQIDEAPP)/Contents
- $(MKDIR) $@
- $(INSTALLLIB) $$("$(PIXBUFBIN)/gdk-pixbuf-query-loaders" | sed -n -e '5 s!.*= \(.*\)$$!\1!p')/libpixbufloader-png.so $@
-
-$(COQIDEAPP)/Contents/Resources/immodules: $(COQIDEAPP)/Contents
- $(MKDIR) $@
- $(INSTALLLIB) "$(GTKLIBS)/gtk-3.0/3.0.0/immodules/"*.dylib $@ || $(INSTALLLIB) "$(GTKLIBS)/gtk-3.0/3.0.0/immodules/"*.so $@
-
-
-$(COQIDEAPP)/Contents/Resources/etc: $(COQIDEAPP)/Contents/Resources/lib
- $(MKDIR) $@/xdg/coq
- $(MKDIR) $@/gtk-3.0
- { "$(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/*.{dylib,so} |\
- sed -e "s!/.*\(/immodules/.*.dylib\)!@executable_path/../Resources/\1!" |\
- sed -e "s!/.*\(/immodules/.*.so\)!@executable_path/../Resources/\1!" |\
- sed -e "s!/.*\(/share/locale\)!@executable_path/../Resources/\1!"; } \
- > $@/gtk-3.0/gtk-immodules.loaders
- $(MKDIR) $@/pango
- echo "[Pango]" > $@/pango/pangorc
-
-$(COQIDEAPP)/Contents/Resources/lib: $(COQIDEAPP)/Contents/Resources/immodules $(COQIDEAPP)/Contents/Resources/loaders $(COQIDEAPP)/Contents $(COQIDEINAPP)
- $(MKDIR) $@
- macpack -d ../Resources/lib $(COQIDEINAPP)
- for i in $@/../bin/*; \
- do \
- macpack -d ../lib $$i; \
- done
- for i in $@/../loaders/*.so $@/../immodules/*.{dylib,so}; \
- do \
- macpack -d ../lib $$i; \
- done
-
-$(COQIDEAPP)/Contents/Resources:$(COQIDEAPP)/Contents/Resources/etc $(COQIDEAPP)/Contents/Resources/share
- $(INSTALLLIB) ide/coqide/MacOS/*.icns $@
-
-$(COQIDEAPP):$(COQIDEAPP)/Contents/Resources
- $(CODESIGN_HIDE) $@
-
-###########################################################################
# CoqIde for Windows special targets
###########################################################################
diff --git a/Makefile.make b/Makefile.make
index 9f0e06dffc..dc123820ee 100644
--- a/Makefile.make
+++ b/Makefile.make
@@ -277,7 +277,7 @@ cacheclean:
find theories user-contrib test-suite -name '.*.aux' -exec rm -f {} +
cleanconfig:
- rm -f config/Makefile config/coq_config.ml dev/ocamldebug-coq config/Info-*.plist
+ rm -f config/Makefile config/coq_config.ml dev/ocamldebug-coq
distclean: clean cleanconfig cacheclean timingclean
diff --git a/configure.ml b/configure.ml
index abea59bd60..68e4621cd5 100644
--- a/configure.ml
+++ b/configure.ml
@@ -13,15 +13,9 @@
open Printf
let coq_version = "8.14+alpha"
-let coq_macos_version = "8.13.90" (** "[...] should be a string comprised of
-three non-negative, period-separated integers [...]" *)
let vo_magic = 81391
let state_magic = 581391
let is_a_released_version = false
-let distributed_exec =
- ["coqtop.opt"; "coqidetop.opt"; "coqqueryworker.opt"; "coqproofworker.opt"; "coqtacticworker.opt";
- "coqc.opt";"coqchk";"coqdoc";"coqworkmgr";"coq_makefile";"coq-tex";"coqwc";"csdpcert";"coqdep";"votour"]
-
let verbose = ref false (* for debugging this script *)
let red, yellow, reset =
@@ -1159,7 +1153,6 @@ let write_makefile f =
List.iter (fun (v,_,dir,_) -> pr "%s=%S\n" v dir) install_dirs;
pr "\n# Coq version\n";
pr "VERSION=%s\n" coq_version;
- pr "VERSION4MACOS=%s\n\n" coq_macos_version;
pr "# Objective-Caml compile command\n";
pr "OCAML=%S\n" camlexec.top;
pr "OCAMLFIND=%S\n" camlexec.find;
@@ -1235,33 +1228,6 @@ let write_dune_c_flags f =
let _ = write_dune_c_flags "config/dune.c_flags"
-let write_macos_metadata exec =
- let f = "config/Info-"^exec^".plist" in
- let () = safe_remove f in
- let o = open_out f in
- let pr s = fprintf o s in
- pr "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
- pr "<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n";
- pr "<plist version=\"1.0\">\n";
- pr "<dict>\n";
- pr " <key>CFBundleIdentifier</key>\n";
- pr " <string>fr.inria.coq.%s</string>\n" exec;
- pr " <key>CFBundleName</key>\n";
- pr " <string>%s</string>\n" exec;
- pr " <key>CFBundleVersion</key>\n";
- pr " <string>%s</string>\n" coq_macos_version;
- pr " <key>CFBundleShortVersionString</key>\n";
- pr " <string>%s</string>\n" coq_macos_version;
- pr " <key>CFBundleInfoDictionaryVersion</key>\n";
- pr " <string>6.0</string>\n";
- pr "</dict>\n";
- pr "</plist>\n";
- let () = close_out o in
- Unix.chmod f 0o444
-
-let () =
- if arch = "Darwin" then List.iter write_macos_metadata distributed_exec
-
let write_configpy f =
safe_remove f;
let o = open_out f in
diff --git a/dev/build/osx/make-macos-dmg.sh b/dev/build/osx/make-macos-dmg.sh
deleted file mode 100755
index 2550cbb31c..0000000000
--- a/dev/build/osx/make-macos-dmg.sh
+++ /dev/null
@@ -1,37 +0,0 @@
-#!/bin/bash
-
-# Fail on first error
-set -e
-
-# Configuration setup
-DMGDIR=$PWD/_dmg
-VERSION=$(sed -n -e '/^let coq_version/ s/^[^"]*"\([^"]*\)"$/\1/p' configure.ml)
-APP=bin/CoqIDE_${VERSION}.app
-
-# Install Coq into the .app file
-make OLDROOT="$OUTDIR" COQINSTALLPREFIX="$APP/Contents/Resources" install-coq install-ide-toploop
-
-# Fill .app file with metadata and other .app specific stuff (like non-system .so)
-make PRIVATEBINARIES="$APP" -j 1 -l2 "$APP" VERBOSE=1
-
-# Create the dmg bundle
-mkdir -p "$DMGDIR"
-ln -sf /Applications "$DMGDIR/Applications"
-cp -r "$APP" "$DMGDIR"
-
-mkdir -p _build
-
-# Temporary countermeasure to hdiutil error 5341
-# head -c9703424 /dev/urandom > $DMGDIR/.padding
-
-hdi_opts=(-volname "coq-$VERSION-installer-macos"
- -srcfolder "$DMGDIR"
- -ov # overwrite existing file
- -format UDZO
- -imagekey "zlib-level=9"
-
- # needed for backward compat since macOS 10.14 which uses APFS by default
- # see discussion in #11803
- -fs hfs+
- )
-hdiutil create "${hdi_opts[@]}" "_build/coq-$VERSION-installer-macos.dmg"
diff --git a/dev/ci/docker/bionic_coq/Dockerfile b/dev/ci/docker/bionic_coq/Dockerfile
index 8f14625c63..00729cd168 100644
--- a/dev/ci/docker/bionic_coq/Dockerfile
+++ b/dev/ci/docker/bionic_coq/Dockerfile
@@ -24,7 +24,7 @@ RUN apt-get update -qq && apt-get install --no-install-recommends -y -qq \
texlive-science tipa
# More dependencies of the sphinx doc, pytest for coqtail
-RUN pip3 install sphinx==2.3.1 sphinx_rtd_theme==0.4.3 \
+RUN pip3 install docutils==0.16 sphinx==2.3.1 sphinx_rtd_theme==0.4.3 \
antlr4-python3-runtime==4.7.1 sphinxcontrib-bibtex==0.4.2 \
pytest==5.4.3
@@ -44,7 +44,7 @@ ENV COMPILER="4.05.0"
# Common OPAM packages
ENV BASE_OPAM="zarith.1.10 ocamlfind.1.8.1 ounit2.2.2.3 odoc.1.5.1" \
CI_OPAM="ocamlgraph.1.8.8" \
- BASE_ONLY_OPAM="elpi.1.13.0"
+ BASE_ONLY_OPAM="elpi.1.13.1"
# BASE switch; CI_OPAM contains Coq's CI dependencies.
ENV COQIDE_OPAM="cairo2.0.6.1 lablgtk3-sourceview3.3.1.0"
diff --git a/dev/ci/user-overlays/14111-gares-update-elpi.sh b/dev/ci/user-overlays/14111-gares-update-elpi.sh
new file mode 100644
index 0000000000..8827127a38
--- /dev/null
+++ b/dev/ci/user-overlays/14111-gares-update-elpi.sh
@@ -0,0 +1,2 @@
+overlay elpi https://github.com/LPCIC/coq-elpi coq-master+1.9.5 14111
+overlay hierarchy_builder https://github.com/math-comp/hierarchy-builder coq-master+1.1.0 14111
diff --git a/doc/changelog/04-tactics/14089-ltac2_unify.rst b/doc/changelog/04-tactics/14089-ltac2_unify.rst
new file mode 100644
index 0000000000..5887781db9
--- /dev/null
+++ b/doc/changelog/04-tactics/14089-ltac2_unify.rst
@@ -0,0 +1,5 @@
+- **Added:**
+ Ltac2 now has a `unify` tactic
+ (`#14089 <https://github.com/coq/coq/pull/14089>`_,
+ fixes `#14083 <https://github.com/coq/coq/issues/14083>`_,
+ by Samuel Gruetter).
diff --git a/doc/changelog/05-tactic-language/13939-ltac2-open-constr-scope.rst b/doc/changelog/05-tactic-language/13939-ltac2-open-constr-scope.rst
new file mode 100644
index 0000000000..9753ce915b
--- /dev/null
+++ b/doc/changelog/05-tactic-language/13939-ltac2-open-constr-scope.rst
@@ -0,0 +1,5 @@
+- **Added:**
+ Allow scope delimiters in Ltac2 open_constr:(...) quotation
+ (`#13939 <https://github.com/coq/coq/pull/13939>`_,
+ fixes `#12806 <https://github.com/coq/coq/issues/12806>`_,
+ by Pierre-Marie Pédrot).
diff --git a/doc/sphinx/_static/notations.css b/doc/sphinx/_static/notations.css
index abb08d98cc..e262a9305d 100644
--- a/doc/sphinx/_static/notations.css
+++ b/doc/sphinx/_static/notations.css
@@ -267,6 +267,11 @@ code span.error {
color: inherit !important;
}
+
+.coqdoc-comment {
+ color: #808080 !important
+}
+
/* make the error message index readable */
.indextable code {
white-space: inherit; /* break long lines */
diff --git a/doc/sphinx/addendum/micromega.rst b/doc/sphinx/addendum/micromega.rst
index d718454364..24e35dd85a 100644
--- a/doc/sphinx/addendum/micromega.rst
+++ b/doc/sphinx/addendum/micromega.rst
@@ -295,7 +295,7 @@ obtain :math:`-1`. By Theorem :ref:`Psatz <psatz_thm>`, the goal is valid.
The :tacn:`zify` tactic can be extended with new types and operators by declaring and registering new typeclass instances using the following commands.
The typeclass declarations can be found in the module ``ZifyClasses`` and the default instances can be found in the module ``ZifyInst``.
-.. cmd:: Add Zify @add_zify @one_term
+.. cmd:: Add Zify @add_zify @qualid
.. insertprodn add_zify add_zify
@@ -304,6 +304,9 @@ obtain :math:`-1`. By Theorem :ref:`Psatz <psatz_thm>`, the goal is valid.
| {| PropOp | PropBinOp | PropUOp | Saturate }
Registers an instance of the specified typeclass.
+ The typeclass type (e.g. :g:`BinOp Z.mul` or :g:`BinRel (@eq Z)`) has the additional constraint that
+ the non-implicit argument (here, :g:`Z.mul` or :g:`(@eq Z)`)
+ is either a :n:`@reference` (here, :g:`Z.mul`) or the application of a :n:`@reference` (here, :g:`@eq`) to a sequence of :n:`@one_term`.
.. cmd:: Show Zify @show_zify
diff --git a/doc/sphinx/language/core/conversion.rst b/doc/sphinx/language/core/conversion.rst
index 06b6c61ea9..e53e6ea1cb 100644
--- a/doc/sphinx/language/core/conversion.rst
+++ b/doc/sphinx/language/core/conversion.rst
@@ -4,10 +4,80 @@ Conversion rules
----------------
Coq has conversion rules that can be used to determine if two
-terms are equal by definition, or :term:`convertible`.
+terms are equal by definition in |CiC|, or :term:`convertible`.
Conversion rules consist of reduction rules and expansion rules.
-See :ref:`applyingconversionrules`,
-which describes tactics that apply these conversion rules.
+Equality is determined by
+converting both terms to a normal form, then verifying they are syntactically
+equal (ignoring differences in the names of bound variables by
+:term:`alpha-conversion <alpha-convertible>`).
+
+.. seealso:: :ref:`applyingconversionrules`, which describes tactics that apply these conversion rules.
+
+:gdef:`Reductions <reduction>` convert terms to something that is incrementally
+closer to its normal form. For example, :term:`zeta-reduction` removes
+:n:`let @ident := @term__1 in @term__2` constructs from a term by replacing
+:n:`@ident` with :n:`@term__1` wherever :n:`@ident` appears in :n:`@term__2`.
+The resulting term may be longer or shorter than the original.
+
+.. coqtop:: all
+
+ Eval cbv zeta in let i := 1 in i + i.
+
+:gdef:`Expansions <expansion>` are reductions applied in the opposite direction,
+for example expanding `2 + 2` to `let i := 2 in i + i`. While applying
+reductions gives a unique result, the associated
+expansion may not be unique. For example, `2 + 2` could also be
+expanded to `let i := 2 in i + 2`. Reductions that have a unique inverse
+expansion are also referred to as :gdef:`contractions <contraction>`.
+
+The normal form is defined as the result of applying a particular
+set of conversion rules (beta-, delta-, iota- and zeta-reduction and eta-expansion)
+repeatedly until it's no longer possible to apply any of them.
+
+Sometimes the result of a reduction tactic will be a simple value, for example reducing
+`2*3+4` with `cbv beta delta iota` to `10`, which requires applying several
+reduction rules repeatedly. In other cases, it may yield an expression containing
+variables, axioms or opaque contants that can't be reduced.
+
+The useful conversion rules are shown below. All of them except for eta-expansion
+can be applied with conversion tactics such as :tacn:`cbv`:
+
+ .. list-table::
+ :header-rows: 1
+
+ * - Conversion name
+ - Description
+
+ * - beta-reduction
+ - eliminates `fun`
+
+ * - delta-reduction
+ - replaces a defined variable or constant with its definition
+
+ * - zeta-reduction
+ - eliminates `let`
+
+ * - eta-expansion
+ - replaces a term `f` of type `forall a : A, B` with `fun x : A => f x`
+
+ * - match-reduction
+ - eliminates `match`
+
+ * - fix-reduction
+ - replaces a `fix` with a :term:`beta-redex`;
+ recursive calls to the symbol are replaced with the `fix` term
+
+ * - cofix-reduction
+ - replaces a `cofix` with a :term:`beta-redex`;
+ recursive calls to the symbol are replaced with the `cofix` term
+
+ * - iota-reduction
+ - match-, fix- and cofix-reduction together
+
+:ref:`applyingconversionrules`
+describes tactics that only apply conversion rules.
+(Other tactics may use conversion rules in addition
+to other changes to the proof state.)
α-conversion
~~~~~~~~~~~~
@@ -123,7 +193,7 @@ for :math:`x` an arbitrary variable name fresh in :math:`t`.
.. math::
λ x:T.~(t~x)~\not\triangleright_η~t
- This is because, in general, the type of :math:`t` need not to be convertible
+ This is because, in general, the type of :math:`t` need not be convertible
to the type of :math:`λ x:T.~(t~x)`. E.g., if we take :math:`f` such that:
.. math::
@@ -142,6 +212,30 @@ for :math:`x` an arbitrary variable name fresh in :math:`t`.
because the type of the reduced term :math:`∀ x:\Type(2),~\Type(1)` would not be
convertible to the type of the original term :math:`∀ x:\Type(1),~\Type(1)`.
+Examples
+~~~~~~~~
+
+ .. example:: Simple delta, fix, beta and match reductions
+
+ ``+`` is a :ref:`notation <Notations>` for ``Nat.add``, which is defined
+ with a :cmd:`Fixpoint`.
+
+ .. coqtop:: all abort
+
+ Print Nat.add.
+ Goal 1 + 1 = 2.
+ cbv delta.
+ cbv fix.
+ cbv beta.
+ cbv match.
+
+ The term can be fully reduced with `cbv`:
+
+ .. coqtop:: all abort
+
+ Goal 1 + 1 = 2.
+ cbv.
+
.. _proof-irrelevance:
Proof Irrelevance
diff --git a/doc/sphinx/proof-engine/ltac2.rst b/doc/sphinx/proof-engine/ltac2.rst
index 294c56ef06..25ac72069b 100644
--- a/doc/sphinx/proof-engine/ltac2.rst
+++ b/doc/sphinx/proof-engine/ltac2.rst
@@ -1375,8 +1375,9 @@ table further down lists the classes that that are handled plainly.
the term (as described in :ref:`LocalInterpretationRulesForNotations`). The last
:token:`scope_key` is the top of the scope stack that's applied to the :token:`term`.
- :n:`open_constr`
- Parses an open :token:`term`.
+ :n:`open_constr {? ( {+, @scope_key } ) }`
+ Parses an open :token:`term`. Like :n:`constr` above, this class
+ accepts a list of notation scopes with the same effects.
:n:`ident`
Parses :token:`ident` or :n:`$@ident`. The first form returns :n:`ident:(@ident)`,
diff --git a/doc/sphinx/proof-engine/ssreflect-proof-language.rst b/doc/sphinx/proof-engine/ssreflect-proof-language.rst
index bab9d35099..d4749f781a 100644
--- a/doc/sphinx/proof-engine/ssreflect-proof-language.rst
+++ b/doc/sphinx/proof-engine/ssreflect-proof-language.rst
@@ -609,7 +609,7 @@ Abbreviations
|SSR| extends the :tacn:`set` tactic by supplying:
- + an open syntax, similarly to the :tacn:`pose (ssreflect)` tactic;
+ + an open syntax, similarly to the :tacn:`pose <pose (ssreflect)>` tactic;
+ a more aggressive matching algorithm;
+ an improved interpretation of wildcards, taking advantage of the
matching algorithm;
@@ -899,7 +899,7 @@ context of a goal thanks to the ``in`` tactical.
.. tacv:: set @ident := @term in {+ @ident}
- This variant of :tacn:`set (ssreflect)` introduces a defined constant
+ This variant of :tacn:`set <set (ssreflect)>` introduces a defined constant
called :token:`ident` in the context, and folds it in
the context entries mentioned on the right hand side of ``in``.
The body of :token:`ident` is the first subterm matching these context
@@ -1202,7 +1202,7 @@ The move tactic.
Goal not False.
move.
- More precisely, the :tacn:`move` tactic inspects the goal and does nothing
+ More precisely, the :tacn:`move <move (ssreflect)>` tactic inspects the goal and does nothing
(:tacn:`idtac`) if an introduction step is possible, i.e. if the goal is a
product or a ``let … in``, and performs :tacn:`hnf` otherwise.
@@ -1301,7 +1301,7 @@ The apply tactic
this use of the :tacn:`refine` tactic implies that the tactic tries to match
the goal up to expansion of constants and evaluation of subterms.
-:tacn:`apply (ssreflect)` has a special behavior on goals containing
+:tacn:`apply <apply (ssreflect)>` has a special behavior on goals containing
existential metavariables of sort :g:`Prop`.
.. example::
@@ -2461,7 +2461,7 @@ The have tactic.
redex, and introduces the lemma under a fresh name, automatically
chosen.
-Like in the case of the :n:`pose (ssreflect)` tactic (see section :ref:`definitions_ssr`), the types of
+Like in the case of the :n:`pose <pose (ssreflect)>` tactic (see section :ref:`definitions_ssr`), the types of
the holes are abstracted in term.
.. example::
@@ -3775,7 +3775,7 @@ involves the following steps:
``forall n, F1 n = F2 n`` for ``eq_map``).
3. If so :tacn:`under` puts these n goals in head normal form (using
- the defective form of the tactic :tacn:`move`), then executes
+ the defective form of the tactic :tacn:`move <move (ssreflect)>`), then executes
the corresponding intro pattern :n:`@i_pattern__i` in each goal.
4. Then :tacn:`under` checks that the first n subgoals
@@ -5665,6 +5665,7 @@ Tactics
respectively.
.. tacn:: move
+ :name: move (ssreflect)
:tacn:`idtac` or :tacn:`hnf` (see :ref:`bookkeeping_ssr`)
diff --git a/doc/sphinx/proof-engine/tactics.rst b/doc/sphinx/proof-engine/tactics.rst
index fad02b2645..7bc009fcfe 100644
--- a/doc/sphinx/proof-engine/tactics.rst
+++ b/doc/sphinx/proof-engine/tactics.rst
@@ -1148,7 +1148,7 @@ Managing the local context
or at the bottom of the local context. All hypotheses on which the new
hypothesis depends are moved too so as to respect the order of
dependencies between hypotheses. It is equivalent to :n:`intro {? @ident__1 }`
- followed by the appropriate call to :tacn:`move … after …`,
+ followed by the appropriate call to :tacn:`move`,
:tacn:`move … before …`, :tacn:`move … at top`,
or :tacn:`move … at bottom`.
@@ -1235,7 +1235,6 @@ Managing the local context
hypotheses that depend on it.
.. tacn:: move @ident__1 after @ident__2
- :name: move … after …
This moves the hypothesis named :n:`@ident__1` in the local context after
the hypothesis named :n:`@ident__2`, where “after” is in reference to the
@@ -1256,7 +1255,7 @@ Managing the local context
:name: move … before …
This moves :n:`@ident__1` towards and just before the hypothesis
- named :n:`@ident__2`. As for :tacn:`move … after …`, dependencies
+ named :n:`@ident__2`. As for :tacn:`move`, dependencies
over :n:`@ident__1` (when :n:`@ident__1` comes before :n:`@ident__2` in
the order of dependencies) or in the type of :n:`@ident__1`
(when :n:`@ident__1` comes after :n:`@ident__2` in the order of
@@ -2502,7 +2501,7 @@ and an explanation of the underlying technique.
:name: inversion ... using ...
.. todo using … instead of ... in the name above gives a Sphinx error, even though
- this works just find for :tacn:`move … after …`
+ this works just find for :tacn:`move`
Let :n:`@ident` have type :g:`(I t)` (:g:`I` an inductive predicate) in the
local context, and :n:`@ident` be a (dependent) inversion lemma. Then, this
diff --git a/doc/sphinx/refman-preamble.rst b/doc/sphinx/refman-preamble.rst
index 32d3e87e68..dd1d6051b5 100644
--- a/doc/sphinx/refman-preamble.rst
+++ b/doc/sphinx/refman-preamble.rst
@@ -15,7 +15,7 @@
.. |c_i| replace:: `c`\ :math:`_{i}`
.. |c_n| replace:: `c`\ :math:`_{n}`
.. |Cic| replace:: CIC
-.. |eq_beta_delta_iota_zeta| replace:: `=`\ :math:`_{\beta\delta\iota\zeta}`
+.. |eq_beta_delta_iota_zeta| replace:: `=`\ :math:`_{βδιζ}`
.. |Latex| replace:: :smallcaps:`LaTeX`
.. |Ltac| replace:: `L`:sub:`tac`
.. |p_1| replace:: `p`\ :math:`_{1}`
diff --git a/doc/tools/coqrst/coqdoc/main.py b/doc/tools/coqrst/coqdoc/main.py
index 522b9900a5..51e26a9082 100644
--- a/doc/tools/coqrst/coqdoc/main.py
+++ b/doc/tools/coqrst/coqdoc/main.py
@@ -28,7 +28,7 @@ from bs4 import BeautifulSoup
from bs4.element import NavigableString
COQDOC_OPTIONS = ['--body-only', '--no-glob', '--no-index', '--no-externals',
- '-s', '--html', '--stdout', '--utf8']
+ '-s', '--html', '--stdout', '--utf8', '--parse-comments']
COQDOC_SYMBOLS = ["->", "<-", "<->", "=>", "<=", ">=", "<>", "~", "/\\", "\\/", "|-", "*", "forall", "exists"]
COQDOC_HEADER = "".join("(** remove printing {} *)".format(s) for s in COQDOC_SYMBOLS)
@@ -68,8 +68,19 @@ def lex(source):
if isinstance(elem, NavigableString):
yield [], elem
elif elem.name == "span":
- cls = "coqdoc-{}".format(elem['title'])
- yield [cls], elem.string
+ if elem.string:
+ cls = "coqdoc-{}".format(elem.get("title", "comment"))
+ yield [cls], elem.string
+ else:
+ # handle multi-line comments
+ children = list(elem.children)
+ mlc = children[0].startswith("(*") and children[-1].endswith ("*)")
+ for elem2 in children:
+ if isinstance(elem2, NavigableString):
+ cls = ["coqdoc-comment"] if mlc else []
+ yield cls, elem2
+ elif elem2.name == 'br':
+ pass
elif elem.name == 'br':
pass
else:
diff --git a/doc/tools/coqrst/coqdomain.py b/doc/tools/coqrst/coqdomain.py
index 1428dae7ef..468b6b648d 100644
--- a/doc/tools/coqrst/coqdomain.py
+++ b/doc/tools/coqrst/coqdomain.py
@@ -938,10 +938,11 @@ class CoqtopBlocksTransform(Transform):
@staticmethod
def split_lines(source):
- r"""Split Coq input in chunks
+ r"""Split Coq input into chunks, which may include single- or
+ multi-line comments. Nested comments are not supported.
A chunk is a minimal sequence of consecutive lines of the input that
- ends with a '.'
+ ends with a '.' or '*)'
>>> split_lines('A.\nB.''')
['A.', 'B.']
@@ -962,8 +963,14 @@ class CoqtopBlocksTransform(Transform):
>>> split_lines('SearchHead le.\nSearchHead (@eq bool).')
['SearchHead le.', 'SearchHead (@eq bool).']
+
+ >>> split_lines("(* *) x. (* *)\ny.\n")
+ ['(* *) x. (* *)', 'y.']
+
+ >>> split_lines("(* *) x (* \n *)\ny.\n")
+ ['(* *) x (* \n *)', 'y.']
"""
- return re.split(r"(?<=(?<!\.)\.)\n", source.strip())
+ return re.split(r"(?:(?<=(?<!\.)\.)|(?<=\*\)))\n", source.strip())
@staticmethod
def parse_options(node):
@@ -1039,7 +1046,11 @@ class CoqtopBlocksTransform(Transform):
if options['warn']:
repl.sendone('Set Warnings "default".')
for sentence in self.split_lines(node.rawsource):
- pairs.append((sentence, repl.sendone(sentence)))
+ comment = re.compile(r"\s*\(\*.*?\*\)\s*", re.DOTALL)
+ wo_comments = re.sub(comment, "", sentence)
+ has_tac = wo_comments != "" and not wo_comments.isspace()
+ output = repl.sendone(sentence) if has_tac else ""
+ pairs.append((sentence, output))
if options['abort']:
repl.sendone('Abort All.')
if options['fail']:
@@ -1052,9 +1063,10 @@ class CoqtopBlocksTransform(Transform):
# Use Coqdoc to highlight input
in_chunks = highlight_using_coqdoc(sentence)
dli += nodes.term(sentence, '', *in_chunks, classes=self.block_classes(options['input']))
- # Parse ANSI sequences to highlight output
- out_chunks = AnsiColorsParser().colorize_str(output)
- dli += nodes.definition(output, *out_chunks, classes=self.block_classes(options['output'], output))
+ if output:
+ # Parse ANSI sequences to highlight output
+ out_chunks = AnsiColorsParser().colorize_str(output)
+ dli += nodes.definition(output, *out_chunks, classes=self.block_classes(options['output'], output))
node.clear()
node.rawsource = self.make_rawsource(pairs, options['input'], options['output'])
node['classes'].extend(self.block_classes(options['input'] or options['output']))
@@ -1180,8 +1192,7 @@ class StdGlossaryIndex(Index):
if type == 'term':
entries = content[itemname[0].lower()]
entries.append([itemname, 0, docname, anchor, '', '', ''])
- content = sorted(content.items())
- return content, False
+ return content.items(), False
def GrammarProductionRole(typ, rawtext, text, lineno, inliner, options={}, content=[]):
"""A grammar production not included in a ``prodn`` directive.
diff --git a/ide/coqide/MacOS/Info.plist.template b/ide/coqide/MacOS/Info.plist.template
deleted file mode 100644
index e4fb0e5980..0000000000
--- a/ide/coqide/MacOS/Info.plist.template
+++ /dev/null
@@ -1,89 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
-<plist version="1.0">
-<dict>
- <key>CFBundleDocumentTypes</key>
- <array>
- <dict>
- <key>CFBundleTypeExtensions</key>
- <array>
- <string>*</string>
- </array>
- <key>CFBundleTypeName</key>
- <string>NSStringPboardType</string>
- <key>CFBundleTypeOSTypes</key>
- <array>
- <string>****</string>
- </array>
- <key>CFBundleTypeRole</key>
- <string>Editor</string>
- </dict>
- <dict>
- <key>CFBundleTypeIconFile</key>
- <string>coqfile.icns</string>
- <key>CFBundleTypeName</key>
- <string>Coq file</string>
- <key>CFBundleTypeRole</key>
- <string>Editor</string>
- <key>CFBundleTypeMIMETypes</key>
- <array>
- <string>text/plain</string>
- </array>
- <key>CFBundleTypeExtensions</key>
- <array>
- <string>v</string>
- </array>
- <key>LSHandlerRank</key>
- <string>Owner</string>
- </dict>
- <dict>
- <key>CFBundleTypeName</key>
- <string>All</string>
- <key>CFBundleTypeRole</key>
- <string>Editor</string>
- <key>CFBundleTypeMIMETypes</key>
- <array>
- <string>text/plain</string>
- </array>
- <key>LSHandlerRank</key>
- <string>Default</string>
- <key>CFBundleTypeExtensions</key>
- <array>
- <string>*</string>
- </array>
- </dict>
- </array>
- <key>CFBundleIconFile</key>
- <string>coqide.icns</string>
- <key>CFBundleVersion</key>
- <string>390</string>
- <key>CFBundleName</key>
- <string>CoqIDE</string>
- <key>CFBundleShortVersionString</key>
- <string>VERSION</string>
- <key>CFBundleDisplayName</key>
- <string>Coq Proof Assistant vVERSION</string>
- <key>CFBundleGetInfoString</key>
- <string>Coq_vVERSION</string>
- <key>NSHumanReadableCopyright</key>
- <string>Copyright 1999-2019, Inria, CNRS and contributors</string>
- <key>CFBundleHelpBookFolder</key>
- <string>share/doc/coq/html/</string>
- <key>CFAppleHelpAnchor</key>
- <string>index</string>
- <key>CFBundleExecutable</key>
- <string>coqide</string>
- <key>CFBundlePackageType</key>
- <string>APPL</string>
- <key>CFBundleInfoDictionaryVersion</key>
- <string>6.0</string>
- <key>CFBundleIdentifier</key>
- <string>fr.inria.coq.coqide</string>
- <key>LSApplicationCategoryType</key>
- <string>public.app-category.developer-tools</string>
- <key>CFBundleDevelopmentRegion</key>
- <string>English</string>
- <key>NSPrincipalClass</key>
- <string>NSApplication</string>
-</dict>
-</plist>
diff --git a/ide/coqide/configwin_ihm.ml b/ide/coqide/configwin_ihm.ml
index e768131dcf..da1553d751 100644
--- a/ide/coqide/configwin_ihm.ml
+++ b/ide/coqide/configwin_ihm.ml
@@ -31,6 +31,10 @@ let set_help_tip wev = function
| None -> ()
| Some help -> GtkBase.Widget.Tooltip.set_text wev#as_widget help
+let select_arch m m_osx =
+ if Coq_config.arch = "Darwin" then m_osx else m
+
+(* How the modifiers are named in the preference box *)
let modifiers_to_string m =
let rec iter m s =
match m with
@@ -41,6 +45,7 @@ let modifiers_to_string m =
`CONTROL -> "<ctrl>"
| `SHIFT -> "<shft>"
| `LOCK -> "<lock>"
+ | `META -> select_arch "<meta>" "<cmd>"
| `MOD1 -> "<alt>"
| `MOD2 -> "<mod2>"
| `MOD3 -> "<mod3>"
@@ -773,7 +778,7 @@ let modifiers
?(editable=true)
?(expand=true)
?help
- ?(allow=[`CONTROL;`SHIFT;`LOCK;`MOD1;`MOD2;`MOD3;`MOD4;`MOD5])
+ ?(allow=[`CONTROL;`SHIFT;`LOCK;`META;`MOD1;`MOD2;`MOD3;`MOD4;`MOD5])
?(f=(fun _ -> ())) label v =
Modifiers_param
{
diff --git a/ide/coqide/preferences.ml b/ide/coqide/preferences.ml
index 8361cc3940..838da6303d 100644
--- a/ide/coqide/preferences.ml
+++ b/ide/coqide/preferences.ml
@@ -321,18 +321,21 @@ let attach_modifiers (pref : string preference) prefix =
in
pref#connect#changed ~callback:cb
-let select_arch m m_osx =
- if Coq_config.arch = "Darwin" then m_osx else m
-
let modifier_for_navigation =
new preference ~name:["modifier_for_navigation"]
- ~init:(select_arch "<Control>" "<Control><Primary>") ~repr:Repr.(string)
+ (* Note: on Darwin, this will give "<Control><Meta>", i.e. Ctrl and Command; on other
+ architectures, "<Primary>" binds to "<Control>" so it will give "<Control>" alone *)
+ ~init:"<Control><Primary>" ~repr:Repr.(string)
let modifier_for_templates =
new preference ~name:["modifier_for_templates"] ~init:"<Control><Shift>" ~repr:Repr.(string)
+let select_arch m m_osx =
+ if Coq_config.arch = "Darwin" then m_osx else m
+
let modifier_for_display =
new preference ~name:["modifier_for_display"]
+ (* Note: <Primary> (i.e. <Meta>, i.e. "Command") on Darwin, i.e. MacOS X, but <Alt> elsewhere *)
~init:(select_arch "<Alt><Shift>" "<Primary><Shift>")~repr:Repr.(string)
let modifier_for_queries =
@@ -348,7 +351,9 @@ let attach_modifiers_callback () =
()
let modifiers_valid =
- new preference ~name:["modifiers_valid"] ~init:"<Alt><Control><Shift>" ~repr:Repr.(string)
+ new preference ~name:["modifiers_valid"]
+ (* Note: <Primary> is providing <Meta> (i.e. "Command") for Darwin, i.e. MacOS X *)
+ ~init:"<Alt><Control><Shift><Primary>" ~repr:Repr.(string)
let browser_cmd_fmt =
try
diff --git a/plugins/micromega/zify.ml b/plugins/micromega/zify.ml
index b780c1833e..3ea7408067 100644
--- a/plugins/micromega/zify.ml
+++ b/plugins/micromega/zify.ml
@@ -46,6 +46,7 @@ let mkrel = lazy (zify "mkrel")
let iff_refl = lazy (zify "iff_refl")
let eq_iff = lazy (zify "eq_iff")
let rew_iff = lazy (zify "rew_iff")
+let rew_iff_rev = lazy (zify "rew_iff_rev")
(* propositional logic *)
@@ -621,14 +622,20 @@ module MakeTable (E : Elt) = struct
failwith ("Cannot register term " ^ t)
| Some a -> E.mk_elt evd i a
+ let safe_ref evd c =
+ try
+ fst (EConstr.destRef evd c)
+ with DestKO -> CErrors.user_err Pp.(str "Add Zify "++str E.name ++ str ": the term "++
+ gl_pr_constr c ++ str " should be a global reference")
+
let register_hint evd t elt =
match EConstr.kind evd t with
| App (c, _) ->
- let gr = fst (EConstr.destRef evd c) in
- E.table := ConstrMap.add gr (Application t, E.cast elt) !E.table
+ let gr = safe_ref evd c in
+ E.table := ConstrMap.add gr (Application t, E.cast elt) !E.table
| _ ->
- let gr = fst (EConstr.destRef evd t) in
- E.table := ConstrMap.add gr (OtherTerm t, E.cast elt) !E.table
+ let gr = safe_ref evd t in
+ E.table := ConstrMap.add gr (OtherTerm t, E.cast elt) !E.table
let register_constr env evd c =
let c = EConstr.of_constr c in
@@ -1365,7 +1372,15 @@ let trans_concl prfp =
Tactics.change_concl t')
| TProof (t, prf) ->
Proofview.Goal.enter (fun gl ->
- Equality.general_rewrite true Locus.AllOccurrences true false prf)
+ let env = Tacmach.New.pf_env gl in
+ let evd = Tacmach.New.project gl in
+ let typ = get_type_of env evd prf in
+ match EConstr.kind evd typ with
+ | App (c, a) when Array.length a = 2 ->
+ Tactics.apply
+ (EConstr.mkApp (Lazy.force rew_iff_rev, [|a.(0); a.(1); prf|]))
+ | _ ->
+ raise (CErrors.anomaly Pp.(str "zify cannot transform conclusion")))
let tclTHENOpt e tac tac' =
match e with None -> tac' | Some e' -> Tacticals.New.tclTHEN (tac e') tac'
diff --git a/tactics/hipattern.ml b/tactics/hipattern.ml
index 5338e0eef5..783a317b3a 100644
--- a/tactics/hipattern.ml
+++ b/tactics/hipattern.ml
@@ -293,31 +293,34 @@ let match_with_equation env sigma t =
let (hdapp,args) = destApp sigma t in
match EConstr.kind sigma hdapp with
| Ind (ind,u) ->
- if Coqlib.check_ind_ref "core.eq.type" ind then
- Some (build_coq_eq_data()),hdapp,
- PolymorphicLeibnizEq(args.(0),args.(1),args.(2))
- else if Coqlib.check_ind_ref "core.identity.type" ind then
- Some (build_coq_identity_data()),hdapp,
- PolymorphicLeibnizEq(args.(0),args.(1),args.(2))
- else if Coqlib.check_ind_ref "core.JMeq.type" ind then
- Some (build_coq_jmeq_data()),hdapp,
- HeterogenousEq(args.(0),args.(1),args.(2),args.(3))
- else
- let (mib,mip) = Global.lookup_inductive ind in
- let constr_types = mip.mind_nf_lc in
- let nconstr = Array.length mip.mind_consnames in
- if Int.equal nconstr 1 then
- let (ctx, cty) = constr_types.(0) in
- let cty = EConstr.of_constr (Term.it_mkProd_or_LetIn cty ctx) in
- if is_matching env sigma coq_refl_leibniz1_pattern cty then
- None, hdapp, MonomorphicLeibnizEq(args.(0),args.(1))
- else if is_matching env sigma coq_refl_leibniz2_pattern cty then
- None, hdapp, PolymorphicLeibnizEq(args.(0),args.(1),args.(2))
- else if is_matching env sigma coq_refl_jm_pattern cty then
- None, hdapp, HeterogenousEq(args.(0),args.(1),args.(2),args.(3))
- else raise NoEquationFound
- else raise NoEquationFound
- | _ -> raise NoEquationFound
+ (try
+ if Coqlib.check_ind_ref "core.eq.type" ind then
+ Some (build_coq_eq_data()),hdapp,
+ PolymorphicLeibnizEq(args.(0),args.(1),args.(2))
+ else if Coqlib.check_ind_ref "core.identity.type" ind then
+ Some (build_coq_identity_data()),hdapp,
+ PolymorphicLeibnizEq(args.(0),args.(1),args.(2))
+ else if Coqlib.check_ind_ref "core.JMeq.type" ind then
+ Some (build_coq_jmeq_data()),hdapp,
+ HeterogenousEq(args.(0),args.(1),args.(2),args.(3))
+ else
+ let (mib,mip) = Global.lookup_inductive ind in
+ let constr_types = mip.mind_nf_lc in
+ let nconstr = Array.length mip.mind_consnames in
+ if Int.equal nconstr 1 then
+ let (ctx, cty) = constr_types.(0) in
+ let cty = EConstr.of_constr (Term.it_mkProd_or_LetIn cty ctx) in
+ if is_matching env sigma coq_refl_leibniz1_pattern cty then
+ None, hdapp, MonomorphicLeibnizEq(args.(0),args.(1))
+ else if is_matching env sigma coq_refl_leibniz2_pattern cty then
+ None, hdapp, PolymorphicLeibnizEq(args.(0),args.(1),args.(2))
+ else if is_matching env sigma coq_refl_jm_pattern cty then
+ None, hdapp, HeterogenousEq(args.(0),args.(1),args.(2),args.(3))
+ else raise NoEquationFound
+ else raise NoEquationFound
+ with UserError _ ->
+ raise NoEquationFound)
+ | _ -> raise NoEquationFound
(* Note: An "equality type" is any type with a single argument-free
constructor: it captures eq, eq_dep, JMeq, eq_true, etc. but also
diff --git a/test-suite/bugs/closed/bug_12806.v b/test-suite/bugs/closed/bug_12806.v
new file mode 100644
index 0000000000..ee221d33a6
--- /dev/null
+++ b/test-suite/bugs/closed/bug_12806.v
@@ -0,0 +1,9 @@
+Require Import Ltac2.Ltac2.
+
+Declare Scope my_scope.
+Delimit Scope my_scope with my_scope.
+
+Notation "###" := tt : my_scope.
+
+Ltac2 Notation "bar" c(open_constr(my_scope)) := c.
+Ltac2 Eval bar ###.
diff --git a/test-suite/ltac2/std_tactics.v b/test-suite/ltac2/std_tactics.v
new file mode 100644
index 0000000000..39b620a6ac
--- /dev/null
+++ b/test-suite/ltac2/std_tactics.v
@@ -0,0 +1,29 @@
+Require Import Ltac2.Ltac2.
+
+Axiom f: nat -> nat.
+Definition g := f.
+
+Axiom Foo1: nat -> Prop.
+Axiom Foo2: nat -> Prop.
+Axiom Impl: forall n: nat, Foo1 (f n) -> Foo2 (f n).
+
+Create HintDb foo discriminated.
+#[export] Hint Constants Opaque : foo.
+#[export] Hint Resolve Impl : foo.
+
+Goal forall x, Foo1 (f x) -> Foo2 (g x).
+Proof.
+ auto with foo.
+ #[export] Hint Transparent g : foo.
+ auto with foo.
+Qed.
+
+Goal forall (x: nat), exists y, f x = g y.
+Proof.
+ intros.
+ eexists.
+ unify f g.
+ lazy_match! goal with
+ | [ |- ?a ?b = ?rhs ] => unify ($a $b) $rhs
+ end.
+Abort.
diff --git a/test-suite/micromega/bug_11089.v b/test-suite/micromega/bug_11089.v
new file mode 100644
index 0000000000..e62b5b8d9e
--- /dev/null
+++ b/test-suite/micromega/bug_11089.v
@@ -0,0 +1,13 @@
+Require Import Lia.
+Unset Lia Cache.
+Definition t := nat.
+Goal forall (n : t), n = n.
+Proof.
+ intros.
+ lia.
+Qed.
+Goal let t' := nat in forall (n : t'), n = n.
+Proof.
+ intros.
+ lia.
+Qed.
diff --git a/test-suite/micromega/zify.v b/test-suite/micromega/zify.v
index a12623c3c0..2ea320047d 100644
--- a/test-suite/micromega/zify.v
+++ b/test-suite/micromega/zify.v
@@ -167,6 +167,12 @@ Goal @zero znat = 0%nat.
reflexivity.
Qed.
+Require Import ZifyBool.
+Instance Op_bool_inj : UnOp (inj : bool -> bool) :=
+ { TUOp := id; TUOpInj := fun _ => eq_refl }.
+Add Zify UnOp Op_bool_inj.
+
+
Goal forall (x y : positive) (F : forall (P: Pos.le x y) , positive) (P : Pos.le x y),
(F P + 1 = 1 + F P)%positive.
Proof.
@@ -228,6 +234,7 @@ Proof.
intros. lia.
Qed.
+
Ltac Zify.zify_pre_hook ::= unfold is_true in *.
Goal forall x y : nat, is_true (Nat.eqb x 1) ->
diff --git a/theories/micromega/ZifyClasses.v b/theories/micromega/ZifyClasses.v
index 019d11d951..25d9fa9104 100644
--- a/theories/micromega/ZifyClasses.v
+++ b/theories/micromega/ZifyClasses.v
@@ -7,7 +7,6 @@
(* * GNU Lesser General Public License Version 2.1 *)
(* * (see LICENSE file for the text of the license) *)
(************************************************************************)
-Set Primitive Projections.
(** An alternative to [zify] in ML parametrised by user-provided classes instances.
@@ -220,6 +219,13 @@ Proof.
exact (fun H => proj1 IFF H).
Qed.
+Lemma rew_iff_rev (P Q : Prop) (IFF : P <-> Q) : Q -> P.
+Proof.
+ exact (fun H => proj2 IFF H).
+Qed.
+
+
+
(** Registering constants for use by the plugin *)
Register eq_iff as ZifyClasses.eq_iff.
Register target_prop as ZifyClasses.target_prop.
@@ -247,6 +253,7 @@ Register eq as ZifyClasses.eq.
Register mkinjprop as ZifyClasses.mkinjprop.
Register iff_refl as ZifyClasses.iff_refl.
Register rew_iff as ZifyClasses.rew_iff.
+Register rew_iff_rev as ZifyClasses.rew_iff_rev.
Register source_prop as ZifyClasses.source_prop.
Register injprop_ok as ZifyClasses.injprop_ok.
Register iff as ZifyClasses.iff.
diff --git a/user-contrib/Ltac2/Notations.v b/user-contrib/Ltac2/Notations.v
index 931d753521..6ddad8f1c9 100644
--- a/user-contrib/Ltac2/Notations.v
+++ b/user-contrib/Ltac2/Notations.v
@@ -593,6 +593,8 @@ Ltac2 Notation "typeclasses_eauto" "bfs" n(opt(tactic(0)))
Ltac2 Notation typeclasses_eauto := typeclasses_eauto.
+Ltac2 Notation "unify" x(constr) y(constr) := Std.unify x y.
+
(** Congruence *)
Ltac2 f_equal0 () := ltac1:(f_equal).
diff --git a/user-contrib/Ltac2/Std.v b/user-contrib/Ltac2/Std.v
index b69a95faf3..3675df9f75 100644
--- a/user-contrib/Ltac2/Std.v
+++ b/user-contrib/Ltac2/Std.v
@@ -259,3 +259,5 @@ Ltac2 @ external new_auto : debug -> int option -> (unit -> constr) list -> iden
Ltac2 @ external eauto : debug -> int option -> int option -> (unit -> constr) list -> ident list option -> unit := "ltac2" "tac_eauto".
Ltac2 @ external typeclasses_eauto : strategy option -> int option -> ident list option -> unit := "ltac2" "tac_typeclasses_eauto".
+
+Ltac2 @ external unify : constr -> constr -> unit := "ltac2" "tac_unify".
diff --git a/user-contrib/Ltac2/tac2core.ml b/user-contrib/Ltac2/tac2core.ml
index 457b8e1acf..4758ecf5bd 100644
--- a/user-contrib/Ltac2/tac2core.ml
+++ b/user-contrib/Ltac2/tac2core.ml
@@ -1754,6 +1754,16 @@ let () = add_scope "constr" (fun arg ->
Tac2entries.ScopeRule (Pcoq.Symbol.nterm Pcoq.Constr.constr, act)
)
+let () = add_scope "open_constr" (fun arg ->
+ let delimiters = List.map (function
+ | SexprRec (_, { v = Some s }, []) -> s
+ | _ -> scope_fail "open_constr" arg)
+ arg
+ in
+ let act e = Tac2quote.of_open_constr ~delimiters e in
+ Tac2entries.ScopeRule (Pcoq.Symbol.nterm Pcoq.Constr.constr, act)
+ )
+
let add_expr_scope name entry f =
add_scope name begin function
| [] -> Tac2entries.ScopeRule (Pcoq.Symbol.nterm entry, f)
@@ -1782,7 +1792,6 @@ let () = add_expr_scope "constr_matching" q_constr_matching Tac2quote.of_constr_
let () = add_expr_scope "goal_matching" q_goal_matching Tac2quote.of_goal_matching
let () = add_expr_scope "format" Pcoq.Prim.lstring Tac2quote.of_format
-let () = add_generic_scope "open_constr" Pcoq.Constr.constr Tac2quote.wit_open_constr
let () = add_generic_scope "pattern" Pcoq.Constr.constr Tac2quote.wit_pattern
(** seq scope, a bit hairy *)
diff --git a/user-contrib/Ltac2/tac2quote.ml b/user-contrib/Ltac2/tac2quote.ml
index d1a72fcfd1..2d65f9ec3e 100644
--- a/user-contrib/Ltac2/tac2quote.ml
+++ b/user-contrib/Ltac2/tac2quote.ml
@@ -102,18 +102,22 @@ let of_anti f = function
let of_ident {loc;v=id} = inj_wit ?loc wit_ident id
+let quote_constr ?delimiters c =
+ let loc = Constrexpr_ops.constr_loc c in
+ Option.cata
+ (List.fold_left (fun c d ->
+ CAst.make ?loc @@ Constrexpr.CDelimiters(Id.to_string d, c))
+ c)
+ c delimiters
+
let of_constr ?delimiters c =
let loc = Constrexpr_ops.constr_loc c in
- let c = Option.cata
- (List.fold_left (fun c d ->
- CAst.make ?loc @@ Constrexpr.CDelimiters(Id.to_string d, c))
- c)
- c delimiters
- in
+ let c = quote_constr ?delimiters c in
inj_wit ?loc wit_constr c
-let of_open_constr c =
+let of_open_constr ?delimiters c =
let loc = Constrexpr_ops.constr_loc c in
+ let c = quote_constr ?delimiters c in
inj_wit ?loc wit_open_constr c
let of_bool ?loc b =
diff --git a/user-contrib/Ltac2/tac2quote.mli b/user-contrib/Ltac2/tac2quote.mli
index fcd1339cd7..6e2f548319 100644
--- a/user-contrib/Ltac2/tac2quote.mli
+++ b/user-contrib/Ltac2/tac2quote.mli
@@ -36,7 +36,7 @@ val of_ident : Id.t CAst.t -> raw_tacexpr
val of_constr : ?delimiters:Id.t list -> Constrexpr.constr_expr -> raw_tacexpr
-val of_open_constr : Constrexpr.constr_expr -> raw_tacexpr
+val of_open_constr : ?delimiters:Id.t list -> Constrexpr.constr_expr -> raw_tacexpr
val of_list : ?loc:Loc.t -> ('a -> raw_tacexpr) -> 'a list -> raw_tacexpr
diff --git a/user-contrib/Ltac2/tac2stdlib.ml b/user-contrib/Ltac2/tac2stdlib.ml
index 895b6d3975..c7dfb3e69e 100644
--- a/user-contrib/Ltac2/tac2stdlib.ml
+++ b/user-contrib/Ltac2/tac2stdlib.ml
@@ -572,3 +572,7 @@ end
let () = define_prim3 "tac_typeclasses_eauto" (option strategy) (option int) (option (list ident)) begin fun str n dbs ->
Tac2tactics.typeclasses_eauto str n dbs
end
+
+let () = define_prim2 "tac_unify" constr constr begin fun x y ->
+ Tac2tactics.unify x y
+end
diff --git a/user-contrib/Ltac2/tac2tactics.ml b/user-contrib/Ltac2/tac2tactics.ml
index 54f5a2cf68..a30f6e7945 100644
--- a/user-contrib/Ltac2/tac2tactics.ml
+++ b/user-contrib/Ltac2/tac2tactics.ml
@@ -414,6 +414,8 @@ let typeclasses_eauto strategy depth dbs =
in
Class_tactics.typeclasses_eauto ~only_classes ?strategy ~depth dbs
+let unify x y = Tactics.unify x y
+
(** Inversion *)
let inversion knd arg pat ids =
diff --git a/user-contrib/Ltac2/tac2tactics.mli b/user-contrib/Ltac2/tac2tactics.mli
index f63f7e722a..47a3fd5987 100644
--- a/user-contrib/Ltac2/tac2tactics.mli
+++ b/user-contrib/Ltac2/tac2tactics.mli
@@ -119,6 +119,8 @@ val eauto : Hints.debug -> int option -> int option -> constr thunk list ->
val typeclasses_eauto : Class_tactics.search_strategy option -> int option ->
Id.t list option -> unit Proofview.tactic
+val unify : constr -> constr -> unit tactic
+
val inversion : Inv.inversion_kind -> destruction_arg -> intro_pattern option -> Id.t list option -> unit tactic
val contradiction : constr_with_bindings option -> unit tactic
diff --git a/vernac/record.ml b/vernac/record.ml
index fccc3e4fbd..53f3508806 100644
--- a/vernac/record.ml
+++ b/vernac/record.ml
@@ -766,11 +766,9 @@ let add_inductive_class env sigma ind =
let k =
let ctx = oneind.mind_arity_ctxt in
let univs = Declareops.inductive_polymorphic_context mind in
- let env = push_context ~strict:false (Univ.AUContext.repr univs) env in
- let env = push_rel_context ctx env in
let inst = Univ.make_abstract_instance univs in
let ty = Inductive.type_of_inductive ((mind, oneind), inst) in
- let r = Inductive.relevance_of_inductive env ind in
+ let r = oneind.mind_relevance in
{ cl_univs = univs;
cl_impl = GlobRef.IndRef ind;
cl_context = ctx;