diff options
200 files changed, 3935 insertions, 3035 deletions
diff --git a/.circleci/config.yml b/.circleci/config.yml index 441d89d42..352ec5a51 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1,3 +1,7 @@ +# This file used to contain configuration to also build documentation and CoqIDE, +# run the test-suite and the validate targets, +# including with 32-bits architecture or bleeding-edge compiler. + defaults: params: ¶ms # Following parameters are used in Coq CircleCI Job (using yaml @@ -16,20 +20,8 @@ defaults: NATIVE_COMP: "yes" # some useful values - COMPILER_32BIT: &compiler-32bit "4.02.3+32bit" - - COMPILER_BLEEDING_EDGE: &compiler-be "4.06.0" - CAMLP5_VER_BLEEDING_EDGE: &camlp5-ver-be "7.03" - TIMING_PACKAGES: &timing-packages "time python" - COQIDE_PACKAGES: &coqide-packages "libgtk2.0-dev libgtksourceview2.0-dev" - #COQIDE_PACKAGES_32BIT: "libgtk2.0-dev:i386 libgtksourceview2.0-dev:i386" - COQIDE_OPAM: &coqide-opam "lablgtk-extras" - COQIDE_OPAM_BE: &coqide-opam-be "num lablgtk.2.18.6 lablgtk-extras.1.6" - COQDOC_PACKAGES: &coqdoc-packages "texlive-latex-base texlive-latex-recommended texlive-latex-extra texlive-math-extra texlive-fonts-recommended texlive-fonts-extra latex-xcolor ghostscript transfig imagemagick tipa" - COQDOC_OPAM: &coqdoc-opam "hevea" - version: 2 before_script: &before_script @@ -38,7 +30,6 @@ before_script: &before_script echo export TERM=xterm >> ~/.profile source ~/.profile printenv - #if [ "$COMPILER" = "$COMPILER_32BIT" ]; then sudo dpkg --add-architecture i386; fi if [ -n "${EXTRA_PACKAGES}" ]; then sudo apt-get update -yq && sudo apt-get install -yq --no-install-recommends ${EXTRA_PACKAGES}; fi opam-switch: &opam-switch @@ -76,7 +67,7 @@ opam-switch: &opam-switch command: | source ~/.profile opam switch -j ${NJOBS} ${COMPILER} - opam install -j ${NJOBS} -y camlp5.${CAMLP5_VER} ocamlfind ${COQIDE_OPAM} ${COQDOC_OPAM} ${EXTRA_OPAM} + opam install -j ${NJOBS} -y camlp5.${CAMLP5_VER} ocamlfind ${EXTRA_OPAM} - run: name: Clean cache command: | @@ -104,7 +95,7 @@ opam-switch: &opam-switch command: | source ~/.profile - ./configure -local -native-compiler ${NATIVE_COMP} ${EXTRA_CONF} + ./configure -local -native-compiler ${NATIVE_COMP} -coqide no - run: &build-build name: Build command: | @@ -117,53 +108,8 @@ opam-switch: &opam-switch paths: - coq/ - environment: &build-variables - <<: *envvars - EXTRA_CONF: "-coqide opt" - EXTRA_PACKAGES: *coqide-packages - -.validate-template: &validate-template - <<: *params - steps: - - run: *before_script - - attach_workspace: *attach_workspace - - run: - name: Validate - command: | - source ~/.profile - make validate environment: *envvars -.documentation-template: &documentation-template - <<: *params - steps: - - run: *before_script - - attach_workspace: *attach_workspace - - run: - name: Documentation - command: | - source ~/.profile - make -j ${NJOBS} doc - environment: &documentation-variables - <<: *envvars - EXTRA_PACKAGES: *coqdoc-packages - -.test-suite-template: &test-suite-template - <<: *params - steps: - - run: *before_script - - attach_workspace: *attach_workspace - - run: - name: Test - command: | - source ~/.profile - cd test-suite - make clean - make -j ${NJOBS} all - environment: &test-suite-variables - <<: *envvars - EXTRA_PACKAGES: *timing-packages - .ci-template: &ci-template <<: *params steps: @@ -184,84 +130,16 @@ opam-switch: &opam-switch # Defines individual jobs, see the workflows section below for job orchestration jobs: - # TODO: linter opam-boot: <<: *opam-boot-template environment: <<: *envvars - EXTRA_PACKAGES: *coqide-packages EXTRA_OPAM: "ocamlgraph ppx_tools_versioned ppx_deriving ocaml-migrate-parsetree" - opam-boot-32bit: - <<: *opam-boot-template - environment: - <<: *envvars - EXTRA_PACKAGES: "gcc-multilib" - COMPILER: *compiler-32bit - COQIDE_OPAM: "" - COQDOC_OPAM: "" - - opam-boot-be: - <<: *opam-boot-template - environment: - <<: *envvars - EXTRA_PACKAGES: *coqide-packages - COMPILER: *compiler-be - CAMLP5_VER: *camlp5-ver-be - COQIDE_OPAM: *coqide-opam-be - # Build and prepare test environment build: *build-template - build-32bit: - <<: *build-template - environment: - <<: *envvars # no coqide for 32bit - EXTRA_PACKAGES: "gcc-multilib" - COMPILER: *compiler-32bit - - build-be: - <<: *build-template - environment: - <<: *build-variables - COMPILER: *compiler-be - - validate: *validate-template - - validate-32bit: - <<: *validate-template - environment: - <<: *envvars - COMPILER: *compiler-32bit - EXTRA_PACKAGES: "gcc-multilib" - - documentation: *documentation-template - - documentation-be: - <<: *documentation-template - environment: - <<: *documentation-variables - COMPILER: *compiler-be - CAMLP5_VER: *camlp5-ver-be - - test-suite: - <<: *test-suite-template - - test-suite-32bit: - <<: *test-suite-template - environment: - <<: *test-suite-variables - COMPILER: *compiler-32bit - EXTRA_PACKAGES: "gcc-multilib time python" - - test-suite-be: - <<: *test-suite-template - environment: - <<: *test-suite-variables - COMPILER: *compiler-be - EXTRA_PACKAGES: *timing-packages - bignums: <<: *ci-template @@ -352,19 +230,14 @@ workflows: main: jobs: - opam-boot - - opam-boot-32bit - - opam-boot-be - build: requires: - opam-boot - - validate: &req-main + + - bignums: &req-main requires: - build - - test-suite: *req-main - - documentation: *req-main - - - bignums: *req-main - color: requires: - build @@ -397,19 +270,3 @@ workflows: - sf: *req-main - unimath: *req-main - vst: *req-main - - - build-32bit: - requires: - - opam-boot-32bit - - validate-32bit: &req-32bit - requires: - - build-32bit - - test-suite-32bit: *req-32bit - - - build-be: - requires: - - opam-boot-be - - test-suite-be: &req-be - requires: - - build-be - - documentation-be: *req-be diff --git a/.gitattributes b/.gitattributes index 51fa208a7..db179c8d2 100644 --- a/.gitattributes +++ b/.gitattributes @@ -2,10 +2,18 @@ .gitignore export-ignore .mailmap export-ignore -*.out -whitespace +# Because our commit hook automatically does [apply whitespace=fix] we +# disable whitespace checking for all files except those where we want +# it. Otherwise rogue global configuration and forgotten local +# configuration can break commits. +* -whitespace +# tabs are allowed in Makefiles. +Makefile* whitespace=trailing-space +tools/CoqMakefile.in whitespace=trailing-space + +# in general we don't want tabs. *.asciidoc whitespace=trailing-space,tab-in-indent -*.bat whitespace=cr-at-eol,trailing-space,tab-in-indent *.bib whitespace=trailing-space,tab-in-indent *.c whitespace=trailing-space,tab-in-indent *.css whitespace=trailing-space,tab-in-indent @@ -36,3 +44,6 @@ *.v whitespace=trailing-space,tab-in-indent *.xml whitespace=trailing-space,tab-in-indent *.yml whitespace=trailing-space,tab-in-indent + +# CR is desired for these Windows files. +*.bat whitespace=cr-at-eol,trailing-space,tab-in-indent diff --git a/.travis.yml b/.travis.yml index f4f01d2f0..9ec936b0c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -40,10 +40,10 @@ env: # system is == 4.02.3 - COMPILER="system" - COMPILER_BE="4.06.0" - - CAMLP5_VER="6.14" - - CAMLP5_VER_BE="7.03" - - FINDLIB_VER="1.4.1" - - FINDLIB_VER_BE="1.7.3" + - CAMLP5_VER=".6.14" + - CAMLP5_VER_BE=".7.03" + - FINDLIB_VER=".1.4.1" + - FINDLIB_VER_BE=".1.7.3" - LABLGTK="lablgtk.2.18.3 lablgtk-extras.1.6" - LABLGTK_BE="lablgtk.2.18.6 lablgtk-extras.1.6" - NATIVE_COMP="yes" @@ -76,6 +76,8 @@ matrix: - TEST_TARGET="ci-coquelicot" - if: NOT (type = pull_request) env: + # ppx_tools_versioned requires a specific version findlib + - FINDLIB_VER="" - TEST_TARGET="ci-elpi" EXTRA_OPAM="ppx_tools_versioned ppx_deriving ocaml-migrate-parsetree" - if: NOT (type = pull_request) env: @@ -221,7 +223,7 @@ matrix: env: - TEST_TARGET="test-suite" - COMPILER="4.02.3" - - CAMLP5_VER="6.17" + - CAMLP5_VER=".6.17" - NATIVE_COMP="no" - COQ_DEST="-local" before_install: @@ -234,7 +236,7 @@ matrix: env: - TEST_TARGET="" - COMPILER="4.02.3" - - CAMLP5_VER="6.17" + - CAMLP5_VER=".6.17" - NATIVE_COMP="no" - COQ_DEST="-prefix ${PWD}/_install" - EXTRA_CONF="-coqide opt -warn-error" @@ -264,7 +266,7 @@ install: - opam init -j ${NJOBS} --compiler=${COMPILER} -n -y - eval $(opam config env) - opam config list -- opam install -j ${NJOBS} -y camlp5.${CAMLP5_VER} ocamlfind.${FINDLIB_VER} ${EXTRA_OPAM} +- opam install -j ${NJOBS} -y camlp5${CAMLP5_VER} ocamlfind${FINDLIB_VER} ${EXTRA_OPAM} - opam list script: @@ -54,6 +54,9 @@ Tactics with let bindings in the parameters. - The tactic "dtauto" now handles some inductives such as "@sigT A (fun _ => B)" as non-dependent conjunctions. +- A bug fixed in "rewrite H in *" and "rewrite H in * |-" may cause a + few rare incompatibilities (it was unintendedly recursively + rewriting in the side conditions generated by H). Focusing @@ -108,6 +111,12 @@ Standard Library facts about them, and conversions between decimal numbers and nat, positive, N, Z, and string. +- Some deprecated aliases are now emitting warnings when used. + +Compatibility support + +- Support for compatibility with versions before 8.6 was dropped. + Changes from 8.7.1 to 8.7.2 =========================== diff --git a/Makefile.doc b/Makefile.doc index 1292f4f3f..894ef9a99 100644 --- a/Makefile.doc +++ b/Makefile.doc @@ -402,7 +402,7 @@ source-doc: mli-doc $(OCAMLDOCDIR)/coq.pdf $(OCAMLDOCDIR)/coq.tex: $(DOCMLIS:.mli=.cmi) $(SHOW)'OCAMLDOC -latex -o $@' - $(HIDE)$(OCAMLFIND) ocamldoc -latex -rectypes -I $(MYCAMLP4LIB) $(MLINCLUDES)\ + $(HIDE)$(OCAMLFIND) ocamldoc -latex -rectypes -I $(MYCAMLP5LIB) $(MLINCLUDES)\ $(DOCMLIS) -noheader -t "Coq mlis documentation" \ -intro $(OCAMLDOCDIR)/docintro -o $@.tmp $(SHOW)'OCAMLDOC utf8 fix' @@ -412,13 +412,13 @@ $(OCAMLDOCDIR)/coq.tex: $(DOCMLIS:.mli=.cmi) mli-doc: $(DOCMLIS:.mli=.cmi) $(SHOW)'OCAMLDOC -html' - $(HIDE)$(OCAMLFIND) ocamldoc -charset utf-8 -html -rectypes -I +threads -I $(MYCAMLP4LIB) $(MLINCLUDES) \ + $(HIDE)$(OCAMLFIND) ocamldoc -charset utf-8 -html -rectypes -I +threads -I $(MYCAMLP5LIB) $(MLINCLUDES) \ $(DOCMLIS) -d $(OCAMLDOCDIR)/html -colorize-code \ -t "Coq mlis documentation" -intro $(OCAMLDOCDIR)/docintro \ -css-style style.css ml-dot: $(MLFILES) - $(OCAMLFIND) ocamldoc -dot -dot-reduce -rectypes -I +threads -I $(CAMLLIB) -I $(MYCAMLP4LIB) $(MLINCLUDES) \ + $(OCAMLFIND) ocamldoc -dot -dot-reduce -rectypes -I +threads -I $(CAMLLIB) -I $(MYCAMLP5LIB) $(MLINCLUDES) \ $(filter $(addsuffix /%.ml,$(CORESRCDIRS)),$(MLFILES)) -o $(OCAMLDOCDIR)/coq.dot %_dep.png: %.dot @@ -451,7 +451,7 @@ tactics/tactics.dot: | tactics/tactics.mllib.d ltac/ltac.mllib.d $(OCAMLDOCDIR)/%.pdf: $(OCAMLDOCDIR)/%.tex $(SHOW)'PDFLATEX $*.tex' $(HIDE)(cd $(OCAMLDOCDIR) ; pdflatex -interaction=batchmode $*.tex && pdflatex -interaction=batchmode $*.tex) - $(HIDE)(cd doc/tools/; show_latex_messages -no-overfull ../../$(OCAMLDOCDIR)/$*.log) + $(HIDE)(cd doc/tools/; ./show_latex_messages -no-overfull ../../$(OCAMLDOCDIR)/$*.log) ########################################################################### # local web server diff --git a/checker/reduction.ml b/checker/reduction.ml index 53d064b08..67d00b21d 100644 --- a/checker/reduction.ml +++ b/checker/reduction.ml @@ -584,7 +584,6 @@ let dest_prod_assum env = | LetIn (x,b,t,c) -> let d = LocalDef (x,b,t) in prodec_rec (push_rel d env) (d::l) c - | Cast (c,_,_) -> prodec_rec env l c | _ -> let rty' = whd_all env rty in if Term.eq_constr rty' rty then l, rty @@ -602,7 +601,6 @@ let dest_lam_assum env = | LetIn (x,b,t,c) -> let d = LocalDef (x,b,t) in lamec_rec (push_rel d env) (d::l) c - | Cast (c,_,_) -> lamec_rec env l c | _ -> l,rty in lamec_rec env empty_rel_context diff --git a/dev/base_include b/dev/base_include index 350ccaa10..3320a2a94 100644 --- a/dev/base_include +++ b/dev/base_include @@ -196,7 +196,10 @@ let parse_tac = Pcoq.parse_string Ltac_plugin.Pltac.tactic;; (* build a term of type glob_constr without type-checking or resolution of implicit syntax *) -let e s = Constrintern.intern_constr (Global.env()) (parse_constr s);; +let e s = + let env = Global.env () in + let sigma = Evd.from_env env in + Constrintern.intern_constr env sigma (parse_constr s);; (* build a term of type constr with type-checking and resolution of implicit syntax *) @@ -229,7 +232,7 @@ let _ = Flags.in_toplevel := true let _ = Constrextern.set_extern_reference (fun ?loc _ r -> Libnames.Qualid (loc,Nametab.shortest_qualid_of_global Id.Set.empty r));; -let go () = Coqloop.loop ~time:false ~state:Option.(get !Coqtop.drop_last_doc) +let go () = Coqloop.loop ~time:false ~state:Option.(get !Coqloop.drop_last_doc) let _ = print_string diff --git a/dev/ci/user-overlays/06511-ejgallego-econstr+more_fix.sh b/dev/ci/user-overlays/06511-ejgallego-econstr+more_fix.sh new file mode 100644 index 000000000..4b681909d --- /dev/null +++ b/dev/ci/user-overlays/06511-ejgallego-econstr+more_fix.sh @@ -0,0 +1,7 @@ + if [ "$CI_PULL_REQUEST" = "6511" ] || [ "$CI_BRANCH" = "econstr+more_fix" ]; then + ltac2_CI_BRANCH=econstr+more_fix + ltac2_CI_GITURL=https://github.com/ejgallego/ltac2 + + Equations_CI_BRANCH=econstr+more_fix + Equations_CI_GITURL=https://github.com/ejgallego/Coq-Equations +fi diff --git a/dev/ci/user-overlays/06676-gares-proofview-goals-come-with-a-state.sh b/dev/ci/user-overlays/06676-gares-proofview-goals-come-with-a-state.sh new file mode 100644 index 000000000..2451657d4 --- /dev/null +++ b/dev/ci/user-overlays/06676-gares-proofview-goals-come-with-a-state.sh @@ -0,0 +1,6 @@ +if [ "$CI_PULL_REQUEST" = "6676" ] || [ "$CI_BRANCH" = "proofview/goal-w-state" ]; then + ltac2_CI_BRANCH=fix-for/6676 + ltac2_CI_GITURL=https://github.com/gares/ltac2.git + Equations_CI_BRANCH=fix-for/6676 + Equations_CI_GITURL=https://github.com/gares/Coq-Equations.git +fi diff --git a/dev/doc/build-system.txt b/dev/doc/build-system.txt index 1c4fd2eba..fd3101613 100644 --- a/dev/doc/build-system.txt +++ b/dev/doc/build-system.txt @@ -143,7 +143,9 @@ file list(s): These files are also used by the experimental ocamlbuild plugin, which is quite touchy about them : be careful with order, duplicated entries, whitespace errors, and do not mention .mli there. - - For .v, in the corresponding vo.itarget (e.g theories/Init/vo.itarget) + If module B depends on module A, then B should be after A in the .mllib + file. +- For .v, in the corresponding vo.itarget (e.g theories/Init/vo.itarget) - The definitions in Makefile.common might have to be adapted too. - If your file needs a specific rule, add it to Makefile.build diff --git a/dev/lint-commits.sh b/dev/lint-commits.sh index eb12bc227..d8043558e 100755 --- a/dev/lint-commits.sh +++ b/dev/lint-commits.sh @@ -19,14 +19,21 @@ fi BASE_COMMIT="$1" HEAD_COMMIT="$2" -# git diff --check -# uses .gitattributes to know what to check -if git diff --check "$BASE_COMMIT" "$HEAD_COMMIT"; +bad=() +while IFS= read -r commit; do + echo Checking "$commit" + # git diff --check + # uses .gitattributes to know what to check + if ! git diff --check "${commit}^" "$commit"; + then + bad+=("$commit") + fi +done < <(git rev-list "$HEAD_COMMIT" --not "$BASE_COMMIT" --) + +if [ "${#bad[@]}" != 0 ] then - : -else >&2 echo "Whitespace errors!" - >&2 echo "Running 'git diff --check $BASE_COMMIT $HEAD_COMMIT'." + >&2 echo "In commits ${bad[*]}" >&2 echo "If you use emacs, you can prevent this kind of error from reocurring by installing ws-butler and enabling ws-butler-convert-leading-tabs-or-spaces." exit 1 fi diff --git a/dev/top_printers.ml b/dev/top_printers.ml index 0c3f03d0a..74cdd788b 100644 --- a/dev/top_printers.ml +++ b/dev/top_printers.ml @@ -315,6 +315,8 @@ let constr_display csr = in pp (str (term_display csr) ++fnl ()) +let econstr_display c = constr_display EConstr.Unsafe.(to_constr c) ;; + open Format;; let print_pure_constr csr = @@ -454,6 +456,8 @@ let print_pure_constr csr = print_string (Printexc.to_string e);print_flush (); raise e +let print_pure_econstr c = print_pure_constr EConstr.Unsafe.(to_constr c) ;; + let pploc x = let (l,r) = Loc.unloc x in print_string"(";print_int l;print_string",";print_int r;print_string")" @@ -507,7 +511,7 @@ let _ = (function [c] when genarg_tag c = unquote (topwit wit_constr) && true -> let c = out_gen (rawwit wit_constr) c in - (fun ~atts ~st -> in_current_context constr_display c; st) + (fun ~atts ~st -> in_current_context econstr_display c; st) | _ -> failwith "Vernac extension: cannot occur") with e -> pp (CErrors.print e) @@ -523,7 +527,7 @@ let _ = (function [c] when genarg_tag c = unquote (topwit wit_constr) && true -> let c = out_gen (rawwit wit_constr) c in - (fun ~atts ~st -> in_current_context print_pure_constr c; st) + (fun ~atts ~st -> in_current_context print_pure_econstr c; st) | _ -> failwith "Vernac extension: cannot occur") with e -> pp (CErrors.print e) diff --git a/dev/vm_printers.ml b/dev/vm_printers.ml index f819d2e6a..2ddf927d9 100644 --- a/dev/vm_printers.ml +++ b/dev/vm_printers.ml @@ -36,6 +36,10 @@ let print_idkey idk = print_string ")" | VarKey id -> print_string (Id.to_string id) | RelKey i -> print_string "~";print_int i + | EvarKey evk -> + print_string "Evar("; + print_int (Evar.repr evk); + print_string ")" let rec ppzipper z = match z with @@ -61,7 +65,7 @@ and ppstack s = and ppatom a = match a with | Aid idk -> print_idkey idk - | Atype u -> print_string "Type(...)" + | Asort u -> print_string "Sort(...)" | Aind(sp,i) -> print_string "Ind("; print_string (MutInd.to_string sp); print_string ","; print_int i; @@ -69,7 +73,6 @@ and ppatom a = and ppwhd whd = match whd with - | Vsort s -> ppsort s | Vprod _ -> print_string "product" | Vfun _ -> print_string "function" | Vfix _ -> print_vfix() diff --git a/doc/refman/RefMan-oth.tex b/doc/refman/RefMan-oth.tex index 1cd23c929..bef31d3fa 100644 --- a/doc/refman/RefMan-oth.tex +++ b/doc/refman/RefMan-oth.tex @@ -513,6 +513,9 @@ This command loads the file named {\ident}{\tt .v}, searching successively in each of the directories specified in the {\em loadpath}. (see Section~\ref{loadpath}) +Files loaded this way cannot leave proofs open, and neither the {\tt + Load} command can be use inside a proof. + \begin{Variants} \item {\tt Load {\str}.}\label{Load-str}\\ Loads the file denoted by the string {\str}, where {\str} is any @@ -530,6 +533,8 @@ successively in each of the directories specified in the {\em \begin{ErrMsgs} \item \errindex{Can't find file {\ident} on loadpath} +\item \errindex{Load is not supported inside proofs} +\item \errindex{Files processed by Load cannot leave open proofs} \end{ErrMsgs} \section[Compiled files]{Compiled files\label{compiled}\index{Compiled files}} diff --git a/doc/refman/RefMan-tac.tex b/doc/refman/RefMan-tac.tex index 66a5f107a..6dca314b4 100644 --- a/doc/refman/RefMan-tac.tex +++ b/doc/refman/RefMan-tac.tex @@ -2904,7 +2904,7 @@ This happens if \term$_1$ does not occur in the goal. rewrite H in H2 at - 2}. In particular a failure will happen if any of these three simpler tactics fails. \item \texttt{rewrite H in * |- } will do \texttt{rewrite H in - H$_i$} for all hypothesis \texttt{H$_i$ <> H}. A success will happen + H$_i$} for all hypotheses \texttt{H$_i$} different from \texttt{H}. A success will happen as soon as at least one of these simpler tactics succeeds. \item \texttt{rewrite H in *} is a combination of \texttt{rewrite H} and \texttt{rewrite H in * |-} that succeeds if at @@ -3611,7 +3611,7 @@ $\beta$-expansion (the inverse of $\bt$-reduction) of the current goal \item applying the abstracted goal to {\term} \end{enumerate} -For instance, if the current goal $T$ is expressible has $\phi(t)$ +For instance, if the current goal $T$ is expressible as $\phi(t)$ where the notation captures all the instances of $t$ in $\phi(t)$, then {\tt pattern $t$} transforms it into {\tt (fun x:$A$ => $\phi(${\tt x}$)$) $t$}. This command can be used, for instance, when the tactic diff --git a/doc/stdlib/index-list.html.template b/doc/stdlib/index-list.html.template index 95e541f81..a2739e457 100644 --- a/doc/stdlib/index-list.html.template +++ b/doc/stdlib/index-list.html.template @@ -596,7 +596,6 @@ through the <tt>Require Import</tt> command.</p> </dt> <dd> theories/Compat/AdmitAxiom.v - theories/Compat/Coq85.v theories/Compat/Coq86.v theories/Compat/Coq87.v </dd> diff --git a/engine/eConstr.mli b/engine/eConstr.mli index b1821b4b3..36b6093d0 100644 --- a/engine/eConstr.mli +++ b/engine/eConstr.mli @@ -69,7 +69,10 @@ val kind : Evd.evar_map -> t -> (t, t, ESorts.t, EInstance.t) Constr.kind_of_ter val kind_upto : Evd.evar_map -> Constr.t -> (Constr.t, Constr.t, Sorts.t, Univ.Instance.t) Constr.kind_of_term val to_constr : Evd.evar_map -> t -> Constr.t -(** Returns the evar-normal form of the argument. See {!Evarutil.nf_evar}. *) +(** Returns the evar-normal form of the argument, and cast it as a theoretically + evar-free term. In practice this function does not check that the result + is actually evar-free, it is currently the duty of the caller to do so. + This might change in the future. *) val kind_of_type : Evd.evar_map -> t -> (t, t) Term.kind_of_type diff --git a/engine/proofview.ml b/engine/proofview.ml index be0c83577..25c8e2d80 100644 --- a/engine/proofview.ml +++ b/engine/proofview.ml @@ -35,7 +35,7 @@ type entry = (EConstr.constr * EConstr.types) list (* In this version: returns the list of focused goals together with the [evar_map] context. *) let proofview p = - p.comb , p.solution + List.map drop_state p.comb , p.solution let compact el ({ solution } as pv) = let nf c = Evarutil.nf_evar solution c in @@ -76,7 +76,7 @@ let dependent_init = let (gl, _) = EConstr.destEvar sigma econstr in let ret, { solution = sol; comb = comb } = aux (t sigma econstr) in let entry = (econstr, typ) :: ret in - entry, { solution = sol; comb = gl :: comb; shelf = [] } + entry, { solution = sol; comb = with_empty_state gl :: comb; shelf = [] } in fun t -> let entry, v = aux t in @@ -112,7 +112,7 @@ let partial_proof entry pv = CList.map (return_constr pv) (CList.map fst entry) (* First component is a reverse list of the goals which come before and second component is the list of the goals which go after (in the expected order). *) -type focus_context = Evar.t list * Evar.t list +type focus_context = goal_with_state list * goal_with_state list (** Returns a stylised view of a focus_context for use by, for @@ -122,7 +122,8 @@ type focus_context = Evar.t list * Evar.t list new nearly identical function everytime. Hence the generic name. *) (* In this version: the goals in the context, as a "zipper" (the first list is in reversed order). *) -let focus_context f = f +let focus_context (left,right) = + (List.map drop_state left, List.map drop_state right) (** This (internal) function extracts a sublist between two indices, and returns this sublist together with its context: if it returns @@ -151,21 +152,35 @@ let unfocus_sublist (left,right) s = proofview. It returns the focused proofview, and a context for the focus stack. *) let focus i j sp = - let (new_comb, context) = focus_sublist i j sp.comb in - ( { sp with comb = new_comb } , context ) + let (new_comb, (left, right)) = focus_sublist i j sp.comb in + ( { sp with comb = new_comb } , (left, right) ) + +let cleared_alias evd g = + let evk = drop_state g in + let state = get_state g in + Option.map (fun g -> goal_with_state g state) (Evarutil.advance evd evk) (** [undefined defs l] is the list of goals in [l] which are still unsolved (after advancing cleared goals). Note that order matters. *) -let undefined defs l = +let undefined_evars defs l = List.fold_right (fun evk l -> match Evarutil.advance defs evk with | Some evk -> List.add_set Evar.equal evk l | None -> l) l [] +let goal_with_state_equal x y = Evar.equal (drop_state x) (drop_state y) +let undefined defs l = + List.fold_right (fun evk l -> + match cleared_alias defs evk with + | Some evk -> List.add_set goal_with_state_equal evk l + | None -> l) l [] (** Unfocuses a proofview with respect to a context. *) -let unfocus c sp = - { sp with comb = undefined sp.solution (unfocus_sublist c sp.comb) } +let unfocus (left, right) sp = + { sp with comb = undefined sp.solution (unfocus_sublist (left, right) sp.comb) } +let with_empty_state = Proofview_monad.with_empty_state +let drop_state = Proofview_monad.drop_state +let goal_with_state = Proofview_monad.goal_with_state (** {6 The tactic monad} *) @@ -408,7 +423,8 @@ let tclFOCUSID id t = try let ev = Evd.evar_key id initial.solution in try - let n = CList.index Evar.equal ev initial.comb in + let comb = CList.map drop_state initial.comb in + let n = CList.index Evar.equal ev comb in (* goal is already under focus *) let (focused,context) = focus n n initial in Pv.set focused >> @@ -417,7 +433,7 @@ let tclFOCUSID id t = return result with Not_found -> (* otherwise, save current focus and work purely on the shelve *) - Comb.set [ev] >> + Comb.set [with_empty_state ev] >> t >>= fun result -> Comb.set initial.comb >> return result @@ -447,7 +463,7 @@ let iter_goal i = Comb.get >>= fun initial -> Proof.List.fold_left begin fun (subgoals as cur) goal -> Solution.get >>= fun step -> - match Evarutil.advance step goal with + match cleared_alias step goal with | None -> return cur | Some goal -> Comb.set [goal] >> @@ -464,7 +480,7 @@ let map_goal i = Comb.get >>= fun initial -> Proof.List.fold_left begin fun (acc, subgoals as cur) goal -> Solution.get >>= fun step -> - match Evarutil.advance step goal with + match cleared_alias step goal with | None -> return cur | Some goal -> Comb.set [goal] >> @@ -490,7 +506,7 @@ let fold_left2_goal i s l = in Proof.List.fold_left2 err begin fun ((r,subgoals) as cur) goal a -> Solution.get >>= fun step -> - match Evarutil.advance step goal with + match cleared_alias step goal with | None -> return cur | Some goal -> Comb.set [goal] >> @@ -534,7 +550,7 @@ let tclDISPATCHGEN0 join tacs = let open Proof in Pv.get >>= function | { comb=[goal] ; solution } -> - begin match Evarutil.advance solution goal with + begin match cleared_alias solution goal with | None -> tclUNIT (join []) | Some _ -> Proof.map (fun res -> join [res]) tac end @@ -626,12 +642,12 @@ let shelve = Comb.get >>= fun initial -> Comb.set [] >> InfoL.leaf (Info.Tactic (fun () -> Pp.str"shelve")) >> - Shelf.modify (fun gls -> gls @ initial) + Shelf.modify (fun gls -> gls @ CList.map drop_state initial) let shelve_goals l = let open Proof in Comb.get >>= fun initial -> - let comb = CList.filter (fun g -> not (CList.mem g l)) initial in + let comb = CList.filter (fun g -> not (CList.mem (drop_state g) l)) initial in Comb.set comb >> InfoL.leaf (Info.Tactic (fun () -> Pp.str"shelve_goals")) >> Shelf.modify (fun gls -> gls @ l) @@ -658,9 +674,27 @@ let free_evars sigma l = in List.map map l +let free_evars_with_state sigma l = + let cache = Evarutil.create_undefined_evars_cache () in + let map ev = + (** Computes the set of evars appearing in the hypotheses, the conclusion or + the body of the evar_info [evi]. Note: since we want to use it on goals, + the body is actually supposed to be empty. *) + let ev = drop_state ev in + let evi = Evd.find sigma ev in + let fevs = lazy (Evarutil.filtered_undefined_evars_of_evar_info ~cache sigma evi) in + (ev, fevs) + in + List.map map l + + (** [unifiable sigma g l] checks whether [g] appears in another subgoal of [l]. The list [l] may contain [g], but it does not affect the result. *) +let unifiable_delayed_with_state sigma g l = + let g = drop_state g in + unifiable_delayed g l + let unifiable sigma g l = let l = free_evars sigma l in unifiable_delayed g l @@ -670,8 +704,8 @@ let unifiable sigma g l = whose definition other goals of [l] depend, and [n] are the non-unifiable goals. *) let partition_unifiable sigma l = - let fevs = free_evars sigma l in - CList.partition (fun g -> unifiable_delayed g fevs) l + let fevs = free_evars_with_state sigma l in + CList.partition (fun g -> unifiable_delayed_with_state sigma g fevs) l (** Shelves the unifiable goals under focus, i.e. the goals which appear in other goals under focus (the unfocused goals are not @@ -682,7 +716,7 @@ let shelve_unifiable = let (u,n) = partition_unifiable initial.solution initial.comb in Comb.set n >> InfoL.leaf (Info.Tactic (fun () -> Pp.str"shelve_unifiable")) >> - Shelf.modify (fun gls -> gls @ u) + Shelf.modify (fun gls -> gls @ CList.map drop_state u) (** [guard_no_unifiable] returns the list of unifiable goals if some goals are unifiable (see {!shelve_unifiable}) in the current focus. *) @@ -693,13 +727,14 @@ let guard_no_unifiable = match u with | [] -> tclUNIT None | gls -> - let l = CList.map (fun g -> Evd.dependent_evar_ident g initial.solution) gls in + let l = CList.map (fun g -> Evd.dependent_evar_ident (drop_state g) initial.solution) gls in let l = CList.map (fun id -> Names.Name id) l in tclUNIT (Some l) (** [unshelve l p] adds all the goals in [l] at the end of the focused goals of p *) let unshelve l p = + let l = List.map with_empty_state l in (* advance the goals in case of clear *) let l = undefined p.solution l in { p with comb = p.comb@l } @@ -738,7 +773,7 @@ let with_shelf tac = let pgoal = Evd.principal_future_goal solution in let sigma = Evd.restore_future_goals sigma fgoals pgoal in (* Ensure we mark and return only unsolved goals *) - let gls' = undefined sigma (CList.rev_append gls' gls) in + let gls' = undefined_evars sigma (CList.rev_append gls' gls) in let sigma = CList.fold_left (mark_in_evm ~goal:false) sigma gls' in let npv = { npv with shelf; solution = sigma } in Pv.set npv >> tclUNIT (gls', ans) @@ -820,7 +855,7 @@ let give_up = Comb.set [] >> mark_as_unsafe >> InfoL.leaf (Info.Tactic (fun () -> Pp.str"give_up")) >> - Giveup.put initial + Giveup.put (CList.map drop_state initial) @@ -861,8 +896,8 @@ module Progress = struct (** Equality function on goals *) let goal_equal evars1 gl1 evars2 gl2 = - let evi1 = Evd.find evars1 gl1 in - let evi2 = Evd.find evars2 gl2 in + let evi1 = Evd.find evars1 (drop_state gl1) in + let evi2 = Evd.find evars2 (drop_state gl2) in eq_evar_info evars1 evars2 evi1 evi2 end @@ -1029,27 +1064,35 @@ module Goal = struct env : Environ.env; sigma : Evd.evar_map; concl : EConstr.constr ; + state : StateStore.t; self : Evar.t ; (* for compatibility with old-style definitions *) } let assume (gl : t) = (gl : t) + let print { sigma; self } = { Evd.it = self; sigma } + + let state { state=state } = state + let env {env} = env let sigma {sigma} = sigma let hyps {env} = EConstr.named_context env let concl {concl} = concl let extra {sigma; self} = goal_extra sigma self - let gmake_with info env sigma goal = + let gmake_with info env sigma goal state = { env = Environ.reset_with_named_context (Evd.evar_filtered_hyps info) env ; sigma = sigma ; concl = EConstr.of_constr (Evd.evar_concl info); + state = state ; self = goal } let nf_gmake env sigma goal = + let state = get_state goal in + let goal = drop_state goal in let info = Evarutil.nf_evar_info sigma (Evd.find sigma goal) in let sigma = Evd.add sigma goal info in - gmake_with info env sigma goal , sigma + gmake_with info env sigma goal state , sigma let nf_enter f = InfoL.tag (Info.Dispatch) begin @@ -1065,15 +1108,17 @@ module Goal = struct end end - let normalize { self } = + let normalize { self; state } = Env.get >>= fun env -> tclEVARMAP >>= fun sigma -> - let (gl,sigma) = nf_gmake env sigma self in + let (gl,sigma) = nf_gmake env sigma (goal_with_state self state) in tclTHEN (Unsafe.tclEVARS sigma) (tclUNIT gl) let gmake env sigma goal = + let state = get_state goal in + let goal = drop_state goal in let info = Evd.find sigma goal in - gmake_with info env sigma goal + gmake_with info env sigma goal state let enter f = let f gl = InfoL.tag (Info.DBranch) (f gl) in @@ -1106,7 +1151,7 @@ module Goal = struct Pv.get >>= fun step -> let sigma = step.solution in let map goal = - match Evarutil.advance sigma goal with + match cleared_alias sigma goal with | None -> None (** ppedrot: Is this check really necessary? *) | Some goal -> let gl = @@ -1159,25 +1204,29 @@ let tclCHECKINTERRUPT = module V82 = struct type tac = Evar.t Evd.sigma -> Evar.t list Evd.sigma - let tactic tac = + let tactic ?(nf_evars=true) tac = (* spiwack: we ignore the dependencies between goals here, expectingly preserving the semantics of <= 8.2 tactics *) (* spiwack: convenience notations, waiting for ocaml 3.12 *) let open Proof in Pv.get >>= fun ps -> try - let tac gl evd = + let tac g_w_s evd = + let g, w = drop_state g_w_s, get_state g_w_s in let glsigma = - tac { Evd.it = gl ; sigma = evd; } in + tac { Evd.it = g ; sigma = evd; } in let sigma = glsigma.Evd.sigma in - let g = glsigma.Evd.it in + let g = CList.map (fun g -> goal_with_state g w) glsigma.Evd.it in ( g, sigma ) in (* Old style tactics expect the goals normalized with respect to evars. *) - let (initgoals,initevd) = - Evd.Monad.List.map (fun g s -> goal_nf_evar s g) ps.comb ps.solution + let (initgoals_w_state, initevd) = + Evd.Monad.List.map (fun g_w_s s -> + let g, w = drop_state g_w_s, get_state g_w_s in + let g, s = if nf_evars then goal_nf_evar s g else g, s in + goal_with_state g w, s) ps.comb ps.solution in - let (goalss,evd) = Evd.Monad.List.map tac initgoals initevd in + let (goalss,evd) = Evd.Monad.List.map tac initgoals_w_state initevd in let sgs = CList.flatten goalss in let sgs = undefined evd sgs in InfoL.leaf (Info.Tactic (fun () -> Pp.str"<unknown>")) >> @@ -1192,8 +1241,9 @@ module V82 = struct let nf_evar_goals = Pv.modify begin fun ps -> let map g s = goal_nf_evar s g in - let (goals,evd) = Evd.Monad.List.map map ps.comb ps.solution in - { ps with solution = evd; comb = goals; } + let comb = CList.map drop_state ps.comb in + let (_goals,evd) = Evd.Monad.List.map map comb ps.solution in + { ps with solution = evd; } end let has_unresolved_evar pv = @@ -1203,14 +1253,14 @@ module V82 = struct let grab pv = let undef = Evd.undefined_map pv.solution in let goals = CList.rev_map fst (Evar.Map.bindings undef) in - { pv with comb = goals } + { pv with comb = List.map with_empty_state goals } (* Returns the open goals of the proofview together with the evar_map to interpret them. *) let goals { comb = comb ; solution = solution; } = - { Evd.it = comb ; sigma = solution } + { Evd.it = List.map drop_state comb ; sigma = solution } let top_goals initial { solution=solution; } = let goals = CList.map (fun (t,_) -> fst (Constr.destEvar (EConstr.Unsafe.to_constr t))) initial in @@ -1224,9 +1274,9 @@ module V82 = struct let of_tactic t gls = try - let init = { shelf = []; solution = gls.Evd.sigma ; comb = [gls.Evd.it] } in + let init = { shelf = []; solution = gls.Evd.sigma ; comb = [with_empty_state gls.Evd.it] } in let (_,final,_,_) = apply (goal_env gls.Evd.sigma gls.Evd.it) t init in - { Evd.sigma = final.solution ; it = final.comb } + { Evd.sigma = final.solution ; it = CList.map drop_state final.comb } with Logic_monad.TacticFailure e as src -> let (_, info) = CErrors.push src in iraise (e, info) diff --git a/engine/proofview.mli b/engine/proofview.mli index c106133ee..486279187 100644 --- a/engine/proofview.mli +++ b/engine/proofview.mli @@ -74,7 +74,15 @@ val return : proofview -> Evd.evar_map val partial_proof : entry -> proofview -> constr list val initial_goals : entry -> (constr * types) list +(** goal <-> goal_with_state *) +val with_empty_state : + Proofview_monad.goal -> Proofview_monad.goal_with_state +val drop_state : + Proofview_monad.goal_with_state -> Proofview_monad.goal +val goal_with_state : + Proofview_monad.goal -> Proofview_monad.StateStore.t -> + Proofview_monad.goal_with_state (** {6 Focusing commands} *) @@ -418,14 +426,14 @@ module Unsafe : sig (** [tclNEWGOALS gls] adds the goals [gls] to the ones currently being proved, appending them to the list of focused goals. If a goal is already solved, it is not added. *) - val tclNEWGOALS : Evar.t list -> unit tactic + val tclNEWGOALS : Proofview_monad.goal_with_state list -> unit tactic (** [tclSETGOALS gls] sets goals [gls] as the goals being under focus. If a goal is already solved, it is not set. *) - val tclSETGOALS : Evar.t list -> unit tactic + val tclSETGOALS : Proofview_monad.goal_with_state list -> unit tactic (** [tclGETGOALS] returns the list of goals under focus. *) - val tclGETGOALS : Evar.t list tactic + val tclGETGOALS : Proofview_monad.goal_with_state list tactic (** Sets the evar universe context. *) val tclEVARUNIVCONTEXT : UState.t -> unit tactic @@ -482,6 +490,7 @@ module Goal : sig val env : t -> Environ.env val sigma : t -> Evd.evar_map val extra : t -> Evd.Store.t + val state : t -> Proofview_monad.StateStore.t (** [nf_enter t] applies the goal-dependent tactic [t] in each goal independently, in the manner of {!tclINDEPENDENT} except that @@ -506,6 +515,7 @@ module Goal : sig (** Compatibility: avoid if possible *) val goal : t -> Evar.t + val print : t -> Goal.goal Evd.sigma end @@ -542,7 +552,10 @@ val tclLIFT : 'a NonLogical.t -> 'a tactic (*** Compatibility layer with <= 8.2 tactics ***) module V82 : sig type tac = Evar.t Evd.sigma -> Evar.t list Evd.sigma - val tactic : tac -> unit tactic + + (* [nf_evars=true] applies the evar (assignment) map to the goals + * (conclusion and context) before calling the tactic *) + val tactic : ?nf_evars:bool -> tac -> unit tactic (* normalises the evars in the goals, and stores the result in solution. *) diff --git a/engine/proofview_monad.ml b/engine/proofview_monad.ml index c9182746d..52bcabf95 100644 --- a/engine/proofview_monad.ml +++ b/engine/proofview_monad.ml @@ -151,13 +151,25 @@ module Info = struct CList.map_append (collapse_tree n) f end +module StateStore = Store.Make(struct end) + +(* let (set_state, get_state) = StateDyn.Easy.make_dyn "goal_state" *) + +type goal = Evar.t +type goal_with_state = Evar.t * StateStore.t + +let drop_state = fst +let get_state = snd +let goal_with_state g s = (g, s) +let with_empty_state g = (g, StateStore.empty) +let map_goal_with_state f (g, s) = (f g, s) (** Type of proof views: current [evar_map] together with the list of focused goals. *) type proofview = { solution : Evd.evar_map; - comb : Evar.t list; - shelf : Evar.t list; + comb : goal_with_state list; + shelf : goal list; } (** {6 Instantiation of the logic monad} *) @@ -171,7 +183,7 @@ module P = struct type e = bool (** Status (safe/unsafe) * shelved goals * given up *) - type w = bool * Evar.t list + type w = bool * goal list let wunit = true , [] let wprod (b1, g1) (b2, g2) = b1 && b2 , g1@g2 @@ -211,9 +223,9 @@ module Solution : State with type t := Evd.evar_map = struct let modify f = Pv.modify (fun pv -> { pv with solution = f pv.solution }) end -module Comb : State with type t = Evar.t list = struct +module Comb : State with type t = goal_with_state list = struct (* spiwack: I don't know why I cannot substitute ([:=]) [t] with a type expression. *) - type t = Evar.t list + type t = goal_with_state list let get = Logical.map (fun {comb} -> comb) Pv.get let set c = Pv.modify (fun pv -> { pv with comb = c }) let modify f = Pv.modify (fun pv -> { pv with comb = f pv.comb }) @@ -229,17 +241,17 @@ module Status : Writer with type t := bool = struct let put s = Logical.put (s, []) end -module Shelf : State with type t = Evar.t list = struct +module Shelf : State with type t = goal list = struct (* spiwack: I don't know why I cannot substitute ([:=]) [t] with a type expression. *) - type t = Evar.t list + type t = goal list let get = Logical.map (fun {shelf} -> shelf) Pv.get let set c = Pv.modify (fun pv -> { pv with shelf = c }) let modify f = Pv.modify (fun pv -> { pv with shelf = f pv.shelf }) end -module Giveup : Writer with type t = Evar.t list = struct +module Giveup : Writer with type t = goal list = struct (* spiwack: I don't know why I cannot substitute ([:=]) [t] with a type expression. *) - type t = Evar.t list + type t = goal list let put gs = Logical.put (true, gs) end diff --git a/engine/proofview_monad.mli b/engine/proofview_monad.mli index 66293d6e4..9d7524217 100644 --- a/engine/proofview_monad.mli +++ b/engine/proofview_monad.mli @@ -69,12 +69,21 @@ module Info : sig end +module StateStore : Store.S +type goal = Evar.t +type goal_with_state +val drop_state : goal_with_state -> goal +val get_state : goal_with_state -> StateStore.t +val goal_with_state : goal -> StateStore.t -> goal_with_state +val with_empty_state : goal -> goal_with_state +val map_goal_with_state : (goal -> goal) -> goal_with_state -> goal_with_state + (** Type of proof views: current [evar_map] together with the list of focused goals. *) type proofview = { solution : Evd.evar_map; - comb : Evar.t list; - shelf : Evar.t list; + comb : goal_with_state list; + shelf : goal list; } (** {6 Instantiation of the logic monad} *) @@ -83,7 +92,7 @@ module P : sig type s = proofview * Environ.env (** Status (safe/unsafe) * given up *) - type w = bool * Evar.t list + type w = bool * goal list val wunit : w val wprod : w -> w -> w @@ -120,7 +129,7 @@ module Pv : State with type t := proofview module Solution : State with type t := Evd.evar_map (** Lens to the list of focused goals. *) -module Comb : State with type t = Evar.t list +module Comb : State with type t = goal_with_state list (** Lens to the global environment. *) module Env : State with type t := Environ.env @@ -130,11 +139,11 @@ module Status : Writer with type t := bool (** Lens to the list of goals which have been shelved during the execution of the tactic. *) -module Shelf : State with type t = Evar.t list +module Shelf : State with type t = goal list (** Lens to the list of goals which were given up during the execution of the tactic. *) -module Giveup : Writer with type t = Evar.t list +module Giveup : Writer with type t = goal list (** Lens and utilies pertaining to the info trace *) module InfoL : sig diff --git a/engine/termops.ml b/engine/termops.ml index 57412e9f6..c615155d1 100644 --- a/engine/termops.ml +++ b/engine/termops.ml @@ -799,9 +799,9 @@ let fold_constr_with_binders sigma g f n acc c = each binder traversal; it is not recursive and the order with which subterms are processed is not specified *) -let iter_constr_with_full_binders g f l c = +let iter_constr_with_full_binders sigma g f l c = let open RelDecl in - match kind c with + match EConstr.kind sigma c with | (Rel _ | Meta _ | Var _ | Sort _ | Const _ | Ind _ | Construct _) -> () | Cast (c,_, t) -> f l c; f l t diff --git a/engine/termops.mli b/engine/termops.mli index 10af007cd..ef3cb91be 100644 --- a/engine/termops.mli +++ b/engine/termops.mli @@ -78,9 +78,10 @@ val fold_constr_with_full_binders : Evd.evar_map -> (Context.Rel.Declaration.t -> 'a -> 'a) -> ('a -> 'b -> constr -> 'b) -> 'a -> 'b -> constr -> 'b -val iter_constr_with_full_binders : - (Context.Rel.Declaration.t -> 'a -> 'a) -> ('a -> Constr.constr -> unit) -> 'a -> - Constr.constr -> unit +val iter_constr_with_full_binders : Evd.evar_map -> + (rel_declaration -> 'a -> 'a) -> + ('a -> constr -> unit) -> 'a -> + constr -> unit (**********************************************************************) diff --git a/ide/ide_slave.ml b/ide/ide_slave.ml index efbf668a4..0ba1b3a4f 100644 --- a/ide/ide_slave.ml +++ b/ide/ide_slave.ml @@ -283,7 +283,7 @@ let pattern_of_string ?env s = | Some e -> e in let constr = Pcoq.parse_string Pcoq.Constr.lconstr_pattern s in - let (_, pat) = Constrintern.intern_constr_pattern env constr in + let (_, pat) = Constrintern.intern_constr_pattern env Evd.empty constr in pat let dirpath_of_string_list s = diff --git a/interp/constrintern.ml b/interp/constrintern.ml index 5df926de7..84162ca89 100644 --- a/interp/constrintern.ml +++ b/interp/constrintern.ml @@ -186,14 +186,14 @@ let compute_explicitable_implicit imps = function (* Unable to know in advance what the implicit arguments will be *) [] -let compute_internalization_data env ty typ impl = - let impl = compute_implicits_with_manual env typ (is_implicit_args()) impl in +let compute_internalization_data env sigma ty typ impl = + let impl = compute_implicits_with_manual env sigma typ (is_implicit_args()) impl in let expls_impl = compute_explicitable_implicit impl ty in - (ty, expls_impl, impl, compute_arguments_scope typ) + (ty, expls_impl, impl, compute_arguments_scope sigma typ) -let compute_internalization_env env ?(impls=empty_internalization_env) ty = +let compute_internalization_env env sigma ?(impls=empty_internalization_env) ty = List.fold_left3 - (fun map id typ impl -> Id.Map.add id (compute_internalization_data env ty typ impl) map) + (fun map id typ impl -> Id.Map.add id (compute_internalization_data env sigma ty typ impl) map) impls (**********************************************************************) @@ -2209,9 +2209,9 @@ let extract_ids env = (Termops.ids_of_rel_context (Environ.rel_context env)) Id.Set.empty -let scope_of_type_kind = function +let scope_of_type_kind sigma = function | IsType -> Notation.current_type_scope_name () - | OfType typ -> compute_type_scope (EConstr.Unsafe.to_constr typ) + | OfType typ -> compute_type_scope sigma typ | WithoutTypeConstraint -> None let empty_ltac_sign = { @@ -2220,19 +2220,17 @@ let empty_ltac_sign = { ltac_extra = Genintern.Store.empty; } -let intern_gen kind env +let intern_gen kind env sigma ?(impls=empty_internalization_env) ?(pattern_mode=false) ?(ltacvars=empty_ltac_sign) c = - let tmp_scope = scope_of_type_kind kind in + let tmp_scope = scope_of_type_kind sigma kind in internalize env {ids = extract_ids env; unb = false; tmp_scope = tmp_scope; scopes = []; impls = impls} pattern_mode (ltacvars, Id.Map.empty) c -let intern_constr env c = intern_gen WithoutTypeConstraint env c - -let intern_type env c = intern_gen IsType env c - +let intern_constr env sigma c = intern_gen WithoutTypeConstraint env sigma c +let intern_type env sigma c = intern_gen IsType env sigma c let intern_pattern globalenv patt = try intern_cases_pattern globalenv Id.Map.empty (None,[]) empty_alias patt @@ -2247,7 +2245,7 @@ let intern_pattern globalenv patt = (* All evars resolved *) let interp_gen kind env sigma ?(impls=empty_internalization_env) c = - let c = intern_gen kind ~impls env c in + let c = intern_gen kind ~impls env sigma c in understand ~expected_type:kind env sigma c let interp_constr env sigma ?(impls=empty_internalization_env) c = @@ -2262,13 +2260,13 @@ let interp_casted_constr env sigma ?(impls=empty_internalization_env) c typ = (* Not all evars expected to be resolved *) let interp_open_constr env sigma c = - understand_tcc env sigma (intern_constr env c) + understand_tcc env sigma (intern_constr env sigma c) (* Not all evars expected to be resolved and computation of implicit args *) let interp_constr_evars_gen_impls env sigma ?(impls=empty_internalization_env) expected_type c = - let c = intern_gen expected_type ~impls env c in + let c = intern_gen expected_type ~impls env sigma c in let imps = Implicit_quantifiers.implicits_of_glob_constr ~with_products:(expected_type == IsType) c in let sigma, c = understand_tcc env sigma ~expected_type c in sigma, (c, imps) @@ -2285,7 +2283,7 @@ let interp_type_evars_impls env sigma ?(impls=empty_internalization_env) c = (* Not all evars expected to be resolved, with side-effect on evars *) let interp_constr_evars_gen env sigma ?(impls=empty_internalization_env) expected_type c = - let c = intern_gen expected_type ~impls env c in + let c = intern_gen expected_type ~impls env sigma c in understand_tcc env sigma ~expected_type c let interp_constr_evars env evdref ?(impls=empty_internalization_env) c = @@ -2299,9 +2297,9 @@ let interp_type_evars env sigma ?(impls=empty_internalization_env) c = (* Miscellaneous *) -let intern_constr_pattern env ?(as_type=false) ?(ltacvars=empty_ltac_sign) c = +let intern_constr_pattern env sigma ?(as_type=false) ?(ltacvars=empty_ltac_sign) c = let c = intern_gen (if as_type then IsType else WithoutTypeConstraint) - ~pattern_mode:true ~ltacvars env c in + ~pattern_mode:true ~ltacvars env sigma c in pattern_of_glob_constr c let interp_notation_constr env ?(impls=empty_internalization_env) nenv a = @@ -2325,16 +2323,14 @@ let interp_notation_constr env ?(impls=empty_internalization_env) nenv a = (* Interpret binders and contexts *) let interp_binder env sigma na t = - let t = intern_gen IsType env t in + let t = intern_gen IsType env sigma t in let t' = locate_if_hole ?loc:(loc_of_glob_constr t) na t in understand ~expected_type:IsType env sigma t' -let interp_binder_evars env evdref na t = - let t = intern_gen IsType env t in +let interp_binder_evars env sigma na t = + let t = intern_gen IsType env sigma t in let t' = locate_if_hole ?loc:(loc_of_glob_constr t) na t in - let evd, c = understand_tcc env !evdref ~expected_type:IsType t' in - evdref := evd; - c + understand_tcc env sigma ~expected_type:IsType t' let my_intern_constr env lvar acc c = internalize env acc false lvar c diff --git a/interp/constrintern.mli b/interp/constrintern.mli index 48f07536a..f5e32dc4c 100644 --- a/interp/constrintern.mli +++ b/interp/constrintern.mli @@ -9,17 +9,17 @@ (************************************************************************) open Names -open Constr open Evd open Environ +open Misctypes open Libnames open Globnames open Glob_term open Pattern +open EConstr open Constrexpr open Notation_term open Pretyping -open Misctypes (** Translation from front abstract syntax of term to untyped terms (glob_constr) *) @@ -60,10 +60,10 @@ type internalization_env = var_internalization_data Id.Map.t val empty_internalization_env : internalization_env -val compute_internalization_data : env -> var_internalization_type -> +val compute_internalization_data : env -> evar_map -> var_internalization_type -> types -> Impargs.manual_explicitation list -> var_internalization_data -val compute_internalization_env : env -> ?impls:internalization_env -> var_internalization_type -> +val compute_internalization_env : env -> evar_map -> ?impls:internalization_env -> var_internalization_type -> Id.t list -> types list -> Impargs.manual_explicitation list list -> internalization_env @@ -80,11 +80,10 @@ val empty_ltac_sign : ltac_sign (** {6 Internalization performs interpretation of global names and notations } *) -val intern_constr : env -> constr_expr -> glob_constr - -val intern_type : env -> constr_expr -> glob_constr +val intern_constr : env -> evar_map -> constr_expr -> glob_constr +val intern_type : env -> evar_map -> constr_expr -> glob_constr -val intern_gen : typing_constraint -> env -> +val intern_gen : typing_constraint -> env -> evar_map -> ?impls:internalization_env -> ?pattern_mode:bool -> ?ltacvars:ltac_sign -> constr_expr -> glob_constr @@ -102,7 +101,7 @@ val interp_constr : env -> evar_map -> ?impls:internalization_env -> constr_expr -> constr Evd.in_evar_universe_context val interp_casted_constr : env -> evar_map -> ?impls:internalization_env -> - constr_expr -> EConstr.types -> constr Evd.in_evar_universe_context + constr_expr -> types -> constr Evd.in_evar_universe_context val interp_type : env -> evar_map -> ?impls:internalization_env -> constr_expr -> types Evd.in_evar_universe_context @@ -110,37 +109,37 @@ val interp_type : env -> evar_map -> ?impls:internalization_env -> (** Main interpretation function expecting all postponed problems to be resolved, but possibly leaving evars. *) -val interp_open_constr : env -> evar_map -> constr_expr -> evar_map * EConstr.constr +val interp_open_constr : env -> evar_map -> constr_expr -> evar_map * constr (** Accepting unresolved evars *) val interp_constr_evars : env -> evar_map -> - ?impls:internalization_env -> constr_expr -> evar_map * EConstr.constr + ?impls:internalization_env -> constr_expr -> evar_map * constr val interp_casted_constr_evars : env -> evar_map -> - ?impls:internalization_env -> constr_expr -> EConstr.types -> evar_map * EConstr.constr + ?impls:internalization_env -> constr_expr -> types -> evar_map * constr val interp_type_evars : env -> evar_map -> - ?impls:internalization_env -> constr_expr -> evar_map * EConstr.types + ?impls:internalization_env -> constr_expr -> evar_map * types (** Accepting unresolved evars and giving back the manual implicit arguments *) val interp_constr_evars_impls : env -> evar_map -> ?impls:internalization_env -> constr_expr -> - evar_map * (EConstr.constr * Impargs.manual_implicits) + evar_map * (constr * Impargs.manual_implicits) val interp_casted_constr_evars_impls : env -> evar_map -> - ?impls:internalization_env -> constr_expr -> EConstr.types -> - evar_map * (EConstr.constr * Impargs.manual_implicits) + ?impls:internalization_env -> constr_expr -> types -> + evar_map * (constr * Impargs.manual_implicits) val interp_type_evars_impls : env -> evar_map -> ?impls:internalization_env -> constr_expr -> - evar_map * (EConstr.types * Impargs.manual_implicits) + evar_map * (types * Impargs.manual_implicits) (** Interprets constr patterns *) val intern_constr_pattern : - env -> ?as_type:bool -> ?ltacvars:ltac_sign -> + env -> evar_map -> ?as_type:bool -> ?ltacvars:ltac_sign -> constr_pattern_expr -> patvar list * constr_pattern (** Raise Not_found if syndef not bound to a name and error if unexisting ref *) @@ -154,14 +153,14 @@ val interp_reference : ltac_sign -> reference -> glob_constr val interp_binder : env -> evar_map -> Name.t -> constr_expr -> types Evd.in_evar_universe_context -val interp_binder_evars : env -> evar_map ref -> Name.t -> constr_expr -> EConstr.types +val interp_binder_evars : env -> evar_map -> Name.t -> constr_expr -> evar_map * types (** Interpret contexts: returns extended env and context *) val interp_context_evars : ?global_level:bool -> ?impl_env:internalization_env -> ?shift:int -> env -> evar_map -> local_binder_expr list -> - evar_map * (internalization_env * ((env * EConstr.rel_context) * Impargs.manual_implicits)) + evar_map * (internalization_env * ((env * rel_context) * Impargs.manual_implicits)) (* val interp_context_gen : (env -> glob_constr -> unsafe_type_judgment Evd.in_evar_universe_context) -> *) (* (env -> Evarutil.type_constraint -> glob_constr -> unsafe_judgment Evd.in_evar_universe_context) -> *) diff --git a/interp/declare.ml b/interp/declare.ml index a5f537513..7dd73fbb5 100644 --- a/interp/declare.ml +++ b/interp/declare.ml @@ -137,7 +137,7 @@ let set_declare_scheme f = declare_scheme := f let update_tables c = declare_constant_implicits c; Heads.declare_head (EvalConstRef c); - Notation.declare_ref_arguments_scope (ConstRef c) + Notation.declare_ref_arguments_scope Evd.empty (ConstRef c) let register_side_effect (c, role) = let o = inConstant { @@ -277,7 +277,7 @@ let inVariable : variable_obj -> obj = let declare_variable id obj = let oname = add_leaf id (inVariable (Inr (id,obj))) in declare_var_implicits id; - Notation.declare_ref_arguments_scope (VarRef id); + Notation.declare_ref_arguments_scope Evd.empty (VarRef id); Heads.declare_head (EvalVarRef id); oname @@ -285,9 +285,9 @@ let declare_variable id obj = let declare_inductive_argument_scopes kn mie = List.iteri (fun i {mind_entry_consnames=lc} -> - Notation.declare_ref_arguments_scope (IndRef (kn,i)); + Notation.declare_ref_arguments_scope Evd.empty (IndRef (kn,i)); for j=1 to List.length lc do - Notation.declare_ref_arguments_scope (ConstructRef ((kn,i),j)); + Notation.declare_ref_arguments_scope Evd.empty (ConstructRef ((kn,i),j)); done) mie.mind_entry_inds let inductive_names sp kn mie = diff --git a/interp/impargs.ml b/interp/impargs.ml index 519224c4f..9ad62c0de 100644 --- a/interp/impargs.ml +++ b/interp/impargs.ml @@ -9,21 +9,20 @@ (************************************************************************) open CErrors +open Pp open Util open Names -open Globnames open Constr -open Reduction +open Globnames open Declarations -open Environ -open Libobject +open Decl_kinds open Lib -open Pp -open Constrexpr +open Libobject +open EConstr open Termops +open Reductionops +open Constrexpr open Namegen -open Decl_kinds -open Context.Named.Declaration module NamedDecl = Context.Named.Declaration @@ -167,8 +166,8 @@ let update pos rig (na,st) = in na, Some e (* modified is_rigid_reference with a truncated env *) -let is_flexible_reference env bound depth f = - match kind f with +let is_flexible_reference env sigma bound depth f = + match kind sigma f with | Rel n when n >= bound+depth -> (* inductive type *) false | Rel n when n >= depth -> (* previous argument *) true | Rel n -> (* since local definitions have been expanded *) false @@ -176,102 +175,101 @@ let is_flexible_reference env bound depth f = let cb = Environ.lookup_constant kn env in (match cb.const_body with Def _ -> true | _ -> false) | Var id -> - env |> Environ.lookup_named id |> is_local_def + env |> Environ.lookup_named id |> NamedDecl.is_local_def | Ind _ | Construct _ -> false | _ -> true let push_lift d (e,n) = (push_rel d e,n+1) -let is_reversible_pattern bound depth f l = - isRel f && let n = destRel f in (n < bound+depth) && (n >= depth) && - Array.for_all (fun c -> isRel c && destRel c < depth) l && +let is_reversible_pattern sigma bound depth f l = + isRel sigma f && let n = destRel sigma f in (n < bound+depth) && (n >= depth) && + Array.for_all (fun c -> isRel sigma c && destRel sigma c < depth) l && Array.distinct l (* Precondition: rels in env are for inductive types only *) -let add_free_rels_until strict strongly_strict revpat bound env m pos acc = +let add_free_rels_until strict strongly_strict revpat bound env sigma m pos acc = let rec frec rig (env,depth as ed) c = - let hd = if strict then whd_all env c else c in + let hd = if strict then whd_all env sigma c else c in let c = if strongly_strict then hd else c in - match kind hd with + match kind sigma hd with | Rel n when (n < bound+depth) && (n >= depth) -> let i = bound + depth - n - 1 in acc.(i) <- update pos rig acc.(i) - | App (f,l) when revpat && is_reversible_pattern bound depth f l -> - let i = bound + depth - destRel f - 1 in + | App (f,l) when revpat && is_reversible_pattern sigma bound depth f l -> + let i = bound + depth - EConstr.destRel sigma f - 1 in acc.(i) <- update pos rig acc.(i) - | App (f,_) when rig && is_flexible_reference env bound depth f -> + | App (f,_) when rig && is_flexible_reference env sigma bound depth f -> if strict then () else - iter_constr_with_full_binders push_lift (frec false) ed c + iter_constr_with_full_binders sigma push_lift (frec false) ed c | Proj (p,c) when rig -> if strict then () else - iter_constr_with_full_binders push_lift (frec false) ed c + iter_constr_with_full_binders sigma push_lift (frec false) ed c | Case _ when rig -> if strict then () else - iter_constr_with_full_binders push_lift (frec false) ed c + iter_constr_with_full_binders sigma push_lift (frec false) ed c | Evar _ -> () | _ -> - iter_constr_with_full_binders push_lift (frec rig) ed c + iter_constr_with_full_binders sigma push_lift (frec rig) ed c in - let () = if not (Vars.noccur_between 1 bound m) then frec true (env,1) m in + let () = if not (Vars.noccur_between sigma 1 bound m) then frec true (env,1) m in acc -let rec is_rigid_head t = match kind t with +let rec is_rigid_head sigma t = match kind sigma t with | Rel _ | Evar _ -> false | Ind _ | Const _ | Var _ | Sort _ -> true - | Case (_,_,f,_) -> is_rigid_head f + | Case (_,_,f,_) -> is_rigid_head sigma f | Proj (p,c) -> true | App (f,args) -> - (match kind f with - | Fix ((fi,i),_) -> is_rigid_head (args.(fi.(i))) - | _ -> is_rigid_head f) + (match kind sigma f with + | Fix ((fi,i),_) -> is_rigid_head sigma (args.(fi.(i))) + | _ -> is_rigid_head sigma f) | Lambda _ | LetIn _ | Construct _ | CoFix _ | Fix _ | Prod _ | Meta _ | Cast _ -> assert false (* calcule la liste des arguments implicites *) let find_displayed_name_in all avoid na (env, b) = - let b = EConstr.of_constr b in let envnames_b = (env, b) in let flag = RenamingElsewhereFor envnames_b in if all then compute_and_force_displayed_name_in Evd.empty flag avoid na b else compute_displayed_name_in Evd.empty flag avoid na b -let compute_implicits_gen strict strongly_strict revpat contextual all env t = +let compute_implicits_gen strict strongly_strict revpat contextual all env sigma (t : EConstr.t) = let rigid = ref true in let open Context.Rel.Declaration in - let rec aux env avoid n names t = - let t = whd_all env t in - match kind t with + let rec aux env avoid n names (t : EConstr.t) = + let t = whd_all env sigma t in + match kind sigma t with | Prod (na,a,b) -> let na',avoid' = find_displayed_name_in all avoid na (names,b) in - add_free_rels_until strict strongly_strict revpat n env a (Hyp (n+1)) + add_free_rels_until strict strongly_strict revpat n env sigma a (Hyp (n+1)) (aux (push_rel (LocalAssum (na',a)) env) avoid' (n+1) (na'::names) b) | _ -> - rigid := is_rigid_head t; + rigid := is_rigid_head sigma t; let names = List.rev names in let v = Array.map (fun na -> na,None) (Array.of_list names) in if contextual then - add_free_rels_until strict strongly_strict revpat n env t Conclusion v + add_free_rels_until strict strongly_strict revpat n env sigma t Conclusion v else v in - match kind (whd_all env t) with + match kind sigma (whd_all env sigma t) with | Prod (na,a,b) -> let na',avoid = find_displayed_name_in all Id.Set.empty na ([],b) in let v = aux (push_rel (LocalAssum (na',a)) env) avoid 1 [na'] b in !rigid, Array.to_list v | _ -> true, [] -let compute_implicits_flags env f all t = +let compute_implicits_flags env sigma f all t = compute_implicits_gen (f.strict || f.strongly_strict) f.strongly_strict - f.reversible_pattern f.contextual all env t + f.reversible_pattern f.contextual all env sigma t -let compute_auto_implicits env flags enriching t = - if enriching then compute_implicits_flags env flags true t - else compute_implicits_gen false false false true true env t +let compute_auto_implicits env sigma flags enriching t = + if enriching then compute_implicits_flags env sigma flags true t + else compute_implicits_gen false false false true true env sigma t -let compute_implicits_names env t = - let _, impls = compute_implicits_gen false false false false true env t in +let compute_implicits_names env sigma t = + let _, impls = compute_implicits_gen false false false false true env sigma t in List.map fst impls (* Extra information about implicit arguments *) @@ -400,24 +398,25 @@ let set_manual_implicits env flags enriching autoimps l = in merge 1 l autoimps -let compute_semi_auto_implicits env f manual t = +let compute_semi_auto_implicits env sigma f manual t = match manual with | [] -> if not f.auto then [DefaultImpArgs, []] - else let _,l = compute_implicits_flags env f false t in + else let _,l = compute_implicits_flags env sigma f false t in [DefaultImpArgs, prepare_implicits f l] | _ -> - let _,autoimpls = compute_auto_implicits env f f.auto t in + let _,autoimpls = compute_auto_implicits env sigma f f.auto t in [DefaultImpArgs, set_manual_implicits env f f.auto autoimpls manual] (*s Constants. *) let compute_constant_implicits flags manual cst = let env = Global.env () in + let sigma = Evd.from_env env in let cb = Environ.lookup_constant cst env in - let ty = cb.const_type in - let impls = compute_semi_auto_implicits env flags manual ty in - impls + let ty = of_constr cb.const_type in + let impls = compute_semi_auto_implicits env sigma flags manual ty in + impls (*s Inductives and constructors. Their implicit arguments are stored in an array, indexed by the inductive number, of pairs $(i,v)$ where @@ -426,7 +425,8 @@ let compute_constant_implicits flags manual cst = let compute_mib_implicits flags manual kn = let env = Global.env () in - let mib = lookup_mind kn env in + let sigma = Evd.from_env env in + let mib = Environ.lookup_mind kn env in let ar = Array.to_list (Array.mapi (* No need to lift, arities contain no de Bruijn *) @@ -435,14 +435,14 @@ let compute_mib_implicits flags manual kn = let ty, _ = Global.type_of_global_in_context env (IndRef (kn,i)) in Context.Rel.Declaration.LocalAssum (Name mip.mind_typename, ty)) mib.mind_packets) in - let env_ar = push_rel_context ar env in + let env_ar = Environ.push_rel_context ar env in let imps_one_inductive i mip = let ind = (kn,i) in let ar, _ = Global.type_of_global_in_context env (IndRef ind) in - ((IndRef ind,compute_semi_auto_implicits env flags manual ar), + ((IndRef ind,compute_semi_auto_implicits env sigma flags manual (of_constr ar)), Array.mapi (fun j c -> - (ConstructRef (ind,j+1),compute_semi_auto_implicits env_ar flags manual c)) - mip.mind_nf_lc) + (ConstructRef (ind,j+1),compute_semi_auto_implicits env_ar sigma flags manual c)) + (Array.map of_constr mip.mind_nf_lc)) in Array.mapi imps_one_inductive mib.mind_packets @@ -455,7 +455,8 @@ let compute_all_mib_implicits flags manual kn = let compute_var_implicits flags manual id = let env = Global.env () in - compute_semi_auto_implicits env flags manual (NamedDecl.get_type (lookup_named id env)) + let sigma = Evd.from_env env in + compute_semi_auto_implicits env sigma flags manual (NamedDecl.get_type (lookup_named id env)) (* Implicits of a global reference. *) @@ -526,7 +527,7 @@ let impls_of_context ctx = | Implicit -> Some (NamedDecl.get_id decl, Manual, (true, true)) | _ -> None in - List.rev_map map (List.filter (fst %> is_local_assum) ctx) + List.rev_map map (List.filter (fst %> NamedDecl.is_local_assum) ctx) let adjust_side_condition p = function | LessArgsThan n -> LessArgsThan (n+p) @@ -651,8 +652,8 @@ type manual_explicitation = Constrexpr.explicitation * (bool * bool * bool) type manual_implicits = manual_explicitation list -let compute_implicits_with_manual env typ enriching l = - let _,autoimpls = compute_auto_implicits env !implicit_args enriching typ in +let compute_implicits_with_manual env sigma typ enriching l = + let _,autoimpls = compute_auto_implicits env sigma !implicit_args enriching typ in set_manual_implicits env !implicit_args enriching autoimpls l let check_inclusion l = @@ -676,9 +677,10 @@ let projection_implicits env p impls = let declare_manual_implicits local ref ?enriching l = let flags = !implicit_args in let env = Global.env () in - let t, _ = Global.type_of_global_in_context (Global.env ()) ref in + let sigma = Evd.from_env env in + let t, _ = Global.type_of_global_in_context env ref in let enriching = Option.default flags.auto enriching in - let isrigid,autoimpls = compute_auto_implicits env flags enriching t in + let isrigid,autoimpls = compute_auto_implicits env sigma flags enriching (of_constr t) in let l' = match l with | [] -> assert false | [l] -> diff --git a/interp/impargs.mli b/interp/impargs.mli index 44f76c633..1eeb8e41a 100644 --- a/interp/impargs.mli +++ b/interp/impargs.mli @@ -9,7 +9,7 @@ (************************************************************************) open Names -open Constr +open EConstr open Globnames open Environ @@ -92,10 +92,10 @@ type manual_explicitation = Constrexpr.explicitation * type manual_implicits = manual_explicitation list -val compute_implicits_with_manual : env -> types -> bool -> +val compute_implicits_with_manual : env -> Evd.evar_map -> types -> bool -> manual_implicits -> implicit_status list -val compute_implicits_names : env -> types -> Name.t list +val compute_implicits_names : env -> Evd.evar_map -> types -> Name.t list (** {6 Computation of implicits (done using the global environment). } *) diff --git a/interp/modintern.ml b/interp/modintern.ml index 108dca2de..92264fb72 100644 --- a/interp/modintern.ml +++ b/interp/modintern.ml @@ -63,13 +63,16 @@ let transl_with_decl env = function | CWith_Module ((_,fqid),qid) -> WithMod (fqid,lookup_module qid), Univ.ContextSet.empty | CWith_Definition ((_,fqid),c) -> - let c, ectx = interp_constr env (Evd.from_env env) c in + let sigma = Evd.from_env env in + let c, ectx = interp_constr env sigma c in if Flags.is_universe_polymorphism () then let ctx = UState.context ectx in let inst, ctx = Univ.abstract_universes ctx in - let c = Vars.subst_univs_level_constr (Univ.make_instance_subst inst) c in + let c = EConstr.Vars.subst_univs_level_constr (Univ.make_instance_subst inst) c in + let c = EConstr.to_constr sigma c in WithDef (fqid,(c, Some ctx)), Univ.ContextSet.empty else + let c = EConstr.to_constr sigma c in WithDef (fqid,(c, None)), UState.context_set ectx let loc_of_module l = l.CAst.loc diff --git a/interp/notation.ml b/interp/notation.ml index e42226f99..da3ed6b8c 100644 --- a/interp/notation.ml +++ b/interp/notation.ml @@ -670,8 +670,8 @@ type scope_class = cl_typ let scope_class_compare : scope_class -> scope_class -> int = cl_typ_ord -let compute_scope_class t = - let (cl,_,_) = find_class_type Evd.empty (EConstr.of_constr t) in +let compute_scope_class sigma t = + let (cl,_,_) = find_class_type sigma t in cl module ScopeClassOrd = @@ -700,22 +700,22 @@ let find_scope_class_opt = function (**********************************************************************) (* Special scopes associated to arguments of a global reference *) -let rec compute_arguments_classes t = - match Constr.kind (EConstr.Unsafe.to_constr (Reductionops.whd_betaiotazeta Evd.empty (EConstr.of_constr t))) with +let rec compute_arguments_classes sigma t = + match EConstr.kind sigma (Reductionops.whd_betaiotazeta sigma t) with | Prod (_,t,u) -> - let cl = try Some (compute_scope_class t) with Not_found -> None in - cl :: compute_arguments_classes u + let cl = try Some (compute_scope_class sigma t) with Not_found -> None in + cl :: compute_arguments_classes sigma u | _ -> [] -let compute_arguments_scope_full t = - let cls = compute_arguments_classes t in +let compute_arguments_scope_full sigma t = + let cls = compute_arguments_classes sigma t in let scs = List.map find_scope_class_opt cls in scs, cls -let compute_arguments_scope t = fst (compute_arguments_scope_full t) +let compute_arguments_scope sigma t = fst (compute_arguments_scope_full sigma t) -let compute_type_scope t = - find_scope_class_opt (try Some (compute_scope_class t) with Not_found -> None) +let compute_type_scope sigma t = + find_scope_class_opt (try Some (compute_scope_class sigma t) with Not_found -> None) let current_type_scope_name () = find_scope_class_opt (Some CL_SORT) @@ -781,20 +781,24 @@ let discharge_arguments_scope (_,(req,r,n,l,_)) = let classify_arguments_scope (req,_,_,_,_ as obj) = if req == ArgsScopeNoDischarge then Dispose else Substitute obj -let rebuild_arguments_scope (req,r,n,l,_) = +let rebuild_arguments_scope sigma (req,r,n,l,_) = match req with | ArgsScopeNoDischarge -> assert false | ArgsScopeAuto -> - let scs,cls = compute_arguments_scope_full (fst(Global.type_of_global_in_context (Global.env ()) r)(*FIXME?*)) in - (req,r,List.length scs,scs,cls) + let env = Global.env () in (*FIXME?*) + let typ = EConstr.of_constr @@ fst (Global.type_of_global_in_context env r) in + let scs,cls = compute_arguments_scope_full sigma typ in + (req,r,List.length scs,scs,cls) | ArgsScopeManual -> - (* Add to the manually given scopes the one found automatically - for the extra parameters of the section. Discard the classes - of the manually given scopes to avoid further re-computations. *) - let l',cls = compute_arguments_scope_full (fst (Global.type_of_global_in_context (Global.env ()) r)) in - let l1 = List.firstn n l' in - let cls1 = List.firstn n cls in - (req,r,0,l1@l,cls1) + (* Add to the manually given scopes the one found automatically + for the extra parameters of the section. Discard the classes + of the manually given scopes to avoid further re-computations. *) + let env = Global.env () in (*FIXME?*) + let typ = EConstr.of_constr @@ fst (Global.type_of_global_in_context env r) in + let l',cls = compute_arguments_scope_full sigma typ in + let l1 = List.firstn n l' in + let cls1 = List.firstn n cls in + (req,r,0,l1@l,cls1) type arguments_scope_obj = arguments_scope_discharge_request * global_reference * @@ -809,7 +813,8 @@ let inArgumentsScope : arguments_scope_obj -> obj = subst_function = subst_arguments_scope; classify_function = classify_arguments_scope; discharge_function = discharge_arguments_scope; - rebuild_function = rebuild_arguments_scope } + (* XXX: Should we pass the sigma here or not, see @herbelin's comment in 6511 *) + rebuild_function = rebuild_arguments_scope Evd.empty } let is_local local ref = local || isVarRef ref && Lib.is_in_section ref @@ -821,7 +826,7 @@ let declare_arguments_scope local r scl = (* We empty the list of argument classes to disable further scope re-computations and keep these manually given scopes. *) declare_arguments_scope_gen req r 0 (scl,[]) - + let find_arguments_scope r = try let (scl,cls,stamp) = Refmap.find r !arguments_scope in @@ -834,12 +839,12 @@ let find_arguments_scope r = scl' with Not_found -> [] -let declare_ref_arguments_scope ref = - let t, _ = Global.type_of_global_in_context (Global.env ()) ref in - let (scs,cls as o) = compute_arguments_scope_full t in +let declare_ref_arguments_scope sigma ref = + let env = Global.env () in (* FIXME? *) + let typ = EConstr.of_constr @@ fst @@ Global.type_of_global_in_context env ref in + let (scs,cls as o) = compute_arguments_scope_full sigma typ in declare_arguments_scope_gen ArgsScopeAuto ref (List.length scs) o - (********************************) (* Encoding notations as string *) diff --git a/interp/notation.mli b/interp/notation.mli index 820d1d86f..aa52b858a 100644 --- a/interp/notation.mli +++ b/interp/notation.mli @@ -165,10 +165,10 @@ val subst_scope_class : Mod_subst.substitution -> scope_class -> scope_class option val declare_scope_class : scope_name -> scope_class -> unit -val declare_ref_arguments_scope : global_reference -> unit +val declare_ref_arguments_scope : Evd.evar_map -> global_reference -> unit -val compute_arguments_scope : Constr.types -> scope_name option list -val compute_type_scope : Constr.types -> scope_name option +val compute_arguments_scope : Evd.evar_map -> EConstr.types -> scope_name option list +val compute_type_scope : Evd.evar_map -> EConstr.types -> scope_name option (** Get the current scope bound to Sortclass, if it exists *) val current_type_scope_name : unit -> scope_name option diff --git a/interp/notation_ops.ml b/interp/notation_ops.ml index b7e306df6..77ef601b7 100644 --- a/interp/notation_ops.ml +++ b/interp/notation_ops.ml @@ -1134,7 +1134,7 @@ let rec match_ inner u alp metas sigma a1 a2 = else f1,l1, f2, l2 in let may_use_eta = does_not_come_from_already_eta_expanded_var f1 in List.fold_left2 (match_ may_use_eta u alp metas) - (match_in u alp metas sigma f1 f2) l1 l2 + (match_hd u alp metas sigma f1 f2) l1 l2 | GLambda (na1,bk1,t1,b1), NLambda (na2,t2,b2) -> match_extended_binders false u alp metas na1 na2 bk1 t1 (match_in u alp metas sigma t1 t2) b1 b2 | GProd (na1,bk1,t1,b1), NProd (na2,t2,b2) -> diff --git a/interp/syntax_def.ml b/interp/syntax_def.ml index a0cafff38..47faa5885 100644 --- a/interp/syntax_def.ml +++ b/interp/syntax_def.ml @@ -90,12 +90,11 @@ let pr_compat_warning (kn, def, v) = | [], NRef r -> spc () ++ str "is" ++ spc () ++ pr_global_env Id.Set.empty r | _ -> strbrk " is a compatibility notation" in - let since = strbrk " since Coq > " ++ str (Flags.pr_version v) ++ str "." in - pr_syndef kn ++ pp_def ++ since + pr_syndef kn ++ pp_def let warn_compatibility_notation = CWarnings.(create ~name:"compatibility-notation" - ~category:"deprecated" ~default:Disabled pr_compat_warning) + ~category:"deprecated" ~default:Enabled pr_compat_warning) let verbose_compat kn def = function | Some v when Flags.version_strictly_greater v -> diff --git a/kernel/cbytecodes.ml b/kernel/cbytecodes.ml index 1b1c59c2e..5ed9b6c67 100644 --- a/kernel/cbytecodes.ml +++ b/kernel/cbytecodes.ml @@ -34,13 +34,12 @@ let cofix_evaluated_tag = 7 let last_variant_tag = 245 type structured_constant = - | Const_sorts of Sorts.t + | Const_sort of Sorts.t | Const_ind of inductive | Const_proj of Constant.t | Const_b0 of tag | Const_bn of tag * structured_constant array | Const_univ_level of Univ.Level.t - | Const_type of Univ.Universe.t type reloc_table = (tag * int) array @@ -48,8 +47,8 @@ type annot_switch = {ci : case_info; rtbl : reloc_table; tailcall : bool; max_stack_size : int} let rec eq_structured_constant c1 c2 = match c1, c2 with -| Const_sorts s1, Const_sorts s2 -> Sorts.equal s1 s2 -| Const_sorts _, _ -> false +| Const_sort s1, Const_sort s2 -> Sorts.equal s1 s2 +| Const_sort _, _ -> false | Const_ind i1, Const_ind i2 -> eq_ind i1 i2 | Const_ind _, _ -> false | Const_proj p1, Const_proj p2 -> Constant.equal p1 p2 @@ -61,13 +60,11 @@ let rec eq_structured_constant c1 c2 = match c1, c2 with | Const_bn _, _ -> false | Const_univ_level l1 , Const_univ_level l2 -> Univ.Level.equal l1 l2 | Const_univ_level _ , _ -> false -| Const_type u1 , Const_type u2 -> Univ.Universe.equal u1 u2 -| Const_type _ , _ -> false let rec hash_structured_constant c = let open Hashset.Combine in match c with - | Const_sorts s -> combinesmall 1 (Sorts.hash s) + | Const_sort s -> combinesmall 1 (Sorts.hash s) | Const_ind i -> combinesmall 2 (ind_hash i) | Const_proj p -> combinesmall 3 (Constant.hash p) | Const_b0 t -> combinesmall 4 (Int.hash t) @@ -76,7 +73,6 @@ let rec hash_structured_constant c = let h = Array.fold_left fold 0 a in combinesmall 5 (combine (Int.hash t) h) | Const_univ_level l -> combinesmall 6 (Univ.Level.hash l) - | Const_type u -> combinesmall 7 (Univ.Universe.hash u) let eq_annot_switch asw1 asw2 = let eq_ci ci1 ci2 = @@ -186,6 +182,7 @@ type fv_elem = | FVnamed of Id.t | FVrel of int | FVuniv_var of int + | FVevar of Evar.t type fv = fv_elem array @@ -200,12 +197,15 @@ type t = fv_elem let compare e1 e2 = match e1, e2 with | FVnamed id1, FVnamed id2 -> Id.compare id1 id2 -| FVnamed _, _ -> -1 +| FVnamed _, (FVrel _ | FVuniv_var _ | FVevar _) -> -1 | FVrel _, FVnamed _ -> 1 | FVrel r1, FVrel r2 -> Int.compare r1 r2 -| FVrel _, FVuniv_var _ -> -1 +| FVrel _, (FVuniv_var _ | FVevar _) -> -1 | FVuniv_var i1, FVuniv_var i2 -> Int.compare i1 i2 -| FVuniv_var i1, _ -> 1 +| FVuniv_var i1, (FVnamed _ | FVrel _) -> 1 +| FVuniv_var i1, FVevar _ -> -1 +| FVevar _, (FVnamed _ | FVrel _ | FVuniv_var _) -> 1 +| FVevar e1, FVevar e2 -> Evar.compare e1 e2 end @@ -238,20 +238,19 @@ open Util let pp_sort s = let open Sorts in - match family s with - | InSet -> str "Set" - | InProp -> str "Prop" - | InType -> str "Type" + match s with + | Prop Null -> str "Prop" + | Prop Pos -> str "Set" + | Type u -> str "Type@{" ++ Univ.pr_uni u ++ str "}" let rec pp_struct_const = function - | Const_sorts s -> pp_sort s + | Const_sort s -> pp_sort s | Const_ind (mind, i) -> MutInd.print mind ++ str"#" ++ int i | Const_proj p -> Constant.print p | Const_b0 i -> int i | Const_bn (i,t) -> int i ++ surround (prvect_with_sep pr_comma pp_struct_const t) | Const_univ_level l -> Univ.Level.pr l - | Const_type u -> str "Type@{" ++ Univ.pr_uni u ++ str "}" let pp_lbl lbl = str "L" ++ int lbl @@ -259,6 +258,7 @@ let pp_fv_elem = function | FVnamed id -> str "FVnamed(" ++ Id.print id ++ str ")" | FVrel i -> str "Rel(" ++ int i ++ str ")" | FVuniv_var v -> str "FVuniv(" ++ int v ++ str ")" + | FVevar e -> str "FVevar(" ++ int (Evar.repr e) ++ str ")" let rec pp_instr i = match i with diff --git a/kernel/cbytecodes.mli b/kernel/cbytecodes.mli index f197c7679..03b6bc619 100644 --- a/kernel/cbytecodes.mli +++ b/kernel/cbytecodes.mli @@ -28,13 +28,12 @@ val cofix_evaluated_tag : tag val last_variant_tag : tag type structured_constant = - | Const_sorts of Sorts.t + | Const_sort of Sorts.t | Const_ind of inductive | Const_proj of Constant.t | Const_b0 of tag | Const_bn of tag * structured_constant array | Const_univ_level of Univ.Level.t - | Const_type of Univ.Universe.t val pp_struct_const : structured_constant -> Pp.t @@ -140,6 +139,7 @@ type fv_elem = FVnamed of Id.t | FVrel of int | FVuniv_var of int +| FVevar of Evar.t type fv = fv_elem array diff --git a/kernel/cbytegen.ml b/kernel/cbytegen.ml index 2aba0d7c5..0766f49b3 100644 --- a/kernel/cbytegen.ml +++ b/kernel/cbytegen.ml @@ -259,6 +259,15 @@ let pos_universe_var i r sz = r.in_env := push_fv db env; Kenvacc(r.offset + pos) +let pos_evar evk r = + let env = !(r.in_env) in + let cid = FVevar evk in + try Kenvacc(r.offset + find_at cid env) + with Not_found -> + let pos = env.size in + r.in_env := push_fv cid env; + Kenvacc (r.offset + pos) + (*i Examination of the continuation *) (* Discard all instructions up to the next label. *) @@ -429,6 +438,7 @@ let compile_fv_elem reloc fv sz cont = | FVrel i -> pos_rel i reloc sz :: cont | FVnamed id -> pos_named id reloc :: cont | FVuniv_var i -> pos_universe_var i reloc sz :: cont + | FVevar evk -> pos_evar evk reloc :: cont let rec compile_fv reloc l sz cont = match l with @@ -473,6 +483,12 @@ let rec compile_lam env reloc lam sz cont = | Lvar id -> pos_named id reloc :: cont + | Levar (evk, args) -> + if Array.is_empty args then + compile_fv_elem reloc (FVevar evk) sz cont + else + comp_app compile_fv_elem (compile_lam env) reloc (FVevar evk) args sz cont + | Lconst (kn,u) -> compile_constant env reloc kn u [||] sz cont | Lind (ind,u) -> @@ -482,23 +498,23 @@ let rec compile_lam env reloc lam sz cont = (Const_ind ind) (Univ.Instance.to_array u) sz cont | Lsort (Sorts.Prop _ as s) -> - compile_structured_constant reloc (Const_sorts s) sz cont + compile_structured_constant reloc (Const_sort s) sz cont | Lsort (Sorts.Type u) -> - (* We separate global and local universes in [u]. The former will be part - of the structured constant, while the later (if any) will be applied as - arguments. *) - let open Univ in begin + (* We separate global and local universes in [u]. The former will be part + of the structured constant, while the later (if any) will be applied as + arguments. *) + let open Univ in begin let u,s = Universe.compact u in (* We assume that [Universe.type0m] is a neutral element for [Universe.sup] *) + let compile_get_univ reloc idx sz cont = + set_max_stack_size sz; + compile_fv_elem reloc (FVuniv_var idx) sz cont + in if List.is_empty s then - compile_structured_constant reloc (Const_sorts (Sorts.Type u)) sz cont + compile_structured_constant reloc (Const_sort (Sorts.Type u)) sz cont else - let compile_get_univ reloc idx sz cont = - set_max_stack_size sz; - compile_fv_elem reloc (FVuniv_var idx) sz cont - in comp_app compile_structured_constant compile_get_univ reloc - (Const_type u) (Array.of_list s) sz cont + (Const_sort (Sorts.Type u)) (Array.of_list s) sz cont end | Llet (id,def,body) -> diff --git a/kernel/cemitcodes.ml b/kernel/cemitcodes.ml index a4b1ff051..14f4f27c0 100644 --- a/kernel/cemitcodes.ml +++ b/kernel/cemitcodes.ml @@ -352,7 +352,7 @@ type to_patch = emitcodes * patches * fv (* Substitution *) let rec subst_strcst s sc = match sc with - | Const_sorts _ | Const_b0 _ | Const_univ_level _ | Const_type _ -> sc + | Const_sort _ | Const_b0 _ | Const_univ_level _ -> sc | Const_proj p -> Const_proj (subst_constant s p) | Const_bn(tag,args) -> Const_bn(tag,Array.map (subst_strcst s) args) | Const_ind ind -> let kn,i = ind in Const_ind (subst_mind s kn, i) diff --git a/kernel/cinstr.mli b/kernel/cinstr.mli index e22703e76..4a3c03d85 100644 --- a/kernel/cinstr.mli +++ b/kernel/cinstr.mli @@ -22,6 +22,7 @@ type uint = and lambda = | Lrel of Name.t * int | Lvar of Id.t + | Levar of Evar.t * lambda array | Lprod of lambda * lambda | Llam of Name.t array * lambda | Llet of Name.t * lambda * lambda diff --git a/kernel/clambda.ml b/kernel/clambda.ml index 636ed3510..7b637c20e 100644 --- a/kernel/clambda.ml +++ b/kernel/clambda.ml @@ -29,6 +29,9 @@ let rec pp_lam lam = match lam with | Lrel (id,n) -> pp_rel id n | Lvar id -> Id.print id + | Levar (evk, args) -> + hov 1 (str "evar(" ++ Evar.print evk ++ str "," ++ spc () ++ + prlist_with_sep spc pp_lam (Array.to_list args) ++ str ")") | Lprod(dom,codom) -> hov 1 (str "forall(" ++ pp_lam dom ++ @@ -148,6 +151,9 @@ let shift subst = subs_shft (1, subst) let rec map_lam_with_binders g f n lam = match lam with | Lrel _ | Lvar _ | Lconst _ | Lval _ | Lsort _ | Lind _ -> lam + | Levar (evk, args) -> + let args' = Array.smartmap (f n) args in + if args == args' then lam else Levar (evk, args') | Lprod(dom,codom) -> let dom' = f n dom in let codom' = f n codom in @@ -344,6 +350,8 @@ let rec occurrence k kind lam = if kind then false else raise Not_found else kind | Lvar _ | Lconst _ | Lval _ | Lsort _ | Lind _ -> kind + | Levar (_, args) -> + occurrence_args k kind args | Lprod(dom, codom) -> occurrence k (occurrence k kind dom) codom | Llam(ids,body) -> @@ -600,7 +608,9 @@ open Renv let rec lambda_of_constr env c = match Constr.kind c with | Meta _ -> raise (Invalid_argument "Cbytegen.lambda_of_constr: Meta") - | Evar _ -> raise (Invalid_argument "Cbytegen.lambda_of_constr : Evar") + | Evar (evk, args) -> + let args = lambda_of_args env 0 args in + Levar (evk, args) | Cast (c, _, _) -> lambda_of_constr env c diff --git a/kernel/csymtable.ml b/kernel/csymtable.ml index 922fbc406..012948954 100644 --- a/kernel/csymtable.ml +++ b/kernel/csymtable.ml @@ -152,6 +152,7 @@ and slot_for_fv env fv = env |> Pre_env.lookup_rel i |> RelDecl.get_value |> fill_fv_cache rv i val_of_rel env_of_rel | Some (v, _) -> v end + | FVevar evk -> val_of_evar evk | FVuniv_var idu -> assert false diff --git a/kernel/reduction.ml b/kernel/reduction.ml index 158261fe3..e9be1b35d 100644 --- a/kernel/reduction.ml +++ b/kernel/reduction.ml @@ -920,7 +920,6 @@ let dest_prod_assum env = | LetIn (x,b,t,c) -> let d = LocalDef (x,b,t) in prodec_rec (push_rel d env) (Context.Rel.add d l) c - | Cast (c,_,_) -> prodec_rec env l c | _ -> let rty' = whd_all env rty in if Constr.equal rty' rty then l, rty @@ -938,7 +937,6 @@ let dest_lam_assum env = | LetIn (x,b,t,c) -> let d = LocalDef (x,b,t) in lamec_rec (push_rel d env) (Context.Rel.add d l) c - | Cast (c,_,_) -> lamec_rec env l c | _ -> l,rty in lamec_rec env Context.Rel.empty diff --git a/kernel/uGraph.ml b/kernel/uGraph.ml index 6dfd19306..5d1644614 100644 --- a/kernel/uGraph.ml +++ b/kernel/uGraph.ml @@ -835,7 +835,7 @@ let sort_universes g = (** Subtyping of polymorphic contexts *) let check_subtype univs ctxT ctx = - if AUContext.size ctx == AUContext.size ctx then + if AUContext.size ctxT == AUContext.size ctx then let (inst, cst) = UContext.dest (AUContext.repr ctx) in let cstT = UContext.constraints (AUContext.repr ctxT) in let push accu v = add_universe v false accu in diff --git a/kernel/vars.ml b/kernel/vars.ml index b95ac2c9a..0f588a630 100644 --- a/kernel/vars.ml +++ b/kernel/vars.ml @@ -312,6 +312,3 @@ let subst_instance_constr subst c = let subst_instance_context s ctx = if Univ.Instance.is_empty s then ctx else Context.Rel.map (fun x -> subst_instance_constr s x) ctx - -type id_key = Constant.t tableKey -let eq_id_key x y = Names.eq_table_key Constant.equal x y diff --git a/kernel/vars.mli b/kernel/vars.mli index 660096713..a0c7ba4bd 100644 --- a/kernel/vars.mli +++ b/kernel/vars.mli @@ -139,6 +139,3 @@ val subst_univs_level_context : Univ.universe_level_subst -> Context.Rel.t -> Co (** Instance substitution for polymorphism. *) val subst_instance_constr : Instance.t -> constr -> constr val subst_instance_context : Instance.t -> Context.Rel.t -> Context.Rel.t - -type id_key = Constant.t tableKey -val eq_id_key : id_key -> id_key -> bool diff --git a/kernel/vconv.ml b/kernel/vconv.ml index 8c7658147..f11803b67 100644 --- a/kernel/vconv.ml +++ b/kernel/vconv.ml @@ -44,7 +44,6 @@ let rec conv_val env pb k v1 v2 cu = and conv_whd env pb k whd1 whd2 cu = (* Pp.(msg_debug (str "conv_whd(" ++ pr_whd whd1 ++ str ", " ++ pr_whd whd2 ++ str ")")) ; *) match whd1, whd2 with - | Vsort s1, Vsort s2 -> sort_cmp_universes env pb s1 s2 cu | Vuniv_level _ , _ | _ , Vuniv_level _ -> (** Both of these are invalid since universes are handled via @@ -81,7 +80,7 @@ and conv_whd env pb k whd1 whd2 cu = (* on the fly eta expansion *) conv_val env CONV (k+1) (apply_whd k whd1) (apply_whd k whd2) cu - | Vsort _, _ | Vprod _, _ | Vfix _, _ | Vcofix _, _ | Vconstr_const _, _ + | Vprod _, _ | Vfix _, _ | Vcofix _, _ | Vconstr_const _, _ | Vconstr_block _, _ | Vatom_stk _, _ -> raise NotConvertible @@ -116,11 +115,12 @@ and conv_atom env pb k a1 stk1 a2 stk2 cu = conv_stack env k stk1 stk2 cu else raise NotConvertible | Aid ik1, Aid ik2 -> - if Vars.eq_id_key ik1 ik2 && compare_stack stk1 stk2 then + if Vmvalues.eq_id_key ik1 ik2 && compare_stack stk1 stk2 then conv_stack env k stk1 stk2 cu else raise NotConvertible - | Atype _ , _ | _, Atype _ -> assert false - | Aind _, _ | Aid _, _ -> raise NotConvertible + | Asort s1, Asort s2 -> + sort_cmp_universes env pb s1 s2 cu + | Asort _ , _ | Aind _, _ | Aid _, _ -> raise NotConvertible and conv_stack env k stk1 stk2 cu = match stk1, stk2 with diff --git a/kernel/vm.ml b/kernel/vm.ml index 5d82e862b..14aeb732f 100644 --- a/kernel/vm.ml +++ b/kernel/vm.ml @@ -30,7 +30,6 @@ let popstop_code i = let stop = popstop_code 0 - (************************************************) (* Abstract machine *****************************) (************************************************) @@ -72,7 +71,6 @@ let apply_varray vf varray = interprete (fun_code vf) (fun_val vf) (fun_env vf) (n - 1) end -(* Functions over vfun *) let mkrel_vstack k arity = let max = k + arity - 1 in Array.init arity (fun i -> val_of_rel (max - i)) @@ -170,7 +168,7 @@ let rec apply_stack a stk v = let apply_whd k whd = let v = val_of_rel k in match whd with - | Vsort _ | Vprod _ | Vconstr_const _ | Vconstr_block _ -> assert false + | Vprod _ | Vconstr_const _ | Vconstr_block _ -> assert false | Vfun f -> reduce_fun k f | Vfix(f, None) -> push_ra stop; diff --git a/kernel/vmvalues.ml b/kernel/vmvalues.ml index a6edb68b1..0e0cb4e58 100644 --- a/kernel/vmvalues.ml +++ b/kernel/vmvalues.ml @@ -120,10 +120,23 @@ type vswitch = { (* Do not edit this type without editing C code, especially "coq_values.h" *) +type id_key = +| ConstKey of Constant.t +| VarKey of Id.t +| RelKey of Int.t +| EvarKey of Evar.t + +let eq_id_key k1 k2 = match k1, k2 with +| ConstKey c1, ConstKey c2 -> Constant.equal c1 c2 +| VarKey id1, VarKey id2 -> Id.equal id1 id2 +| RelKey n1, RelKey n2 -> Int.equal n1 n2 +| EvarKey evk1, EvarKey evk2 -> Evar.equal evk1 evk2 +| _ -> false + type atom = - | Aid of Vars.id_key + | Aid of id_key | Aind of inductive - | Atype of Univ.Universe.t + | Asort of Sorts.t (* Zippers *) @@ -138,7 +151,6 @@ type stack = zipper list type to_update = values type whd = - | Vsort of Sorts.t | Vprod of vprod | Vfun of vfun | Vfix of vfix * arguments option @@ -169,7 +181,6 @@ let uni_lvl_val (v : values) : Univ.Level.t = let pr = let open Pp in match whd with - | Vsort _ -> str "Vsort" | Vprod _ -> str "Vprod" | Vfun _ -> str "Vfun" | Vfix _ -> str "Vfix" @@ -191,12 +202,17 @@ let rec whd_accu a stk = match Obj.tag at with | i when Int.equal i type_atom_tag -> begin match stk with + | [] -> Vatom_stk(Obj.magic at, stk) | [Zapp args] -> let args = Array.init (nargs args) (arg args) in - let u = Obj.obj (Obj.field at 0) in - let inst = Instance.of_array (Array.map uni_lvl_val args) in - let u = Univ.subst_instance_universe inst u in - Vsort (Type u) + let s = Obj.obj (Obj.field at 0) in + begin match s with + | Type u -> + let inst = Instance.of_array (Array.map uni_lvl_val args) in + let u = Univ.subst_instance_universe inst u in + Vatom_stk (Asort (Type u), []) + | _ -> assert false + end | _ -> assert false end | i when i <= max_atom_tag -> @@ -245,11 +261,8 @@ let whd_val : values -> whd = else let tag = Obj.tag o in if tag = accu_tag then - ( - if Int.equal (Obj.size o) 1 then Obj.obj o (* sort *) - else - if is_accumulate (fun_code o) then whd_accu o [] - else Vprod(Obj.obj o)) + if is_accumulate (fun_code o) then whd_accu o [] + else Vprod(Obj.obj o) else if tag = Obj.closure_tag || tag = Obj.infix_tag then (match kind_of_closure o with @@ -275,7 +288,7 @@ let obj_of_atom : atom -> Obj.t = (* obj_of_str_const : structured_constant -> Obj.t *) let rec obj_of_str_const str = match str with - | Const_sorts s -> Obj.repr (Vsort s) + | Const_sort s -> obj_of_atom (Asort s) | Const_ind ind -> obj_of_atom (Aind ind) | Const_proj p -> Obj.repr p | Const_b0 tag -> Obj.repr tag @@ -287,7 +300,6 @@ let rec obj_of_str_const str = done; res | Const_univ_level l -> Obj.repr (Vuniv_level l) - | Const_type u -> obj_of_atom (Atype u) let val_of_obj o = ((Obj.obj o) : values) @@ -306,13 +318,14 @@ let val_of_proj kn v = module IdKeyHash = struct - type t = Constant.t tableKey - let equal = Names.eq_table_key Constant.equal + type t = id_key + let equal = eq_id_key open Hashset.Combine let hash = function | ConstKey c -> combinesmall 1 (Constant.hash c) | VarKey id -> combinesmall 2 (Id.hash id) | RelKey i -> combinesmall 3 (Int.hash i) + | EvarKey evk -> combinesmall 4 (Evar.hash evk) end module KeyTable = Hashtbl.Make(IdKeyHash) @@ -332,6 +345,8 @@ let val_of_named id = val_of_idkey (VarKey id) let val_of_constant c = val_of_idkey (ConstKey c) +let val_of_evar evk = val_of_idkey (EvarKey evk) + external val_of_annot_switch : annot_switch -> values = "%identity" (*************************************************) @@ -504,10 +519,9 @@ let rec pr_atom a = | RelKey i -> str "#" ++ int i | _ -> str "...") ++ str ")" | Aind (mi,i) -> str "Aind(" ++ MutInd.print mi ++ str "#" ++ int i ++ str ")" - | Atype _ -> str "Atype(") + | Asort _ -> str "Asort(") and pr_whd w = Pp.(match w with - | Vsort _ -> str "Vsort" | Vprod _ -> str "Vprod" | Vfun _ -> str "Vfun" | Vfix _ -> str "Vfix" diff --git a/kernel/vmvalues.mli b/kernel/vmvalues.mli index 8d6adbf43..c6e342a96 100644 --- a/kernel/vmvalues.mli +++ b/kernel/vmvalues.mli @@ -56,10 +56,18 @@ val fun_code : vfun -> tcode val fix_code : vfix -> tcode val cofix_upd_code : to_update -> tcode +type id_key = +| ConstKey of Constant.t +| VarKey of Id.t +| RelKey of Int.t +| EvarKey of Evar.t + +val eq_id_key : id_key -> id_key -> bool + type atom = - | Aid of Vars.id_key + | Aid of id_key | Aind of inductive - | Atype of Univ.Universe.t + | Asort of Sorts.t (** Zippers *) @@ -72,7 +80,6 @@ type zipper = type stack = zipper list type whd = - | Vsort of Sorts.t | Vprod of vprod | Vfun of vfun | Vfix of vfix * arguments option @@ -94,6 +101,7 @@ val val_of_str_const : structured_constant -> values val val_of_rel : int -> values val val_of_named : Id.t -> values val val_of_constant : Constant.t -> values +val val_of_evar : Evar.t -> values val val_of_proj : Constant.t -> values -> values val val_of_atom : atom -> values diff --git a/lib/flags.ml b/lib/flags.ml index 341e7f8e4..8491873e0 100644 --- a/lib/flags.ml +++ b/lib/flags.ml @@ -69,17 +69,11 @@ 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 = VOld | V8_5 | V8_6 | V8_7 | Current +type compat_version = V8_6 | V8_7 | Current let compat_version = ref Current let version_compare v1 v2 = match v1, v2 with - | VOld, VOld -> 0 - | VOld, _ -> -1 - | _, VOld -> 1 - | V8_5, V8_5 -> 0 - | V8_5, _ -> -1 - | _, V8_5 -> 1 | V8_6, V8_6 -> 0 | V8_6, _ -> -1 | _, V8_6 -> 1 @@ -92,8 +86,6 @@ let version_strictly_greater v = version_compare !compat_version v > 0 let version_less_or_equal v = not (version_strictly_greater v) let pr_version = function - | VOld -> "old" - | V8_5 -> "8.5" | V8_6 -> "8.6" | V8_7 -> "8.7" | Current -> "current" diff --git a/lib/flags.mli b/lib/flags.mli index a128617ce..85aaf879f 100644 --- a/lib/flags.mli +++ b/lib/flags.mli @@ -45,7 +45,7 @@ val raw_print : bool ref (* Univ print flag, never set anywere. Maybe should belong to Univ? *) val univ_print : bool ref -type compat_version = VOld | V8_5 | V8_6 | V8_7 | Current +type compat_version = V8_6 | V8_7 | 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/lib/system.ml b/lib/system.ml index 547c5a691..dfede29e8 100644 --- a/lib/system.ml +++ b/lib/system.ml @@ -56,7 +56,8 @@ let make_dir_table dir = let filter_dotfiles s f = if f.[0] = '.' then s else StrSet.add f s in Array.fold_left filter_dotfiles StrSet.empty (Sys.readdir dir) -let trust_file_cache = ref true +(** Don't trust in interactive mode (the default) *) +let trust_file_cache = ref false let exists_in_dir_respecting_case dir bf = let cache_dir dir = diff --git a/parsing/cLexer.ml4 b/parsing/cLexer.ml4 index e9c6ebfa0..d65b35c46 100644 --- a/parsing/cLexer.ml4 +++ b/parsing/cLexer.ml4 @@ -386,16 +386,6 @@ let comments = ref [] let current_comment = Buffer.create 8192 let between_commands = ref true -let rec split_comments comacc acc pos = function - [] -> comments := List.rev acc; comacc - | ((b,e),c as com)::coms -> - (* Take all comments that terminates before pos, or begin exactly - at pos (used to print comments attached after an expression) *) - if e<=pos || pos=b then split_comments (c::comacc) acc pos coms - else split_comments comacc (com::acc) pos coms - -let extract_comments pos = split_comments [] [] pos !comments - (* The state of the lexer visible from outside *) type lexer_state = int option * string * bool * ((int * int) * string) list * Loc.source @@ -406,11 +396,14 @@ let set_lexer_state (o,s,b,c,f) = between_commands := b; comments := c; current_file := f -let release_lexer_state () = +let get_lexer_state () = (!comment_begin, Buffer.contents current_comment, !between_commands, !comments, !current_file) +let release_lexer_state = get_lexer_state let drop_lexer_state () = set_lexer_state (init_lexer_state Loc.ToplevelInput) +let get_comment_state (_,_,_,c,_) = c + let real_push_char c = Buffer.add_char current_comment c (* Add a char if it is between two commands, if it is a newline or diff --git a/parsing/cLexer.mli b/parsing/cLexer.mli index 58673fefb..a14f08d91 100644 --- a/parsing/cLexer.mli +++ b/parsing/cLexer.mli @@ -53,9 +53,8 @@ type lexer_state val init_lexer_state : Loc.source -> lexer_state val set_lexer_state : lexer_state -> unit +val get_lexer_state : unit -> lexer_state val release_lexer_state : unit -> lexer_state +[@@ocaml.deprecated "Use get_lexer_state"] val drop_lexer_state : unit -> unit - -(* Retrieve the comments lexed at a given location of the stream - currently being processeed *) -val extract_comments : int -> string list +val get_comment_state : lexer_state -> ((int * int) * string) list diff --git a/parsing/doc.tex b/parsing/doc.tex deleted file mode 100644 index 68ab601cc..000000000 --- a/parsing/doc.tex +++ /dev/null @@ -1,9 +0,0 @@ - -\newpage -\section*{The Coq parsers and printers} - -\ocwsection \label{parsing} -This chapter describes the implementation of the \Coq\ parsers and printers. - -\bigskip -\begin{center}\epsfig{file=parsing.dep.ps}\end{center} diff --git a/parsing/g_vernac.ml4 b/parsing/g_vernac.ml4 index d1abfbe44..595a60f33 100644 --- a/parsing/g_vernac.ml4 +++ b/parsing/g_vernac.ml4 @@ -58,9 +58,7 @@ let parse_compat_version ?(allow_old = true) = let open Flags in function | "8.8" -> Current | "8.7" -> V8_7 | "8.6" -> V8_6 - | "8.5" -> V8_5 - | ("8.4" | "8.3" | "8.2" | "8.1" | "8.0") as s -> - if allow_old then VOld else + | ("8.5" | "8.4" | "8.3" | "8.2" | "8.1" | "8.0") as s -> CErrors.user_err ~hdr:"get_compat_version" Pp.(str "Compatibility with version " ++ str s ++ str " not supported.") | s -> diff --git a/parsing/pcoq.ml b/parsing/pcoq.ml index bd4495fb4..9aae251f1 100644 --- a/parsing/pcoq.ml +++ b/parsing/pcoq.ml @@ -90,7 +90,9 @@ module type S = val entry_create : string -> 'a entry val entry_parse : 'a entry -> coq_parsable -> 'a val entry_print : Format.formatter -> 'a entry -> unit - val with_parsable : coq_parsable -> ('a -> 'b) -> 'a -> 'b + + val comment_state : coq_parsable -> ((int * int) * string) list + val srules' : production_rule list -> symbol val parse_tokens_after_filter : 'a entry -> Tok.t Stream.t -> 'a @@ -107,13 +109,14 @@ end with type 'a Entry.e = 'a Grammar.GMake(CLexer).Entry.e = struct string option * Gramext.g_assoc option * production_rule list type extend_statment = Gramext.position option * single_extend_statment list + type coq_parsable = parsable * CLexer.lexer_state ref let parsable ?(file=Loc.ToplevelInput) c = let state = ref (CLexer.init_lexer_state file) in CLexer.set_lexer_state !state; let a = parsable c in - state := CLexer.release_lexer_state (); + state := CLexer.get_lexer_state (); (a,state) let action = Gramext.action @@ -123,7 +126,7 @@ end with type 'a Entry.e = 'a Grammar.GMake(CLexer).Entry.e = struct CLexer.set_lexer_state !state; try let c = Entry.parse e p in - state := CLexer.release_lexer_state (); + state := CLexer.get_lexer_state (); c with Ploc.Exc (loc,e) -> CLexer.drop_lexer_state (); @@ -131,15 +134,8 @@ end with type 'a Entry.e = 'a Grammar.GMake(CLexer).Entry.e = struct let loc = match loc' with None -> to_coqloc loc | Some loc -> loc in Loc.raise ~loc e - let with_parsable (p,state) f x = - CLexer.set_lexer_state !state; - try - let a = f x in - state := CLexer.release_lexer_state (); - a - with e -> - CLexer.drop_lexer_state (); - raise e + let comment_state (p,state) = + CLexer.get_comment_state !state let entry_print ft x = Entry.print ft x diff --git a/parsing/pcoq.mli b/parsing/pcoq.mli index 9bb8bd31a..8592968dc 100644 --- a/parsing/pcoq.mli +++ b/parsing/pcoq.mli @@ -80,7 +80,9 @@ module type S = val entry_create : string -> 'a entry val entry_parse : 'a entry -> coq_parsable -> 'a val entry_print : Format.formatter -> 'a entry -> unit - val with_parsable : coq_parsable -> ('a -> 'b) -> 'a -> 'b + + (* Get comment parsing information from the Lexer *) + val comment_state : coq_parsable -> ((int * int) * string) list (* Apparently not used *) val srules' : production_rule list -> symbol diff --git a/plugins/funind/glob_term_to_relation.ml b/plugins/funind/glob_term_to_relation.ml index 22881c32c..7159614d9 100644 --- a/plugins/funind/glob_term_to_relation.ml +++ b/plugins/funind/glob_term_to_relation.ml @@ -352,9 +352,9 @@ let raw_push_named (na,raw_value,raw_typ) env = let typ,_ = Pretyping.understand env (Evd.from_env env) ~expected_type:Pretyping.IsType raw_typ in (match raw_value with | None -> - Environ.push_named (NamedDecl.LocalAssum (id,typ)) env + EConstr.push_named (NamedDecl.LocalAssum (id,typ)) env | Some value -> - Environ.push_named (NamedDecl.LocalDef (id, value, typ)) env) + EConstr.push_named (NamedDecl.LocalDef (id, value, typ)) env) let add_pat_variables pat typ env : Environ.env = @@ -519,7 +519,7 @@ let rec build_entry_lc env funnames avoid rt : glob_constr build_entry_return = The "value" of this branch is then simply [res] *) let rt_as_constr,ctx = Pretyping.understand env (Evd.from_env env) rt in - let rt_typ = Typing.unsafe_type_of env (Evd.from_env env) (EConstr.of_constr rt_as_constr) in + let rt_typ = Typing.unsafe_type_of env (Evd.from_env env) rt_as_constr in let res_raw_type = Detyping.detype Detyping.Now false Id.Set.empty env (Evd.from_env env) rt_typ in let res = fresh_id args_res.to_avoid "_res" in let new_avoid = res::args_res.to_avoid in @@ -631,12 +631,11 @@ let rec build_entry_lc env funnames avoid rt : glob_constr build_entry_return = let v = match typ with None -> v | Some t -> DAst.make ?loc:rt.loc @@ GCast (v,CastConv t) in let v_res = build_entry_lc env funnames avoid v in let v_as_constr,ctx = Pretyping.understand env (Evd.from_env env) v in - let v_type = Typing.unsafe_type_of env (Evd.from_env env) (EConstr.of_constr v_as_constr) in - let v_type = EConstr.Unsafe.to_constr v_type in + let v_type = Typing.unsafe_type_of env (Evd.from_env env) v_as_constr in let new_env = match n with Anonymous -> env - | Name id -> Environ.push_named (NamedDecl.LocalDef (id,v_as_constr,v_type)) env + | Name id -> EConstr.push_named (NamedDecl.LocalDef (id,v_as_constr,v_type)) env in let b_res = build_entry_lc new_env funnames avoid b in combine_results (combine_letin n) v_res b_res @@ -648,7 +647,7 @@ let rec build_entry_lc env funnames avoid rt : glob_constr build_entry_return = build_entry_lc_from_case env funnames make_discr el brl avoid | GIf(b,(na,e_option),lhs,rhs) -> let b_as_constr,ctx = Pretyping.understand env (Evd.from_env env) b in - let b_typ = Typing.unsafe_type_of env (Evd.from_env env) (EConstr.of_constr b_as_constr) in + let b_typ = Typing.unsafe_type_of env (Evd.from_env env) b_as_constr in let (ind,_) = try Inductiveops.find_inductive env (Evd.from_env env) b_typ with Not_found -> @@ -680,7 +679,7 @@ let rec build_entry_lc env funnames avoid rt : glob_constr build_entry_return = nal in let b_as_constr,ctx = Pretyping.understand env (Evd.from_env env) b in - let b_typ = Typing.unsafe_type_of env (Evd.from_env env) (EConstr.of_constr b_as_constr) in + let b_typ = Typing.unsafe_type_of env (Evd.from_env env) b_as_constr in let (ind,_) = try Inductiveops.find_inductive env (Evd.from_env env) b_typ with Not_found -> @@ -726,7 +725,7 @@ and build_entry_lc_from_case env funname make_discr let types = List.map (fun (case_arg,_) -> let case_arg_as_constr,ctx = Pretyping.understand env (Evd.from_env env) case_arg in - EConstr.Unsafe.to_constr (Typing.unsafe_type_of env (Evd.from_env env) (EConstr.of_constr case_arg_as_constr)) + EConstr.Unsafe.to_constr (Typing.unsafe_type_of env (Evd.from_env env) case_arg_as_constr) ) el in (****** The next works only if the match is not dependent ****) @@ -948,7 +947,7 @@ let rec rebuild_cons env nb_args relname args crossed_types depth rt = mkGApp(mkGVar(mk_rel_id this_relname),List.tl args'@[res_rt]) in let t',ctx = Pretyping.understand env (Evd.from_env env) new_t in - let new_env = Environ.push_rel (LocalAssum (n,t')) env in + let new_env = EConstr.push_rel (LocalAssum (n,t')) env in let new_b,id_to_exclude = rebuild_cons new_env nb_args relname @@ -983,7 +982,7 @@ let rec rebuild_cons env nb_args relname args crossed_types depth rt = let subst_b = if is_in_b then b else replace_var_by_term id rt b in - let new_env = Environ.push_rel (LocalAssum (n,t')) env in + let new_env = EConstr.push_rel (LocalAssum (n,t')) env in let new_b,id_to_exclude = rebuild_cons new_env @@ -995,7 +994,7 @@ let rec rebuild_cons env nb_args relname args crossed_types depth rt = with Continue -> let jmeq = Globnames.IndRef (fst (EConstr.destInd Evd.empty (jmeq ()))) in let ty',ctx = Pretyping.understand env (Evd.from_env env) ty in - let ind,args' = Inductive.find_inductive env ty' in + let ind,args' = Inductiveops.find_inductive env Evd.(from_env env) ty' in let mib,_ = Global.lookup_inductive (fst ind) in let nparam = mib.Declarations.mind_nparams in let params,arg' = @@ -1017,14 +1016,14 @@ let rec rebuild_cons env nb_args relname args crossed_types depth rt = observe (str "computing new type for jmeq : " ++ pr_glob_constr_env env eq'); let eq'_as_constr,ctx = Pretyping.understand env (Evd.from_env env) eq' in observe (str " computing new type for jmeq : done") ; + let sigma = Evd.(from_env env) in let new_args = - match Constr.kind eq'_as_constr with + match EConstr.kind sigma eq'_as_constr with | App(_,[|_;_;ty;_|]) -> - let ty = Array.to_list (snd (destApp ty)) in + let ty = Array.to_list (snd (EConstr.destApp sigma ty)) in let ty' = snd (Util.List.chop nparam ty) in List.fold_left2 (fun acc var_as_constr arg -> - let arg = EConstr.of_constr arg in if isRel var_as_constr then let na = RelDecl.get_name (Environ.lookup_rel (destRel var_as_constr) env) in @@ -1065,7 +1064,7 @@ let rec rebuild_cons env nb_args relname args crossed_types depth rt = in let new_env = let t',ctx = Pretyping.understand env (Evd.from_env env) eq' in - Environ.push_rel (LocalAssum (n,t')) env + EConstr.push_rel (LocalAssum (n,t')) env in let new_b,id_to_exclude = rebuild_cons @@ -1103,7 +1102,7 @@ let rec rebuild_cons env nb_args relname args crossed_types depth rt = with Continue -> observe (str "computing new type for prod : " ++ pr_glob_constr_env env rt); let t',ctx = Pretyping.understand env (Evd.from_env env) t in - let new_env = Environ.push_rel (LocalAssum (n,t')) env in + let new_env = EConstr.push_rel (LocalAssum (n,t')) env in let new_b,id_to_exclude = rebuild_cons new_env nb_args relname @@ -1119,7 +1118,7 @@ let rec rebuild_cons env nb_args relname args crossed_types depth rt = | _ -> observe (str "computing new type for prod : " ++ pr_glob_constr_env env rt); let t',ctx = Pretyping.understand env (Evd.from_env env) t in - let new_env = Environ.push_rel (LocalAssum (n,t')) env in + let new_env = EConstr.push_rel (LocalAssum (n,t')) env in let new_b,id_to_exclude = rebuild_cons new_env nb_args relname @@ -1140,7 +1139,7 @@ let rec rebuild_cons env nb_args relname args crossed_types depth rt = let t',ctx = Pretyping.understand env (Evd.from_env env) t in match n with | Name id -> - let new_env = Environ.push_rel (LocalAssum (n,t')) env in + let new_env = EConstr.push_rel (LocalAssum (n,t')) env in let new_b,id_to_exclude = rebuild_cons new_env nb_args relname @@ -1163,7 +1162,8 @@ let rec rebuild_cons env nb_args relname args crossed_types depth rt = let evd = (Evd.from_env env) in let t',ctx = Pretyping.understand env evd t in let evd = Evd.from_ctx ctx in - let type_t' = Typing.unsafe_type_of env evd (EConstr.of_constr t') in + let type_t' = Typing.unsafe_type_of env evd t' in + let t' = EConstr.Unsafe.to_constr t' in let type_t' = EConstr.Unsafe.to_constr type_t' in let new_env = Environ.push_rel (LocalDef (n,t',type_t')) env in let new_b,id_to_exclude = @@ -1189,7 +1189,7 @@ let rec rebuild_cons env nb_args relname args crossed_types depth rt = depth t in let t',ctx = Pretyping.understand env (Evd.from_env env) new_t in - let new_env = Environ.push_rel (LocalAssum (na,t')) env in + let new_env = EConstr.push_rel (LocalAssum (na,t')) env in let new_b,id_to_exclude = rebuild_cons new_env nb_args relname @@ -1369,8 +1369,9 @@ let do_build_inductive *) let rel_arities = Array.mapi rel_arity funsargs in Util.Array.fold_left2 (fun env rel_name rel_ar -> - Environ.push_named (LocalAssum (rel_name, - fst (with_full_print (Constrintern.interp_constr env evd) rel_ar))) env) env relnames rel_arities + let rex = fst (with_full_print (Constrintern.interp_constr env evd) rel_ar) in + let rex = EConstr.Unsafe.to_constr rex in + Environ.push_named (LocalAssum (rel_name,rex)) env) env relnames rel_arities in (* and of the real constructors*) let constr i res = diff --git a/plugins/funind/indfun.ml b/plugins/funind/indfun.ml index e19fc9b62..13eda3952 100644 --- a/plugins/funind/indfun.ml +++ b/plugins/funind/indfun.ml @@ -141,8 +141,7 @@ let rec abstract_glob_constr c = function | Constrexpr.CLocalPattern _::bl -> assert false let interp_casted_constr_with_implicits env sigma impls c = - Constrintern.intern_gen Pretyping.WithoutTypeConstraint env ~impls - c + Constrintern.intern_gen Pretyping.WithoutTypeConstraint env sigma ~impls c (* Construct a fixpoint as a Glob_term @@ -160,9 +159,9 @@ let build_newrecursive let arity,ctx = Constrintern.interp_type env0 sigma arityc in let evd = Evd.from_env env0 in let evd, (_, (_, impls')) = Constrintern.interp_context_evars env evd bl in - let impl = Constrintern.compute_internalization_data env0 Constrintern.Recursive arity impls' in + let impl = Constrintern.compute_internalization_data env0 evd Constrintern.Recursive arity impls' in let open Context.Named.Declaration in - (Environ.push_named (LocalAssum (recname,arity)) env, Id.Map.add recname impl impls)) + (EConstr.push_named (LocalAssum (recname,arity)) env, Id.Map.add recname impl impls)) (env0,Constrintern.empty_internalization_env) lnameargsardef in let recdef = (* Declare local notations *) diff --git a/plugins/funind/recdef.ml b/plugins/funind/recdef.ml index ae623e3a5..759c88633 100644 --- a/plugins/funind/recdef.ml +++ b/plugins/funind/recdef.ml @@ -212,6 +212,7 @@ let (value_f: Constr.t list -> global_reference -> Constr.t) = DAst.make @@ GVar v_id)]) in let body = fst (understand env (Evd.from_env env) glob_body)(*FIXME*) in + let body = EConstr.Unsafe.to_constr body in it_mkLambda_or_LetIn body context let (declare_f : Id.t -> logical_kind -> Constr.t list -> global_reference -> global_reference) = @@ -1402,7 +1403,7 @@ let open_new_goal build_proof sigma using_lemmas ref_ goal_name (gls_type,decomp (fun c -> Proofview.V82.of_tactic (Tacticals.New.tclTHENLIST [intros; - Simple.apply (EConstr.of_constr (fst (interp_constr (Global.env()) Evd.empty c))) (*FIXME*); + Simple.apply (fst (interp_constr (Global.env()) Evd.empty c)) (*FIXME*); Tacticals.New.tclCOMPLETE Auto.default_auto ]) ) @@ -1601,7 +1602,9 @@ let recursive_definition is_mes function_name rec_impls type_of_f r rec_arg_num and functional_ref = destConst (constr_of_global functional_ref) and eq_ref = destConst (constr_of_global eq_ref) in generate_induction_principle f_ref tcc_lemma_constr - functional_ref eq_ref rec_arg_num (EConstr.of_constr rec_arg_type) (nb_prod evd (EConstr.of_constr res)) (EConstr.of_constr relation); + functional_ref eq_ref rec_arg_num + (EConstr.of_constr rec_arg_type) + (nb_prod evd (EConstr.of_constr res)) relation; Flags.if_verbose msgnl (h 1 (Ppconstr.pr_id function_name ++ spc () ++ str"is defined" )++ fnl () ++ @@ -1616,7 +1619,7 @@ let recursive_definition is_mes function_name rec_impls type_of_f r rec_arg_num tcc_lemma_constr is_mes functional_ref (EConstr.of_constr rec_arg_type) - (EConstr.of_constr relation) rec_arg_num + relation rec_arg_num term_id using_lemmas (List.length res_vars) diff --git a/plugins/ltac/coretactics.ml4 b/plugins/ltac/coretactics.ml4 index e867f63b7..931633e1a 100644 --- a/plugins/ltac/coretactics.ml4 +++ b/plugins/ltac/coretactics.ml4 @@ -241,12 +241,20 @@ END (** Simple induction / destruct *) +let simple_induct h = + Tacticals.New.tclTHEN (Tactics.intros_until h) + (Tacticals.New.onLastHyp Tactics.simplest_elim) + TACTIC EXTEND simple_induction - [ "simple" "induction" quantified_hypothesis(h) ] -> [ Tactics.simple_induct h ] + [ "simple" "induction" quantified_hypothesis(h) ] -> [ simple_induct h ] END +let simple_destruct h = + Tacticals.New.tclTHEN (Tactics.intros_until h) + (Tacticals.New.onLastHyp Tactics.simplest_case) + TACTIC EXTEND simple_destruct - [ "simple" "destruct" quantified_hypothesis(h) ] -> [ Tactics.simple_destruct h ] + [ "simple" "destruct" quantified_hypothesis(h) ] -> [ simple_destruct h ] END (** Double induction *) diff --git a/plugins/ltac/extratactics.ml4 b/plugins/ltac/extratactics.ml4 index 3c0a6550c..7d43f1986 100644 --- a/plugins/ltac/extratactics.ml4 +++ b/plugins/ltac/extratactics.ml4 @@ -255,6 +255,7 @@ let add_rewrite_hint ~poly bases ort t lcsr = let sigma = Evd.from_env env in let f ce = let c, ctx = Constrintern.interp_constr env sigma ce in + let c = EConstr.to_constr sigma c in let ctx = let ctx = UState.context_set ctx in if poly then ctx @@ -556,6 +557,7 @@ let add_transitivity_lemma left lem = let env = Global.env () in let sigma = Evd.from_env env in let lem',ctx (*FIXME*) = Constrintern.interp_constr env sigma lem in + let lem' = EConstr.to_constr sigma lem' in add_anonymous_leaf (inTransitivity (left,lem')) (* Vernacular syntax *) @@ -613,8 +615,10 @@ END VERNAC COMMAND EXTEND RetroknowledgeRegister CLASSIFIED AS SIDEFF | [ "Register" constr(c) "as" retroknowledge_field(f) "by" constr(b)] -> - [ let tc,ctx = Constrintern.interp_constr (Global.env ()) Evd.empty c in - let tb,ctx(*FIXME*) = Constrintern.interp_constr (Global.env ()) Evd.empty b in + [ let tc,_ctx = Constrintern.interp_constr (Global.env ()) Evd.empty c in + let tb,_ctx(*FIXME*) = Constrintern.interp_constr (Global.env ()) Evd.empty b in + let tc = EConstr.to_constr Evd.empty tc in + let tb = EConstr.to_constr Evd.empty tb in Global.register f tc tb ] END @@ -707,7 +711,6 @@ let hResolve id c occ t = resolve_hole (subst_hole_with_term loc_begin c_raw t_hole) in let t_constr,ctx = resolve_hole (subst_var_with_hole occ id t_raw) in - let t_constr = EConstr.of_constr t_constr in let sigma = Evd.merge_universe_context sigma ctx in let t_constr_type = Retyping.get_type_of env sigma t_constr in Proofview.tclTHEN (Proofview.Unsafe.tclEVARS sigma) @@ -975,6 +978,7 @@ TACTIC EXTEND unshelve | [ "unshelve" tactic1(t) ] -> [ Proofview.with_shelf (Tacinterp.tactic_of_value ist t) >>= fun (gls, ()) -> + let gls = List.map Proofview.with_empty_state gls in Proofview.Unsafe.tclGETGOALS >>= fun ogls -> Proofview.Unsafe.tclSETGOALS (gls @ ogls) ] diff --git a/plugins/ltac/rewrite.ml b/plugins/ltac/rewrite.ml index bc441d44b..6e38b4641 100644 --- a/plugins/ltac/rewrite.ml +++ b/plugins/ltac/rewrite.ml @@ -1570,7 +1570,8 @@ let cl_rewrite_clause_newtac ?abs ?origsigma ~progress strat clause = let (undef, prf, newt) = res in let fold ev _ accu = if Evd.mem sigma ev then accu else ev :: accu in let gls = List.rev (Evd.fold_undefined fold undef []) in - match clause, prf with + let gls = List.map Proofview.with_empty_state gls in + match clause, prf with | Some id, Some p -> let tac = tclTHENLIST [ Refine.refine ~typecheck:true (fun h -> (h,p)); @@ -1898,7 +1899,6 @@ let declare_projection n instance_id r = let build_morphism_signature env sigma m = let m,ctx = Constrintern.interp_constr env sigma m in - let m = EConstr.of_constr m in let sigma = Evd.from_ctx ctx in let t = Typing.unsafe_type_of env sigma m in let cstrs = diff --git a/plugins/ltac/tacintern.ml b/plugins/ltac/tacintern.ml index 11a04f5df..121075f72 100644 --- a/plugins/ltac/tacintern.ml +++ b/plugins/ltac/tacintern.ml @@ -201,7 +201,7 @@ let intern_constr_gen pattern_mode isarity {ltacvars=lfun; genv=env; extra} c = ltac_extra = extra; } in let c' = - warn (Constrintern.intern_gen scope ~pattern_mode ~ltacvars env) c + warn (Constrintern.intern_gen scope ~pattern_mode ~ltacvars env Evd.(from_env env)) c in (c',if !strict_check then None else Some c) @@ -318,7 +318,7 @@ let intern_constr_pattern ist ~as_type ~ltacvars pc = ltac_extra = ist.extra; } in let metas,pat = Constrintern.intern_constr_pattern - ist.genv ~as_type ~ltacvars pc + ist.genv Evd.(from_env ist.genv) ~as_type ~ltacvars pc in let (glob,_ as c) = intern_constr_gen true false ist pc in let bound_names = Glob_ops.bound_glob_vars glob in @@ -337,7 +337,7 @@ let intern_typed_pattern ist ~as_type ~ltacvars p = ltac_bound = Id.Set.empty; ltac_extra = ist.extra; } in - Constrintern.intern_constr_pattern ist.genv ~as_type ~ltacvars p + Constrintern.intern_constr_pattern ist.genv Evd.(from_env ist.genv) ~as_type ~ltacvars p else [], dummy_pat in let (glob,_ as c) = intern_constr_gen true false ist p in diff --git a/plugins/ltac/tacinterp.ml b/plugins/ltac/tacinterp.ml index 31dd0e7ea..cd9d9bac2 100644 --- a/plugins/ltac/tacinterp.ml +++ b/plugins/ltac/tacinterp.ml @@ -586,7 +586,7 @@ let interp_glob_closure ist env sigma ?(kind=WithoutTypeConstraint) ?(pattern_mo ltac_bound = Id.Map.domain ist.lfun; ltac_extra = Genintern.Store.empty; } in - { closure ; term = intern_gen kind ~pattern_mode ~ltacvars env term_expr } + { closure ; term = intern_gen kind ~pattern_mode ~ltacvars env sigma term_expr } let interp_uconstr ist env sigma c = interp_glob_closure ist env sigma c diff --git a/plugins/setoid_ring/Ring_theory.v b/plugins/setoid_ring/Ring_theory.v index 61cd7761d..d67a8d8dc 100644 --- a/plugins/setoid_ring/Ring_theory.v +++ b/plugins/setoid_ring/Ring_theory.v @@ -265,7 +265,7 @@ Section ALMOST_RING. Variable SRth : semi_ring_theory 0 1 radd rmul req. (** Every semi ring can be seen as an almost ring, by taking : - -x = x and x - y = x + y *) + [-x = x] and [x - y = x + y] *) Definition SRopp (x:R) := x. Notation "- x" := (SRopp x). Definition SRsub x y := x + -y. Infix "-" := SRsub. diff --git a/plugins/setoid_ring/newring.ml b/plugins/setoid_ring/newring.ml index 4803e925d..b6bac1a14 100644 --- a/plugins/setoid_ring/newring.ml +++ b/plugins/setoid_ring/newring.ml @@ -150,7 +150,7 @@ let ic c = let ic_unsafe c = (*FIXME remove *) let env = Global.env() in let sigma = Evd.from_env env in - EConstr.of_constr (fst (Constrintern.interp_constr env sigma c)) + fst (Constrintern.interp_constr env sigma c) let decl_constant na univs c = let open Constr in diff --git a/plugins/ssr/ssrast.mli b/plugins/ssr/ssrast.mli index 9e1435181..9783bc61d 100644 --- a/plugins/ssr/ssrast.mli +++ b/plugins/ssr/ssrast.mli @@ -45,12 +45,24 @@ type ssrclear = ssrhyps (* Discharge occ switch (combined occurrence / clear switch) *) type ssrdocc = ssrclear option * ssrocc -(* FIXME, make algebraic *) -type ssrtermkind = char - +(* OLD ssr terms *) +type ssrtermkind = char (* FIXME, make algebraic *) type ssrterm = ssrtermkind * Tacexpr.glob_constr_and_expr -type ssrview = ssrterm list +(* NEW ssr term *) + +(* These terms are raw but closed with the intenalization/interpretation + * context. It is up to the tactic receiving it to decide if such contexts + * are useful or not, and eventually manipulate the term before turning it + * into a constr *) +type ast_closure_term = { + body : Constrexpr.constr_expr; + glob_env : Genintern.glob_sign option; (* for Tacintern.intern_constr *) + interp_env : Geninterp.interp_sign option; (* for Tacinterp.interp_open_constr_with_bindings *) + annotation : [ `None | `Parens | `DoubleParens | `At ]; +} + +type ssrview = ast_closure_term list (* TODO type id_mod = Hat | HatTilde | Sharp @@ -61,7 +73,6 @@ type anon_iter = | One | Drop | All - (* TODO | Dependent (* fast mode *) | UntilMark @@ -73,15 +84,15 @@ type ssripat = | IPatId of (*TODO id_mod option * *) Id.t | IPatAnon of anon_iter (* inaccessible name *) (* TODO | IPatClearMark *) -(* TODO | IPatDispatch of ssripatss (* /[..|..] *) *) + | IPatDispatch of ssripatss (* /[..|..] *) | IPatCase of (* ipats_mod option * *) ssripatss (* this is not equivalent to /case /[..|..] if there are already multiple goals *) | IPatInj of ssripatss | IPatRewrite of (*occurrence option * rewrite_pattern **) ssrocc * ssrdir - | IPatView of ssrterm list (* /view *) + | IPatView of ssrview (* /view *) | IPatClear of ssrclear (* {H1 H2} *) | IPatSimpl of ssrsimpl - | IPatNewHidden of Id.t list -(* | IPatVarsForAbstract of Id.t list *) + | IPatAbstractVars of Id.t list + | IPatTac of unit Proofview.tactic and ssripats = ssripat list and ssripatss = ssripats list @@ -129,12 +140,12 @@ type 'tac ssrhint = bool * 'tac option list type 'tac fwdbinders = bool * (ssrhpats * ((ssrfwdfmt * ssrterm) * 'tac ssrhint)) -type clause = +type clause = (ssrclear * ((ssrhyp_or_id * string) * Ssrmatching_plugin.Ssrmatching.cpattern option) option) type clauses = clause list * ssrclseq -type wgen = +type wgen = (ssrclear * ((ssrhyp_or_id * string) * Ssrmatching_plugin.Ssrmatching.cpattern option) @@ -143,9 +154,20 @@ type wgen = type 'a ssrdoarg = ((ssrindex * ssrmmod) * 'a ssrhint) * clauses type 'a ssrseqarg = ssrindex * ('a ssrhint * 'a option) + +open Ssrmatching_plugin +open Ssrmatching +type ssrdgens = { dgens : (ssrdocc * cpattern) list; + gens : (ssrdocc * cpattern) list; + clr : ssrclear } +type ssrcasearg = ssripat option * (ssrdgens * ssripats) +type ssrmovearg = ssrview * ssrcasearg +type ssragens = ((ssrhyps option * occ) * ssrterm) list list * ssrclear +type ssrapplyarg = ssrterm list * (ssragens * ssripats) + (* OOP : these are general shortcuts *) type gist = Tacintern.glob_sign type ist = Tacinterp.interp_sign -type goal = Goal.goal +type goal = Goal.goal type 'a sigma = 'a Evd.sigma type v82tac = Tacmach.tactic diff --git a/plugins/ssr/ssrbwd.ml b/plugins/ssr/ssrbwd.ml index 2bf3d5fbf..1c4508abf 100644 --- a/plugins/ssr/ssrbwd.ml +++ b/plugins/ssr/ssrbwd.ml @@ -53,6 +53,24 @@ let interp_agen ist gl ((goclr, _), (k, gc as c)) (clr, rcs) = let pf_pr_glob_constr gl = pr_glob_constr_env (pf_env gl) +let interp_nbargs ist gl rc = + try + let rc6 = mkRApp rc (mkRHoles 6) in + let sigma, t = interp_open_constr ist gl (rc6, None) in + let si = sig_it gl in + let gl = re_sig si sigma in + 6 + Ssrcommon.nbargs_open_constr gl t + with _ -> 5 + +let interp_view_nbimps ist gl rc = + try + let sigma, t = interp_open_constr ist gl (rc, None) in + let si = sig_it gl in + let gl = re_sig si sigma in + let pl, c = splay_open_constr gl t in + if Ssrcommon.isAppInd (pf_env gl) (project gl) c then List.length pl else (-(List.length pl)) + with _ -> 0 + let interp_agens ist gl gagens = match List.fold_right (interp_agen ist gl) gagens ([], []) with | clr, rlemma :: args -> @@ -88,40 +106,55 @@ let mkRAppView ist gl rv gv = let prof_apply_interp_with = mk_profiler "ssrapplytac.interp_with";; -let refine_interp_apply_view i ist gl gv = +let refine_interp_apply_view dbl ist gl gv = let pair i = List.map (fun x -> i, x) in let rv = pf_intern_term ist gl gv in let v = mkRAppView ist gl rv gv in - let interp_with (i, hint) = + let interp_with (dbl, hint) = + let i = if dbl = Ssrview.AdaptorDb.Equivalence then 2 else 1 in interp_refine ist gl (mkRApp hint (v :: mkRHoles i)) in let interp_with x = prof_apply_interp_with.profile interp_with x in let rec loop = function | [] -> (try apply_rconstr ~ist rv gl with _ -> view_error "apply" gv) | h :: hs -> (try refine_with (snd (interp_with h)) gl with _ -> loop hs) in - loop (pair i Ssrview.viewtab.(i) @ - if i = 2 then pair 1 Ssrview.viewtab.(1) else []) - -let apply_top_tac gl = - Tacticals.tclTHENLIST [introid top_id; apply_rconstr (mkRVar top_id); Proofview.V82.of_tactic (Tactics.clear [top_id])] gl - -let inner_ssrapplytac gviews ggenl gclr ist gl = + loop (pair dbl (Ssrview.AdaptorDb.get dbl) @ + if dbl = Ssrview.AdaptorDb.Equivalence + then pair Ssrview.AdaptorDb.Backward (Ssrview.AdaptorDb.(get Backward)) + else []) + +let apply_top_tac = + Tacticals.tclTHENLIST [ + introid top_id; + apply_rconstr (mkRVar top_id); + old_cleartac [SsrHyp(None,top_id)] + ] + +let inner_ssrapplytac gviews (ggenl, gclr) ist = Proofview.V82.tactic ~nf_evars:false (fun gl -> let _, clr = interp_hyps ist gl gclr in let vtac gv i gl' = refine_interp_apply_view i ist gl' gv in let ggenl, tclGENTAC = if gviews <> [] && ggenl <> [] then - let ggenl= List.map (fun (x,g) -> x, cpattern_of_term g) (List.hd ggenl) in - [], Tacticals.tclTHEN (genstac (ggenl,[]) ist) + let ggenl= List.map (fun (x,g) -> x, cpattern_of_term g ist) (List.hd ggenl) in + [], Tacticals.tclTHEN (genstac (ggenl,[])) else ggenl, Tacticals.tclTHEN Tacticals.tclIDTAC in tclGENTAC (fun gl -> match gviews, ggenl with | v :: tl, [] -> - let dbl = if List.length tl = 1 then 2 else 1 in + let dbl = + if List.length tl = 1 + then Ssrview.AdaptorDb.Equivalence + else Ssrview.AdaptorDb.Backward in Tacticals.tclTHEN - (List.fold_left (fun acc v -> Tacticals.tclTHENLAST acc (vtac v dbl)) (vtac v 1) tl) - (cleartac clr) gl + (List.fold_left (fun acc v -> + Tacticals.tclTHENLAST acc (vtac v dbl)) + (vtac v Ssrview.AdaptorDb.Backward) tl) + (old_cleartac clr) gl | [], [agens] -> let clr', (sigma, lemma) = interp_agens ist gl agens in let gl = pf_merge_uc_of sigma gl in - Tacticals.tclTHENLIST [cleartac clr; refine_with ~beta:true lemma; cleartac clr'] gl - | _, _ -> Tacticals.tclTHEN apply_top_tac (cleartac clr) gl) gl + Tacticals.tclTHENLIST [old_cleartac clr; refine_with ~beta:true lemma; old_cleartac clr'] gl + | _, _ -> + Tacticals.tclTHENLIST [apply_top_tac; old_cleartac clr] gl) gl +) +let apply_top_tac = Proofview.V82.tactic ~nf_evars:false apply_top_tac diff --git a/plugins/ssr/ssrbwd.mli b/plugins/ssr/ssrbwd.mli index 6e1cce556..6243e5e68 100644 --- a/plugins/ssr/ssrbwd.mli +++ b/plugins/ssr/ssrbwd.mli @@ -8,16 +8,9 @@ (* * (see LICENSE file for the text of the license) *) (************************************************************************) -(* This file is (C) Copyright 2006-2015 Microsoft Corporation and Inria. *) +open Ssrast +open Proofview +val apply_top_tac : unit tactic -val apply_top_tac : Goal.goal Evd.sigma -> Goal.goal list Evd.sigma - -val inner_ssrapplytac : - Ssrast.ssrterm list -> - ((Ssrast.ssrhyps option * Ssrmatching_plugin.Ssrmatching.occ) * - (Ssrast.ssrtermkind * Tacexpr.glob_constr_and_expr)) - list list -> - Ssrast.ssrhyps -> - Ssrast.ist -> - Goal.goal Evd.sigma -> Goal.goal list Evd.sigma +val inner_ssrapplytac : ssrterm list -> ssragens -> ist -> unit tactic diff --git a/plugins/ssr/ssrcommon.ml b/plugins/ssr/ssrcommon.ml index b44db2e22..5163ec7b3 100644 --- a/plugins/ssr/ssrcommon.ml +++ b/plugins/ssr/ssrcommon.ml @@ -172,6 +172,11 @@ let array_list_of_tl v = (* end patch *) +let option_assert_get o msg = + match o with + | None -> CErrors.anomaly msg + | Some x -> x + (** Constructors for rawconstr *) open Glob_term @@ -205,7 +210,7 @@ let glob_constr ist genv = function let vars = Id.Map.fold (fun x _ accu -> Id.Set.add x accu) ist.Tacinterp.lfun Id.Set.empty in let ltacvars = { Constrintern.empty_ltac_sign with Constrintern.ltac_vars = vars } in - Constrintern.intern_gen Pretyping.WithoutTypeConstraint ~ltacvars genv ce + Constrintern.intern_gen Pretyping.WithoutTypeConstraint ~ltacvars genv Evd.(from_env genv) ce | rc, None -> rc let pf_intern_term ist gl (_, c) = glob_constr ist (pf_env gl) c @@ -222,8 +227,9 @@ let splay_open_constr gl (sigma, c) = let env = pf_env gl in let t = Retyping.get_type_of env sigma c in Reductionops.splay_prod env sigma t -let isAppInd gl c = - try ignore (pf_reduce_to_atomic_ind gl c); true with _ -> false +let isAppInd env sigma c = + try ignore(Tacred.reduce_to_atomic_ind env sigma c); true + with CErrors.UserError _ -> false (** Generic argument-based globbing/typing utilities *) @@ -278,30 +284,46 @@ let interp_hyps ist gl ghyps = let hyps = List.map snd (List.map (interp_hyp ist gl) ghyps) in check_hyps_uniq [] hyps; Tacmach.project gl, hyps +(* Old terms *) let mk_term k c = k, (mkRHole, Some c) let mk_lterm c = mk_term xNoFlag c -let interp_view_nbimps ist gl rc = - try - let sigma, t = interp_open_constr ist gl (rc, None) in - let si = sig_it gl in - let gl = re_sig si sigma in - let pl, c = splay_open_constr gl t in - if isAppInd gl c then List.length pl else (-(List.length pl)) - with _ -> 0 +(* New terms *) + +let mk_ast_closure_term a t = { + annotation = a; + body = t; + interp_env = None; + glob_env = None; +} + +let glob_ast_closure_term (ist : Genintern.glob_sign) t = + { t with glob_env = Some ist } +let subst_ast_closure_term (_s : Mod_subst.substitution) t = + (* _s makes sense only for glob constr *) + t +let interp_ast_closure_term (ist : Geninterp.interp_sign) (gl : 'goal Evd.sigma) t = + (* gl is only useful if we want to interp *now*, later we have + * a potentially different gl.sigma *) + Tacmach.project gl, { t with interp_env = Some ist } + +let ssrterm_of_ast_closure_term { body; annotation } = + let c = match annotation with + | `Parens -> xInParens + | `At -> xWithAt + | _ -> xNoFlag in + mk_term c body + +let ssrdgens_of_parsed_dgens = function + | [], clr -> { dgens = []; gens = []; clr } + | [gens], clr -> { dgens = []; gens; clr } + | [dgens;gens], clr -> { dgens; gens; clr } + | _ -> assert false + let nbargs_open_constr gl oc = let pl, _ = splay_open_constr gl oc in List.length pl -let interp_nbargs ist gl rc = - try - let rc6 = mkRApp rc (mkRHoles 6) in - let sigma, t = interp_open_constr ist gl (rc6, None) in - let si = sig_it gl in - let gl = re_sig si sigma in - 6 + nbargs_open_constr gl t - with _ -> 5 - let pf_nbargs gl c = nbargs_open_constr gl (project gl, c) let internal_names = ref [] @@ -380,7 +402,7 @@ let max_suffix m (t, j0 as tj0) id = dt < ds && skip_digits s i = n in loop m -let mk_anon_id t gl = +let mk_anon_id t gl_ids = let m, si0, id0 = let s = ref (Printf.sprintf "_%s_" t) in if is_internal_name !s then s := "_" ^ !s; @@ -389,7 +411,6 @@ let mk_anon_id t gl = let d = !s.[i] in if not (is_digit d) then i + 1, j else loop (i - 1) (if d = '0' then j else i) in let m, j = loop (n - 1) n in m, (!s, j), Id.of_string !s in - let gl_ids = pf_ids_of_hyps gl in if not (List.mem id0 gl_ids) then id0 else let s, i = List.fold_left (max_suffix m) si0 gl_ids in let open Bytes in @@ -437,8 +458,8 @@ let red_product_skip_id env sigma c = match EConstr.kind sigma c with | App(hd,args) when Array.length args = 1 && is_id_constr sigma hd -> args.(0) | _ -> try Tacred.red_product env sigma c with _ -> c -let ssrevaltac ist gtac = - Proofview.V82.of_tactic (Tacinterp.tactic_of_value ist gtac) +let ssrevaltac ist gtac = Tacinterp.tactic_of_value ist gtac + (** Open term to lambda-term coercion {{{ ************************************) (* This operation takes a goal gl and an open term (sigma, t), and *) @@ -482,7 +503,7 @@ let nf_evar sigma t = EConstr.Unsafe.to_constr (Evarutil.nf_evar sigma (EConstr.of_constr t)) let pf_abs_evars2 gl rigid (sigma, c0) = - let c0 = EConstr.Unsafe.to_constr c0 in + let c0 = EConstr.to_constr sigma c0 in let sigma0, ucst = project gl, Evd.evar_universe_context sigma in let nenv = env_size (pf_env gl) in let abs_evar n k = @@ -778,7 +799,7 @@ let rec is_name_in_ipats name = function List.exists (function SsrHyp(_,id) -> id = name) clr || is_name_in_ipats name tl | IPatId id :: tl -> id = name || is_name_in_ipats name tl - | IPatCase l :: tl -> List.exists (is_name_in_ipats name) l || is_name_in_ipats name tl + | (IPatCase l | IPatDispatch l) :: tl -> List.exists (is_name_in_ipats name) l || is_name_in_ipats name tl | _ :: tl -> is_name_in_ipats name tl | [] -> false @@ -1084,14 +1105,10 @@ let introid ?(orig=ref Anonymous) name = tclTHEN (fun gl -> let anontac decl gl = let id = match RelDecl.get_name decl with | Name id -> - if is_discharged_id id then id else mk_anon_id (Id.to_string id) gl - | _ -> mk_anon_id ssr_anon_hyp gl in + if is_discharged_id id then id else mk_anon_id (Id.to_string id) (Tacmach.pf_ids_of_hyps gl) + | _ -> mk_anon_id ssr_anon_hyp (Tacmach.pf_ids_of_hyps gl) in introid id gl -let intro_all gl = - let dc, _ = EConstr.decompose_prod_assum (project gl) (Tacmach.pf_concl gl) in - tclTHENLIST (List.map anontac (List.rev dc)) gl - let rec intro_anon gl = try anontac (List.hd (fst (EConstr.decompose_prod_n_assum (project gl) 1 (Tacmach.pf_concl gl)))) gl with err0 -> try tclTHEN (Proofview.V82.of_tactic Tactics.red_in_concl) intro_anon gl with e when CErrors.noncritical e -> raise err0 @@ -1148,15 +1165,16 @@ let tclMULT = function | n, Must when n > 1 -> tclDO n | _ -> tclID -let cleartac clr = check_hyps_uniq [] clr; Proofview.V82.of_tactic (Tactics.clear (hyps_ids clr)) +let old_cleartac clr = check_hyps_uniq [] clr; Proofview.V82.of_tactic (Tactics.clear (hyps_ids clr)) +let cleartac clr = check_hyps_uniq [] clr; Tactics.clear (hyps_ids clr) (** }}} *) (** Generalize tactic *) (* XXX the k of the redex should percolate out *) -let pf_interp_gen_aux ist gl to_ind ((oclr, occ), t) = - let pat = interp_cpattern ist gl t None in (* UGLY API *) +let pf_interp_gen_aux gl to_ind ((oclr, occ), t) = + let pat = interp_cpattern gl t None in (* UGLY API *) let cl, env, sigma = Tacmach.pf_concl gl, pf_env gl, project gl in let (c, ucst), cl = try fill_occ_pattern ~raise_NoMatch:true env sigma (EConstr.Unsafe.to_constr cl) pat occ 1 @@ -1197,22 +1215,22 @@ let genclrtac cl cs clr = (fun type_err gl -> tclTHEN (tclTHEN (Proofview.V82.of_tactic (Tactics.elim_type (EConstr.of_constr - (Universes.constr_of_global @@ Coqlib.build_coq_False ())))) (cleartac clr)) + (Universes.constr_of_global @@ Coqlib.build_coq_False ())))) (old_cleartac clr)) (fun gl -> raise type_err) gl)) - (cleartac clr) + (old_cleartac clr) -let gentac ist gen gl = +let gentac gen gl = (* ppdebug(lazy(str"sigma@gentac=" ++ pr_evar_map None (project gl))); *) - let conv, _, cl, c, clr, ucst,gl = pf_interp_gen_aux ist gl false gen in + let conv, _, cl, c, clr, ucst,gl = pf_interp_gen_aux gl false gen in ppdebug(lazy(str"c@gentac=" ++ pr_econstr_env (pf_env gl) (project gl) c)); let gl = pf_merge_uc ucst gl in if conv - then tclTHEN (Proofview.V82.of_tactic (convert_concl cl)) (cleartac clr) gl + then tclTHEN (Proofview.V82.of_tactic (convert_concl cl)) (old_cleartac clr) gl else genclrtac cl [c] clr gl -let genstac (gens, clr) ist = - tclTHENLIST (cleartac clr :: List.rev_map (gentac ist) gens) +let genstac (gens, clr) = + tclTHENLIST (old_cleartac clr :: List.rev_map gentac gens) let gen_tmp_ids ?(ist=Geninterp.({ lfun = Id.Map.empty; extra = Tacinterp.TacStore.empty })) gl @@ -1222,13 +1240,13 @@ let gen_tmp_ids (tclTHENLIST (List.map (fun (id,orig_ref) -> tclTHEN - (gentac ist ((None,Some(false,[])),cpattern_of_id id)) + (gentac ((None,Some(false,[])),cpattern_of_id id)) (rename_hd_prod orig_ref)) ctx.tmp_ids) gl) ;; -let pf_interp_gen ist gl to_ind gen = - let _, _, a, b, c, ucst,gl = pf_interp_gen_aux ist gl to_ind gen in +let pf_interp_gen gl to_ind gen = + let _, _, a, b, c, ucst,gl = pf_interp_gen_aux gl to_ind gen in a, b ,c, pf_merge_uc ucst gl (* TASSI: This version of unprotects inlines the unfold tactic definition, @@ -1249,7 +1267,11 @@ let unprotecttac gl = CClosure.RedFlags.fCOFIX]), DEFAULTcast) hyploc)) allHypsAndConcl gl -let abs_wgen keep_let ist f gen (gl,args,c) = +let is_protect hd env sigma = + let _, protectC = mkSsrConst "protect_term" env sigma in + EConstr.eq_constr_nounivs sigma hd protectC + +let abs_wgen keep_let f gen (gl,args,c) = let sigma, env = project gl, pf_env gl in let evar_closed t p = if occur_existential sigma t then @@ -1269,7 +1291,7 @@ let abs_wgen keep_let ist f gen (gl,args,c) = gl, EConstr.mkVar x :: args, EConstr.mkProd (Name (f x),Tacmach.pf_get_hyp_typ gl x, EConstr.Vars.subst_var x c) | _, Some ((x, "@"), Some p) -> let x = hoi_id x in - let cp = interp_cpattern ist gl p None in + let cp = interp_cpattern gl p None in let (t, ucst), c = try fill_occ_pattern ~raise_NoMatch:true env sigma (EConstr.Unsafe.to_constr c) cp None 1 with NoMatch -> redex_of_pattern env cp, (EConstr.Unsafe.to_constr c) in @@ -1281,7 +1303,7 @@ let abs_wgen keep_let ist f gen (gl,args,c) = pf_merge_uc ucst gl, args, EConstr.mkLetIn(Name (f x), ut, ty, c) | _, Some ((x, _), Some p) -> let x = hoi_id x in - let cp = interp_cpattern ist gl p None in + let cp = interp_cpattern gl p None in let (t, ucst), c = try fill_occ_pattern ~raise_NoMatch:true env sigma (EConstr.Unsafe.to_constr c) cp None 1 with NoMatch -> redex_of_pattern env cp, (EConstr.Unsafe.to_constr c) in @@ -1295,8 +1317,252 @@ let abs_wgen keep_let ist f gen (gl,args,c) = let clr_of_wgen gen clrs = match gen with | clr, Some ((x, _), None) -> let x = hoi_id x in - cleartac clr :: cleartac [SsrHyp(Loc.tag x)] :: clrs - | clr, _ -> cleartac clr :: clrs + old_cleartac clr :: old_cleartac [SsrHyp(Loc.tag x)] :: clrs + | clr, _ -> old_cleartac clr :: clrs + + +let reduct_in_concl t = Tactics.reduct_in_concl (t, DEFAULTcast) +let unfold cl = + let module R = Reductionops in let module F = CClosure.RedFlags in + reduct_in_concl (R.clos_norm_flags (F.mkflags + (List.map (fun c -> F.fCONST (fst (destConst (EConstr.Unsafe.to_constr c)))) cl @ + [F.fBETA; F.fMATCH; F.fFIX; F.fCOFIX]))) + +open Proofview +open Notations + +let tacSIGMA = Goal.enter_one begin fun g -> + let k = Goal.goal g in + let sigma = Goal.sigma g in + tclUNIT (Tacmach.re_sig k sigma) +end + +let tclINTERP_AST_CLOSURE_TERM_AS_CONSTR c = + tclINDEPENDENTL begin tacSIGMA >>= fun gl -> + let old_ssrterm = mkRHole, Some c.Ssrast.body in + let ist = + option_assert_get c.Ssrast.interp_env + Pp.(str "tclINTERP_AST_CLOSURE_TERM_AS_CONSTR: term with no ist") in + let sigma, t = + interp_wit Stdarg.wit_constr ist gl old_ssrterm in + Unsafe.tclEVARS sigma <*> + tclUNIT t +end + +let tacREDUCE_TO_QUANTIFIED_IND ty = + tacSIGMA >>= fun gl -> + tclUNIT (Tacmach.pf_reduce_to_quantified_ind gl ty) + +let tacTYPEOF c = Goal.enter_one ~__LOC__ (fun g -> + let sigma, env = Goal.sigma g, Goal.env g in + let sigma, ty = Typing.type_of env sigma c in + Unsafe.tclEVARS sigma <*> tclUNIT ty) + +(** This tactic creates a partial proof realizing the introduction rule, but + does not check anything. *) +let unsafe_intro env store decl b = + let open Context.Named.Declaration in + Refine.refine ~typecheck:false begin fun sigma -> + let ctx = Environ.named_context_val env in + let nctx = EConstr.push_named_context_val decl ctx in + let inst = List.map (get_id %> EConstr.mkVar) (Environ.named_context env) in + let ninst = EConstr.mkRel 1 :: inst in + let nb = EConstr.Vars.subst1 (EConstr.mkVar (get_id decl)) b in + let sigma, ev = + Evarutil.new_evar_instance nctx sigma nb ~principal:true ~store ninst in + sigma, EConstr.mkNamedLambda_or_LetIn decl ev + end + +let set_decl_id id = let open Context in function + | Rel.Declaration.LocalAssum(name,ty) -> Named.Declaration.LocalAssum(id,ty) + | Rel.Declaration.LocalDef(name,ty,t) -> Named.Declaration.LocalDef(id,ty,t) + +let rec decompose_assum env sigma orig_goal = + let open Context in + match EConstr.kind sigma orig_goal with + | Prod(name,ty,t) -> + Rel.Declaration.LocalAssum(name,ty), t, true + | LetIn(name,ty,t1,t2) -> Rel.Declaration.LocalDef(name, ty, t1), t2, true + | _ -> + let goal = Reductionops.whd_allnolet env sigma orig_goal in + match EConstr.kind sigma goal with + | Prod(name,ty,t) -> Rel.Declaration.LocalAssum(name,ty), t, false + | LetIn(name,ty,t1,t2) -> Rel.Declaration.LocalDef(name,ty,t1), t2, false + | App(hd,args) when EConstr.isLetIn sigma hd -> (* hack *) + let _,v,_,b = EConstr.destLetIn sigma hd in + let ctx, t, _ = + decompose_assum env sigma + (EConstr.mkApp (EConstr.Vars.subst1 v b, args)) in + ctx, t, false + | _ -> CErrors.user_err + Pp.(str "No assumption in " ++ Printer.pr_econstr_env env sigma goal) + +let tclFULL_BETAIOTA = Goal.enter begin fun gl -> + let r, _ = Redexpr.reduction_of_red_expr (Goal.env gl) + Genredexpr.(Lazy { + rBeta=true; rMatch=true; rFix=true; rCofix=true; + rZeta=false; rDelta=false; rConst=[]}) in + Tactics.e_reduct_in_concl ~check:false (r,Constr.DEFAULTcast) +end + +(** [intro id k] introduces the first premise (product or let-in) of the goal + under the name [id], reducing the head of the goal (using beta, iota, delta + but not zeta) if necessary. If [id] is None, a name is generated, that will + not be user accessible. If the goal does not start with a product or a +let-in even after reduction, it fails. In case of success, the original name +and final id are passed to the continuation [k] which gets evaluated. *) +let tclINTRO ~id ~conclusion:k = Goal.enter begin fun gl -> + let open Context in + let env, sigma, extra, g = Goal.(env gl, sigma gl, extra gl, concl gl) in + let decl, t, no_red = decompose_assum env sigma g in + let original_name = Rel.Declaration.get_name decl in + let already_used = Tacmach.New.pf_ids_of_hyps gl in + let id = match id, original_name with + | Some id, _ -> id + | _, Name id -> + if is_discharged_id id then id + else mk_anon_id (Id.to_string id) already_used + | _, _ -> + let ids = Tacmach.New.pf_ids_of_hyps gl in + mk_anon_id ssr_anon_hyp ids + in + if List.mem id already_used then + errorstrm Pp.(Id.print id ++ str" already used"); + unsafe_intro env extra (set_decl_id id decl) t <*> + (if no_red then tclUNIT () else tclFULL_BETAIOTA) <*> + k ~orig_name:original_name ~new_name:id +end + +let return ~orig_name:_ ~new_name:_ = tclUNIT () + +let tclINTRO_ID id = tclINTRO ~id:(Some id) ~conclusion:return +let tclINTRO_ANON = tclINTRO ~id:None ~conclusion:return + +let tclRENAME_HD_PROD name = Goal.enter begin fun gl -> + let convert_concl_no_check t = + Tactics.convert_concl_no_check t Term.DEFAULTcast in + let concl = Goal.concl gl in + let sigma = Goal.sigma gl in + match EConstr.kind sigma concl with + | Prod(_,src,tgt) -> + convert_concl_no_check EConstr.(mkProd (name,src,tgt)) + | _ -> CErrors.anomaly (Pp.str "rename_hd_prod: no head product") +end + +let tcl0G tac = + numgoals >>= fun ng -> if ng = 0 then tclUNIT () else tac + +let rec tclFIRSTa = function + | [] -> Tacticals.New.tclZEROMSG Pp.(str"No applicable tactic.") + | tac :: rest -> tclORELSE tac (fun _ -> tclFIRSTa rest) + +let rec tclFIRSTi tac n = + if n < 0 then Tacticals.New.tclZEROMSG Pp.(str "tclFIRSTi") + else tclORELSE (tclFIRSTi tac (n-1)) (fun _ -> tac n) + +let tacCONSTR_NAME ?name c = + match name with + | Some n -> tclUNIT n + | None -> + Goal.enter_one ~__LOC__ (fun g -> + let sigma = Goal.sigma g in + tclUNIT (constr_name sigma c)) + +let tacMKPROD c ?name cl = + tacTYPEOF c >>= fun t -> + tacCONSTR_NAME ?name c >>= fun name -> + Goal.enter_one ~__LOC__ begin fun g -> + let sigma, env = Goal.sigma g, Goal.env g in + if name <> Names.Name.Anonymous || EConstr.Vars.noccurn sigma 1 cl + then tclUNIT (EConstr.mkProd (name, t, cl)) + else + let name = Names.Id.of_string (Namegen.hdchar env sigma t) in + tclUNIT (EConstr.mkProd (Names.Name.Name name, t, cl)) +end + +let tacINTERP_CPATTERN cp = + tacSIGMA >>= begin fun gl -> + tclUNIT (Ssrmatching.interp_cpattern gl cp None) +end + +let tacUNIFY a b = + tacSIGMA >>= begin fun gl -> + let gl = Ssrmatching.pf_unify_HO gl a b in + Unsafe.tclEVARS (Tacmach.project gl) +end + +let tclOPTION o d = + match o with + | None -> d >>= tclUNIT + | Some x -> tclUNIT x + +let tacIS_INJECTION_CASE ?ty t = begin + tclOPTION ty (tacTYPEOF t) >>= fun ty -> + tacREDUCE_TO_QUANTIFIED_IND ty >>= fun ((mind,_),_) -> + tclUNIT (Globnames.eq_gr (Globnames.IndRef mind) (Coqlib.build_coq_eq ())) +end + +let tclWITHTOP tac = Goal.enter begin fun gl -> + let top = + mk_anon_id "top_assumption" (Tacmach.New.pf_ids_of_hyps gl) in + tclINTRO_ID top <*> + tac (EConstr.mkVar top) <*> + Tactics.clear [top] +end + +let tacMK_SSR_CONST name = Goal.enter_one ~__LOC__ begin fun g -> + let sigma, env = Goal.(sigma g, env g) in + let sigma, c = mkSsrConst name env sigma in + Unsafe.tclEVARS sigma <*> + tclUNIT c +end + +module type StateType = sig + type state + val init : state +end + +module MakeState(S : StateType) = struct + +let state_field : S.state Proofview_monad.StateStore.field = + Proofview_monad.StateStore.field () + +(* FIXME: should not inject fresh_state, but initialize it at the beginning *) +let lift_upd_state upd s = + let open Proofview_monad.StateStore in + let old_state = Option.default S.init (get s state_field) in + upd old_state >>= fun new_state -> + tclUNIT (set s state_field new_state) + +let tacUPDATE upd = Goal.enter begin fun gl -> + let s0 = Goal.state gl in + Goal.enter_one ~__LOC__ (fun _ -> lift_upd_state upd s0) >>= fun s -> + Unsafe.tclGETGOALS >>= fun gls -> + let gls = List.map (fun gs -> + let g = Proofview_monad.drop_state gs in + Proofview_monad.goal_with_state g s) gls in + Unsafe.tclSETGOALS gls +end + +let tclGET k = Goal.enter begin fun gl -> + let open Proofview_monad.StateStore in + k (Option.default S.init (get (Goal.state gl) state_field)) +end + +let tclSET new_s = + let open Proofview_monad.StateStore in + Unsafe.tclGETGOALS >>= fun gls -> + let gls = List.map (fun gs -> + let g = Proofview_monad.drop_state gs in + let s = Proofview_monad.get_state gs in + Proofview_monad.goal_with_state g (set s state_field new_s)) gls in + Unsafe.tclSETGOALS gls + +let get g = + Option.default S.init + (Proofview_monad.StateStore.get (Goal.state g) state_field) + +end (* vim: set filetype=ocaml foldmethod=marker: *) diff --git a/plugins/ssr/ssrcommon.mli b/plugins/ssr/ssrcommon.mli index dd3531d90..7c16e1ba9 100644 --- a/plugins/ssr/ssrcommon.mli +++ b/plugins/ssr/ssrcommon.mli @@ -20,6 +20,8 @@ open Ssrast open Ltac_plugin open Genarg +open Ssrmatching_plugin + val allocc : ssrocc (******************************** hyps ************************************) @@ -50,6 +52,8 @@ val array_app_tl : 'a array -> 'a list -> 'a list val array_list_of_tl : 'a array -> 'a list val array_fold_right_from : int -> ('a -> 'b -> 'b) -> 'a array -> 'b -> 'b +val option_assert_get : 'a option -> Pp.t -> 'a + (**************************** lifted tactics ******************************) (* tactics with extra data attached to each goals, e.g. the list of @@ -152,17 +156,22 @@ val splay_open_constr : Goal.goal Evd.sigma -> evar_map * EConstr.t -> (Names.Name.t * EConstr.t) list * EConstr.t -val isAppInd : Goal.goal Evd.sigma -> EConstr.types -> bool -val interp_view_nbimps : - Tacinterp.interp_sign -> - Goal.goal Evd.sigma -> Glob_term.glob_constr -> int -val interp_nbargs : - Tacinterp.interp_sign -> - Goal.goal Evd.sigma -> Glob_term.glob_constr -> int +val isAppInd : Environ.env -> Evd.evar_map -> EConstr.types -> bool +val mk_term : ssrtermkind -> constr_expr -> ssrterm +val mk_lterm : constr_expr -> ssrterm -val mk_term : ssrtermkind -> 'b -> ssrtermkind * (Glob_term.glob_constr * 'b option) -val mk_lterm : 'a -> ssrtermkind * (Glob_term.glob_constr * 'a option) +val mk_ast_closure_term : + [ `None | `Parens | `DoubleParens | `At ] -> + Constrexpr.constr_expr -> ast_closure_term +val interp_ast_closure_term : Geninterp.interp_sign -> Proof_type.goal +Evd.sigma -> ast_closure_term -> Evd.evar_map * ast_closure_term +val subst_ast_closure_term : Mod_subst.substitution -> ast_closure_term -> ast_closure_term +val glob_ast_closure_term : Genintern.glob_sign -> ast_closure_term -> ast_closure_term +val ssrterm_of_ast_closure_term : ast_closure_term -> ssrterm + +val ssrdgens_of_parsed_dgens : + (ssrdocc * Ssrmatching.cpattern) list list * ssrclear -> ssrdgens val is_internal_name : string -> bool val add_internal_name : (string -> bool) -> unit @@ -201,11 +210,6 @@ val pf_abs_prod : Goal.goal Evd.sigma -> EConstr.t -> EConstr.t -> Goal.goal Evd.sigma * EConstr.types -val pf_mkprod : - Goal.goal Evd.sigma -> - EConstr.t -> - ?name:Name.t -> - EConstr.t -> Goal.goal Evd.sigma * EConstr.types val mkSsrRRef : string -> Glob_term.glob_constr * 'a option val mkSsrRef : string -> Globnames.global_reference @@ -231,17 +235,19 @@ val has_discharged_tag : string -> bool val ssrqid : string -> Libnames.qualid val new_tmp_id : tac_ctx -> (Names.Id.t * Name.t ref) * tac_ctx -val mk_anon_id : string -> Goal.goal Evd.sigma -> Id.t +val mk_anon_id : string -> Id.t list -> Id.t val pf_abs_evars_pirrel : Goal.goal Evd.sigma -> evar_map * Constr.constr -> int * Constr.constr +val nbargs_open_constr : Goal.goal Evd.sigma -> Evd.evar_map * EConstr.t -> int val pf_nbargs : Goal.goal Evd.sigma -> EConstr.t -> int val gen_tmp_ids : ?ist:Geninterp.interp_sign -> (Goal.goal * tac_ctx) Evd.sigma -> (Goal.goal * tac_ctx) list Evd.sigma -val ssrevaltac : Tacinterp.interp_sign -> Tacinterp.Value.t -> Proofview.V82.tac +val ssrevaltac : + Tacinterp.interp_sign -> Tacinterp.Value.t -> unit Proofview.tactic val convert_concl_no_check : EConstr.t -> unit Proofview.tactic val convert_concl : EConstr.t -> unit Proofview.tactic @@ -336,33 +342,29 @@ val rewritetac : ssrdir -> EConstr.t -> tactic type name_hint = (int * EConstr.types array) option ref -val gentac : - (Geninterp.interp_sign -> - (Ssrast.ssrdocc) * - Ssrmatching_plugin.Ssrmatching.cpattern -> Tacmach.tactic) +val gentac : + Ssrast.ssrdocc * Ssrmatching.cpattern -> v82tac val genstac : - ((Ssrast.ssrhyp list option * Ssrmatching_plugin.Ssrmatching.occ) * - Ssrmatching_plugin.Ssrmatching.cpattern) + ((Ssrast.ssrhyp list option * Ssrmatching.occ) * + Ssrmatching.cpattern) list * Ssrast.ssrhyp list -> - Tacinterp.interp_sign -> Tacmach.tactic + Tacmach.tactic val pf_interp_gen : - Tacinterp.interp_sign -> Goal.goal Evd.sigma -> bool -> - (Ssrast.ssrhyp list option * Ssrmatching_plugin.Ssrmatching.occ) * - Ssrmatching_plugin.Ssrmatching.cpattern -> + (Ssrast.ssrhyp list option * Ssrmatching.occ) * + Ssrmatching.cpattern -> EConstr.t * EConstr.t * Ssrast.ssrhyp list * Goal.goal Evd.sigma val pf_interp_gen_aux : - Tacinterp.interp_sign -> Goal.goal Evd.sigma -> bool -> - (Ssrast.ssrhyp list option * Ssrmatching_plugin.Ssrmatching.occ) * - Ssrmatching_plugin.Ssrmatching.cpattern -> - bool * Ssrmatching_plugin.Ssrmatching.pattern * EConstr.t * + (Ssrast.ssrhyp list option * Ssrmatching.occ) * + Ssrmatching.cpattern -> + bool * Ssrmatching.pattern * EConstr.t * EConstr.t * Ssrast.ssrhyp list * UState.t * Goal.goal Evd.sigma @@ -380,7 +382,6 @@ val mk_profiler : string -> profiler val introid : ?orig:Name.t ref -> Id.t -> v82tac val intro_anon : v82tac -val intro_all : v82tac val interp_clr : evar_map -> ssrhyps option * (ssrtermkind * EConstr.t) -> ssrhyps @@ -388,19 +389,20 @@ val interp_clr : val genclrtac : EConstr.constr -> EConstr.constr list -> Ssrast.ssrhyp list -> Tacmach.tactic -val cleartac : ssrhyps -> v82tac +val old_cleartac : ssrhyps -> v82tac +val cleartac : ssrhyps -> unit Proofview.tactic val tclMULT : int * ssrmmod -> Tacmach.tactic -> Tacmach.tactic val unprotecttac : Goal.goal Evd.sigma -> Goal.goal list Evd.sigma +val is_protect : EConstr.t -> Environ.env -> Evd.evar_map -> bool val abs_wgen : bool -> - Tacinterp.interp_sign -> (Id.t -> Id.t) -> 'a * ((Ssrast.ssrhyp_or_id * string) * - Ssrmatching_plugin.Ssrmatching.cpattern option) + Ssrmatching.cpattern option) option -> Goal.goal Evd.sigma * EConstr.t list * EConstr.t -> Goal.goal Evd.sigma * EConstr.t list * EConstr.t @@ -410,3 +412,69 @@ val clr_of_wgen : Proofview.V82.tac list -> Proofview.V82.tac list +val unfold : EConstr.t list -> unit Proofview.tactic + +(* New code ****************************************************************) + +(* To call old code *) +val tacSIGMA : Goal.goal Evd.sigma Proofview.tactic + +val tclINTERP_AST_CLOSURE_TERM_AS_CONSTR : + ast_closure_term -> EConstr.t list Proofview.tactic + +val tacREDUCE_TO_QUANTIFIED_IND : + EConstr.types -> + ((Names.inductive * EConstr.EInstance.t) * EConstr.types) Proofview.tactic + +val tacTYPEOF : EConstr.t -> EConstr.types Proofview.tactic + +val tclINTRO_ID : Id.t -> unit Proofview.tactic +val tclINTRO_ANON : unit Proofview.tactic + +(* Lower level API, calls conclusion with the name taken from the prod *) +val tclINTRO : + id:Id.t option -> + conclusion:(orig_name:Name.t -> new_name:Id.t -> unit Proofview.tactic) -> + unit Proofview.tactic + +val tclRENAME_HD_PROD : Name.t -> unit Proofview.tactic + +(* calls the tactic only if there are more than 0 goals *) +val tcl0G : unit Proofview.tactic -> unit Proofview.tactic + +(* like tclFIRST but with 'a tactic *) +val tclFIRSTa : 'a Proofview.tactic list -> 'a Proofview.tactic +val tclFIRSTi : (int -> 'a Proofview.tactic) -> int -> 'a Proofview.tactic + +val tacCONSTR_NAME : ?name:Name.t -> EConstr.t -> Name.t Proofview.tactic + +(* [tacMKPROD t name ctx] (where ctx is a term possibly containing an unbound + * Rel 1) builds [forall name : ty_t, ctx] *) +val tacMKPROD : + EConstr.t -> ?name:Name.t -> EConstr.types -> EConstr.types Proofview.tactic + +val tacINTERP_CPATTERN : Ssrmatching.cpattern -> Ssrmatching.pattern Proofview.tactic +val tacUNIFY : EConstr.t -> EConstr.t -> unit Proofview.tactic + +(* if [(t : eq _ _ _)] then we can inject it *) +val tacIS_INJECTION_CASE : ?ty:EConstr.types -> EConstr.t -> bool Proofview.tactic + +(** 1 shot, hands-on the top of the stack, eg for [=> ->] *) +val tclWITHTOP : (EConstr.t -> unit Proofview.tactic) -> unit Proofview.tactic + +val tacMK_SSR_CONST : string -> EConstr.t Proofview.tactic + +module type StateType = sig + type state + val init : state +end + +module MakeState(S : StateType) : sig + + val tclGET : (S.state -> unit Proofview.tactic) -> unit Proofview.tactic + val tclSET : S.state -> unit Proofview.tactic + val tacUPDATE : (S.state -> S.state Proofview.tactic) -> unit Proofview.tactic + + val get : Proofview.Goal.t -> S.state + +end diff --git a/plugins/ssr/ssrelim.ml b/plugins/ssr/ssrelim.ml index c4c724b58..33ebe26b6 100644 --- a/plugins/ssr/ssrelim.ml +++ b/plugins/ssr/ssrelim.ml @@ -99,20 +99,18 @@ let subgoals_tys sigma (relctx, concl) = * generalize the equality in case eqid is not None * 4. build the tactic handle intructions and clears as required in ipats and * by eqid *) -let ssrelim ?(ind=ref None) ?(is_case=false) ?ist deps what ?elim eqid elim_intro_tac gl = +let ssrelim ?(ind=ref None) ?(is_case=false) deps what ?elim eqid elim_intro_tac gl = (* some sanity checks *) let oc, orig_clr, occ, c_gen, gl = match what with | `EConstr(_,_,t) when EConstr.isEvar (project gl) t -> anomaly "elim called on a constr evar" - | `EGen _ when ist = None -> - anomaly "no ist and non simple elimination" | `EGen (_, g) when elim = None && is_wildcard g -> errorstrm Pp.(str"Indeterminate pattern and no eliminator") | `EGen ((Some clr,occ), g) when is_wildcard g -> None, clr, occ, None, gl | `EGen ((None, occ), g) when is_wildcard g -> None,[],occ,None,gl | `EGen ((_, occ), p as gen) -> - let _, c, clr,gl = pf_interp_gen (Option.get ist) gl true gen in + let _, c, clr,gl = pf_interp_gen gl true gen in Some c, clr, occ, Some p,gl | `EConstr (clr, occ, c) -> Some c, clr, occ, None,gl in let orig_gl, concl, env = gl, pf_concl gl, pf_env gl in @@ -162,7 +160,7 @@ let ssrelim ?(ind=ref None) ?(is_case=false) ?ist deps what ?elim eqid elim_intr else let c = Option.get oc in let gl, c_ty = pfe_type_of gl c in let pc = match c_gen with - | Some p -> interp_cpattern (Option.get ist) orig_gl p None + | Some p -> interp_cpattern orig_gl p None | _ -> mkTpat gl c in Some(c, c_ty, pc), gl in cty, elim, elimty, elim_args, n_elim_args, elim_is_dep, is_rec, pred, gl @@ -196,7 +194,7 @@ let ssrelim ?(ind=ref None) ?(is_case=false) ?ist deps what ?elim eqid elim_intr pf_saturate ~beta:is_case gl elim ~ty:elimty n_elim_args in let pred = List.assoc pred_id elim_args in let pc = match n_c_args, c_gen with - | 0, Some p -> interp_cpattern (Option.get ist) orig_gl p None + | 0, Some p -> interp_cpattern orig_gl p None | _ -> mkTpat gl c in let cty = Some (c, c_ty, pc) in let elimty = Reductionops.whd_all env (project gl) elimty in @@ -254,8 +252,7 @@ let ssrelim ?(ind=ref None) ?(is_case=false) ?ist deps what ?elim eqid elim_intr let rec loop patterns clr i = function | [],[] -> patterns, clr, gl | ((oclr, occ), t):: deps, inf_t :: inf_deps -> - let ist = match ist with Some x -> x | None -> assert false in - let p = interp_cpattern ist orig_gl t None in + let p = interp_cpattern orig_gl t None in let clr_t = interp_clr (project gl) (oclr,(tag_of_cpattern t,EConstr.of_constr (fst (redex_of_pattern env p)))) in (* if we are the index for the equation we do not clear *) @@ -376,12 +373,14 @@ let ssrelim ?(ind=ref None) ?(is_case=false) ?ist deps what ?elim eqid elim_intr (* the elim tactic, with the eliminator and the predicated we computed *) let elim = project gl, elim in let elim_tac gl = - Tacticals.tclTHENLIST [refine_with ~with_evars:false elim; cleartac clr] gl in - Tacticals.tclTHENLIST [gen_eq_tac; elim_intro_tac ?ist what eqid elim_tac is_rec clr] orig_gl + Tacticals.tclTHENLIST [refine_with ~with_evars:false elim; old_cleartac clr] gl in + Tacticals.tclTHENLIST [gen_eq_tac; elim_intro_tac what eqid elim_tac is_rec clr] orig_gl let no_intro ?ist what eqid elim_tac is_rec clr = elim_tac -let elimtac x = ssrelim ~is_case:false [] (`EConstr ([],None,x)) None no_intro +let elimtac x = + Proofview.V82.tactic ~nf_evars:false + (ssrelim ~is_case:false [] (`EConstr ([],None,x)) None no_intro) let casetac x = ssrelim ~is_case:true [] (`EConstr ([],None,x)) None no_intro let pf_nb_prod gl = nb_prod (project gl) (pf_concl gl) @@ -438,6 +437,9 @@ let perform_injection c gl = let injtac = Tacticals.tclTHEN (introid id) (injectidl2rtac id id_with_ebind) in Tacticals.tclTHENLAST (Proofview.V82.of_tactic (Tactics.apply (EConstr.compose_lam dc cl1))) injtac gl -let ssrscasetac force_inj c gl = - if force_inj || is_injection_case c gl then perform_injection c gl - else casetac c gl +let ssrscase_or_inj_tac c = Proofview.V82.tactic ~nf_evars:false (fun gl -> + if is_injection_case c gl then perform_injection c gl + else casetac c gl) + +let ssrscasetac c = + Proofview.V82.tactic ~nf_evars:false (fun gl -> casetac c gl) diff --git a/plugins/ssr/ssrelim.mli b/plugins/ssr/ssrelim.mli index 9a3da3714..c7ffba917 100644 --- a/plugins/ssr/ssrelim.mli +++ b/plugins/ssr/ssrelim.mli @@ -15,7 +15,6 @@ open Ssrmatching_plugin val ssrelim : ?ind:(int * EConstr.types array) option ref -> ?is_case:bool -> - ?ist:Ltac_plugin.Tacinterp.interp_sign -> ((Ssrast.ssrhyps option * Ssrast.ssrocc) * Ssrmatching.cpattern) list -> @@ -30,16 +29,14 @@ val ssrelim : as 'a) -> ?elim:EConstr.constr -> Ssrast.ssripat option -> - (?ist:Ltac_plugin.Tacinterp.interp_sign -> - 'a -> + ( 'a -> Ssrast.ssripat option -> (Goal.goal Evd.sigma -> Goal.goal list Evd.sigma) -> bool -> Ssrast.ssrhyp list -> Tacmach.tactic) -> Goal.goal Evd.sigma -> Goal.goal list Evd.sigma -val elimtac : - EConstr.constr -> - Goal.goal Evd.sigma -> Goal.goal list Evd.sigma +val elimtac : EConstr.constr -> unit Proofview.tactic + val casetac : EConstr.constr -> Goal.goal Evd.sigma -> Goal.goal list Evd.sigma @@ -50,6 +47,9 @@ val perform_injection : Goal.goal Evd.sigma -> Goal.goal list Evd.sigma val ssrscasetac : - bool -> EConstr.constr -> - Goal.goal Evd.sigma -> Goal.goal list Evd.sigma + unit Proofview.tactic + +val ssrscase_or_inj_tac : + EConstr.constr -> + unit Proofview.tactic diff --git a/plugins/ssr/ssrequality.ml b/plugins/ssr/ssrequality.ml index b6bbc9349..71cde0ca1 100644 --- a/plugins/ssr/ssrequality.ml +++ b/plugins/ssr/ssrequality.ml @@ -619,20 +619,20 @@ let ipat_rewrite occ dir c gl = rwrxtac occ None dir (project gl, c) gl let rwargtac ist ((dir, mult), (((oclr, occ), grx), (kind, gt))) gl = let fail = ref false in - let interp_rpattern ist gl gc = - try interp_rpattern ist gl gc + let interp_rpattern gl gc = + try interp_rpattern gl gc with _ when snd mult = May -> fail := true; project gl, T mkProp in let interp gc gl = try interp_term ist gl gc with _ when snd mult = May -> fail := true; (project gl, EConstr.mkProp) in let rwtac gl = - let rx = Option.map (interp_rpattern ist gl) grx in + let rx = Option.map (interp_rpattern gl) grx in let t = interp gt gl in (match kind with | RWred sim -> simplintac occ rx sim | RWdef -> if dir = R2L then foldtac occ rx t else unfoldintac occ rx t gt | RWeq -> rwrxtac occ rx dir t) gl in - let ctac = cleartac (interp_clr (project gl) (oclr, (fst gt, snd (interp gt gl)))) in + let ctac = old_cleartac (interp_clr (project gl) (oclr, (fst gt, snd (interp gt gl)))) in if !fail then ctac gl else tclTHEN (tclMULT mult rwtac) ctac gl (** Rewrite argument sequence *) diff --git a/plugins/ssr/ssrfun.v b/plugins/ssr/ssrfun.v index 3856a54ce..96b6ed295 100644 --- a/plugins/ssr/ssrfun.v +++ b/plugins/ssr/ssrfun.v @@ -445,14 +445,14 @@ Section Tag. Variables (I : Type) (i : I) (T_ U_ : I -> Type). -Definition tag := projS1. -Definition tagged : forall w, T_(tag w) := @projS2 I [eta T_]. -Definition Tagged x := @existS I [eta T_] i x. +Definition tag := projT1. +Definition tagged : forall w, T_(tag w) := @projT2 I [eta T_]. +Definition Tagged x := @existT I [eta T_] i x. Definition tag2 (w : @sigT2 I T_ U_) := let: existT2 _ _ i _ _ := w in i. Definition tagged2 w : T_(tag2 w) := let: existT2 _ _ _ x _ := w in x. Definition tagged2' w : U_(tag2 w) := let: existT2 _ _ _ _ y := w in y. -Definition Tagged2 x y := @existS2 I [eta T_] [eta U_] i x y. +Definition Tagged2 x y := @existT2 I [eta T_] [eta U_] i x y. End Tag. diff --git a/plugins/ssr/ssrfwd.ml b/plugins/ssr/ssrfwd.ml index eeb519b47..6e17e8e15 100644 --- a/plugins/ssr/ssrfwd.ml +++ b/plugins/ssr/ssrfwd.ml @@ -29,12 +29,19 @@ module RelDecl = Context.Rel.Declaration let settac id c = Tactics.letin_tac None (Name id) c None let posetac id cl = Proofview.V82.of_tactic (settac id cl Locusops.nowhere) -let ssrposetac ist (id, (_, t)) gl = +let ssrposetac (id, (_, t)) gl = + let ist, t = + match t.Ssrast.interp_env with + | Some ist -> ist, Ssrcommon.ssrterm_of_ast_closure_term t + | None -> assert false in let sigma, t, ucst, _ = pf_abs_ssrterm ist gl t in posetac id t (pf_merge_uc ucst gl) -let ssrsettac ist id ((_, (pat, pty)), (_, occ)) gl = - let pat = interp_cpattern ist gl pat (Option.map snd pty) in +let ssrsettac id ((_, (pat, pty)), (_, occ)) gl = + let pty = Option.map (fun { Ssrast.body; interp_env } -> + let ist = Option.get interp_env in + (mkRHole, Some body), ist) pty in + let pat = interp_cpattern gl pat pty in let cl, sigma, env = pf_concl gl, project gl, pf_env gl in let (c, ucst), cl = let cl = EConstr.Unsafe.to_constr cl in @@ -54,57 +61,8 @@ let ssrsettac ist id ((_, (pat, pty)), (_, occ)) gl = open Util -let rec is_Evar_or_CastedMeta sigma x = - EConstr.isEvar sigma x || EConstr.isMeta sigma x || - (EConstr.isCast sigma x && is_Evar_or_CastedMeta sigma (pi1 (EConstr.destCast sigma x))) - -let occur_existential_or_casted_meta c = - let rec occrec c = match Constr.kind c with - | Evar _ -> raise Not_found - | Cast (m,_,_) when isMeta m -> raise Not_found - | _ -> Constr.iter occrec c - in try occrec c; false with Not_found -> true - open Printer -let examine_abstract id gl = - let gl, tid = pfe_type_of gl id in - let abstract, gl = pf_mkSsrConst "abstract" gl in - let sigma = project gl in - let env = pf_env gl in - if not (EConstr.isApp sigma tid) || not (EConstr.eq_constr sigma (fst(EConstr.destApp sigma tid)) abstract) then - errorstrm(strbrk"not an abstract constant: "++ pr_econstr_env env sigma id); - let _, args_id = EConstr.destApp sigma tid in - if Array.length args_id <> 3 then - errorstrm(strbrk"not a proper abstract constant: "++ pr_econstr_env env sigma id); - if not (is_Evar_or_CastedMeta sigma args_id.(2)) then - errorstrm(strbrk"abstract constant "++ pr_econstr_env env sigma id++str" already used"); - tid, args_id - -let pf_find_abstract_proof check_lock gl abstract_n = - let fire gl t = EConstr.Unsafe.to_constr (Reductionops.nf_evar (project gl) (EConstr.of_constr t)) in - let abstract, gl = pf_mkSsrConst "abstract" gl in - let l = Evd.fold_undefined (fun e ei l -> - match Constr.kind ei.Evd.evar_concl with - | App(hd, [|ty; n; lock|]) - when (not check_lock || - (occur_existential_or_casted_meta (fire gl ty) && - is_Evar_or_CastedMeta (project gl) (EConstr.of_constr @@ fire gl lock))) && - Constr.equal hd (EConstr.Unsafe.to_constr abstract) && Constr.equal n abstract_n -> e::l - | _ -> l) (project gl) [] in - match l with - | [e] -> e - | _ -> errorstrm(strbrk"abstract constant "++ pr_constr_env (pf_env gl) (project gl) abstract_n ++ - strbrk" not found in the evar map exactly once. "++ - strbrk"Did you tamper with it?") - -let reduct_in_concl t = Tactics.reduct_in_concl (t, DEFAULTcast) -let unfold cl = - let module R = Reductionops in let module F = CClosure.RedFlags in - reduct_in_concl (R.clos_norm_flags (F.mkflags - (List.map (fun c -> F.fCONST (fst (destConst (EConstr.Unsafe.to_constr c)))) cl @ - [F.fBETA; F.fMATCH; F.fFIX; F.fCOFIX]))) - open Ssrast open Ssripats @@ -142,21 +100,23 @@ let basecuttac name c gl = let gl, _ = pf_e_type_of gl t in Proofview.V82.of_tactic (Tactics.apply t) gl +let introstac ipats = Proofview.V82.of_tactic (tclIPAT ipats) + let havetac ist (transp,((((clr, pats), binders), simpl), (((fk, _), t), hint))) suff namefst gl = let concl = pf_concl gl in let skols, pats = - List.partition (function IPatNewHidden _ -> true | _ -> false) pats in - let itac_mkabs = introstac ~ist skols in - let itac_c = introstac ~ist (IPatClear clr :: pats) in - let itac, id, clr = introstac ~ist pats, Tacticals.tclIDTAC, cleartac clr in + List.partition (function IPatAbstractVars _ -> true | _ -> false) pats in + let itac_mkabs = introstac skols in + let itac_c = introstac (IPatClear clr :: pats) in + let itac, id, clr = introstac pats, Tacticals.tclIDTAC, old_cleartac clr in let binderstac n = let rec aux = function 0 -> [] | n -> IPatAnon One :: aux (n-1) in - Tacticals.tclTHEN (if binders <> [] then introstac ~ist (aux n) else Tacticals.tclIDTAC) - (introstac ~ist binders) in - let simpltac = introstac ~ist simpl in + Tacticals.tclTHEN (if binders <> [] then introstac (aux n) else Tacticals.tclIDTAC) + (introstac binders) in + let simpltac = introstac simpl in let fixtc = not !ssrhaveNOtcresolution && match fk with FwdHint(_,true) -> false | _ -> true in @@ -180,7 +140,7 @@ let havetac ist let interp_ty gl rtc t = let a,b,_,u = pf_interp_ty ~resolve_typeclasses:rtc ist gl t in a,b,u in let open CAst in - let ct, cty, hole, loc = match t with + let ct, cty, hole, loc = match Ssrcommon.ssrterm_of_ast_closure_term t with | _, (_, Some { loc; v = CCast (ct, CastConv cty)}) -> mkt ct, mkt cty, mkt (mkCHole None), loc | _, (_, Some ct) -> @@ -209,10 +169,10 @@ let havetac ist gl, ty, Tacticals.tclTHEN assert_is_conv (Proofview.V82.of_tactic (Tactics.apply t)), id, itac_c | FwdHave, false, false -> let skols = List.flatten (List.map (function - | IPatNewHidden ids -> ids + | IPatAbstractVars ids -> ids | _ -> assert false) skols) in let skols_args = - List.map (fun id -> examine_abstract (EConstr.mkVar id) gl) skols in + List.map (fun id -> Ssripats.Internal.examine_abstract (EConstr.mkVar id) gl) skols in let gl = List.fold_right unlock_abs skols_args gl in let sigma, t, uc, n_evars = interp gl false (combineCG ct cty (mkCCast ?loc) mkRCast) in @@ -223,7 +183,7 @@ let havetac ist let gl = re_sig (sig_it gl) (Evd.merge_universe_context sigma uc) in let gs = List.map (fun (_,a) -> - pf_find_abstract_proof false gl (EConstr.Unsafe.to_constr a.(1))) skols_args in + Ssripats.Internal.pf_find_abstract_proof false gl (EConstr.Unsafe.to_constr a.(1))) skols_args in let tacopen_skols gl = let stuff, g = Refiner.unpackage gl in Refiner.repackage stuff (gs @ [g]) in @@ -247,75 +207,6 @@ let havetac ist gl ;; -(* to extend the abstract value one needs: - Utility lemma to partially instantiate an abstract constant type. - Lemma use_abstract T n l (x : abstract T n l) : T. - Proof. by case: l x. Qed. -*) -let ssrabstract ist gens (*last*) gl = - let main _ (_,cid) ist gl = -(* - let proj1, proj2, prod = - let pdata = build_prod () in - pdata.Coqlib.proj1, pdata.Coqlib.proj2, pdata.Coqlib.typ in -*) - let concl, env = pf_concl gl, pf_env gl in - let fire gl t = Reductionops.nf_evar (project gl) t in - let abstract, gl = pf_mkSsrConst "abstract" gl in - let abstract_key, gl = pf_mkSsrConst "abstract_key" gl in - let cid_interpreted = interp_cpattern ist gl cid None in - let id = EConstr.mkVar (Option.get (id_of_pattern cid_interpreted)) in - let idty, args_id = examine_abstract id gl in - let abstract_n = args_id.(1) in - let abstract_proof = pf_find_abstract_proof true gl (EConstr.Unsafe.to_constr abstract_n) in - let gl, proof = - let pf_unify_HO gl a b = - try pf_unify_HO gl a b - with _ -> errorstrm(strbrk"The abstract variable "++ pr_econstr_env env (project gl) id++ - strbrk" cannot abstract this goal. Did you generalize it?") in - let find_hole p t = - match EConstr.kind (project gl) t with - | Evar _ (*when last*) -> pf_unify_HO gl concl t, p - | Meta _ (*when last*) -> pf_unify_HO gl concl t, p - | Cast(m,_,_) when EConstr.isEvar (project gl) m || EConstr.isMeta - (project gl) m (*when last*) -> pf_unify_HO gl concl t, p -(* - | Evar _ -> - let sigma, it = project gl, sig_it gl in - let sigma, ty = Evarutil.new_type_evar sigma env in - let gl = re_sig it sigma in - let p = mkApp (proj2,[|ty;concl;p|]) in - let concl = mkApp(prod,[|ty; concl|]) in - pf_unify_HO gl concl t, p - | App(hd, [|left; right|]) when Term.Constr.equal hd prod -> - find_hole (mkApp (proj1,[|left;right;p|])) left -*) - | _ -> errorstrm(strbrk"abstract constant "++ pr_econstr_env env (project gl) abstract_n++ - strbrk" has an unexpected shape. Did you tamper with it?") - in - find_hole - ((*if last then*) id - (*else mkApp(mkSsrConst "use_abstract",Array.append args_id [|id|])*)) - (fire gl args_id.(0)) in - let gl = (*if last then*) pf_unify_HO gl abstract_key args_id.(2) (*else gl*) in - let gl, _ = pf_e_type_of gl idty in - let proof = fire gl proof in -(* if last then *) - let tacopen gl = - let stuff, g = Refiner.unpackage gl in - Refiner.repackage stuff [ g; abstract_proof ] in - Tacticals.tclTHENS tacopen [Tacticals.tclSOLVE [Proofview.V82.of_tactic (Tactics.apply proof)]; Proofview.V82.of_tactic (unfold[abstract;abstract_key])] gl -(* else apply proof gl *) - in - let introback ist (gens, _) = - introstac ~ist - (List.map (fun (_,cp) -> match id_of_pattern (interp_cpattern ist gl cp None) with - | None -> IPatAnon One - | Some id -> IPatId id) - (List.tl (List.hd gens))) in - Tacticals.tclTHEN (with_dgens gens main ist) (introback ist gens) gl - - let destProd_or_LetIn sigma c = match EConstr.kind sigma c with | Prod (n,ty,c) -> RelDecl.LocalAssum (n, ty), c @@ -323,12 +214,12 @@ let destProd_or_LetIn sigma c = | _ -> raise DestKO let wlogtac ist (((clr0, pats),_),_) (gens, ((_, ct))) hint suff ghave gl = - let mkabs gen = abs_wgen false ist (fun x -> x) gen in + let mkabs gen = abs_wgen false (fun x -> x) gen in let mkclr gen clrs = clr_of_wgen gen clrs in let mkpats = function | _, Some ((x, _), _) -> fun pats -> IPatId (hoi_id x) :: pats | _ -> fun x -> x in - let ct = match ct with + let ct = match Ssrcommon.ssrterm_of_ast_closure_term ct with | (a, (b, Some ct)) -> begin match ct.CAst.v with | CCast (_, CastConv cty) -> a, (b, Some cty) @@ -370,11 +261,11 @@ let wlogtac ist (((clr0, pats),_),_) (gens, ((_, ct))) hint suff ghave gl = | LetIn(id,b,ty,c) -> EConstr.mkLetIn (id,b,ty,pired c args) | _ -> CErrors.anomaly(str"SSR: wlog: pired: " ++ pr_econstr_env env sigma c) in c, args, pired c args, pf_merge_uc uc gl in - let tacipat pats = introstac ~ist pats in + let tacipat pats = introstac pats in let tacigens = Tacticals.tclTHEN - (Tacticals.tclTHENLIST(List.rev(List.fold_right mkclr gens [cleartac clr0]))) - (introstac ~ist (List.fold_right mkpats gens [])) in + (Tacticals.tclTHENLIST(List.rev(List.fold_right mkclr gens [old_cleartac clr0]))) + (introstac (List.fold_right mkpats gens [])) in let hinttac = hinttac ist true hint in let cut_kind, fst_goal_tac, snd_goal_tac = match suff, ghave with @@ -383,13 +274,13 @@ let wlogtac ist (((clr0, pats),_),_) (gens, ((_, ct))) hint suff ghave gl = | true, `Gen _ -> assert false | false, `Gen id -> if gens = [] then errorstrm(str"gen have requires some generalizations"); - let clear0 = cleartac clr0 in + let clear0 = old_cleartac clr0 in let id, name_general_hyp, cleanup, pats = match id, pats with | None, (IPatId id as ip)::pats -> Some id, tacipat [ip], clear0, pats | None, _ -> None, Tacticals.tclIDTAC, clear0, pats | Some (Some id),_ -> Some id, introid id, clear0, pats | Some _,_ -> - let id = mk_anon_id "tmp" gl in + let id = mk_anon_id "tmp" (Tacmach.pf_ids_of_hyps gl) in Some id, introid id, Tacticals.tclTHEN clear0 (Proofview.V82.of_tactic (Tactics.clear [id])), pats in let tac_specialize = match id with | None -> Tacticals.tclIDTAC @@ -409,8 +300,8 @@ let wlogtac ist (((clr0, pats),_),_) (gens, ((_, ct))) hint suff ghave gl = (** The "suffice" tactic *) let sufftac ist ((((clr, pats),binders),simpl), ((_, c), hint)) = - let htac = Tacticals.tclTHEN (introstac ~ist pats) (hinttac ist true hint) in - let c = match c with + let htac = Tacticals.tclTHEN (introstac pats) (hinttac ist true hint) in + let c = match Ssrcommon.ssrterm_of_ast_closure_term c with | (a, (b, Some ct)) -> begin match ct.CAst.v with | CCast (_, CastConv cty) -> a, (b, Some cty) @@ -425,4 +316,4 @@ let sufftac ist ((((clr, pats),binders),simpl), ((_, c), hint)) = let ctac gl = let _,ty,_,uc = pf_interp_ty ist gl c in let gl = pf_merge_uc uc gl in basecuttac "ssr_suff" ty gl in - Tacticals.tclTHENS ctac [htac; Tacticals.tclTHEN (cleartac clr) (introstac ~ist (binders@simpl))] + Tacticals.tclTHENS ctac [htac; Tacticals.tclTHEN (old_cleartac clr) (introstac (binders@simpl))] diff --git a/plugins/ssr/ssrfwd.mli b/plugins/ssr/ssrfwd.mli index f5e4bd0ad..8a05e2550 100644 --- a/plugins/ssr/ssrfwd.mli +++ b/plugins/ssr/ssrfwd.mli @@ -16,24 +16,18 @@ open Ltac_plugin open Ssrast -val ssrsettac : ist -> Id.t -> ((ssrfwdfmt * (Ssrmatching_plugin.Ssrmatching.cpattern * ssrterm option)) * ssrdocc) -> v82tac +val ssrsettac : Id.t -> ((ssrfwdfmt * (Ssrmatching_plugin.Ssrmatching.cpattern * ast_closure_term option)) * ssrdocc) -> v82tac -val ssrposetac : ist -> (Id.t * (ssrfwdfmt * ssrterm)) -> v82tac +val ssrposetac : Id.t * (ssrfwdfmt * ast_closure_term) -> v82tac -val havetac : - Ssrast.ist -> +val havetac : ist -> bool * ((((Ssrast.ssrclear * Ssrast.ssripat list) * Ssrast.ssripats) * Ssrast.ssripats) * - (((Ssrast.ssrfwdkind * 'a) * - ('b * (Glob_term.glob_constr * Constrexpr.constr_expr option))) * + (((Ssrast.ssrfwdkind * 'a) * ast_closure_term) * (bool * Tacinterp.Value.t option list))) -> bool -> bool -> v82tac -val ssrabstract : - Tacinterp.interp_sign -> - (Ssrast.ssrdocc * Ssrmatching_plugin.Ssrmatching.cpattern) list - list * Ssrast.ssrclear -> v82tac val basecuttac : string -> @@ -48,8 +42,7 @@ val wlogtac : option) list * ('c * - (Ssrast.ssrtermkind * - (Glob_term.glob_constr * Constrexpr.constr_expr option))) -> + ast_closure_term) -> Ltac_plugin.Tacinterp.Value.t Ssrast.ssrhint -> bool -> [< `Gen of Names.Id.t option option | `NoGen > `NoGen ] -> @@ -60,8 +53,7 @@ val sufftac : (((Ssrast.ssrhyps * Ssrast.ssripats) * Ssrast.ssripat list) * Ssrast.ssripat list) * (('a * - (Ssrast.ssrtermkind * - (Glob_term.glob_constr * Constrexpr.constr_expr option))) * + ast_closure_term) * (bool * Tacinterp.Value.t option list)) -> Tacmach.tactic diff --git a/plugins/ssr/ssripats.ml b/plugins/ssr/ssripats.ml index 4a8fa9972..42566575c 100644 --- a/plugins/ssr/ssripats.ml +++ b/plugins/ssr/ssripats.ml @@ -8,395 +8,696 @@ (* * (see LICENSE file for the text of the license) *) (************************************************************************) -(* This file is (C) Copyright 2006-2015 Microsoft Corporation and Inria. *) +open Ssrmatching_plugin -open Names -open Pp -open Term -open Tactics -open Tacticals -open Tacmach -open Coqlib open Util -open Evd -open Printer +open Names + +open Proofview +open Proofview.Notations -open Ssrmatching_plugin -open Ssrmatching open Ssrast -open Ssrprinters -open Ssrcommon -open Ssrequality -open Ssrview -open Ssrelim -open Ssrbwd - -module RelDecl = Context.Rel.Declaration -(** Extended intro patterns {{{ ***********************************************) - - -(* There are two ways of "applying" a view to term: *) -(* 1- using a view hint if the view is an instance of some *) -(* (reflection) inductive predicate. *) -(* 2- applying the view if it coerces to a function, adding *) -(* implicit arguments. *) -(* They require guessing the view hints and the number of *) -(* implicits, respectively, which we do by brute force. *) - -let apply_type x xs = Proofview.V82.of_tactic (apply_type ~typecheck:false x xs) - -let new_tac = Proofview.V82.of_tactic - -let with_top tac gl = - tac_ctx - (tclTHENLIST [ introid top_id; tac (EConstr.mkVar top_id); new_tac (clear [top_id])]) - gl - -let tclTHENS_nonstrict tac tacl taclname gl = - let tacres = tac gl in - let n_gls = List.length (sig_it tacres) in - let n_tac = List.length tacl in - if n_gls = n_tac then tclTHENS_a (fun _ -> tacres) tacl gl else - if n_gls = 0 then tacres else - let pr_only n1 n2 = if n1 < n2 then str "only " else mt () in - let pr_nb n1 n2 name = - pr_only n1 n2 ++ int n1 ++ str (" " ^ String.plural n1 name) in - errorstrm (pr_nb n_tac n_gls taclname ++ spc () - ++ str "for " ++ pr_nb n_gls n_tac "subgoal") - -let rec nat_of_n n = - if n = 0 then EConstr.mkConstruct path_of_O - else EConstr.mkApp (EConstr.mkConstruct path_of_S, [|nat_of_n (n-1)|]) - -let ssr_abstract_id = Summary.ref ~name:"SSR:abstractid" 0 - -let mk_abstract_id () = incr ssr_abstract_id; nat_of_n !ssr_abstract_id - -let ssrmkabs id gl = - let env, concl = pf_env gl, Tacmach.pf_concl gl in + +module IpatMachine : sig + + (* the => tactical. ?eqtac is a tactic to be eventually run + * after the first [..] block. first_case_is_dispatch is the + * ssr exception to elim: and case: *) + val main : ?eqtac:unit tactic -> first_case_is_dispatch:bool -> + ssripats -> unit tactic + +end = struct (* {{{ *) + +module State : sig + + (* to_clear API *) + val isCLR_PUSH : Id.t -> unit tactic + val isCLR_PUSHL : Id.t list -> unit tactic + val isCLR_CONSUME : unit tactic + + (* Some data may expire *) + val isTICK : ssripat -> unit tactic + + val isPRINT : Proofview.Goal.t -> Pp.t + +end = struct (* {{{ *) + +type istate = { + + (* Delayed clear *) + to_clear : Id.t list; + +} + +let empty_state = { + to_clear = []; +} + +include Ssrcommon.MakeState(struct + type state = istate + let init = empty_state +end) + +let isPRINT g = + let state = get g in + Pp.(str"{{ to_clear: " ++ + prlist_with_sep spc Id.print state.to_clear ++ spc () ++ + str" }}") + + +let isCLR_PUSH id = + tclGET (fun { to_clear = ids } -> + tclSET { to_clear = id :: ids }) + +let isCLR_PUSHL more_ids = + tclGET (fun { to_clear = ids } -> + tclSET { to_clear = more_ids @ ids }) + +let isCLR_CONSUME = + tclGET (fun { to_clear = ids } -> + tclSET { to_clear = [] } <*> + Tactics.clear ids) + + +let isTICK _ = tclUNIT () + +end (* }}} *************************************************************** *) + +open State + +(** [=> *] ****************************************************************) +(** [nb_assums] returns the number of dependent premises *) +(** Warning: unlike [nb_deps_assums], it does not perform reduction *) +let rec nb_assums cur env sigma t = + match EConstr.kind sigma t with + | Term.Prod(name,ty,body) -> + nb_assums (cur+1) env sigma body + | Term.LetIn(name,ty,t1,t2) -> + nb_assums (cur+1) env sigma t2 + | Term.Cast(t,_,_) -> + nb_assums cur env sigma t + | _ -> cur +let nb_assums = nb_assums 0 + +let intro_anon_all = Goal.enter begin fun gl -> + let env = Goal.env gl in + let sigma = Goal.sigma gl in + let g = Goal.concl gl in + let n = nb_assums env sigma g in + Tacticals.New.tclDO n Ssrcommon.tclINTRO_ANON +end + +(** [intro_drop] behaves like [intro_anon] but registers the id of the + introduced assumption for a delayed clear. *) +let intro_drop = + Ssrcommon.tclINTRO ~id:None + ~conclusion:(fun ~orig_name:_ ~new_name -> isCLR_PUSH new_name) + +(** [intro_end] performs the actions that have been delayed. *) +let intro_end = + Ssrcommon.tcl0G (isCLR_CONSUME) + +(** [=> _] *****************************************************************) +let intro_clear ids future_ipats = + Goal.enter begin fun gl -> + let _, clear_ids, ren = + List.fold_left (fun (used_ids, clear_ids, ren) id -> + if not(Ssrcommon.is_name_in_ipats id future_ipats) then begin + used_ids, id :: clear_ids, ren + end else + let new_id = Ssrcommon.mk_anon_id (Id.to_string id) used_ids in + (new_id :: used_ids, new_id :: clear_ids, (id, new_id) :: ren)) + (Tacmach.New.pf_ids_of_hyps gl, [], []) ids + in + Tactics.rename_hyp ren <*> + isCLR_PUSHL clear_ids +end + +(** [=> []] *****************************************************************) +let tac_case t = + Goal.enter begin fun _ -> + Ssrcommon.tacTYPEOF t >>= fun ty -> + Ssrcommon.tacIS_INJECTION_CASE ~ty t >>= fun is_inj -> + if is_inj then + V82.tactic ~nf_evars:false (Ssrelim.perform_injection t) + else + Ssrelim.ssrscasetac t +end + +(** [=> [: id]] ************************************************************) +let mk_abstract_id = + let open Coqlib in + let ssr_abstract_id = Summary.ref ~name:"SSR:abstractid" 0 in +begin fun () -> + let rec nat_of_n n = + if n = 0 then EConstr.mkConstruct path_of_O + else EConstr.mkApp (EConstr.mkConstruct path_of_S, [|nat_of_n (n-1)|]) in + incr ssr_abstract_id; nat_of_n !ssr_abstract_id +end + +let tcltclMK_ABSTRACT_VAR id = Goal.enter begin fun gl -> + let env, concl = Goal.(env gl, concl gl) in let step = begin fun sigma -> let (sigma, (abstract_proof, abstract_ty)) = let (sigma, (ty, _)) = Evarutil.new_type_evar env sigma Evd.univ_flexible_alg in - let (sigma, ablock) = mkSsrConst "abstract_lock" env sigma in + let (sigma, ablock) = Ssrcommon.mkSsrConst "abstract_lock" env sigma in let (sigma, lock) = Evarutil.new_evar env sigma ablock in - let (sigma, abstract) = mkSsrConst "abstract" env sigma in - let abstract_ty = EConstr.mkApp(abstract, [|ty;mk_abstract_id ();lock|]) in - let (sigma, m) = Evarutil.new_evar env sigma abstract_ty in - (sigma, (m, abstract_ty)) in + let (sigma, abstract) = Ssrcommon.mkSsrConst "abstract" env sigma in + let abstract_ty = + EConstr.mkApp(abstract, [|ty;mk_abstract_id ();lock|]) in + let sigma, m = Evarutil.new_evar env sigma abstract_ty in + sigma, (m, abstract_ty) in let sigma, kont = - let rd = RelDecl.LocalAssum (Name id, abstract_ty) in - let (sigma, ev) = Evarutil.new_evar (EConstr.push_rel rd env) sigma concl in - (sigma, ev) + let rd = Context.Rel.Declaration.LocalAssum (Name id, abstract_ty) in + let sigma, ev = Evarutil.new_evar (EConstr.push_rel rd env) sigma concl in + sigma, ev in -(* pp(lazy(pr_econstr concl)); *) - let term = EConstr.(mkApp (mkLambda(Name id,abstract_ty,kont) ,[|abstract_proof|])) in + let term = + EConstr.(mkApp (mkLambda(Name id,abstract_ty,kont),[|abstract_proof|])) in let sigma, _ = Typing.type_of env sigma term in - (sigma, term) + sigma, term end in - Proofview.V82.of_tactic - (Proofview.tclTHEN - (Tactics.New.refine ~typecheck:false step) - (Proofview.tclFOCUS 1 3 Proofview.shelve)) gl - -let ssrmkabstac ids = - List.fold_right (fun id tac -> tclTHENFIRST (ssrmkabs id) tac) ids tclIDTAC - -(* introstac: for "move" and "clear", tclEQINTROS: for "case" and "elim" *) -(* This block hides the spaghetti-code needed to implement the only two *) -(* tactics that should be used to process intro patters. *) -(* The difficulty is that we don't want to always rename, but we can *) -(* compute needeed renamings only at runtime, so we theread a tree like *) -(* imperativestructure so that outer renamigs are inherited by inner *) -(* ipts and that the cler performed at the end of ipatstac clears hyps *) -(* eventually renamed at runtime. *) -let delayed_clear force rest clr gl = - let gl, ctx = pull_ctx gl in - let hyps = pf_hyps gl in - let () = if not force then List.iter (check_hyp_exists hyps) clr in - if List.exists (fun x -> force || is_name_in_ipats (hyp_id x) rest) clr then - let ren_clr, ren = - List.split (List.map (fun x -> - let x = hyp_id x in - let x' = mk_anon_id (Id.to_string x) gl in - x', (x, x')) clr) in - let ctx = { ctx with delayed_clears = ren_clr @ ctx.delayed_clears } in - let gl = push_ctx ctx gl in - tac_ctx (Proofview.V82.of_tactic (rename_hyp ren)) gl - else - let ctx = { ctx with delayed_clears = hyps_ids clr @ ctx.delayed_clears } in - let gl = push_ctx ctx gl in - tac_ctx tclIDTAC gl - -(* Common code to handle generalization lists along with the defective case *) + Tactics.New.refine ~typecheck:false step <*> + tclFOCUS 1 3 Proofview.shelve +end + +let tclMK_ABSTRACT_VARS ids = + List.fold_right (fun id tac -> + Tacticals.New.tclTHENFIRST (tcltclMK_ABSTRACT_VAR id) tac) ids (tclUNIT ()) + +(* Debugging *) +let tclLOG p t = + tclUNIT () >>= begin fun () -> + Ssrprinters.ppdebug (lazy Pp.(str "exec: " ++ Ssrprinters.pr_ipat p)); + tclUNIT () + end <*> + Goal.enter begin fun g -> + Ssrprinters.ppdebug (lazy Pp.(str" on state:" ++ spc () ++ + isPRINT g ++ + str" goal:" ++ spc () ++ Printer.pr_goal (Goal.print g))); + tclUNIT () + end + <*> + t p + <*> + Goal.enter begin fun g -> + Ssrprinters.ppdebug (lazy Pp.(str "done: " ++ isPRINT g)); + tclUNIT () + end + +let rec ipat_tac1 future_ipats ipat : unit tactic = + match ipat with + | IPatView l -> + Ssrview.tclIPAT_VIEWS ~views:l + ~conclusion:(fun ~to_clear:clr -> intro_clear clr future_ipats) + | IPatDispatch ipatss -> + tclEXTEND (List.map ipat_tac ipatss) (tclUNIT ()) [] + + | IPatId id -> Ssrcommon.tclINTRO_ID id + + | IPatCase ipatss -> + tclIORPAT (Ssrcommon.tclWITHTOP tac_case) ipatss + | IPatInj ipatss -> + tclIORPAT (Ssrcommon.tclWITHTOP + (fun t -> V82.tactic ~nf_evars:false (Ssrelim.perform_injection t))) ipatss + + | IPatAnon Drop -> intro_drop + | IPatAnon One -> Ssrcommon.tclINTRO_ANON + | IPatAnon All -> intro_anon_all + + | IPatNoop -> tclUNIT () + | IPatSimpl Nop -> tclUNIT () + + | IPatClear ids -> intro_clear (List.map Ssrcommon.hyp_id ids) future_ipats + + | IPatSimpl (Simpl n) -> + V82.tactic ~nf_evars:false (Ssrequality.simpltac (Simpl n)) + | IPatSimpl (Cut n) -> + V82.tactic ~nf_evars:false (Ssrequality.simpltac (Cut n)) + | IPatSimpl (SimplCut (n,m)) -> + V82.tactic ~nf_evars:false (Ssrequality.simpltac (SimplCut (n,m))) + + | IPatRewrite (occ,dir) -> + Ssrcommon.tclWITHTOP + (fun x -> V82.tactic ~nf_evars:false (Ssrequality.ipat_rewrite occ dir x)) + + | IPatAbstractVars ids -> tclMK_ABSTRACT_VARS ids + + | IPatTac t -> t + +and ipat_tac pl : unit tactic = + match pl with + | [] -> tclUNIT () + | pat :: pl -> + Ssrcommon.tcl0G (tclLOG pat (ipat_tac1 pl)) <*> + isTICK pat <*> + ipat_tac pl + +and tclIORPAT tac = function + | [[]] -> tac + | p -> Tacticals.New.tclTHENS tac (List.map ipat_tac p) -let with_defective maintac deps clr ist gl = - let top_id = - match EConstr.kind_of_type (project gl) (pf_concl gl) with - | ProdType (Name id, _, _) - when has_discharged_tag (Id.to_string id) -> id - | _ -> top_id in - let top_gen = mkclr clr, cpattern_of_id top_id in - tclTHEN (introid top_id) (maintac deps top_gen ist) gl - -let with_defective_a maintac deps clr ist gl = - let sigma = sig_sig gl in - let top_id = - match EConstr.kind_of_type sigma (without_ctx pf_concl gl) with - | ProdType (Name id, _, _) - when has_discharged_tag (Id.to_string id) -> id - | _ -> top_id in - let top_gen = mkclr clr, cpattern_of_id top_id in - tclTHEN_a (tac_ctx (introid top_id)) (maintac deps top_gen ist) gl - -let with_dgens (gensl, clr) maintac ist = match gensl with - | [deps; []] -> with_defective maintac deps clr ist - | [deps; gen :: gens] -> - tclTHEN (genstac (gens, clr) ist) (maintac deps gen ist) - | [gen :: gens] -> tclTHEN (genstac (gens, clr) ist) (maintac [] gen ist) - | _ -> with_defective maintac [] clr ist - -let viewmovetac_aux ?(next=ref []) clear name_ref (_, vl as v) _ gen ist gl = - let cl, c, clr, gl, gen_pat = - let gl, ctx = pull_ctx gl in - let _, gen_pat, a, b, c, ucst, gl = pf_interp_gen_aux ist gl false gen in - a, b ,c, push_ctx ctx (pf_merge_uc ucst gl), gen_pat in - let clr = if clear then clr else [] in - name_ref := (match id_of_pattern gen_pat with Some id -> id | _ -> top_id); - let clr = if clear then clr else [] in - if vl = [] then tac_ctx (genclrtac cl [c] clr) gl - else - let _, _, gl = - pfa_with_view ist ~next v cl c - (fun cl c -> tac_ctx (genclrtac cl [c] clr)) clr gl in - gl +let split_at_first_case ipats = + let rec loop acc = function + | (IPatSimpl _ | IPatClear _) as x :: rest -> loop (x :: acc) rest + | IPatCase _ as x :: xs -> CList.rev acc, Some x, xs + | pats -> CList.rev acc, None, pats + in + loop [] ipats -let move_top_with_view ~next c r v = - with_defective_a (viewmovetac_aux ~next c r v) [] [] +let ssr_exception is_on = function + | Some (IPatCase l) when is_on -> Some (IPatDispatch l) + | x -> x -type block_names = (int * EConstr.types array) option +let option_to_list = function None -> [] | Some x -> [x] -let (introstac : ?ist:Tacinterp.interp_sign -> ssripats -> Tacmach.tactic), - (tclEQINTROS : ?ind:block_names ref -> ?ist:Tacinterp.interp_sign -> - Tacmach.tactic -> Tacmach.tactic -> ssripats -> - Tacmach.tactic) -= +let main ?eqtac ~first_case_is_dispatch ipats = + let ip_before, case, ip_after = split_at_first_case ipats in + let case = ssr_exception first_case_is_dispatch case in + let case = option_to_list case in + let eqtac = option_to_list (Option.map (fun x -> IPatTac x) eqtac) in + Ssrcommon.tcl0G (ipat_tac (ip_before @ case @ eqtac @ ip_after) <*> intro_end) - let rec ipattac ?ist ~next p : tac_ctx tac_a = fun gl -> -(* pp(lazy(str"ipattac: " ++ pr_ipat p)); *) - match p with - | IPatAnon Drop -> - let id, gl = with_ctx new_wild_id gl in - tac_ctx (introid id) gl - | IPatAnon All -> tac_ctx intro_all gl - (* TODO - | IPatAnon Temporary -> - let (id, orig), gl = with_ctx new_tmp_id gl in - introid_a ~orig id gl - *) - | IPatCase(iorpat) -> - tclIORPAT ?ist (with_top (ssrscasetac false)) iorpat gl - | IPatInj iorpat -> - tclIORPAT ?ist (with_top (ssrscasetac true)) iorpat gl - | IPatRewrite (occ, dir) -> - with_top (ipat_rewrite occ dir) gl - | IPatId id -> tac_ctx (introid id) gl - | IPatNewHidden idl -> tac_ctx (ssrmkabstac idl) gl - | IPatSimpl sim -> - tac_ctx (simpltac sim) gl - | IPatClear clr -> - delayed_clear false !next clr gl - | IPatAnon One -> tac_ctx intro_anon gl - | IPatNoop -> tac_ctx tclIDTAC gl - | IPatView v -> - let ist = - match ist with Some x -> x | _ -> anomaly "ipat: view with no ist" in - let next_keeps = - match !next with (IPatCase _ | IPatRewrite _)::_ -> false | _ -> true in - let top_id = ref top_id in - tclTHENLIST_a [ - (move_top_with_view ~next next_keeps top_id (next_keeps,v) ist); - (fun gl -> - let hyps = without_ctx pf_hyps gl in - if not next_keeps && test_hypname_exists hyps !top_id then - delayed_clear true !next [SsrHyp (Loc.tag !top_id)] gl - else tac_ctx tclIDTAC gl)] - gl - - and tclIORPAT ?ist tac = function - | [[]] -> tac - | orp -> tclTHENS_nonstrict tac (List.map (ipatstac ?ist) orp) "intro pattern" - - and ipatstac ?ist ipats gl = - let rec aux ipats gl = - match ipats with - | [] -> tac_ctx tclIDTAC gl - | p :: ps -> - let next = ref ps in - let gl = ipattac ?ist ~next p gl in - tac_on_all gl (aux !next) - in - aux ipats gl - in +end (* }}} *) + +let tclIPAT_EQ eqtac ip = + Ssrprinters.ppdebug (lazy Pp.(str "ipat@run: " ++ Ssrprinters.pr_ipats ip)); + IpatMachine.main ~eqtac ~first_case_is_dispatch:true ip + +let tclIPATssr ip = + Ssrprinters.ppdebug (lazy Pp.(str "ipat@run: " ++ Ssrprinters.pr_ipats ip)); + IpatMachine.main ~first_case_is_dispatch:true ip - let rec split_itacs ?ist ~ind tac' = function - | (IPatSimpl _ | IPatClear _ as spat) :: ipats' -> - let tac = ipattac ?ist ~next:(ref ipats') spat in - split_itacs ?ist ~ind (tclTHEN_a tac' tac) ipats' - | IPatCase iorpat :: ipats' -> - tclIORPAT ?ist tac' iorpat, ipats' - | ipats' -> tac', ipats' in - - let combine_tacs tac eqtac ipats ?ist ~ind gl = - let tac1, ipats' = split_itacs ?ist ~ind tac ipats in - let tac2 = ipatstac ?ist ipats' in - tclTHENLIST_a [ tac1; eqtac; tac2 ] gl in - - (* Exported code *) - let introstac ?ist ipats gl = - with_fresh_ctx (tclTHENLIST_a [ - ipatstac ?ist ipats; - gen_tmp_ids ?ist; - clear_wilds_and_tmp_and_delayed_ids - ]) gl in - - let tclEQINTROS ?(ind=ref None) ?ist tac eqtac ipats gl = - with_fresh_ctx (tclTHENLIST_a [ - combine_tacs (tac_ctx tac) (tac_ctx eqtac) ipats ?ist ~ind; - gen_tmp_ids ?ist; - clear_wilds_and_tmp_and_delayed_ids; - ]) gl in - - introstac, tclEQINTROS -;; - -(* Intro patterns processing for elim tactic*) -let elim_intro_tac ipats ?ist what eqid ssrelim is_rec clr gl = - (* Utils of local interest only *) - let iD s ?t gl = let t = match t with None -> pf_concl gl | Some x -> x in - ppdebug(lazy Pp.(str s ++ pr_econstr_env (pf_env gl) (project gl) t)); Tacticals.tclIDTAC gl in - let protectC, gl = pf_mkSsrConst "protect_term" gl in - let eq, gl = pf_fresh_global (Coqlib.build_coq_eq ()) gl in - let eq = EConstr.of_constr eq in - let fire_subst gl t = Reductionops.nf_evar (project gl) t in - let intro_eq = - match eqid with - | Some (IPatId ipat) when not is_rec -> - let rec intro_eq gl = match EConstr.kind_of_type (project gl) (pf_concl gl) with - | ProdType (_, src, tgt) -> - (match EConstr.kind_of_type (project gl) src with - | AtomicType (hd, _) when EConstr.eq_constr (project gl) hd protectC -> - Tacticals.tclTHENLIST [unprotecttac; introid ipat] gl - | _ -> Tacticals.tclTHENLIST [ iD "IA"; Ssrcommon.intro_anon; intro_eq] gl) - |_ -> errorstrm (Pp.str "Too many names in intro pattern") in - intro_eq - | Some (IPatId ipat) -> - let name gl = mk_anon_id "K" gl in - let intro_lhs gl = +(* Common code to handle generalization lists along with the defective case *) +let with_defective maintac deps clr = Goal.enter begin fun g -> + let sigma, concl = Goal.(sigma g, concl g) in + let top_id = + match EConstr.kind_of_type sigma concl with + | Term.ProdType (Name id, _, _) + when Ssrcommon.is_discharged_id id -> id + | _ -> Ssrcommon.top_id in + let top_gen = Ssrequality.mkclr clr, Ssrmatching.cpattern_of_id top_id in + Ssrcommon.tclINTRO_ID top_id <*> maintac deps top_gen +end + +let with_dgens { dgens; gens; clr } maintac = match gens with + | [] -> with_defective maintac dgens clr + | gen :: gens -> + V82.tactic ~nf_evars:false (Ssrcommon.genstac (gens, clr)) <*> maintac dgens gen + +let mkCoqEq env sigma = + let eq = Coqlib.((build_coq_eq_data ()).eq) in + let sigma, eq = EConstr.fresh_global env sigma eq in + eq, sigma + +let mkCoqRefl t c env sigma = + let refl = Coqlib.((build_coq_eq_data()).refl) in + let sigma, refl = EConstr.fresh_global env sigma refl in + EConstr.mkApp (refl, [|t; c|]), sigma + +(** Intro patterns processing for elim tactic, in particular when used in + conjunction with equation generation as in [elim E: x] *) +let elim_intro_tac ipats ?ist what eqid ssrelim is_rec clr = + let intro_eq = + match eqid with + | Some (IPatId ipat) when not is_rec -> + let rec intro_eq () = Goal.enter begin fun g -> + let sigma, env, concl = Goal.(sigma g, env g, concl g) in + match EConstr.kind_of_type sigma concl with + | Term.ProdType (_, src, tgt) -> begin + match EConstr.kind_of_type sigma src with + | Term.AtomicType (hd, _) when Ssrcommon.is_protect hd env sigma -> + V82.tactic ~nf_evars:false Ssrcommon.unprotecttac <*> + Ssrcommon.tclINTRO_ID ipat + | _ -> Ssrcommon.tclINTRO_ANON <*> intro_eq () + end + |_ -> Ssrcommon.errorstrm (Pp.str "Too many names in intro pattern") + end in + intro_eq () + | Some (IPatId ipat) -> + let intro_lhs = Goal.enter begin fun g -> + let sigma = Goal.sigma g in let elim_name = match clr, what with | [SsrHyp(_, x)], _ -> x - | _, `EConstr(_,_,t) when EConstr.isVar (project gl) t -> EConstr.destVar (project gl) t - | _ -> name gl in - if is_name_in_ipats elim_name ipats then introid (name gl) gl - else introid elim_name gl - in - let rec gen_eq_tac gl = - let concl = pf_concl gl in - let ctx, last = EConstr.decompose_prod_assum (project gl) concl in - let args = match EConstr.kind_of_type (project gl) last with - | AtomicType (hd, args) -> assert(EConstr.eq_constr (project gl) hd protectC); args + | _, `EConstr(_,_,t) when EConstr.isVar sigma t -> + EConstr.destVar sigma t + | _ -> Ssrcommon.mk_anon_id "K" (Tacmach.New.pf_ids_of_hyps g) in + let elim_name = + if Ssrcommon.is_name_in_ipats elim_name ipats then + Ssrcommon.mk_anon_id "K" (Tacmach.New.pf_ids_of_hyps g) + else elim_name + in + Ssrcommon.tclINTRO_ID elim_name + end in + let rec gen_eq_tac () = Goal.enter begin fun g -> + let sigma, env, concl = Goal.(sigma g, env g, concl g) in + let sigma, eq = + EConstr.fresh_global env sigma (Coqlib.build_coq_eq ()) in + let ctx, last = EConstr.decompose_prod_assum sigma concl in + let args = match EConstr.kind_of_type sigma last with + | Term.AtomicType (hd, args) -> + assert(Ssrcommon.is_protect hd env sigma); + args | _ -> assert false in let case = args.(Array.length args-1) in - if not(EConstr.Vars.closed0 (project gl) case) then Tacticals.tclTHEN Ssrcommon.intro_anon gen_eq_tac gl + if not(EConstr.Vars.closed0 sigma case) + then Ssrcommon.tclINTRO_ANON <*> gen_eq_tac () else - let gl, case_ty = pfe_type_of gl case in - let refl = EConstr.mkApp (eq, [|EConstr.Vars.lift 1 case_ty; EConstr.mkRel 1; EConstr.Vars.lift 1 case|]) in - let new_concl = fire_subst gl - EConstr.(mkProd (Name (name gl), case_ty, mkArrow refl (Vars.lift 2 concl))) in - let erefl, gl = mkRefl case_ty case gl in - let erefl = fire_subst gl erefl in - apply_type new_concl [case;erefl] gl in - Tacticals.tclTHENLIST [gen_eq_tac; intro_lhs; introid ipat] - | _ -> Tacticals.tclIDTAC in - let unprot = if eqid <> None && is_rec then unprotecttac else Tacticals.tclIDTAC in - tclEQINTROS ?ist ssrelim (Tacticals.tclTHENLIST [intro_eq; unprot]) ipats gl - -(* General case *) -let tclINTROS ist t ip = tclEQINTROS ~ist (t ist) tclIDTAC ip - -(* }}} *) - -let viewmovetac ?next v deps gen ist gl = - with_fresh_ctx - (tclTHEN_a - (viewmovetac_aux ?next true (ref top_id) v deps gen ist) - clear_wilds_and_tmp_and_delayed_ids) - gl - -let mkCoqEq gl = - let sigma = project gl in - let (sigma, eq) = EConstr.fresh_global (pf_env gl) sigma (build_coq_eq_data()).eq in - let gl = { gl with sigma } in - eq, gl - -let mkEq dir cl c t n gl = - let open EConstr in - let eqargs = [|t; c; c|] in eqargs.(dir_org dir) <- mkRel n; - let eq, gl = mkCoqEq gl in - let refl, gl = mkRefl t c gl in - mkArrow (mkApp (eq, eqargs)) (EConstr.Vars.lift 1 cl), refl, gl - -let pushmoveeqtac cl c gl = + Ssrcommon.tacTYPEOF case >>= fun case_ty -> + let open EConstr in + let refl = + mkApp (eq, [|Vars.lift 1 case_ty; mkRel 1; Vars.lift 1 case|]) in + let name = Ssrcommon.mk_anon_id "K" (Tacmach.New.pf_ids_of_hyps g) in + + let new_concl = + mkProd (Name name, case_ty, mkArrow refl (Vars.lift 2 concl)) in + let erefl, sigma = mkCoqRefl case_ty case env sigma in + Proofview.Unsafe.tclEVARS sigma <*> + Tactics.apply_type ~typecheck:true new_concl [case;erefl] + end in + gen_eq_tac () <*> + intro_lhs <*> + Ssrcommon.tclINTRO_ID ipat + | _ -> tclUNIT () in + let unprot = + if eqid <> None && is_rec + then V82.tactic ~nf_evars:false Ssrcommon.unprotecttac else tclUNIT () in + V82.of_tactic begin + V82.tactic ~nf_evars:false ssrelim <*> + tclIPAT_EQ (intro_eq <*> unprot) ipats + end + +let mkEq dir cl c t n env sigma = let open EConstr in - let x, t, cl1 = destProd (project gl) cl in - let cl2, eqc, gl = mkEq R2L cl1 c t 1 gl in - apply_type (mkProd (x, t, cl2)) [c; eqc] gl - -let eqmovetac _ gen ist gl = - let cl, c, _, gl = pf_interp_gen ist gl false gen in pushmoveeqtac cl c gl - -let movehnftac gl = match EConstr.kind (project gl) (pf_concl gl) with - | Prod _ | LetIn _ -> tclIDTAC gl - | _ -> new_tac hnf_in_concl gl + let eqargs = [|t; c; c|] in + eqargs.(Ssrequality.dir_org dir) <- mkRel n; + let eq, sigma = mkCoqEq env sigma in + let refl, sigma = mkCoqRefl t c env sigma in + mkArrow (mkApp (eq, eqargs)) (Vars.lift 1 cl), refl, sigma + +(** in [tac/v: last gens..] the first (last to be run) generalization is + "special" in that is it also the main argument of [tac] and is eventually + to be processed forward with view [v]. The behavior implemented is + very close to [tac: (v last) gens..] but: + - [v last] may use a view adaptor + - eventually clear for [last] is taken into account + - [tac/v {clr}] is also supported, and [{clr}] is to be run later + The code here does not "grab" [v last] nor apply [v] to [last], see the + [tacVIEW_THEN_GRAB] combinator. *) +let tclLAST_GEN ~to_ind ((oclr, occ), t) conclusion = tclINDEPENDENTL begin + Ssrcommon.tacSIGMA >>= fun sigma0 -> + Goal.enter_one begin fun g -> + let pat = Ssrmatching.interp_cpattern sigma0 t None in + let cl0, env, sigma, hyps = Goal.(concl g, env g, sigma g, hyps g) in + let cl = EConstr.to_constr sigma cl0 in + let (c, ucst), cl = + try Ssrmatching.fill_occ_pattern ~raise_NoMatch:true env sigma cl pat occ 1 + with Ssrmatching.NoMatch -> Ssrmatching.redex_of_pattern env pat, cl in + let sigma = Evd.merge_universe_context sigma ucst in + let c, cl = EConstr.of_constr c, EConstr.of_constr cl in + let clr = + Ssrcommon.interp_clr sigma (oclr, (Ssrmatching.tag_of_cpattern t,c)) in + (* Historically in Coq, and hence in ssr, [case t] accepts [t] of type + [A.. -> Ind] and opens new goals for [A..] as well as for the branches + of [Ind], see the [~to_ind] argument *) + if not(Termops.occur_existential sigma c) then + if Ssrmatching.tag_of_cpattern t = Ssrprinters.xWithAt then + if not (EConstr.isVar sigma c) then + Ssrcommon.errorstrm Pp.(str "@ can be used with variables only") + else match Context.Named.lookup (EConstr.destVar sigma c) hyps with + | Context.Named.Declaration.LocalAssum _ -> + Ssrcommon.errorstrm Pp.(str "@ can be used with let-ins only") + | Context.Named.Declaration.LocalDef (name, b, ty) -> + Unsafe.tclEVARS sigma <*> + tclUNIT (true, EConstr.mkLetIn (Name name,b,ty,cl), c, clr) + else + Unsafe.tclEVARS sigma <*> + Ssrcommon.tacMKPROD c cl >>= fun ccl -> + tclUNIT (false, ccl, c, clr) + else + if to_ind && occ = None then + let _, p, _, ucst' = + (* TODO: use abs_evars2 *) + Ssrcommon.pf_abs_evars sigma0 (fst pat, c) in + let sigma = Evd.merge_universe_context sigma ucst' in + Unsafe.tclEVARS sigma <*> + Ssrcommon.tacTYPEOF p >>= fun pty -> + (* TODO: check bug: cl0 no lift? *) + let ccl = EConstr.mkProd (Ssrcommon.constr_name sigma c, pty, cl0) in + tclUNIT (false, ccl, p, clr) + else + Ssrcommon.errorstrm Pp.(str "generalized term didn't match") +end end >>= begin + fun infos -> tclDISPATCH (infos |> List.map conclusion) +end + +(** a typical mate of [tclLAST_GEN] doing the job of applying the views [cs] + to [c] and generalizing the resulting term *) +let tacVIEW_THEN_GRAB ?(simple_types=true) + vs ~conclusion (is_letin, new_concl, c, clear) += + Ssrview.tclWITH_FWD_VIEWS ~simple_types ~subject:c ~views:vs + ~conclusion:(fun t -> + Ssrcommon.tacCONSTR_NAME c >>= fun name -> + Goal.enter_one ~__LOC__ begin fun g -> + let sigma, env = Goal.sigma g, Goal.env g in + Ssrcommon.tacMKPROD t ~name + (Termops.subst_term sigma t (* NOTE: we grab t here *) + (Termops.prod_applist sigma new_concl [c])) >>= + conclusion is_letin t clear + end) + +(* Elim views are elimination lemmas, so the eliminated term is not added *) +(* to the dependent terms as for "case", unless it actually occurs in the *) +(* goal, the "all occurrences" {+} switch is used, or the equation switch *) +(* is used and there are no dependents. *) + +let ssrelimtac (view, (eqid, (dgens, ipats))) = + let ndefectelimtac view eqid ipats deps gen = + match view with + | [v] -> + Ssrcommon.tclINTERP_AST_CLOSURE_TERM_AS_CONSTR v >>= fun cs -> + tclDISPATCH (List.map (fun elim -> + V82.tactic ~nf_evars:false + (Ssrelim.ssrelim deps (`EGen gen) ~elim eqid (elim_intro_tac ipats))) + cs) + | [] -> + tclINDEPENDENT + (V82.tactic ~nf_evars:false + (Ssrelim.ssrelim deps (`EGen gen) eqid (elim_intro_tac ipats))) + | _ -> + Ssrcommon.errorstrm + Pp.(str "elim: only one elimination lemma can be provided") + in + with_dgens dgens (ndefectelimtac view eqid ipats) + +let ssrcasetac (view, (eqid, (dgens, ipats))) = + let ndefectcasetac view eqid ipats deps ((_, occ), _ as gen) = + tclLAST_GEN ~to_ind:true gen (fun (_, cl, c, clear as info) -> + let conclusion _ vc _clear _cl = + Ssrcommon.tacIS_INJECTION_CASE vc >>= fun inj -> + let simple = (eqid = None && deps = [] && occ = None) in + if simple && inj then + V82.tactic ~nf_evars:false (Ssrelim.perform_injection vc) <*> + Tactics.clear (List.map Ssrcommon.hyp_id clear) <*> + tclIPATssr ipats + else + (* macro for "case/v E: x" ---> "case E: x / (v x)" *) + let deps, clear, occ = + if view <> [] && eqid <> None && deps = [] + then [gen], [], None + else deps, clear, occ in + V82.tactic ~nf_evars:false + (Ssrelim.ssrelim ~is_case:true deps (`EConstr (clear, occ, vc)) + eqid (elim_intro_tac ipats)) + in + if view = [] then conclusion false c clear c + else tacVIEW_THEN_GRAB ~simple_types:false view ~conclusion info) + in + with_dgens dgens (ndefectcasetac view eqid ipats) + +let ssrscasetoptac = Ssrcommon.tclWITHTOP Ssrelim.ssrscase_or_inj_tac +let ssrselimtoptac = Ssrcommon.tclWITHTOP Ssrelim.elimtac + +(** [move] **************************************************************) +let pushmoveeqtac cl c = Goal.enter begin fun g -> + let env, sigma = Goal.(env g, sigma g) in + let x, t, cl1 = EConstr.destProd sigma cl in + let cl2, eqc, sigma = mkEq R2L cl1 c t 1 env sigma in + Unsafe.tclEVARS sigma <*> + Tactics.apply_type ~typecheck:true (EConstr.mkProd (x, t, cl2)) [c; eqc] +end + +let eqmovetac _ gen = Goal.enter begin fun g -> + Ssrcommon.tacSIGMA >>= fun gl -> + let cl, c, _, gl = Ssrcommon.pf_interp_gen gl false gen in + Unsafe.tclEVARS (Tacmach.project gl) <*> + pushmoveeqtac cl c +end let rec eqmoveipats eqpat = function - | (IPatSimpl _ | IPatClear _ as ipat) :: ipats -> ipat :: eqmoveipats eqpat ipats - | (IPatAnon All :: _ | []) as ipats -> IPatAnon One :: eqpat :: ipats - | ipat :: ipats -> ipat :: eqpat :: ipats - -let ssrmovetac ist = function - | _::_ as view, (_, (dgens, ipats)) -> - let next = ref ipats in - let dgentac = with_dgens dgens (viewmovetac ~next (true, view)) ist in - tclTHEN dgentac (fun gl -> introstac ~ist !next gl) + | (IPatSimpl _ | IPatClear _ as ipat) :: ipats -> + ipat :: eqmoveipats eqpat ipats + | (IPatAnon All :: _ | []) as ipats -> + IPatAnon One :: eqpat :: ipats + | ipat :: ipats -> + ipat :: eqpat :: ipats + +let ssrsmovetac = Goal.enter begin fun g -> + let sigma, concl = Goal.(sigma g, concl g) in + match EConstr.kind sigma concl with + | Term.Prod _ | Term.LetIn _ -> tclUNIT () + | _ -> Tactics.hnf_in_concl +end + +let tclIPAT ip = + Ssrprinters.ppdebug (lazy Pp.(str "ipat@run: " ++ Ssrprinters.pr_ipats ip)); + IpatMachine.main ~first_case_is_dispatch:false ip + +let ssrmovetac = function + | _::_ as view, (_, ({ gens = lastgen :: gens; clr }, ipats)) -> + let gentac = V82.tactic ~nf_evars:false (Ssrcommon.genstac (gens, [])) in + let conclusion _ t clear ccl = + Tactics.apply_type ~typecheck:true ccl [t] <*> + Tactics.clear (List.map Ssrcommon.hyp_id clear) in + gentac <*> + tclLAST_GEN ~to_ind:false lastgen + (tacVIEW_THEN_GRAB view ~conclusion) <*> + tclIPAT (IPatClear clr :: ipats) + | _::_ as view, (_, ({ gens = []; clr }, ipats)) -> + tclIPAT (IPatView view :: IPatClear clr :: ipats) | _, (Some pat, (dgens, ipats)) -> - let dgentac = with_dgens dgens eqmovetac ist in - tclTHEN dgentac (introstac ~ist (eqmoveipats pat ipats)) - | _, (_, (([gens], clr), ipats)) -> - let gentac = genstac (gens, clr) ist in - tclTHEN gentac (introstac ~ist ipats) - | _, (_, ((_, clr), ipats)) -> - tclTHENLIST [movehnftac; cleartac clr; introstac ~ist ipats] - -let ssrcasetac ist (view, (eqid, (dgens, ipats))) = - let ndefectcasetac view eqid ipats deps ((_, occ), _ as gen) ist gl = - let simple = (eqid = None && deps = [] && occ = None) in - let cl, c, clr, gl = pf_interp_gen ist gl true gen in - let _,vc, gl = - if view = [] then c,c, gl else pf_with_view_linear ist gl (false, view) cl c in - if simple && is_injection_case vc gl then - tclTHENLIST [perform_injection vc; cleartac clr; introstac ~ist ipats] gl - else - (* macro for "case/v E: x" ---> "case E: x / (v x)" *) - let deps, clr, occ = - if view <> [] && eqid <> None && deps = [] then [gen], [], None - else deps, clr, occ in - ssrelim ~is_case:true ~ist deps (`EConstr (clr,occ, vc)) eqid (elim_intro_tac ipats) gl + let dgentac = with_dgens dgens eqmovetac in + dgentac <*> tclIPAT (eqmoveipats pat ipats) + | _, (_, ({ gens = (_ :: _ as gens); dgens = []; clr}, ipats)) -> + let gentac = V82.tactic ~nf_evars:false (Ssrcommon.genstac (gens, clr)) in + gentac <*> tclIPAT ipats + | _, (_, ({ clr }, ipats)) -> + Tacticals.New.tclTHENLIST [ssrsmovetac; Tactics.clear (List.map Ssrcommon.hyp_id clr); tclIPAT ipats] + +(** [abstract: absvar gens] **************************************************) +let rec is_Evar_or_CastedMeta sigma x = + EConstr.isEvar sigma x || + EConstr.isMeta sigma x || + (EConstr.isCast sigma x && + is_Evar_or_CastedMeta sigma (pi1 (EConstr.destCast sigma x))) + +let occur_existential_or_casted_meta sigma c = + let rec occrec c = match EConstr.kind sigma c with + | Term.Evar _ -> raise Not_found + | Term.Cast (m,_,_) when EConstr.isMeta sigma m -> raise Not_found + | _ -> EConstr.iter sigma occrec c in - with_dgens dgens (ndefectcasetac view eqid ipats) ist - -let ssrapplytac ist (views, (_, ((gens, clr), intros))) = - tclINTROS ist (inner_ssrapplytac views gens clr) intros - + try occrec c; false + with Not_found -> true + +let tacEXAMINE_ABSTRACT id = Ssrcommon.tacTYPEOF id >>= begin fun tid -> + Ssrcommon.tacMK_SSR_CONST "abstract" >>= fun abstract -> + Goal.enter_one ~__LOC__ begin fun g -> + let sigma, env = Goal.(sigma g, env g) in + let err () = + Ssrcommon.errorstrm + Pp.(strbrk"not a proper abstract constant: "++ + Printer.pr_econstr_env env sigma id) in + if not (EConstr.isApp sigma tid) then err (); + let hd, args_id = EConstr.destApp sigma tid in + if not (EConstr.eq_constr_nounivs sigma hd abstract) then err (); + if Array.length args_id <> 3 then err (); + if not (is_Evar_or_CastedMeta sigma args_id.(2)) then + Ssrcommon.errorstrm Pp.(strbrk"abstract constant "++ + Printer.pr_econstr_env env sigma id++str" already used"); + tclUNIT (tid, args_id) +end end + +let tacFIND_ABSTRACT_PROOF check_lock abstract_n = + Ssrcommon.tacMK_SSR_CONST "abstract" >>= fun abstract -> + Goal.enter_one ~__LOC__ begin fun g -> + let sigma, env = Goal.(sigma g, env g) in + let l = Evd.fold_undefined (fun e ei l -> + match EConstr.kind sigma (EConstr.of_constr ei.Evd.evar_concl) with + | Term.App(hd, [|ty; n; lock|]) + when (not check_lock || + (occur_existential_or_casted_meta sigma ty && + is_Evar_or_CastedMeta sigma lock)) && + EConstr.eq_constr_nounivs sigma hd abstract && + EConstr.eq_constr_nounivs sigma n abstract_n -> e :: l + | _ -> l) sigma [] in + match l with + | [e] -> tclUNIT e + | _ -> Ssrcommon.errorstrm + Pp.(strbrk"abstract constant "++ + Printer.pr_econstr_env env sigma abstract_n ++ + strbrk" not found in the evar map exactly once. "++ + strbrk"Did you tamper with it?") +end + +let ssrabstract dgens = + let main _ (_,cid) = Goal.enter begin fun g -> + Ssrcommon.tacMK_SSR_CONST "abstract" >>= fun abstract -> + Ssrcommon.tacMK_SSR_CONST "abstract_key" >>= fun abstract_key -> + Ssrcommon.tacINTERP_CPATTERN cid >>= fun cid -> + let id = EConstr.mkVar (Option.get (Ssrmatching.id_of_pattern cid)) in + tacEXAMINE_ABSTRACT id >>= fun (idty, args_id) -> + let abstract_n = args_id.(1) in + tacFIND_ABSTRACT_PROOF true abstract_n >>= fun abstract_proof -> + let tacFIND_HOLE = Goal.enter_one ~__LOC__ begin fun g -> + let sigma, env, concl = Goal.(sigma g, env g, concl g) in + let t = args_id.(0) in + match EConstr.kind sigma t with + | (Term.Evar _ | Term.Meta _) -> Ssrcommon.tacUNIFY concl t <*> tclUNIT id + | Term.Cast(m,_,_) + when EConstr.isEvar sigma m || EConstr.isMeta sigma m -> + Ssrcommon.tacUNIFY concl t <*> tclUNIT id + | _ -> + Ssrcommon.errorstrm + Pp.(strbrk"abstract constant "++ + Printer.pr_econstr_env env sigma abstract_n ++ + strbrk" has an unexpected shape. Did you tamper with it?") + end in + tacFIND_HOLE >>= fun proof -> + Ssrcommon.tacUNIFY abstract_key args_id.(2) <*> + Ssrcommon.tacTYPEOF idty >>= fun _ -> + Unsafe.tclGETGOALS >>= fun goals -> + (* Here we jump in the proof tree: we move from the current goal to + the evar that inhabits the abstract variable with the current goal *) + Unsafe.tclSETGOALS + (goals @ [Proofview_monad.with_empty_state abstract_proof]) <*> + tclDISPATCH [ + Tacticals.New.tclSOLVE [Tactics.apply proof]; + Ssrcommon.unfold[abstract;abstract_key] + ] + end in + let interp_gens { gens } ~conclusion = Goal.enter begin fun g -> + Ssrcommon.tacSIGMA >>= fun gl0 -> + let open Ssrmatching in + let ipats = List.map (fun (_,cp) -> + match id_of_pattern (interp_cpattern gl0 cp None) with + | None -> IPatAnon One + | Some id -> IPatId id) + (List.tl gens) in + conclusion ipats + end in + interp_gens dgens ~conclusion:(fun ipats -> + with_dgens dgens main <*> + tclIPATssr ipats) + +module Internal = struct + + let pf_find_abstract_proof b gl t = + let res = ref None in + let _ = V82.of_tactic (tacFIND_ABSTRACT_PROOF b (EConstr.of_constr t) >>= fun x -> res := Some x; tclUNIT ()) gl in + match !res with + | None -> assert false + | Some x -> x + + let examine_abstract t gl = + let res = ref None in + let _ = V82.of_tactic (tacEXAMINE_ABSTRACT t >>= fun x -> res := Some x; tclUNIT ()) gl in + match !res with + | None -> assert false + | Some x -> x + +end (* vim: set filetype=ocaml foldmethod=marker: *) diff --git a/plugins/ssr/ssripats.mli b/plugins/ssr/ssripats.mli index 82763d3ca..b8716c0c4 100644 --- a/plugins/ssr/ssripats.mli +++ b/plugins/ssr/ssripats.mli @@ -8,77 +8,43 @@ (* * (see LICENSE file for the text of the license) *) (************************************************************************) -(* This file is (C) Copyright 2006-2015 Microsoft Corporation and Inria. *) +(* This file implements: + - the [=>] tactical + - the [:] pseudo-tactical for move, case, elim and abstract -open Ssrmatching_plugin -open Ssrast -open Ssrcommon - -type block_names = (int * EConstr.types array) option - -(* For case/elim with eq generation: args are elim_tac introeq_tac ipats - * elim E : "=> ipats" where E give rise to introeq_tac *) -val tclEQINTROS : - ?ind:block_names ref -> - ?ist:ist -> - v82tac -> - v82tac -> ssripats -> v82tac -(* special case with no eq and tactic taking ist *) -val tclINTROS : - ist -> - (ist -> v82tac) -> - ssripats -> v82tac - -(* move=> ipats *) -val introstac : ?ist:ist -> ssripats -> v82tac - -val elim_intro_tac : - Ssrast.ssripats -> - ?ist:Tacinterp.interp_sign -> - [> `EConstr of 'a * 'b * EConstr.t ] -> - Ssrast.ssripat option -> - Tacmach.tactic -> - bool -> - Ssrast.ssrhyp list -> - Goal.goal Evd.sigma -> Goal.goal list Evd.sigma - -(* "move=> top; tac top; clear top" respecting the speed *) -val with_top : (EConstr.t -> v82tac) -> tac_ctx tac_a + Putting these two features in the same file lets one hide much of the + interaction between [tac E:] and [=>] ([E] has to be processed by [=>], + not by [:] +*) -val ssrmovetac : - Ltac_plugin.Tacinterp.interp_sign -> - Ssrast.ssrterm list * - (Ssrast.ssripat option * - (((Ssrast.ssrdocc * Ssrmatching.cpattern) list - list * Ssrast.ssrclear) * - Ssrast.ssripats)) -> - Tacmach.tactic - -val movehnftac : Goal.goal Evd.sigma -> Goal.goal list Evd.sigma - -val with_dgens : - (Ssrast.ssrdocc * Ssrmatching.cpattern) list - list * Ssrast.ssrclear -> - ((Ssrast.ssrdocc * Ssrmatching.cpattern) list -> - Ssrast.ssrdocc * Ssrmatching.cpattern -> - Ltac_plugin.Tacinterp.interp_sign -> Tacmach.tactic) -> - Ltac_plugin.Tacinterp.interp_sign -> Tacmach.tactic - -val ssrcasetac : - Ltac_plugin.Tacinterp.interp_sign -> - Ssrast.ssrterm list * - (Ssrast.ssripat option * - (((Ssrast.ssrdocc * Ssrmatching.cpattern) list list * Ssrast.ssrclear) * - Ssrast.ssripats)) -> - Tacmach.tactic - -val ssrapplytac : - Tacinterp.interp_sign -> - Ssrast.ssrterm list * - ('a * - ((((Ssrast.ssrhyps option * Ssrmatching_plugin.Ssrmatching.occ) * - (Ssrast.ssrtermkind * Tacexpr.glob_constr_and_expr)) - list list * Ssrast.ssrhyps) * - Ssrast.ssripats)) -> - Tacmach.tactic +open Ssrast +(* The => tactical *) +val tclIPAT : ssripats -> unit Proofview.tactic + +(* As above but with the SSR exception: first case is dispatch *) +val tclIPATssr : ssripats -> unit Proofview.tactic + +(* Wrappers to deal with : and eqn generation/naming: + [tac E: gens => ipats] + where [E] is injected into [ipats] (at the right place) and [gens] are + generalized before calling [tac] *) +val ssrmovetac : ssrmovearg -> unit Proofview.tactic +val ssrsmovetac : unit Proofview.tactic +val ssrelimtac : ssrmovearg -> unit Proofview.tactic +val ssrselimtoptac : unit Proofview.tactic +val ssrcasetac : ssrmovearg -> unit Proofview.tactic +val ssrscasetoptac : unit Proofview.tactic + +(* The implementation of abstract: is half here, for the [[: var ]] + * ipat, and in ssrfwd for the integration with [have] *) +val ssrabstract : ssrdgens -> unit Proofview.tactic + +(* Handling of [[:var]], needed in ssrfwd. Since ssrfwd is still outside the + * tactic monad we export code with the V82 interface *) +module Internal : sig +val examine_abstract : + EConstr.t -> Goal.goal Evd.sigma -> EConstr.types * EConstr.t array +val pf_find_abstract_proof : + bool -> Goal.goal Evd.sigma -> Constr.constr -> Evar.t +end diff --git a/plugins/ssr/ssrparser.ml4 b/plugins/ssr/ssrparser.ml4 index 1be53cbdd..70f73c1fe 100644 --- a/plugins/ssr/ssrparser.ml4 +++ b/plugins/ssr/ssrparser.ml4 @@ -20,28 +20,28 @@ open Tacarg open Term open Libnames open Tactics -open Tacticals open Tacmach -open Glob_term open Util open Tacexpr open Tacinterp open Pltac open Extraargs open Ppconstr -open Printer open Misctypes open Decl_kinds open Constrexpr open Constrexpr_ops +open Proofview +open Proofview.Notations + open Ssrprinters open Ssrcommon open Ssrtacticals open Ssrbwd open Ssrequality -open Ssrelim +open Ssripats (** Ssreflect load check. *) @@ -122,7 +122,6 @@ open Ssrast let pr_id = Ppconstr.pr_id let pr_name = function Name id -> pr_id id | Anonymous -> str "_" let pr_spc () = str " " -let pr_bar () = Pp.cut() ++ str "|" let pr_list = prlist_with_sep (**************************** ssrhyp **************************************) @@ -174,7 +173,6 @@ ARGUMENT EXTEND ssrhoi_id TYPED AS ssrhoirep PRINTED BY pr_ssrhoi END -let pr_hyps = pr_list pr_spc pr_hyp let pr_ssrhyps _ _ _ = pr_hyps ARGUMENT EXTEND ssrhyps TYPED AS ssrhyp list PRINTED BY pr_ssrhyps @@ -185,25 +183,12 @@ END (** Rewriting direction *) -let pr_dir = function L2R -> str "->" | R2L -> str "<-" let pr_rwdir = function L2R -> mt() | R2L -> str "-" let wit_ssrdir = add_genarg "ssrdir" pr_dir (** Simpl switch *) - -let pr_simpl = function - | Simpl -1 -> str "/=" - | Cut -1 -> str "//" - | Simpl n -> str "/" ++ int n ++ str "=" - | Cut n -> str "/" ++ int n ++ str"/" - | SimplCut (-1,-1) -> str "//=" - | SimplCut (n,-1) -> str "/" ++ int n ++ str "/=" - | SimplCut (-1,n) -> str "//" ++ int n ++ str "=" - | SimplCut (n,m) -> str "/" ++ int n ++ str "/" ++ int m ++ str "=" - | Nop -> mt () - let pr_ssrsimpl _ _ _ = pr_simpl let wit_ssrsimplrep = add_genarg "ssrsimplrep" pr_simpl @@ -294,8 +279,6 @@ ARGUMENT EXTEND ssrsimpl TYPED AS ssrsimplrep PRINTED BY pr_ssrsimpl | [ ] -> [ Nop ] END -let pr_clear_ne clr = str "{" ++ pr_hyps clr ++ str "}" -let pr_clear sep clr = if clr = [] then mt () else sep () ++ pr_clear_ne clr let pr_ssrclear _ _ _ = pr_clear mt @@ -431,7 +414,7 @@ ARGUMENT EXTEND ssrdocc TYPED AS ssrclear option * ssrocc PRINTED BY pr_ssrdocc | [ "{" ssrocc(occ) "}" ] -> [ mkocc occ ] END -(* kinds of terms *) +(* Old kinds of terms *) let input_ssrtermkind strm = match Util.stream_nth 0 strm with | Tok.KEYWORD "(" -> xInParens @@ -440,12 +423,21 @@ let input_ssrtermkind strm = match Util.stream_nth 0 strm with let ssrtermkind = Pcoq.Gram.Entry.of_parser "ssrtermkind" input_ssrtermkind +(* New kinds of terms *) + +let input_term_annotation strm = + match Stream.npeek 2 strm with + | Tok.KEYWORD "(" :: Tok.KEYWORD "(" :: _ -> `DoubleParens + | Tok.KEYWORD "(" :: _ -> `Parens + | Tok.KEYWORD "@" :: _ -> `At + | _ -> `None +let term_annotation = + Gram.Entry.of_parser "term_annotation" input_term_annotation + (* terms *) (** Terms parsing. ********************************************************) -let interp_constr = interp_wit wit_constr - (* Because we allow wildcards in term references, we need to stage the *) (* interpretation of terms so that it occurs at the right time during *) (* the execution of the tactic (e.g., so that we don't report an error *) @@ -454,9 +446,8 @@ let interp_constr = interp_wit wit_constr (* started with an opening paren, which might avoid a conflict between *) (* the ssrreflect term syntax and Gallina notation. *) -(* terms *) +(* Old terms *) let pr_ssrterm _ _ _ = pr_term -let force_term ist gl (_, c) = interp_constr ist gl c let glob_ssrterm gs = function | k, (_, Some c) -> k, Tacintern.intern_constr gs c | ct -> ct @@ -480,27 +471,71 @@ GEXTEND Gram ssrterm: [[ k = ssrtermkind; c = Pcoq.Constr.constr -> mk_term k c ]]; END -(* Views *) +(* New terms *) + +let pp_ast_closure_term _ _ _ = pr_ast_closure_term + +ARGUMENT EXTEND ast_closure_term + PRINTED BY pp_ast_closure_term + INTERPRETED BY interp_ast_closure_term + GLOBALIZED BY glob_ast_closure_term + SUBSTITUTED BY subst_ast_closure_term + RAW_PRINTED BY pp_ast_closure_term + GLOB_PRINTED BY pp_ast_closure_term + | [ term_annotation(a) constr(c) ] -> [ mk_ast_closure_term a c ] +END +ARGUMENT EXTEND ast_closure_lterm + PRINTED BY pp_ast_closure_term + INTERPRETED BY interp_ast_closure_term + GLOBALIZED BY glob_ast_closure_term + SUBSTITUTED BY subst_ast_closure_term + RAW_PRINTED BY pp_ast_closure_term + GLOB_PRINTED BY pp_ast_closure_term + | [ term_annotation(a) lconstr(c) ] -> [ mk_ast_closure_term a c ] +END + +(* Old Views *) let pr_view = pr_list mt (fun c -> str "/" ++ pr_term c) -let pr_ssrview _ _ _ = pr_view +let pr_ssrbwdview _ _ _ = pr_view -ARGUMENT EXTEND ssrview TYPED AS ssrterm list - PRINTED BY pr_ssrview +ARGUMENT EXTEND ssrbwdview TYPED AS ssrterm list + PRINTED BY pr_ssrbwdview | [ "YouShouldNotTypeThis" ] -> [ [] ] END Pcoq.( GEXTEND Gram - GLOBAL: ssrview; - ssrview: [ + GLOBAL: ssrbwdview; + ssrbwdview: [ [ test_not_ssrslashnum; "/"; c = Pcoq.Constr.constr -> [mk_term xNoFlag c] - | test_not_ssrslashnum; "/"; c = Pcoq.Constr.constr; w = ssrview -> + | test_not_ssrslashnum; "/"; c = Pcoq.Constr.constr; w = ssrbwdview -> (mk_term xNoFlag c) :: w ]]; END ) +(* New Views *) + + +let pr_ssrfwdview _ _ _ = pr_view2 + +ARGUMENT EXTEND ssrfwdview TYPED AS ast_closure_term list + PRINTED BY pr_ssrfwdview +| [ "YouShouldNotTypeThis" ] -> [ [] ] +END + +Pcoq.( +GEXTEND Gram + GLOBAL: ssrfwdview; + ssrfwdview: [ + [ test_not_ssrslashnum; "/"; c = Pcoq.Constr.constr -> + [mk_ast_closure_term `None c] + | test_not_ssrslashnum; "/"; c = Pcoq.Constr.constr; w = ssrfwdview -> + (mk_ast_closure_term `None c) :: w ]]; +END +) + (* }}} *) (* ipats *) @@ -533,24 +568,16 @@ let ipat_of_intro_pattern p = Misctypes.( ipat_of_intro_pattern p ) -let rec pr_ipat p = - match p with - | IPatId id -> pr_id id - | IPatSimpl sim -> pr_simpl sim - | IPatClear clr -> pr_clear mt clr - | IPatCase iorpat -> hov 1 (str "[" ++ pr_iorpat iorpat ++ str "]") - | IPatInj iorpat -> hov 1 (str "[=" ++ pr_iorpat iorpat ++ str "]") - | IPatRewrite (occ, dir) -> pr_occ occ ++ pr_dir dir - | IPatAnon All -> str "*" - | IPatAnon Drop -> str "_" - | IPatAnon One -> str "?" - | IPatView v -> pr_view v - | IPatNoop -> str "-" - | IPatNewHidden l -> str "[:" ++ pr_list spc pr_id l ++ str "]" -(* TODO | IPatAnon Temporary -> str "+" *) - -and pr_iorpat iorpat = pr_list pr_bar pr_ipats iorpat -and pr_ipats ipats = pr_list spc pr_ipat ipats +let rec map_ipat map_id map_ssrhyp map_ast_closure_term = function + | (IPatSimpl _ | IPatAnon _ | IPatRewrite _ | IPatNoop) as x -> x + | IPatId id -> IPatId (map_id id) + | IPatAbstractVars l -> IPatAbstractVars (List.map map_id l) + | IPatClear clr -> IPatClear (List.map map_ssrhyp clr) + | IPatCase iorpat -> IPatCase (List.map (List.map (map_ipat map_id map_ssrhyp map_ast_closure_term)) iorpat) + | IPatDispatch iorpat -> IPatDispatch (List.map (List.map (map_ipat map_id map_ssrhyp map_ast_closure_term)) iorpat) + | IPatInj iorpat -> IPatInj (List.map (List.map (map_ipat map_id map_ssrhyp map_ast_closure_term)) iorpat) + | IPatView v -> IPatView (List.map map_ast_closure_term v) + | IPatTac _ -> assert false (*internal usage only *) let wit_ssripatrep = add_genarg "ssripatrep" pr_ipat @@ -558,13 +585,22 @@ let pr_ssripat _ _ _ = pr_ipat let pr_ssripats _ _ _ = pr_ipats let pr_ssriorpat _ _ _ = pr_iorpat +(* let intern_ipat ist ipat = let rec check_pat = function | IPatClear clr -> ignore (List.map (intern_hyp ist) clr) | IPatCase iorpat -> List.iter (List.iter check_pat) iorpat + | IPatDispatch iorpat -> List.iter (List.iter check_pat) iorpat | IPatInj iorpat -> List.iter (List.iter check_pat) iorpat | _ -> () in check_pat ipat; ipat +*) + +let intern_ipat ist = + map_ipat + (fun id -> id) + (intern_hyp ist) (* TODO: check with ltac, old code was ignoring the result *) + (glob_ast_closure_term ist) let intern_ipats ist = List.map (intern_ipat ist) @@ -575,6 +611,10 @@ let interp_introid ist gl id = Misctypes.( with _ -> snd(snd (interp_intro_pattern ist gl (Loc.tag @@ IntroNaming (IntroIdentifier id)))) ) +let get_intro_id = function + | IntroNaming (IntroIdentifier id) -> id + | _ -> assert false + let rec add_intro_pattern_hyps (loc, ipat) hyps = Misctypes.( match ipat with | IntroNaming (IntroIdentifier id) -> @@ -595,12 +635,14 @@ let rec add_intro_pattern_hyps (loc, ipat) hyps = Misctypes.( of ipat interp_introid could return [HH] *) assert false ) -(* MD: what does this do? *) -let interp_ipat ist gl = Misctypes.( +(* We interp the ipat using the standard ltac machinery for ids, since + * we have no clue what a name could be bound to (maybe another ipat) *) +let interp_ipat ist gl = let ltacvar id = Id.Map.mem id ist.Tacinterp.lfun in let rec interp = function | IPatId id when ltacvar id -> ipat_of_intro_pattern (interp_introid ist gl id) + | IPatId _ as x -> x | IPatClear clr -> let add_hyps (SsrHyp (loc, id) as hyp) hyps = if not (ltacvar id) then hyp :: hyps else @@ -609,16 +651,17 @@ let interp_ipat ist gl = Misctypes.( check_hyps_uniq [] clr'; IPatClear clr' | IPatCase(iorpat) -> IPatCase(List.map (List.map interp) iorpat) + | IPatDispatch(iorpat) -> + IPatDispatch(List.map (List.map interp) iorpat) | IPatInj iorpat -> IPatInj (List.map (List.map interp) iorpat) - | IPatNewHidden l -> - IPatNewHidden - (List.map (function - | IntroNaming (IntroIdentifier id) -> id - | _ -> assert false) - (List.map (interp_introid ist gl) l)) - | ipat -> ipat in + | IPatAbstractVars l -> + IPatAbstractVars (List.map get_intro_id (List.map (interp_introid ist gl) l)) + | IPatView l -> IPatView (List.map (fun x -> snd(interp_ast_closure_term ist + gl x)) l) + | (IPatSimpl _ | IPatAnon _ | IPatRewrite _ | IPatNoop) as x -> x + | IPatTac _ -> assert false (*internal usage only *) + in interp -) let interp_ipats ist gl l = project gl, List.map (interp_ipat ist gl) l @@ -672,9 +715,9 @@ ARGUMENT EXTEND ssripat TYPED AS ssripatrep list PRINTED BY pr_ssripats | [ "-/" integer(n) "/=" ] -> [ [IPatNoop;IPatSimpl(SimplCut (n,~-1))] ] | [ "-/" integer(n) "/" integer (m) "=" ] -> [ [IPatNoop;IPatSimpl(SimplCut(n,m))] ] - | [ ssrview(v) ] -> [ [IPatView v] ] - | [ "[" ":" ident_list(idl) "]" ] -> [ [IPatNewHidden idl] ] - | [ "[:" ident_list(idl) "]" ] -> [ [IPatNewHidden idl] ] + | [ ssrfwdview(v) ] -> [ [IPatView v] ] + | [ "[" ":" ident_list(idl) "]" ] -> [ [IPatAbstractVars idl] ] + | [ "[:" ident_list(idl) "]" ] -> [ [IPatAbstractVars idl] ] END ARGUMENT EXTEND ssripats TYPED AS ssripat PRINTED BY pr_ssripats @@ -715,6 +758,12 @@ GEXTEND Gram (* check_no_inner_seed !@loc false iorpat; IPatCase (understand_case_type iorpat) *) IPatCase iorpat +(* + | test_nohidden; "("; iorpat = ssriorpat; ")" -> +(* check_no_inner_seed !@loc false iorpat; + IPatCase (understand_case_type iorpat) *) + IPatDispatch iorpat +*) | test_nohidden; "[="; iorpat = ssriorpat; "]" -> (* check_no_inner_seed !@loc false iorpat; *) IPatInj iorpat ]]; @@ -752,7 +801,7 @@ let check_ssrhpats loc w_binders ipats = let ipat, binders = let rec loop ipat = function | [] -> ipat, [] - | ( IPatId _| IPatAnon _| IPatCase _| IPatRewrite _ as i) :: tl -> + | ( IPatId _| IPatAnon _| IPatCase _ | IPatDispatch _ | IPatRewrite _ as i) :: tl -> if w_binders then if simpl <> [] && tl <> [] then err_loc(str"binders XOR s-item allowed here: "++pr_ipats(tl@simpl)) @@ -820,8 +869,8 @@ END TACTIC EXTEND ssrtclintros | [ "YouShouldNotTypeThis" ssrintrosarg(arg) ] -> [ let tac, intros = arg in - Proofview.V82.tactic (Ssripats.tclINTROS ist (fun ist -> ssrevaltac ist tac) intros) ] - END + ssrevaltac ist tac <*> tclIPATssr intros ] +END (** Defined identifier *) let pr_ssrfwdid id = pr_spc () ++ pr_id id @@ -1006,15 +1055,6 @@ let pr_binder prl = function | Bcast t -> str ": " ++ prl t -let rec mkBstruct i = function - | Bvar x :: b -> - if i = 0 then [Bstruct x] else mkBstruct (i - 1) b - | Bdecl (xs, _) :: b -> - let i' = i - List.length xs in - if i' < 0 then [Bstruct (List.nth xs i)] else mkBstruct i' b - | _ :: b -> mkBstruct i b - | [] -> [] - let rec format_local_binders h0 bl0 = match h0, bl0 with | BFvar :: h, CLocalAssum ([{CAst.v=x}], _, _) :: bl -> Bvar x :: format_local_binders h bl @@ -1046,51 +1086,6 @@ let rec format_constr_expr h0 c0 = let open CAst in match h0, c0 with | _, c -> [], c -let rec format_glob_decl h0 d0 = match h0, d0 with - | BFvar :: h, (x, _, None, _) :: d -> - Bvar x :: format_glob_decl h d - | BFdecl 1 :: h, (x, _, None, t) :: d -> - Bdecl ([x], t) :: format_glob_decl h d - | BFdecl n :: h, (x, _, None, t) :: d when n > 1 -> - begin match format_glob_decl (BFdecl (n - 1) :: h) d with - | Bdecl (xs, _) :: bs -> Bdecl (x :: xs, t) :: bs - | bs -> Bdecl ([x], t) :: bs - end - | BFdef :: h, (x, _, Some v, _) :: d -> - Bdef (x, None, v) :: format_glob_decl h d - | _, (x, _, None, t) :: d -> - Bdecl ([x], t) :: format_glob_decl [] d - | _, (x, _, Some v, _) :: d -> - Bdef (x, None, v) :: format_glob_decl [] d - | _, [] -> [] - -let rec format_glob_constr h0 c0 = match h0, DAst.get c0 with - | BFvar :: h, GLambda (x, _, _, c) -> - let bs, c' = format_glob_constr h c in - Bvar x :: bs, c' - | BFdecl 1 :: h, GLambda (x, _, t, c) -> - let bs, c' = format_glob_constr h c in - Bdecl ([x], t) :: bs, c' - | BFdecl n :: h, GLambda (x, _, t, c) when n > 1 -> - begin match format_glob_constr (BFdecl (n - 1) :: h) c with - | Bdecl (xs, _) :: bs, c' -> Bdecl (x :: xs, t) :: bs, c' - | _ -> [Bdecl ([x], t)], c - end - | BFdef :: h, GLetIn(x, v, oty, c) -> - let bs, c' = format_glob_constr h c in - Bdef (x, oty, v) :: bs, c' - | [BFcast], GCast (c, CastConv t) -> - [Bcast t], c - | BFrec (has_str, has_cast) :: h, GRec (f, _, bl, t, c) - when Array.length c = 1 -> - let bs = format_glob_decl h bl.(0) in - let bstr = match has_str, f with - | true, GFix ([|Some i, GStructRec|], _) -> mkBstruct i bs - | _ -> [] in - bs @ bstr @ (if has_cast then [Bcast t.(0)] else []), c.(0) - | _, _ -> - [], c0 - (** Forward chaining argument *) (* There are three kinds of forward definitions: *) @@ -1106,19 +1101,32 @@ let wit_ssrfwdfmt = add_genarg "ssrfwdfmt" pr_fwdfmt (* type ssrfwd = ssrfwdfmt * ssrterm *) -let mkFwdVal fk c = ((fk, []), mk_term xNoFlag c) +let mkFwdVal fk c = ((fk, []), c) let mkssrFwdVal fk c = ((fk, []), (c,None)) let dC t = CastConv t -let mkFwdCast fk ?loc t c = ((fk, [BFcast]), mk_term ' ' (CAst.make ?loc @@ CCast (c, dC t))) +let same_ist { interp_env = x } { interp_env = y } = + match x,y with + | None, None -> true + | Some a, Some b -> a == b + | _ -> false + +let mkFwdCast fk ?loc ?c t = + let c = match c with + | None -> mkCHole loc + | Some c -> assert (same_ist t c); c.body in + ((fk, [BFcast]), + { t with annotation = `None; + body = (CAst.make ?loc @@ CCast (c, dC t.body)) }) + let mkssrFwdCast fk loc t c = ((fk, [BFcast]), (c, Some t)) let mkFwdHint s t = - let loc = Constrexpr_ops.constr_loc t in - mkFwdCast (FwdHint (s,false)) ?loc t (mkCHole loc) + let loc = Constrexpr_ops.constr_loc t.body in + mkFwdCast (FwdHint (s,false)) ?loc t let mkFwdHintNoTC s t = - let loc = Constrexpr_ops.constr_loc t in - mkFwdCast (FwdHint (s,true)) ?loc t (mkCHole loc) + let loc = Constrexpr_ops.constr_loc t.body in + mkFwdCast (FwdHint (s,true)) ?loc t let pr_gen_fwd prval prc prlc fk (bs, c) = let prc s = str s ++ spc () ++ prval prc prlc c in @@ -1130,19 +1138,17 @@ let pr_gen_fwd prval prc prlc fk (bs, c) = | _, _ -> spc () ++ pr_list spc (pr_binder prlc) bs ++ prc " :=" let pr_fwd_guarded prval prval' = function -| (fk, h), (_, (_, Some c)) -> - pr_gen_fwd prval pr_constr_expr prl_constr_expr fk (format_constr_expr h c) -| (fk, h), (_, (c, None)) -> - pr_gen_fwd prval' pr_glob_constr_env prl_glob_constr fk (format_glob_constr h c) +| (fk, h), c -> + pr_gen_fwd prval pr_constr_expr prl_constr_expr fk (format_constr_expr h c.body) let pr_unguarded prc prlc = prlc let pr_fwd = pr_fwd_guarded pr_unguarded pr_unguarded let pr_ssrfwd _ _ _ = pr_fwd -ARGUMENT EXTEND ssrfwd TYPED AS (ssrfwdfmt * ssrterm) PRINTED BY pr_ssrfwd - | [ ":=" lconstr(c) ] -> [ mkFwdVal FwdPose c ] - | [ ":" lconstr (t) ":=" lconstr(c) ] -> [ mkFwdCast FwdPose ~loc t c ] +ARGUMENT EXTEND ssrfwd TYPED AS (ssrfwdfmt * ast_closure_lterm) PRINTED BY pr_ssrfwd + | [ ":=" ast_closure_lterm(c) ] -> [ mkFwdVal FwdPose c ] + | [ ":" ast_closure_lterm (t) ":=" ast_closure_lterm(c) ] -> [ mkFwdCast FwdPose ~loc t ~c ] END (** Independent parsing for binders *) @@ -1238,10 +1244,8 @@ END (* The plain pose form. *) -let bind_fwd bs = function - | (fk, h), (ck, (rc, Some c)) -> - (fk,binders_fmts bs @ h), (ck,(rc,Some (push_binders c bs))) - | fwd -> fwd +let bind_fwd bs ((fk, h), c) = + (fk,binders_fmts bs @ h), { c with body = push_binders c.body bs } ARGUMENT EXTEND ssrposefwd TYPED AS ssrfwd PRINTED BY pr_ssrfwd | [ ssrbinder_list(bs) ssrfwd(fwd) ] -> [ bind_fwd bs fwd ] @@ -1259,8 +1263,8 @@ let bvar_locid = function ARGUMENT EXTEND ssrfixfwd TYPED AS ident * ssrfwd PRINTED BY pr_ssrfixfwd | [ "fix" ssrbvar(bv) ssrbinder_list(bs) ssrstruct(sid) ssrfwd(fwd) ] -> [ let { CAst.v=id } as lid = bvar_locid bv in - let (fk, h), (ck, (rc, oc)) = fwd in - let c = Option.get oc in + let (fk, h), ac = fwd in + let c = ac.body in let has_cast, t', c' = match format_constr_expr h c with | [Bcast t'], c' -> true, t', c' | _ -> false, mkCHole (constr_loc c), c in @@ -1276,7 +1280,7 @@ ARGUMENT EXTEND ssrfixfwd TYPED AS ident * ssrfwd PRINTED BY pr_ssrfixfwd loop (names_of_local_assums lb) in let h' = BFrec (has_struct, has_cast) :: binders_fmts bs in let fix = CAst.make ~loc @@ CFix (lid, [lid, (Some i, CStructRec), lb, t', c']) in - id, ((fk, h'), (ck, (rc, Some fix))) ] + id, ((fk, h'), { ac with body = fix }) ] END @@ -1287,14 +1291,14 @@ let pr_ssrcofixfwd _ _ _ (id, fwd) = str " cofix " ++ pr_id id ++ pr_fwd fwd ARGUMENT EXTEND ssrcofixfwd TYPED AS ssrfixfwd PRINTED BY pr_ssrcofixfwd | [ "cofix" ssrbvar(bv) ssrbinder_list(bs) ssrfwd(fwd) ] -> [ let { CAst.v=id } as lid = bvar_locid bv in - let (fk, h), (ck, (rc, oc)) = fwd in - let c = Option.get oc in + let (fk, h), ac = fwd in + let c = ac.body in let has_cast, t', c' = match format_constr_expr h c with | [Bcast t'], c' -> true, t', c' | _ -> false, mkCHole (constr_loc c), c in let h' = BFrec (false, has_cast) :: binders_fmts bs in let cofix = CAst.make ~loc @@ CCoFix (lid, [lid, fix_binders bs, t', c']) in - id, ((fk, h'), (ck, (rc, Some cofix))) + id, ((fk, h'), { ac with body = cofix }) ] END @@ -1304,12 +1308,12 @@ let pr_ssrsetfwd _ _ _ (((fk,_),(t,_)), docc) = (fun _ -> mt()) (fun _ -> mt()) fk ([Bcast ()],t) ARGUMENT EXTEND ssrsetfwd -TYPED AS (ssrfwdfmt * (lcpattern * ssrterm option)) * ssrdocc +TYPED AS (ssrfwdfmt * (lcpattern * ast_closure_lterm option)) * ssrdocc PRINTED BY pr_ssrsetfwd -| [ ":" lconstr(t) ":=" "{" ssrocc(occ) "}" cpattern(c) ] -> - [ mkssrFwdCast FwdPose loc (mk_lterm t) c, mkocc occ ] -| [ ":" lconstr(t) ":=" lcpattern(c) ] -> - [ mkssrFwdCast FwdPose loc (mk_lterm t) c, nodocc ] +| [ ":" ast_closure_lterm(t) ":=" "{" ssrocc(occ) "}" cpattern(c) ] -> + [ mkssrFwdCast FwdPose loc t c, mkocc occ ] +| [ ":" ast_closure_lterm(t) ":=" lcpattern(c) ] -> + [ mkssrFwdCast FwdPose loc t c, nodocc ] | [ ":=" "{" ssrocc(occ) "}" cpattern(c) ] -> [ mkssrFwdVal FwdPose c, mkocc occ ] | [ ":=" lcpattern(c) ] -> [ mkssrFwdVal FwdPose c, nodocc ] @@ -1319,10 +1323,10 @@ END let pr_ssrhavefwd _ _ prt (fwd, hint) = pr_fwd fwd ++ pr_hint prt hint ARGUMENT EXTEND ssrhavefwd TYPED AS ssrfwd * ssrhint PRINTED BY pr_ssrhavefwd -| [ ":" lconstr(t) ssrhint(hint) ] -> [ mkFwdHint ":" t, hint ] -| [ ":" lconstr(t) ":=" lconstr(c) ] -> [ mkFwdCast FwdHave ~loc t c, nohint ] -| [ ":" lconstr(t) ":=" ] -> [ mkFwdHintNoTC ":" t, nohint ] -| [ ":=" lconstr(c) ] -> [ mkFwdVal FwdHave c, nohint ] +| [ ":" ast_closure_lterm(t) ssrhint(hint) ] -> [ mkFwdHint ":" t, hint ] +| [ ":" ast_closure_lterm(t) ":=" ast_closure_lterm(c) ] -> [ mkFwdCast FwdHave ~loc t ~c, nohint ] +| [ ":" ast_closure_lterm(t) ":=" ] -> [ mkFwdHintNoTC ":" t, nohint ] +| [ ":=" ast_closure_lterm(c) ] -> [ mkFwdVal FwdHave c, nohint ] END let intro_id_to_binder = List.map (function @@ -1431,7 +1435,7 @@ let tactic_expr = Pltac.tactic_expr (* debug *) (* Let's play with the new proof engine API *) -let old_tac = Proofview.V82.tactic +let old_tac = V82.tactic (** Name generation {{{ *******************************************************) @@ -1561,12 +1565,12 @@ let ssrautoprop gl = try Tacenv.locate_tactic (qualid_of_ident (Id.of_string "ssrautoprop")) with Not_found -> Tacenv.locate_tactic (ssrqid "ssrautoprop") in let tacexpr = Loc.tag @@ Tacexpr.Reference (ArgArg (Loc.tag @@ tacname)) in - Proofview.V82.of_tactic (eval_tactic (Tacexpr.TacArg tacexpr)) gl - with Not_found -> Proofview.V82.of_tactic (Auto.full_trivial []) gl + V82.of_tactic (eval_tactic (Tacexpr.TacArg tacexpr)) gl + with Not_found -> V82.of_tactic (Auto.full_trivial []) gl let () = ssrautoprop_tac := ssrautoprop -let tclBY tac = tclTHEN tac (donetac ~-1) +let tclBY tac = Tacticals.tclTHEN tac (donetac ~-1) (** Tactical arguments. *) @@ -1582,7 +1586,7 @@ let tclBY tac = tclTHEN tac (donetac ~-1) open Ssrfwd TACTIC EXTEND ssrtclby -| [ "by" ssrhintarg(tac) ] -> [ Proofview.V82.tactic (hinttac ist true tac) ] +| [ "by" ssrhintarg(tac) ] -> [ V82.tactic (hinttac ist true tac) ] END (* }}} *) @@ -1594,15 +1598,13 @@ GEXTEND Gram ssrhint: [[ "by"; arg = ssrhintarg -> arg ]]; END -open Ssripats - (** The "do" tactical. ********************************************************) (* type ssrdoarg = ((ssrindex * ssrmmod) * ssrhint) * ssrclauses *) TACTIC EXTEND ssrtcldo -| [ "YouShouldNotTypeThis" "do" ssrdoarg(arg) ] -> [ Proofview.V82.tactic (ssrdotac ist arg) ] +| [ "YouShouldNotTypeThis" "do" ssrdoarg(arg) ] -> [ V82.tactic (ssrdotac ist arg) ] END set_pr_ssrtac "tcldo" 3 [ArgSep "do "; ArgSsr "doarg"] @@ -1641,7 +1643,7 @@ END TACTIC EXTEND ssrtclseq | [ "YouShouldNotTypeThis" ssrtclarg(tac) ssrseqdir(dir) ssrseqarg(arg) ] -> - [ Proofview.V82.tactic (tclSEQAT ist tac dir arg) ] + [ V82.tactic (tclSEQAT ist tac dir arg) ] END set_pr_ssrtac "tclseq" 5 [ArgSsr "tclarg"; ArgSsr "seqdir"; ArgSsr "seqarg"] @@ -1794,17 +1796,17 @@ END (* the entry point parses only non-empty arguments to avoid conflicts *) (* with the basic Coq tactics. *) -(* type ssrarg = ssrview * (ssreqid * (ssrdgens * ssripats)) *) +(* type ssrarg = ssrbwdview * (ssreqid * (ssrdgens * ssripats)) *) let pr_ssrarg _ _ _ (view, (eqid, (dgens, ipats))) = let pri = pr_intros (gens_sep dgens) in - pr_view view ++ pr_eqid eqid ++ pr_dgens pr_gen dgens ++ pri ipats + pr_view2 view ++ pr_eqid eqid ++ pr_dgens pr_gen dgens ++ pri ipats -ARGUMENT EXTEND ssrarg TYPED AS ssrview * (ssreqid * (ssrdgens * ssrintros)) +ARGUMENT EXTEND ssrarg TYPED AS ssrfwdview * (ssreqid * (ssrdgens * ssrintros)) PRINTED BY pr_ssrarg -| [ ssrview(view) ssreqid(eqid) ssrdgens(dgens) ssrintros(ipats) ] -> +| [ ssrfwdview(view) ssreqid(eqid) ssrdgens(dgens) ssrintros(ipats) ] -> [ view, (eqid, (dgens, ipats)) ] -| [ ssrview(view) ssrclear(clr) ssrintros(ipats) ] -> +| [ ssrfwdview(view) ssrclear(clr) ssrintros(ipats) ] -> [ view, (None, (([], clr), ipats)) ] | [ ssreqid(eqid) ssrdgens(dgens) ssrintros(ipats) ] -> [ [], (eqid, (dgens, ipats)) ] @@ -1818,10 +1820,8 @@ END (* We just add a numeric version that clears the n top assumptions. *) -let poptac ist n = introstac ~ist (List.init n (fun _ -> IPatAnon Drop)) - TACTIC EXTEND ssrclear - | [ "clear" natural(n) ] -> [ Proofview.V82.tactic (poptac ist n) ] + | [ "clear" natural(n) ] -> [ tclIPAT (List.init n (fun _ -> IPatAnon Drop)) ] END (** The "move" tactic *) @@ -1829,7 +1829,7 @@ END (* TODO: review this, in particular the => _ and => [] cases *) let rec improper_intros = function | IPatSimpl _ :: ipats -> improper_intros ipats - | (IPatId _ | IPatAnon _ | IPatCase _) :: _ -> false + | (IPatId _ | IPatAnon _ | IPatCase _ | IPatDispatch _) :: _ -> false | _ -> true (* FIXME *) let check_movearg = function @@ -1847,15 +1847,16 @@ ARGUMENT EXTEND ssrmovearg TYPED AS ssrarg PRINTED BY pr_ssrarg | [ ssrarg(arg) ] -> [ check_movearg arg ] END - +let movearg_of_parsed_movearg (v,(eq,(dg,ip))) = + (v,(eq,(ssrdgens_of_parsed_dgens dg,ip))) TACTIC EXTEND ssrmove | [ "move" ssrmovearg(arg) ssrrpat(pat) ] -> - [ Proofview.V82.tactic (tclTHEN (ssrmovetac ist arg) (introstac ~ist [pat])) ] + [ ssrmovetac (movearg_of_parsed_movearg arg) <*> tclIPAT [pat] ] | [ "move" ssrmovearg(arg) ssrclauses(clauses) ] -> - [ Proofview.V82.tactic (tclCLAUSES ist (ssrmovetac ist arg) clauses) ] -| [ "move" ssrrpat(pat) ] -> [ Proofview.V82.tactic (introstac ~ist [pat]) ] -| [ "move" ] -> [ Proofview.V82.tactic (movehnftac) ] + [ tclCLAUSES (ssrmovetac (movearg_of_parsed_movearg arg)) clauses ] +| [ "move" ssrrpat(pat) ] -> [ tclIPAT [pat] ] +| [ "move" ] -> [ ssrsmovetac ] END let check_casearg = function @@ -1867,31 +1868,18 @@ ARGUMENT EXTEND ssrcasearg TYPED AS ssrarg PRINTED BY pr_ssrarg | [ ssrarg(arg) ] -> [ check_casearg arg ] END - TACTIC EXTEND ssrcase | [ "case" ssrcasearg(arg) ssrclauses(clauses) ] -> - [ old_tac (tclCLAUSES ist (ssrcasetac ist arg) clauses) ] -| [ "case" ] -> [ old_tac (with_fresh_ctx (with_top (ssrscasetac false))) ] + [ tclCLAUSES (ssrcasetac (movearg_of_parsed_movearg arg)) clauses ] +| [ "case" ] -> [ ssrscasetoptac ] END (** The "elim" tactic *) -(* Elim views are elimination lemmas, so the eliminated term is not addded *) -(* to the dependent terms as for "case", unless it actually occurs in the *) -(* goal, the "all occurrences" {+} switch is used, or the equation switch *) -(* is used and there are no dependents. *) - -let ssrelimtac ist (view, (eqid, (dgens, ipats))) = - let ndefectelimtac view eqid ipats deps gen ist gl = - let elim = match view with [v] -> Some (snd(force_term ist gl v)) | _ -> None in - ssrelim ~ist deps (`EGen gen) ?elim eqid (elim_intro_tac ipats) gl - in - with_dgens dgens (ndefectelimtac view eqid ipats) ist - TACTIC EXTEND ssrelim | [ "elim" ssrarg(arg) ssrclauses(clauses) ] -> - [ old_tac (tclCLAUSES ist (ssrelimtac ist arg) clauses) ] -| [ "elim" ] -> [ old_tac (with_fresh_ctx (with_top elimtac)) ] + [ tclCLAUSES (ssrelimtac (movearg_of_parsed_movearg arg)) clauses ] +| [ "elim" ] -> [ ssrselimtoptac ] END (** 6. Backward chaining tactics: apply, exact, congr. *) @@ -1917,14 +1905,14 @@ PRINTED BY pr_ssragens | [ ] -> [ [[]], [] ] END -let mk_applyarg views agens intros = views, (None, (agens, intros)) +let mk_applyarg views agens intros = views, (agens, intros) -let pr_ssraarg _ _ _ (view, (eqid, (dgens, ipats))) = +let pr_ssraarg _ _ _ (view, (dgens, ipats)) = let pri = pr_intros (gens_sep dgens) in - pr_view view ++ pr_eqid eqid ++ pr_dgens pr_agen dgens ++ pri ipats + pr_view view ++ pr_dgens pr_agen dgens ++ pri ipats ARGUMENT EXTEND ssrapplyarg -TYPED AS ssrview * (ssreqid * (ssragens * ssrintros)) +TYPED AS ssrbwdview * (ssragens * ssrintros) PRINTED BY pr_ssraarg | [ ":" ssragen(gen) ssragens(dgens) ssrintros(intros) ] -> [ mk_applyarg [] (cons_gen gen dgens) intros ] @@ -1932,15 +1920,17 @@ PRINTED BY pr_ssraarg [ mk_applyarg [] ([], clr) intros ] | [ ssrintros_ne(intros) ] -> [ mk_applyarg [] ([], []) intros ] -| [ ssrview(view) ":" ssragen(gen) ssragens(dgens) ssrintros(intros) ] -> +| [ ssrbwdview(view) ":" ssragen(gen) ssragens(dgens) ssrintros(intros) ] -> [ mk_applyarg view (cons_gen gen dgens) intros ] -| [ ssrview(view) ssrclear(clr) ssrintros(intros) ] -> +| [ ssrbwdview(view) ssrclear(clr) ssrintros(intros) ] -> [ mk_applyarg view ([], clr) intros ] END TACTIC EXTEND ssrapply -| [ "apply" ssrapplyarg(arg) ] -> [ Proofview.V82.tactic (ssrapplytac ist arg) ] -| [ "apply" ] -> [ Proofview.V82.tactic apply_top_tac ] +| [ "apply" ssrapplyarg(arg) ] -> [ + let views, (gens_clr, intros) = arg in + inner_ssrapplytac views gens_clr ist <*> tclIPATssr intros ] +| [ "apply" ] -> [ apply_top_tac ] END (** The "exact" tactic *) @@ -1950,20 +1940,23 @@ let mk_exactarg views dgens = mk_applyarg views dgens [] ARGUMENT EXTEND ssrexactarg TYPED AS ssrapplyarg PRINTED BY pr_ssraarg | [ ":" ssragen(gen) ssragens(dgens) ] -> [ mk_exactarg [] (cons_gen gen dgens) ] -| [ ssrview(view) ssrclear(clr) ] -> +| [ ssrbwdview(view) ssrclear(clr) ] -> [ mk_exactarg view ([], clr) ] | [ ssrclear_ne(clr) ] -> [ mk_exactarg [] ([], clr) ] END let vmexacttac pf = - Proofview.Goal.nf_enter begin fun gl -> + Goal.nf_enter begin fun gl -> exact_no_check (EConstr.mkCast (pf, VMcast, Tacmach.New.pf_concl gl)) end TACTIC EXTEND ssrexact -| [ "exact" ssrexactarg(arg) ] -> [ Proofview.V82.tactic (tclBY (ssrapplytac ist arg)) ] -| [ "exact" ] -> [ Proofview.V82.tactic (tclORELSE (donetac ~-1) (tclBY apply_top_tac)) ] +| [ "exact" ssrexactarg(arg) ] -> [ + let views, (gens_clr, _) = arg in + V82.tactic (tclBY (V82.of_tactic (inner_ssrapplytac views gens_clr ist))) ] +| [ "exact" ] -> [ + V82.tactic (Tacticals.tclORELSE (donetac ~-1) (tclBY (V82.of_tactic apply_top_tac))) ] | [ "exact" "<:" lconstr(pf) ] -> [ vmexacttac pf ] END @@ -1988,9 +1981,9 @@ END TACTIC EXTEND ssrcongr | [ "congr" ssrcongrarg(arg) ] -> [ let arg, dgens = arg in - Proofview.V82.tactic begin + V82.tactic begin match dgens with - | [gens], clr -> tclTHEN (genstac (gens,clr) ist) (newssrcongrtac arg ist) + | [gens], clr -> Tacticals.tclTHEN (genstac (gens,clr)) (newssrcongrtac arg ist) | _ -> errorstrm (str"Dependent family abstractions not allowed in congr") end] END @@ -2099,10 +2092,10 @@ ARGUMENT EXTEND ssrrwarg END TACTIC EXTEND ssrinstofruleL2R -| [ "ssrinstancesofruleL2R" ssrterm(arg) ] -> [ Proofview.V82.tactic (ssrinstancesofrule ist L2R arg) ] +| [ "ssrinstancesofruleL2R" ssrterm(arg) ] -> [ V82.tactic (ssrinstancesofrule ist L2R arg) ] END TACTIC EXTEND ssrinstofruleR2L -| [ "ssrinstancesofruleR2L" ssrterm(arg) ] -> [ Proofview.V82.tactic (ssrinstancesofrule ist R2L arg) ] +| [ "ssrinstancesofruleR2L" ssrterm(arg) ] -> [ V82.tactic (ssrinstancesofrule ist R2L arg) ] END (** Rewrite argument sequence *) @@ -2143,7 +2136,7 @@ END TACTIC EXTEND ssrrewrite | [ "rewrite" ssrrwargs(args) ssrclauses(clauses) ] -> - [ Proofview.V82.tactic (tclCLAUSES ist (ssrrewritetac ist args) clauses) ] + [ tclCLAUSES (old_tac (ssrrewritetac ist args)) clauses ] END (** The "unlock" tactic *) @@ -2166,16 +2159,16 @@ END TACTIC EXTEND ssrunlock | [ "unlock" ssrunlockargs(args) ssrclauses(clauses) ] -> -[ Proofview.V82.tactic (tclCLAUSES ist (unlocktac ist args) clauses) ] + [ tclCLAUSES (old_tac (unlocktac ist args)) clauses ] END (** 8. Forward chaining tactics (pose, set, have, suffice, wlog) *) TACTIC EXTEND ssrpose -| [ "pose" ssrfixfwd(ffwd) ] -> [ Proofview.V82.tactic (ssrposetac ist ffwd) ] -| [ "pose" ssrcofixfwd(ffwd) ] -> [ Proofview.V82.tactic (ssrposetac ist ffwd) ] -| [ "pose" ssrfwdid(id) ssrposefwd(fwd) ] -> [ Proofview.V82.tactic (ssrposetac ist (id, fwd)) ] +| [ "pose" ssrfixfwd(ffwd) ] -> [ V82.tactic (ssrposetac ffwd) ] +| [ "pose" ssrcofixfwd(ffwd) ] -> [ V82.tactic (ssrposetac ffwd) ] +| [ "pose" ssrfwdid(id) ssrposefwd(fwd) ] -> [ V82.tactic (ssrposetac (id, fwd)) ] END (** The "set" tactic *) @@ -2184,7 +2177,7 @@ END TACTIC EXTEND ssrset | [ "set" ssrfwdid(id) ssrsetfwd(fwd) ssrclauses(clauses) ] -> - [ Proofview.V82.tactic (tclCLAUSES ist (ssrsettac ist id fwd) clauses) ] + [ tclCLAUSES (old_tac (ssrsettac id fwd)) clauses ] END (** The "have" tactic *) @@ -2206,32 +2199,32 @@ TACTIC EXTEND ssrabstract | [ "abstract" ssrdgens(gens) ] -> [ if List.length (fst gens) <> 1 then errorstrm (str"dependents switches '/' not allowed here"); - Proofview.V82.tactic (ssrabstract ist gens) ] + Ssripats.ssrabstract (ssrdgens_of_parsed_dgens gens) ] END TACTIC EXTEND ssrhave | [ "have" ssrhavefwdwbinders(fwd) ] -> - [ Proofview.V82.tactic (havetac ist fwd false false) ] + [ V82.tactic (havetac ist fwd false false) ] END TACTIC EXTEND ssrhavesuff | [ "have" "suff" ssrhpats_nobs(pats) ssrhavefwd(fwd) ] -> - [ Proofview.V82.tactic (havetac ist (false,(pats,fwd)) true false) ] + [ V82.tactic (havetac ist (false,(pats,fwd)) true false) ] END TACTIC EXTEND ssrhavesuffices | [ "have" "suffices" ssrhpats_nobs(pats) ssrhavefwd(fwd) ] -> - [ Proofview.V82.tactic (havetac ist (false,(pats,fwd)) true false) ] + [ V82.tactic (havetac ist (false,(pats,fwd)) true false) ] END TACTIC EXTEND ssrsuffhave | [ "suff" "have" ssrhpats_nobs(pats) ssrhavefwd(fwd) ] -> - [ Proofview.V82.tactic (havetac ist (false,(pats,fwd)) true true) ] + [ V82.tactic (havetac ist (false,(pats,fwd)) true true) ] END TACTIC EXTEND ssrsufficeshave | [ "suffices" "have" ssrhpats_nobs(pats) ssrhavefwd(fwd) ] -> - [ Proofview.V82.tactic (havetac ist (false,(pats,fwd)) true true) ] + [ V82.tactic (havetac ist (false,(pats,fwd)) true true) ] END (** The "suffice" tactic *) @@ -2241,7 +2234,7 @@ let pr_ssrsufffwdwbinders _ _ prt (hpats, (fwd, hint)) = ARGUMENT EXTEND ssrsufffwd TYPED AS ssrhpats * (ssrfwd * ssrhint) PRINTED BY pr_ssrsufffwdwbinders -| [ ssrhpats(pats) ssrbinder_list(bs) ":" lconstr(t) ssrhint(hint) ] -> +| [ ssrhpats(pats) ssrbinder_list(bs) ":" ast_closure_lterm(t) ssrhint(hint) ] -> [ let ((clr, pats), binders), simpl = pats in let allbs = intro_id_to_binder binders @ bs in let allbinders = binders @ List.flatten (binder_to_intro_id bs) in @@ -2251,11 +2244,11 @@ END TACTIC EXTEND ssrsuff -| [ "suff" ssrsufffwd(fwd) ] -> [ Proofview.V82.tactic (sufftac ist fwd) ] +| [ "suff" ssrsufffwd(fwd) ] -> [ V82.tactic (sufftac ist fwd) ] END TACTIC EXTEND ssrsuffices -| [ "suffices" ssrsufffwd(fwd) ] -> [ Proofview.V82.tactic (sufftac ist fwd) ] +| [ "suffices" ssrsufffwd(fwd) ] -> [ V82.tactic (sufftac ist fwd) ] END (** The "wlog" (Without Loss Of Generality) tactic *) @@ -2267,40 +2260,40 @@ let pr_ssrwlogfwd _ _ _ (gens, t) = ARGUMENT EXTEND ssrwlogfwd TYPED AS ssrwgen list * ssrfwd PRINTED BY pr_ssrwlogfwd -| [ ":" ssrwgen_list(gens) "/" lconstr(t) ] -> [ gens, mkFwdHint "/" t] +| [ ":" ssrwgen_list(gens) "/" ast_closure_lterm(t) ] -> [ gens, mkFwdHint "/" t] END TACTIC EXTEND ssrwlog | [ "wlog" ssrhpats_nobs(pats) ssrwlogfwd(fwd) ssrhint(hint) ] -> - [ Proofview.V82.tactic (wlogtac ist pats fwd hint false `NoGen) ] + [ V82.tactic (wlogtac ist pats fwd hint false `NoGen) ] END TACTIC EXTEND ssrwlogs | [ "wlog" "suff" ssrhpats_nobs(pats) ssrwlogfwd(fwd) ssrhint(hint) ] -> - [ Proofview.V82.tactic (wlogtac ist pats fwd hint true `NoGen) ] + [ V82.tactic (wlogtac ist pats fwd hint true `NoGen) ] END TACTIC EXTEND ssrwlogss | [ "wlog" "suffices" ssrhpats_nobs(pats) ssrwlogfwd(fwd) ssrhint(hint) ]-> - [ Proofview.V82.tactic (wlogtac ist pats fwd hint true `NoGen) ] + [ V82.tactic (wlogtac ist pats fwd hint true `NoGen) ] END TACTIC EXTEND ssrwithoutloss | [ "without" "loss" ssrhpats_nobs(pats) ssrwlogfwd(fwd) ssrhint(hint) ] -> - [ Proofview.V82.tactic (wlogtac ist pats fwd hint false `NoGen) ] + [ V82.tactic (wlogtac ist pats fwd hint false `NoGen) ] END TACTIC EXTEND ssrwithoutlosss | [ "without" "loss" "suff" ssrhpats_nobs(pats) ssrwlogfwd(fwd) ssrhint(hint) ] -> - [ Proofview.V82.tactic (wlogtac ist pats fwd hint true `NoGen) ] + [ V82.tactic (wlogtac ist pats fwd hint true `NoGen) ] END TACTIC EXTEND ssrwithoutlossss | [ "without" "loss" "suffices" ssrhpats_nobs(pats) ssrwlogfwd(fwd) ssrhint(hint) ]-> - [ Proofview.V82.tactic (wlogtac ist pats fwd hint true `NoGen) ] + [ V82.tactic (wlogtac ist pats fwd hint true `NoGen) ] END (* Generally have *) @@ -2334,14 +2327,14 @@ TACTIC EXTEND ssrgenhave | [ "gen" "have" ssrclear(clr) ssr_idcomma(id) ssrhpats_nobs(pats) ssrwlogfwd(fwd) ssrhint(hint) ] -> [ let pats = augment_preclr clr pats in - Proofview.V82.tactic (wlogtac ist pats fwd hint false (`Gen id)) ] + V82.tactic (wlogtac ist pats fwd hint false (`Gen id)) ] END TACTIC EXTEND ssrgenhave2 | [ "generally" "have" ssrclear(clr) ssr_idcomma(id) ssrhpats_nobs(pats) ssrwlogfwd(fwd) ssrhint(hint) ] -> [ let pats = augment_preclr clr pats in - Proofview.V82.tactic (wlogtac ist pats fwd hint false (`Gen id)) ] + V82.tactic (wlogtac ist pats fwd hint false (`Gen id)) ] END (* We wipe out all the keywords generated by the grammar rules we defined. *) diff --git a/plugins/ssr/ssrprinters.ml b/plugins/ssr/ssrprinters.ml index 9e9b72fcd..11369228c 100644 --- a/plugins/ssr/ssrprinters.ml +++ b/plugins/ssr/ssrprinters.ml @@ -66,12 +66,55 @@ let pr_glob_constr_and_expr = function let pr_term (k, c) = pr_guarded (guard_term k) pr_glob_constr_and_expr c let pr_hyp (SsrHyp (_, id)) = Id.print id +let pr_hyps = pr_list pr_spc pr_hyp let pr_occ = function | Some (true, occ) -> str "{-" ++ pr_list pr_spc int occ ++ str "}" | Some (false, occ) -> str "{+" ++ pr_list pr_spc int occ ++ str "}" | None -> str "{}" +let pr_clear_ne clr = str "{" ++ pr_hyps clr ++ str "}" +let pr_clear sep clr = if clr = [] then mt () else sep () ++ pr_clear_ne clr + +let pr_dir = function L2R -> str "->" | R2L -> str "<-" + +let pr_simpl = function + | Simpl -1 -> str "/=" + | Cut -1 -> str "//" + | Simpl n -> str "/" ++ int n ++ str "=" + | Cut n -> str "/" ++ int n ++ str"/" + | SimplCut (-1,-1) -> str "//=" + | SimplCut (n,-1) -> str "/" ++ int n ++ str "/=" + | SimplCut (-1,n) -> str "//" ++ int n ++ str "=" + | SimplCut (n,m) -> str "/" ++ int n ++ str "/" ++ int m ++ str "=" + | Nop -> mt () + +(* New terms *) + +let pr_ast_closure_term { body } = Ppconstr.pr_constr_expr body + +let pr_view2 = pr_list mt (fun c -> str "/" ++ pr_ast_closure_term c) + +let rec pr_ipat p = + match p with + | IPatId id -> Id.print id + | IPatSimpl sim -> pr_simpl sim + | IPatClear clr -> pr_clear mt clr + | IPatCase iorpat -> hov 1 (str "[" ++ pr_iorpat iorpat ++ str "]") + | IPatDispatch iorpat -> hov 1 (str "/[" ++ pr_iorpat iorpat ++ str "]") + | IPatInj iorpat -> hov 1 (str "[=" ++ pr_iorpat iorpat ++ str "]") + | IPatRewrite (occ, dir) -> pr_occ occ ++ pr_dir dir + | IPatAnon All -> str "*" + | IPatAnon Drop -> str "_" + | IPatAnon One -> str "?" + | IPatView v -> pr_view2 v + | IPatNoop -> str "-" + | IPatAbstractVars l -> str "[:" ++ pr_list spc Id.print l ++ str "]" + | IPatTac _ -> str "<tac>" +(* TODO | IPatAnon Temporary -> str "+" *) +and pr_ipats ipats = pr_list spc pr_ipat ipats +and pr_iorpat iorpat = pr_list pr_bar pr_ipats iorpat + (* 0 cost pp function. Active only if Debug Ssreflect is Set *) let ppdebug_ref = ref (fun _ -> ()) let ssr_pp s = Feedback.msg_debug (str"SSR: "++Lazy.force s) diff --git a/plugins/ssr/ssrprinters.mli b/plugins/ssr/ssrprinters.mli index 978439d58..31c360ad6 100644 --- a/plugins/ssr/ssrprinters.mli +++ b/plugins/ssr/ssrprinters.mli @@ -29,11 +29,23 @@ val xWithAt : ssrtermkind val xNoFlag : ssrtermkind val xCpattern : ssrtermkind +val pr_clear : (unit -> Pp.t) -> ssrclear -> Pp.t +val pr_clear_ne : ssrclear -> Pp.t +val pr_dir : ssrdir -> Pp.t +val pr_simpl : ssrsimpl -> Pp.t + val pr_term : ssrtermkind * (Glob_term.glob_constr * Constrexpr.constr_expr option) -> Pp.t +val pr_ast_closure_term : ast_closure_term -> Pp.t +val pr_view2 : ast_closure_term list -> Pp.t +val pr_ipat : ssripat -> Pp.t +val pr_ipats : ssripats -> Pp.t +val pr_iorpat : ssripatss -> Pp.t + val pr_hyp : ssrhyp -> Pp.t +val pr_hyps : ssrhyps -> Pp.t val prl_constr_expr : Constrexpr.constr_expr -> Pp.t val prl_glob_constr : Glob_term.glob_constr -> Pp.t diff --git a/plugins/ssr/ssrtacticals.ml b/plugins/ssr/ssrtacticals.ml index 59c1af006..21ad6e6ce 100644 --- a/plugins/ssr/ssrtacticals.ml +++ b/plugins/ssr/ssrtacticals.ml @@ -47,7 +47,7 @@ let rot_hyps dir i hyps = let tclSEQAT ist atac1 dir (ivar, ((_, atacs2), atac3)) = let i = get_index ivar in - let evtac = ssrevaltac ist in + let evtac t = Proofview.V82.of_tactic (ssrevaltac ist t) in let tac1 = evtac atac1 in if atacs2 = [] && atac3 <> None then tclPERM (rot_hyps dir i) tac1 else let evotac = function Some atac -> evtac atac | _ -> Tacticals.tclIDTAC in @@ -93,10 +93,11 @@ let hidetacs clseq idhide cl0 = let endclausestac id_map clseq gl_id cl0 gl = let not_hyp' id = not (List.mem_assoc id id_map) in - let orig_id id = try List.assoc id id_map with _ -> id in + let orig_id id = try List.assoc id id_map with Not_found -> id in let dc, c = EConstr.decompose_prod_assum (project gl) (pf_concl gl) in let hide_goal = hidden_clseq clseq in - let c_hidden = hide_goal && EConstr.eq_constr (project gl) c (EConstr.mkVar gl_id) in + let c_hidden = + hide_goal && EConstr.eq_constr (project gl) c (EConstr.mkVar gl_id) in let rec fits forced = function | (id, _) :: ids, decl :: dc' when RelDecl.get_name decl = Name id -> fits true (ids, dc') @@ -116,26 +117,28 @@ let endclausestac id_map clseq gl_id cl0 gl = let ugtac gl' = Proofview.V82.of_tactic (convert_concl_no_check (unmark (pf_concl gl'))) gl' in - let ctacs = if hide_goal then [Proofview.V82.of_tactic (Tactics.clear [gl_id])] else [] in + let ctacs = + if hide_goal then [Proofview.V82.of_tactic (Tactics.clear [gl_id])] + else [] in let mktac itacs = Tacticals.tclTHENLIST (itacs @ utacs @ ugtac :: ctacs) in let itac (_, id) = Proofview.V82.of_tactic (Tactics.introduction id) in if fits false (id_map, List.rev dc) then mktac (List.map itac id_map) gl else let all_ids = ids_of_rel_context dc @ pf_ids_of_hyps gl in if List.for_all not_hyp' all_ids && not c_hidden then mktac [] gl else - CErrors.user_err (Pp.str "tampering with discharged assumptions of \"in\" tactical") + errorstrm Pp.(str "tampering with discharged assumptions of \"in\" tactical") let apply_type x xs = Proofview.V82.of_tactic (Tactics.apply_type ~typecheck:false x xs) -let tclCLAUSES ist tac (gens, clseq) gl = +let tclCLAUSES tac (gens, clseq) gl = if clseq = InGoal || clseq = InSeqGoal then tac gl else let clr_gens = pf_clauseids gl gens clseq in let clear = Tacticals.tclTHENLIST (List.rev(List.fold_right clr_of_wgen clr_gens [])) in - let gl_id = mk_anon_id hidden_goal_tag gl in + let gl_id = mk_anon_id hidden_goal_tag (Tacmach.pf_ids_of_hyps gl) in let cl0 = pf_concl gl in let dtac gl = let c = pf_concl gl in let gl, args, c = - List.fold_right (abs_wgen true ist mk_discharged_id) gens (gl,[], c) in + List.fold_right (abs_wgen true mk_discharged_id) gens (gl,[], c) in apply_type c args gl in let endtac = let id_map = CList.map_filter (function @@ -149,7 +152,7 @@ let tclCLAUSES ist tac (gens, clseq) gl = let hinttac ist is_by (is_or, atacs) = let dtac = if is_by then donetac ~-1 else Tacticals.tclIDTAC in let mktac = function - | Some atac -> Tacticals.tclTHEN (ssrevaltac ist atac) dtac + | Some atac -> Tacticals.tclTHEN (Proofview.V82.of_tactic (ssrevaltac ist atac)) dtac | _ -> dtac in match List.map mktac atacs with | [] -> if is_or then dtac else Tacticals.tclIDTAC @@ -158,4 +161,7 @@ let hinttac ist is_by (is_or, atacs) = let ssrdotac ist (((n, m), tac), clauses) = let mul = get_index n, m in - tclCLAUSES ist (tclMULT mul (hinttac ist false tac)) clauses + tclCLAUSES (tclMULT mul (hinttac ist false tac)) clauses + +let tclCLAUSES tac g_c = + Proofview.V82.(tactic (tclCLAUSES (of_tactic tac) g_c)) diff --git a/plugins/ssr/ssrtacticals.mli b/plugins/ssr/ssrtacticals.mli index 2f3378a88..84b184713 100644 --- a/plugins/ssr/ssrtacticals.mli +++ b/plugins/ssr/ssrtacticals.mli @@ -21,14 +21,13 @@ val tclSEQAT : Tacmach.tactic val tclCLAUSES : - Ltac_plugin.Tacinterp.interp_sign -> - Proofview.V82.tac -> + unit Proofview.tactic -> (Ssrast.ssrhyps * ((Ssrast.ssrhyp_or_id * string) * Ssrmatching_plugin.Ssrmatching.cpattern option) option) list * Ssrast.ssrclseq -> - Goal.goal Evd.sigma -> Goal.goal list Evd.sigma + unit Proofview.tactic val hinttac : Tacinterp.interp_sign -> diff --git a/plugins/ssr/ssrvernac.ml4 b/plugins/ssr/ssrvernac.ml4 index b3af03d5f..f37452613 100644 --- a/plugins/ssr/ssrvernac.ml4 +++ b/plugins/ssr/ssrvernac.ml4 @@ -337,7 +337,8 @@ let push_rels_assum l e = push_rels_assum l e let coerce_search_pattern_to_sort hpat = - let env = Global.env () and sigma = Evd.empty in + let env = Global.env () in + let sigma = Evd.(from_env env) in let mkPApp fp n_imps args = let args' = Array.append (Array.make n_imps (Pattern.PMeta None)) args in Pattern.PApp (fp, args') in @@ -395,8 +396,9 @@ let interp_search_arg arg = interp_search_notation ~loc s key | RGlobSearchSubPattern p -> try - let intern = Constrintern.intern_constr_pattern in - Search.GlobSearchSubPattern (snd (intern (Global.env()) p)) + let env = Global.env () in + let _, p = Constrintern.intern_constr_pattern env (Evd.from_env env) p in + Search.GlobSearchSubPattern p with e -> let e = CErrors.push e in iraise (ExplainErr.process_vernac_interp_error e)) arg in let hpat, a1 = match arg with | (_, Search.GlobSearchSubPattern (Pattern.PMeta _)) :: a' -> all_true, a' @@ -501,21 +503,19 @@ END (* View purpose *) let pr_viewpos = function - | 0 -> str " for move/" - | 1 -> str " for apply/" - | 2 -> str " for apply//" - | _ -> mt () + | Some Ssrview.AdaptorDb.Forward -> str " for move/" + | Some Ssrview.AdaptorDb.Backward -> str " for apply/" + | Some Ssrview.AdaptorDb.Equivalence -> str " for apply//" + | None -> mt () let pr_ssrviewpos _ _ _ = pr_viewpos -let mapviewpos f n k = if n < 3 then f n else for i = 0 to k - 1 do f i done - -ARGUMENT EXTEND ssrviewpos TYPED AS int PRINTED BY pr_ssrviewpos - | [ "for" "move" "/" ] -> [ 0 ] - | [ "for" "apply" "/" ] -> [ 1 ] - | [ "for" "apply" "/" "/" ] -> [ 2 ] - | [ "for" "apply" "//" ] -> [ 2 ] - | [ ] -> [ 3 ] +ARGUMENT EXTEND ssrviewpos PRINTED BY pr_ssrviewpos + | [ "for" "move" "/" ] -> [ Some Ssrview.AdaptorDb.Forward ] + | [ "for" "apply" "/" ] -> [ Some Ssrview.AdaptorDb.Backward ] + | [ "for" "apply" "/" "/" ] -> [ Some Ssrview.AdaptorDb.Equivalence ] + | [ "for" "apply" "//" ] -> [ Some Ssrview.AdaptorDb.Equivalence ] + | [ ] -> [ None ] END let pr_ssrviewposspc _ _ _ i = pr_viewpos i ++ spc () @@ -524,19 +524,35 @@ ARGUMENT EXTEND ssrviewposspc TYPED AS ssrviewpos PRINTED BY pr_ssrviewposspc | [ ssrviewpos(i) ] -> [ i ] END -let print_view_hints i = - let pp_viewname = str "Hint View" ++ pr_viewpos i ++ str " " in - let pp_hints = pr_list spc pr_rawhintref Ssrview.viewtab.(i) in +let print_view_hints kind l = + let pp_viewname = str "Hint View" ++ pr_viewpos (Some kind) ++ str " " in + let pp_hints = pr_list spc pr_rawhintref l in Feedback.msg_info (pp_viewname ++ hov 0 pp_hints ++ Pp.cut ()) VERNAC COMMAND EXTEND PrintView CLASSIFIED AS QUERY -| [ "Print" "Hint" "View" ssrviewpos(i) ] -> [ mapviewpos print_view_hints i 3 ] +| [ "Print" "Hint" "View" ssrviewpos(i) ] -> + [ match i with + | Some k -> print_view_hints k (Ssrview.AdaptorDb.get k) + | None -> + List.iter (fun k -> print_view_hints k (Ssrview.AdaptorDb.get k)) + [ Ssrview.AdaptorDb.Forward; + Ssrview.AdaptorDb.Backward; + Ssrview.AdaptorDb.Equivalence ] + ] END +let glob_view_hints lvh = + List.map (Constrintern.intern_constr (Global.env ()) (Evd.from_env (Global.env ()))) lvh VERNAC COMMAND EXTEND HintView CLASSIFIED AS SIDEFF | [ "Hint" "View" ssrviewposspc(n) ne_ssrhintref_list(lvh) ] -> - [ mapviewpos (Ssrview.add_view_hints (Ssrview.glob_view_hints lvh)) n 2 ] + [ let hints = glob_view_hints lvh in + match n with + | None -> + Ssrview.AdaptorDb.declare Ssrview.AdaptorDb.Forward hints; + Ssrview.AdaptorDb.declare Ssrview.AdaptorDb.Backward hints + | Some k -> + Ssrview.AdaptorDb.declare k hints ] END (* }}} *) diff --git a/plugins/ssr/ssrview.ml b/plugins/ssr/ssrview.ml index f1a283a69..aa614fbc1 100644 --- a/plugins/ssr/ssrview.ml +++ b/plugins/ssr/ssrview.ml @@ -8,120 +8,325 @@ (* * (see LICENSE file for the text of the license) *) (************************************************************************) -(* This file is (C) Copyright 2006-2015 Microsoft Corporation and Inria. *) - open Util open Names -open Term + open Ltac_plugin -open Tacinterp -open Glob_term -open Tacmach -open Tacticals + +open Proofview +open Notations open Ssrcommon +open Ssrast + +module AdaptorDb = struct + + type kind = Forward | Backward | Equivalence + + module AdaptorKind = struct + type t = kind + let compare = Pervasives.compare + end + module AdaptorMap = Map.Make(AdaptorKind) + + let term_view_adaptor_db = + Summary.ref ~name:"view_adaptor_db" AdaptorMap.empty + + let get k = + try AdaptorMap.find k !term_view_adaptor_db + with Not_found -> [] + + let cache_adaptor (_, (k, t)) = + let lk = get k in + if not (List.exists (Glob_ops.glob_constr_eq t) lk) then + term_view_adaptor_db := AdaptorMap.add k (t :: lk) !term_view_adaptor_db + + let subst_adaptor ( subst, (k, t as a)) = + let t' = Detyping.subst_glob_constr subst t in + if t' == t then a else k, t' + + let classify_adaptor x = Libobject.Substitute x + + let in_db = + Libobject.declare_object { + (Libobject.default_object "VIEW_ADAPTOR_DB") + with + Libobject.open_function = (fun i o -> if i = 1 then cache_adaptor o); + Libobject.cache_function = cache_adaptor; + Libobject.subst_function = subst_adaptor; + Libobject.classify_function = classify_adaptor } + + let declare kind terms = + List.iter (fun term -> Lib.add_anonymous_leaf (in_db (kind,term))) + (List.rev terms) + +end + +(* Forward View application code *****************************************) -(* The table and its display command *) +module State : sig -(* FIXME this looks hackish *) + (* View storage API *) + val vsINIT : EConstr.t -> unit tactic + val vsPUSH : (EConstr.t -> EConstr.t tactic) -> unit tactic + val vsCONSUME : (Id.t option -> EConstr.t -> unit tactic) -> unit tactic + val vsASSERT_EMPTY : unit tactic -let viewtab : glob_constr list array = Array.make 3 [] +end = struct (* {{{ *) -let _ = - let init () = Array.fill viewtab 0 3 [] in - let freeze _ = Array.copy viewtab in - let unfreeze vt = Array.blit vt 0 viewtab 0 3 in - Summary.declare_summary "ssrview" - { Summary.freeze_function = freeze; - Summary.unfreeze_function = unfreeze; - Summary.init_function = init } +type vstate = { + subject_name : Id.t option; (* top *) + (* None if views are being applied to a term *) + view : EConstr.t; (* v2 (v1 top) *) +} -(* Populating the table *) +include Ssrcommon.MakeState(struct + type state = vstate option + let init = None +end) -let cache_viewhint (_, (i, lvh)) = - let mem_raw h = List.exists (Glob_ops.glob_constr_eq h) in - let add_hint h hdb = if mem_raw h hdb then hdb else h :: hdb in - viewtab.(i) <- List.fold_right add_hint lvh viewtab.(i) +let vsINIT view = tclSET (Some { subject_name = None; view }) -let subst_viewhint ( subst, (i, lvh as ilvh)) = - let lvh' = List.smartmap (Detyping.subst_glob_constr subst) lvh in - if lvh' == lvh then ilvh else i, lvh' - -let classify_viewhint x = Libobject.Substitute x +let vsPUSH k = + tacUPDATE (fun s -> match s with + | Some { subject_name; view } -> + k view >>= fun view -> + tclUNIT (Some { subject_name; view }) + | None -> + Goal.enter_one ~__LOC__ begin fun gl -> + let concl = Goal.concl gl in + let id = (* We keep the orig name for checks in "in" tcl *) + match EConstr.kind_of_type (Goal.sigma gl) concl with + | Term.ProdType(Name.Name id, _, _) + when Ssrcommon.is_discharged_id id -> id + | _ -> mk_anon_id "view_subject" (Tacmach.New.pf_ids_of_hyps gl) in + let view = EConstr.mkVar id in + Ssrcommon.tclINTRO_ID id <*> + k view >>= fun view -> + tclUNIT (Some { subject_name = Some id; view }) + end) -let in_viewhint = - Libobject.declare_object {(Libobject.default_object "VIEW_HINTS") with - Libobject.open_function = (fun i o -> if i = 1 then cache_viewhint o); - Libobject.cache_function = cache_viewhint; - Libobject.subst_function = subst_viewhint; - Libobject.classify_function = classify_viewhint } +let vsCONSUME k = + tclGET (fun s -> match s with + | Some { subject_name; view } -> + tclSET None <*> + k subject_name view + | None -> anomaly "vsCONSUME: empty storage") -let glob_view_hints lvh = - List.map (Constrintern.intern_constr (Global.env ())) lvh +let vsASSERT_EMPTY = + tclGET (function + | Some _ -> anomaly ("vsASSERT_EMPTY: not empty") + | _ -> tclUNIT ()) -let add_view_hints lvh i = Lib.add_anonymous_leaf (in_viewhint (i, lvh)) +end (* }}} *) -let interp_view ist si env sigma gv rv rid = - match DAst.get rv with - | GApp (h, rargs) when (match DAst.get h with GHole _ -> true | _ -> false) -> - let loc = rv.CAst.loc in - let rv = DAst.make ?loc @@ GApp (rid, rargs) in - snd (interp_open_constr ist (re_sig si sigma) (rv, None)) +let intern_constr_expr { Genintern.genv; ltacvars = vars } sigma ce = + let ltacvars = { + Constrintern.empty_ltac_sign with Constrintern.ltac_vars = vars } in + Constrintern.intern_gen Pretyping.WithoutTypeConstraint ~ltacvars genv sigma ce + +(* Disambiguation of /t + - t is ltac:(tactic args) + - t is a term + To allow for t being a notation, like "Notation foo x := ltac:(foo x)", we + need to internalize t. +*) +let is_tac_in_term { body; glob_env; interp_env } = + Goal.(enter_one ~__LOC__ begin fun goal -> + let genv = env goal in + let sigma = sigma goal in + let ist = Ssrcommon.option_assert_get glob_env (Pp.str"not a term") in + (* We use the env of the goal, not the global one *) + let ist = { ist with Genintern.genv } in + (* We unravel notations *) + let g = intern_constr_expr ist sigma body in + match DAst.get g with + | Glob_term.GHole (_,_, Some x) + when Genarg.has_type x (Genarg.glbwit Tacarg.wit_tactic) + -> tclUNIT (`Tac (Genarg.out_gen (Genarg.glbwit Tacarg.wit_tactic) x)) + | _ -> tclUNIT (`Term (interp_env, g)) +end) + +(* To inject a constr into a glob_constr we use an Ltac variable *) +let tclINJ_CONSTR_IST ist p = + let fresh_id = Ssrcommon.mk_internal_id "ssr_inj_constr_in_glob" in + let ist = { + ist with Geninterp.lfun = + Id.Map.add fresh_id (Taccoerce.Value.of_constr p) ist.Geninterp.lfun} in + tclUNIT (ist,Glob_term.GVar fresh_id) + +let mkGHole = + DAst.make + (Glob_term.GHole(Evar_kinds.InternalHole, Misctypes.IntroAnonymous, None)) +let rec mkGHoles n = if n > 0 then mkGHole :: mkGHoles (n - 1) else [] +let mkGApp f args = + if args = [] then f + else DAst.make (Glob_term.GApp (f, args)) + +(* From glob_constr to open_constr === (env,sigma,constr) *) +let interp_glob ist glob = Goal.enter_one ~__LOC__ begin fun goal -> + let env = Goal.env goal in + let sigma = Goal.sigma goal in + Ssrprinters.ppdebug (lazy + Pp.(str"interp-in: " ++ Printer.pr_glob_constr_env env glob)); + try + let sigma,term = Tacinterp.interp_open_constr ist env sigma (glob,None) in + Ssrprinters.ppdebug (lazy + Pp.(str"interp-out: " ++ Printer.pr_econstr_env env sigma term)); + tclUNIT (env,sigma,term) + with e -> + Ssrprinters.ppdebug (lazy + Pp.(str"interp-err: " ++ Printer.pr_glob_constr_env env glob)); + tclZERO e +end + +(* Commits the term to the monad *) +(* I think we should make the API safe by storing here the original evar map, + * so that one cannot commit it wrongly. + * We could also commit the term automatically, but this makes the code less + * modular, see the 2 functions below that would need to "uncommit" *) +let tclKeepOpenConstr (_env, sigma, t) = Unsafe.tclEVARS sigma <*> tclUNIT t + +(* The ssr heuristic : *) +(* Estimate a bound on the number of arguments of a raw constr. *) +(* This is not perfect, because the unifier may fail to *) +(* typecheck the partial application, so we use a minimum of 5. *) +(* Also, we don't handle delayed or iterated coercions to *) +(* FUNCLASS, which is probably just as well since these can *) +(* lead to infinite arities. *) +let guess_max_implicits ist glob = + Proofview.tclORELSE + (interp_glob ist (mkGApp glob (mkGHoles 6)) >>= fun (env,sigma,term) -> + let term_ty = Retyping.get_type_of env sigma term in + let ctx, _ = Reductionops.splay_prod env sigma term_ty in + tclUNIT (List.length ctx + 6)) + (fun _ -> tclUNIT 5) + +let pad_to_inductive ist glob = Goal.enter_one ~__LOC__ begin fun goal -> + interp_glob ist glob >>= fun (env, sigma, term) -> + let term_ty = Retyping.get_type_of env sigma term in + let ctx, i = Reductionops.splay_prod env sigma term_ty in + let rel_ctx = + List.map (fun (a,b) -> Context.Rel.Declaration.LocalAssum(a,b)) ctx in + if Ssrcommon.isAppInd (EConstr.push_rel_context rel_ctx env) sigma i + then tclUNIT (mkGApp glob (mkGHoles (List.length ctx))) + else Tacticals.New.tclZEROMSG Pp.(str"not an inductive") +end + +(* There are two ways of "applying" a view to term: *) +(* 1- using a view hint if the view is an instance of some *) +(* (reflection) inductive predicate. *) +(* 2- applying the view if it coerces to a function, adding *) +(* implicit arguments. *) +(* They require guessing the view hints and the number of *) +(* implicits, respectively, which we do by brute force. *) +(* Builds v p *) +let interp_view ist v p = + let is_specialize hd = + match DAst.get hd with Glob_term.GHole _ -> true | _ -> false in + (* We cast the pile of views p into a term p_id *) + tclINJ_CONSTR_IST ist p >>= fun (ist, p_id) -> + let p_id = DAst.make p_id in + match DAst.get v with + | Glob_term.GApp (hd, rargs) when is_specialize hd -> + Ssrprinters.ppdebug (lazy Pp.(str "specialize")); + interp_glob ist (mkGApp p_id rargs) >>= tclKeepOpenConstr | _ -> - let interp rc rargs = - interp_open_constr ist (re_sig si sigma) (mkRApp rc rargs, None) in - let rec simple_view rargs n = - if n < 0 then view_error "use" gv else - try interp rv rargs with _ -> simple_view (mkRHole :: rargs) (n - 1) in - let view_nbimps = interp_view_nbimps ist (re_sig si sigma) rv in - let view_args = [mkRApp rv (mkRHoles view_nbimps); rid] in - let rec view_with = function - | [] -> simple_view [rid] (interp_nbargs ist (re_sig si sigma) rv) - | hint :: hints -> try interp hint view_args with _ -> view_with hints in - snd (view_with (if view_nbimps < 0 then [] else viewtab.(0))) - - -let with_view ist ~next si env (gl0 : (Goal.goal * tac_ctx) Evd.sigma) c name cl prune (conclude : EConstr.t -> EConstr.t -> tac_ctx tac_a) clr = - let c2r ist x = { ist with lfun = - Id.Map.add top_id (Value.of_constr x) ist.lfun } in - let terminate (sigma, c') = - let sigma = Typeclasses.resolve_typeclasses ~fail:false env sigma in - let c' = Reductionops.nf_evar sigma c' in - let n, c', _, ucst = without_ctx pf_abs_evars gl0 (sigma, c') in - let c' = if not prune then c' else without_ctx pf_abs_cterm gl0 n c' in - let gl0 = pf_merge_uc ucst gl0 in - let gl0, ap = - let gl0, ctx = pull_ctx gl0 in - let gl0, ap = pf_abs_prod name gl0 c' (Termops.prod_applist sigma cl [c]) in - push_ctx ctx gl0, ap in - let gl0 = pf_merge_uc_of sigma gl0 in - ap, c', gl0 in - let rec loop (sigma, c') = function - | [] -> - let ap, c', gl = terminate (sigma, c') in - ap, c', conclude ap c' gl - | f :: view -> - let ist, rid = - match EConstr.kind sigma c' with - | Var id -> ist,mkRVar id - | _ -> c2r ist c',mkRltacVar top_id in - let v = intern_term ist env f in - loop (interp_view ist si env sigma f v rid) view - in loop - -let pfa_with_view ist ?(next=ref []) (prune, view) cl c conclude clr gl = - let env, sigma, si = - without_ctx pf_env gl, Refiner.project gl, without_ctx sig_it gl in - with_view - ist ~next si env gl c (constr_name sigma c) cl prune conclude clr (sigma, c) view - -let pf_with_view_linear ist gl v cl c = - let x,y,gl = - pfa_with_view ist v cl c (fun _ _ -> tac_ctx tclIDTAC) [] - (push_ctx (new_ctx ()) gl) in - let gl, _ = pull_ctxs gl in - assert(List.length (sig_it gl) = 1); - x,y,re_sig (List.hd (sig_it gl)) (Refiner.project gl) + Ssrprinters.ppdebug (lazy Pp.(str "view")); + (* We find out how to build (v p) eventually using an adaptor *) + let adaptors = AdaptorDb.(get Forward) in + Proofview.tclORELSE + (pad_to_inductive ist v >>= fun vpad -> + Ssrcommon.tclFIRSTa (List.map + (fun a -> interp_glob ist (mkGApp a [vpad; p_id])) adaptors)) + (fun _ -> + guess_max_implicits ist v >>= fun n -> + Ssrcommon.tclFIRSTi (fun n -> + interp_glob ist (mkGApp v (mkGHoles n @ [p_id]))) n) + >>= tclKeepOpenConstr + +(* we store in the state (v top), then (v1 (v2 top))... *) +let pile_up_view (ist, v) = + let ist = Ssrcommon.option_assert_get ist (Pp.str"not a term") in + State.vsPUSH (fun p -> interp_view ist v p) + +let finalize_view s0 ?(simple_types=true) p = +Goal.enter_one ~__LOC__ begin fun g -> + let env = Goal.env g in + let sigma = Goal.sigma g in + let evars_of_p = Evd.evars_of_term (EConstr.to_constr sigma p) in + let filter x _ = Evar.Set.mem x evars_of_p in + let sigma = Typeclasses.resolve_typeclasses ~fail:false ~filter env sigma in + let p = Reductionops.nf_evar sigma p in + let get_body = function Evd.Evar_defined x -> x | _ -> assert false in + let evars_of_econstr sigma t = + Evd.evars_of_term (EConstr.to_constr sigma (EConstr.of_constr t)) in + let rigid_of s = + List.fold_left (fun l k -> + if Evd.is_defined sigma k then + let bo = get_body Evd.(evar_body (find sigma k)) in + k :: l @ Evar.Set.elements (evars_of_econstr sigma bo) + else l + ) [] s in + let und0 = (* Unassigned evars in the initial goal *) + let sigma0 = Tacmach.project s0 in + let g0info = Evd.find sigma0 (Tacmach.sig_it s0) in + let g0 = Evd.evars_of_filtered_evar_info g0info in + List.filter (fun k -> Evar.Set.mem k g0) + (List.map fst (Evar.Map.bindings (Evd.undefined_map sigma0))) in + let rigid = rigid_of und0 in + let n, p, to_prune, _ucst = pf_abs_evars2 s0 rigid (sigma, p) in + let p = if simple_types then pf_abs_cterm s0 n p else p in + Ssrprinters.ppdebug (lazy Pp.(str"view@finalized: " ++ + Printer.pr_econstr_env env sigma p)); + let sigma = List.fold_left Evd.remove sigma to_prune in + Unsafe.tclEVARS sigma <*> + tclUNIT p +end + +let pose_proof subject_name p = + Tactics.generalize [p] <*> + Option.cata + (fun id -> Ssrcommon.tclRENAME_HD_PROD (Name.Name id)) (tclUNIT()) + subject_name + <*> + Tactics.New.reduce_after_refine + +let rec apply_all_views ending vs s0 = + match vs with + | [] -> ending s0 + | v :: vs -> + Ssrprinters.ppdebug (lazy Pp.(str"piling...")); + is_tac_in_term v >>= function + | `Tac tac -> + Ssrprinters.ppdebug (lazy Pp.(str"..a tactic")); + ending s0 <*> Tacinterp.eval_tactic tac <*> + Ssrcommon.tacSIGMA >>= apply_all_views ending vs + | `Term v -> + Ssrprinters.ppdebug (lazy Pp.(str"..a term")); + pile_up_view v <*> apply_all_views ending vs s0 + +(* Entry points *********************************************************) + +let tclIPAT_VIEWS ~views:vs ~conclusion:tac = + let end_view_application s0 = + State.vsCONSUME (fun name t -> + finalize_view s0 t >>= pose_proof name <*> + tac ~to_clear:(Option.cata (fun x -> [x]) [] name)) in + tclINDEPENDENT begin + State.vsASSERT_EMPTY <*> + Ssrcommon.tacSIGMA >>= apply_all_views end_view_application vs <*> + State.vsASSERT_EMPTY + end +let tclWITH_FWD_VIEWS ~simple_types ~subject ~views:vs ~conclusion:tac = + let ending_tac s0 = + State.vsCONSUME (fun _ t -> finalize_view s0 ~simple_types t >>= tac) in + tclINDEPENDENT begin + State.vsASSERT_EMPTY <*> + State.vsINIT subject <*> + Ssrcommon.tacSIGMA >>= apply_all_views ending_tac vs <*> + State.vsASSERT_EMPTY + end (* vim: set filetype=ocaml foldmethod=marker: *) diff --git a/plugins/ssr/ssrview.mli b/plugins/ssr/ssrview.mli index 882c8035b..be51fe7f9 100644 --- a/plugins/ssr/ssrview.mli +++ b/plugins/ssr/ssrview.mli @@ -8,31 +8,32 @@ (* * (see LICENSE file for the text of the license) *) (************************************************************************) -(* This file is (C) Copyright 2006-2015 Microsoft Corporation and Inria. *) - open Ssrast -open Ssrcommon -val viewtab : Glob_term.glob_constr list array -val add_view_hints : Glob_term.glob_constr list -> int -> unit -val glob_view_hints : Constrexpr.constr_expr list -> Glob_term.glob_constr list +(* Adaptor DB (Hint View) *) +module AdaptorDb : sig + + type kind = Forward | Backward | Equivalence -val pfa_with_view : - ist -> - ?next:ssripats ref -> - bool * ssrterm list -> - EConstr.t -> - EConstr.t -> - (EConstr.t -> EConstr.t -> tac_ctx tac_a) -> - ssrhyps -> - (goal * tac_ctx) sigma -> EConstr.types * EConstr.t * (goal * tac_ctx) list sigma + val get : kind -> Glob_term.glob_constr list + val declare : kind -> Glob_term.glob_constr list -> unit -val pf_with_view_linear : - ist -> - goal sigma -> - bool * ssrterm list -> - EConstr.t -> - EConstr.t -> - EConstr.types * EConstr.t * goal sigma +end +(* Apply views to the top of the stack (intro pattern) *) +val tclIPAT_VIEWS : + views:ast_closure_term list -> + conclusion:(to_clear:Names.Id.t list -> unit Proofview.tactic) -> + unit Proofview.tactic +(* Apply views to a given subject (as if was the top of the stack), then + call conclusion on the obtained term (something like [v2 (v1 subject)]). + The term being passed to conclusion is abstracted over non-resolved evars: + if [simple_types] then all unnecessary dependencies among the abstracted + evars are pruned *) +val tclWITH_FWD_VIEWS : + simple_types:bool -> + subject:EConstr.t -> + views:ast_closure_term list -> + conclusion:(EConstr.t -> unit Proofview.tactic) -> + unit Proofview.tactic diff --git a/plugins/ssrmatching/ssrmatching.ml4 b/plugins/ssrmatching/ssrmatching.ml4 index 79a2dc884..1f1a63dac 100644 --- a/plugins/ssrmatching/ssrmatching.ml4 +++ b/plugins/ssrmatching/ssrmatching.ml4 @@ -75,12 +75,13 @@ let env_size env = List.length (Environ.named_context env) let safeDestApp c = match kind c with App (f, a) -> f, a | _ -> c, [| |] (* Toplevel constr must be globalized twice ! *) -let glob_constr ist genv = function - | _, Some ce -> +let glob_constr ist genv sigma t = match t, ist with + | (_, Some ce), Some ist -> let vars = Id.Map.fold (fun x _ accu -> Id.Set.add x accu) ist.lfun Id.Set.empty in let ltacvars = { Constrintern.empty_ltac_sign with Constrintern.ltac_vars = vars } in - Constrintern.intern_gen WithoutTypeConstraint ~ltacvars:ltacvars genv ce - | rc, None -> rc + Constrintern.intern_gen WithoutTypeConstraint ~ltacvars:ltacvars genv sigma ce + | (rc, None), _ -> rc + | (_, Some _), None -> CErrors.anomaly Pp.(str"glob_constr: term with no ist") (* Term printing utilities functions for deciding bracketing. *) let pr_paren prx x = hov 1 (str "(" ++ prx x ++ str ")") @@ -109,8 +110,8 @@ let prl_glob_constr_and_expr = function let pr_glob_constr_and_expr = function | _, Some c -> pr_constr_expr c | c, None -> pr_glob_constr c -let pr_term (k, c) = pr_guarded (guard_term k) pr_glob_constr_and_expr c -let prl_term (k, c) = pr_guarded (guard_term k) prl_glob_constr_and_expr c +let pr_term (k, c, _) = pr_guarded (guard_term k) pr_glob_constr_and_expr c +let prl_term (k, c, _) = pr_guarded (guard_term k) prl_glob_constr_and_expr c (** Adding a new uninterpreted generic argument type *) let add_genarg tag pr = @@ -150,16 +151,25 @@ let mkRCast rc rt = DAst.make @@ GCast (rc, dC rt) let mkRLambda n s t = DAst.make @@ GLambda (n, Explicit, s, t) (* ssrterm conbinators *) -let combineCG t1 t2 f g = match t1, t2 with - | (x, (t1, None)), (_, (t2, None)) -> x, (g t1 t2, None) - | (x, (_, Some t1)), (_, (_, Some t2)) -> x, (mkRHole, Some (f t1 t2)) - | _, (_, (_, None)) -> CErrors.anomaly (str"have: mixed C-G constr.") +let combineCG t1 t2 f g = + let mk_ist i1 i2 = match i1, i2 with + | None, Some i -> Some i + | Some i, None -> Some i + | None, None -> None + | Some i, Some j when i == j -> Some i + | _ -> CErrors.anomaly (Pp.str "combineCG: different ist") in + match t1, t2 with + | (x, (t1, None), i1), (_, (t2, None), i2) -> + x, (g t1 t2, None), mk_ist i1 i2 + | (x, (_, Some t1), i1), (_, (_, Some t2), i2) -> + x, (mkRHole, Some (f t1 t2)), mk_ist i1 i2 + | _, (_, (_, None), _) -> CErrors.anomaly (str"have: mixed C-G constr.") | _ -> CErrors.anomaly (str"have: mixed G-C constr.") let loc_ofCG = function - | (_, (s, None)) -> Glob_ops.loc_of_glob_constr s - | (_, (_, Some s)) -> Constrexpr_ops.constr_loc s + | (_, (s, None), _) -> Glob_ops.loc_of_glob_constr s + | (_, (_, Some s), _) -> Constrexpr_ops.constr_loc s -let mk_term k c = k, (mkRHole, Some c) +let mk_term k c ist = k, (mkRHole, Some c), ist let mk_lterm = mk_term ' ' let pf_type_of gl t = let sigma, ty = pf_type_of gl t in re_sig (sig_it gl) sigma, ty @@ -892,9 +902,9 @@ let pr_rpattern _ _ _ = pr_pattern let wit_rpatternty = add_genarg "rpatternty" pr_pattern let glob_ssrterm gs = function - | k, (_, Some c) -> k, + | k, (_, Some c), None -> let x = Tacintern.intern_constr gs c in - fst x, Some c + k, (fst x, Some c), None | ct -> ct (* This piece of code asserts the following notations are reserved *) @@ -904,19 +914,19 @@ let glob_ssrterm gs = function (* Reserved Notation "( a 'as' b 'in' c )" (at level 0). *) let glob_cpattern gs p = pp(lazy(str"globbing pattern: " ++ pr_term p)); - let glob x = snd (glob_ssrterm gs (mk_lterm x)) in + let glob x = pi2 (glob_ssrterm gs (mk_lterm x None)) in let encode k s l = let name = Name (Id.of_string ("_ssrpat_" ^ s)) in - k, (mkRCast mkRHole (mkRLambda name mkRHole (mkRApp mkRHole l)), None) in + k, (mkRCast mkRHole (mkRLambda name mkRHole (mkRApp mkRHole l)), None), None in let bind_in t1 t2 = let mkCHole = mkCHole ~loc:None in let n = Name (destCVar t1) in fst (glob (mkCCast mkCHole (mkCLambda n mkCHole t2))) in let check_var t2 = if not (isCVar t2) then loc_error (constr_loc t2) "Only identifiers are allowed here" in match p with - | _, (_, None) as x -> x - | k, (v, Some t) as orig -> - if k = 'x' then glob_ssrterm gs ('(', (v, Some t)) else + | _, (_, None), _ as x -> x + | k, (v, Some t), _ as orig -> + if k = 'x' then glob_ssrterm gs ('(', (v, Some t), None) else match t.CAst.v with | CNotation("( _ in _ )", ([t1; t2], [], [], [])) -> (try match glob t1, glob t2 with @@ -944,7 +954,8 @@ let glob_rpattern s p = | E_In_X_In_T(e,x,t) -> E_In_X_In_T (glob_ssrterm s e,x,glob_ssrterm s t) | E_As_X_In_T(e,x,t) -> E_As_X_In_T (glob_ssrterm s e,x,glob_ssrterm s t) -let subst_ssrterm s (k, c) = k, Tacsubst.subst_glob_constr_and_expr s c +let subst_ssrterm s (k, c, ist) = + k, Tacsubst.subst_glob_constr_and_expr s c, ist let subst_rpattern s = function | T t -> T (subst_ssrterm s t) @@ -954,37 +965,53 @@ let subst_rpattern s = function | E_In_X_In_T(e,x,t) -> E_In_X_In_T (subst_ssrterm s e,x,subst_ssrterm s t) | E_As_X_In_T(e,x,t) -> E_As_X_In_T (subst_ssrterm s e,x,subst_ssrterm s t) +let interp_ssrterm ist (k,t,_) = k, t, Some ist + +let interp_rpattern s = function + | T t -> T (interp_ssrterm s t) + | In_T t -> In_T (interp_ssrterm s t) + | X_In_T(x,t) -> X_In_T (interp_ssrterm s x,interp_ssrterm s t) + | In_X_In_T(x,t) -> In_X_In_T (interp_ssrterm s x,interp_ssrterm s t) + | E_In_X_In_T(e,x,t) -> + E_In_X_In_T (interp_ssrterm s e,interp_ssrterm s x,interp_ssrterm s t) + | E_As_X_In_T(e,x,t) -> + E_As_X_In_T (interp_ssrterm s e,interp_ssrterm s x,interp_ssrterm s t) + +let interp_rpattern ist gl t = Tacmach.project gl, interp_rpattern ist t + ARGUMENT EXTEND rpattern TYPED AS rpatternty PRINTED BY pr_rpattern + INTERPRETED BY interp_rpattern GLOBALIZED BY glob_rpattern SUBSTITUTED BY subst_rpattern - | [ lconstr(c) ] -> [ T (mk_lterm c) ] - | [ "in" lconstr(c) ] -> [ In_T (mk_lterm c) ] + | [ lconstr(c) ] -> [ T (mk_lterm c None) ] + | [ "in" lconstr(c) ] -> [ In_T (mk_lterm c None) ] | [ lconstr(x) "in" lconstr(c) ] -> - [ X_In_T (mk_lterm x, mk_lterm c) ] + [ X_In_T (mk_lterm x None, mk_lterm c None) ] | [ "in" lconstr(x) "in" lconstr(c) ] -> - [ In_X_In_T (mk_lterm x, mk_lterm c) ] + [ In_X_In_T (mk_lterm x None, mk_lterm c None) ] | [ lconstr(e) "in" lconstr(x) "in" lconstr(c) ] -> - [ E_In_X_In_T (mk_lterm e, mk_lterm x, mk_lterm c) ] + [ E_In_X_In_T (mk_lterm e None, mk_lterm x None, mk_lterm c None) ] | [ lconstr(e) "as" lconstr(x) "in" lconstr(c) ] -> - [ E_As_X_In_T (mk_lterm e, mk_lterm x, mk_lterm c) ] + [ E_As_X_In_T (mk_lterm e None, mk_lterm x None, mk_lterm c None) ] END -type cpattern = char * glob_constr_and_expr -let tag_of_cpattern = fst +type cpattern = char * glob_constr_and_expr * Geninterp.interp_sign option +let tag_of_cpattern = pi1 let loc_of_cpattern = loc_ofCG -let cpattern_of_term t = t +let cpattern_of_term (c, t) ist = c, t, Some ist type occ = (bool * int list) option type rpattern = (cpattern, cpattern) ssrpattern -let pr_rpattern = pr_pattern type pattern = Evd.evar_map * (constr, constr) ssrpattern -let id_of_cpattern (_, (c1, c2)) = let open CAst in match DAst.get c1, c2 with +let id_of_cpattern (_, (c1, c2), _) = + let open CAst in + match DAst.get c1, c2 with | _, Some { v = CRef (Ident (_, x), _) } -> Some x | _, Some { v = CAppExpl ((_, Ident (_, x), _), []) } -> Some x | GRef (VarRef x, _), None -> Some x @@ -1011,8 +1038,7 @@ let interp_wit wit ist gl x = sigma, Value.cast (topwit wit) arg let interp_open_constr ist gl gc = interp_wit wit_open_constr ist gl gc -let pf_intern_term ist gl (_, c) = glob_constr ist (pf_env gl) c -let interp_term ist gl (_, c) = on_snd EConstr.Unsafe.to_constr (interp_open_constr ist gl c) +let pf_intern_term gl (_, c, ist) = glob_constr ist (pf_env gl) (project gl) c let pr_ssrterm _ _ _ = pr_term let input_ssrtermkind strm = match stream_nth 0 strm with | Tok.KEYWORD "(" -> '(' @@ -1020,7 +1046,7 @@ let input_ssrtermkind strm = match stream_nth 0 strm with | _ -> ' ' let ssrtermkind = Pcoq.Gram.Entry.of_parser "ssrtermkind" input_ssrtermkind -let interp_ssrterm _ gl t = Tacmach.project gl, t +let interp_ssrterm ist gl t = Tacmach.project gl, interp_ssrterm ist t ARGUMENT EXTEND cpattern PRINTED BY pr_ssrterm @@ -1028,14 +1054,16 @@ ARGUMENT EXTEND cpattern GLOBALIZED BY glob_cpattern SUBSTITUTED BY subst_ssrterm RAW_PRINTED BY pr_ssrterm GLOB_PRINTED BY pr_ssrterm -| [ "Qed" constr(c) ] -> [ mk_lterm c ] +| [ "Qed" constr(c) ] -> [ mk_lterm c None ] END GEXTEND Gram GLOBAL: cpattern; cpattern: [[ k = ssrtermkind; c = constr -> - let pattern = mk_term k c in - if loc_ofCG pattern <> Some !@loc && k = '(' then mk_term 'x' c else pattern ]]; + let pattern = mk_term k c None in + if loc_ofCG pattern <> Some !@loc && k = '(' + then mk_term 'x' c None + else pattern ]]; END ARGUMENT EXTEND lcpattern @@ -1045,16 +1073,23 @@ ARGUMENT EXTEND lcpattern GLOBALIZED BY glob_cpattern SUBSTITUTED BY subst_ssrterm RAW_PRINTED BY pr_ssrterm GLOB_PRINTED BY pr_ssrterm -| [ "Qed" lconstr(c) ] -> [ mk_lterm c ] +| [ "Qed" lconstr(c) ] -> [ mk_lterm c None ] END GEXTEND Gram GLOBAL: lcpattern; lcpattern: [[ k = ssrtermkind; c = lconstr -> - let pattern = mk_term k c in - if loc_ofCG pattern <> Some !@loc && k = '(' then mk_term 'x' c else pattern ]]; + let pattern = mk_term k c None in + if loc_ofCG pattern <> Some !@loc && k = '(' + then mk_term 'x' c None + else pattern ]]; END +let interp_term gl = function + | (_, c, Some ist) -> + on_snd EConstr.Unsafe.to_constr (interp_open_constr ist gl c) + | _ -> errorstrm (str"interpreting a term with no ist") + let thin id sigma goal = let ids = Id.Set.singleton id in let env = Goal.V82.env sigma goal in @@ -1072,32 +1107,35 @@ let thin id sigma goal = let sigma = Goal.V82.partial_solution_to sigma goal gl ev in sigma +(* let pr_ist { lfun= lfun } = prlist_with_sep spc (fun (id, Geninterp.Val.Dyn(ty,_)) -> pr_id id ++ str":" ++ Geninterp.Val.pr ty) (Id.Map.bindings lfun) +*) -let interp_pattern ?wit_ssrpatternarg ist gl red redty = +let interp_pattern ?wit_ssrpatternarg gl red redty = pp(lazy(str"interpreting: " ++ pr_pattern red)); - pp(lazy(str" in ist: " ++ pr_ist ist)); let xInT x y = X_In_T(x,y) and inXInT x y = In_X_In_T(x,y) in let inT x = In_T x and eInXInT e x t = E_In_X_In_T(e,x,t) in let eAsXInT e x t = E_As_X_In_T(e,x,t) in - let mkG ?(k=' ') x = k,(x,None) in - let decode ist t ?reccall f g = - try match DAst.get (pf_intern_term ist gl t) with + let mkG ?(k=' ') x ist = k,(x,None), ist in + let ist_of (_,_,ist) = ist in + let decode (_,_,ist as t) ?reccall f g = + try match DAst.get (pf_intern_term gl t) with | GCast(t,CastConv c) when isGHole t && isGLambda c-> let (x, c) = destGLambda c in - f x (' ',(c,None)) + f x (' ',(c,None),ist) | GVar id - when Id.Map.mem id ist.lfun && + when Option.has_some ist && let ist = Option.get ist in + Id.Map.mem id ist.lfun && not(Option.is_empty reccall) && not(Option.is_empty wit_ssrpatternarg) -> - let v = Id.Map.find id ist.lfun in + let v = Id.Map.find id (Option.get ist).lfun in Option.get reccall (Value.cast (topwit (Option.get wit_ssrpatternarg)) v) | it -> g t with e when CErrors.noncritical e -> g t in - let decodeG t f g = decode ist (mkG t) f g in + let decodeG ist t f g = decode (mkG t ist) f g in let bad_enc id _ = CErrors.anomaly (str"bad encoding for pattern "++str id++str".") in let cleanup_XinE h x rp sigma = let h_k = match kind h with Evar (k,_) -> k | _ -> assert false in @@ -1130,8 +1168,8 @@ let interp_pattern ?wit_ssrpatternarg ist gl red redty = thin name sigma e) sigma new_evars in sigma in - let red = let rec decode_red (ist,red) = match red with - | T(k,(t,None)) -> + let red = let rec decode_red = function + | T(k,(t,None),ist) -> begin match DAst.get t with | GCast (c,CastConv t) when isGHole c && @@ -1141,48 +1179,51 @@ let interp_pattern ?wit_ssrpatternarg ist gl red redty = let (id, t) = destGLambda t in let id = Id.to_string id in let len = String.length id in (match String.sub id 8 (len - 8), DAst.get t with - | "In", GApp( _, [t]) -> decodeG t xInT (fun x -> T x) - | "In", GApp( _, [e; t]) -> decodeG t (eInXInT (mkG e)) (bad_enc id) + | "In", GApp( _, [t]) -> decodeG ist t xInT (fun x -> T x) + | "In", GApp( _, [e; t]) -> decodeG ist t (eInXInT (mkG e ist)) (bad_enc id) | "In", GApp( _, [e; t; e_in_t]) -> - decodeG t (eInXInT (mkG e)) - (fun _ -> decodeG e_in_t xInT (fun _ -> assert false)) - | "As", GApp(_, [e; t]) -> decodeG t (eAsXInT (mkG e)) (bad_enc id) + decodeG ist t (eInXInT (mkG e ist)) + (fun _ -> decodeG ist e_in_t xInT (fun _ -> assert false)) + | "As", GApp(_, [e; t]) -> decodeG ist t (eAsXInT (mkG e ist)) (bad_enc id) | _ -> bad_enc id ()) | _ -> - decode ist ~reccall:decode_red (k, (t, None)) xInT (fun x -> T x) + decode ~reccall:decode_red (mkG ~k t ist) xInT (fun x -> T x) end - | T t -> decode ist ~reccall:decode_red t xInT (fun x -> T x) - | In_T t -> decode ist t inXInT inT - | X_In_T (e,t) -> decode ist t (eInXInT e) (fun x -> xInT (id_of_Cterm e) x) + | T t -> decode ~reccall:decode_red t xInT (fun x -> T x) + | In_T t -> decode t inXInT inT + | X_In_T (e,t) -> decode t (eInXInT e) (fun x -> xInT (id_of_Cterm e) x) | In_X_In_T (e,t) -> inXInT (id_of_Cterm e) t | E_In_X_In_T (e,x,rp) -> eInXInT e (id_of_Cterm x) rp | E_As_X_In_T (e,x,rp) -> eAsXInT e (id_of_Cterm x) rp in - decode_red (ist,red) in + decode_red red in pp(lazy(str"decoded as: " ++ pr_pattern_w_ids red)); - let red = match redty with None -> red | Some ty -> let ty = ' ', ty in + let red = + match redty with + | None -> red + | Some (ty, ist) -> let ty = ' ', ty, Some ist in match red with | T t -> T (combineCG t ty (mkCCast ?loc:(loc_ofCG t)) mkRCast) | X_In_T (x,t) -> - let ty = pf_intern_term ist gl ty in - E_As_X_In_T (mkG (mkRCast mkRHole ty), x, t) + let gty = pf_intern_term gl ty in + E_As_X_In_T (mkG (mkRCast mkRHole gty) (ist_of ty), x, t) | E_In_X_In_T (e,x,t) -> - let ty = mkG (pf_intern_term ist gl ty) in + let ty = mkG (pf_intern_term gl ty) (ist_of ty) in E_In_X_In_T (combineCG e ty (mkCCast ?loc:(loc_ofCG t)) mkRCast, x, t) | E_As_X_In_T (e,x,t) -> - let ty = mkG (pf_intern_term ist gl ty) in + let ty = mkG (pf_intern_term gl ty) (ist_of ty) in E_As_X_In_T (combineCG e ty (mkCCast ?loc:(loc_ofCG t)) mkRCast, x, t) | red -> red in pp(lazy(str"typed as: " ++ pr_pattern_w_ids red)); - let mkXLetIn ?loc x (a,(g,c)) = match c with - | Some b -> a,(g,Some (mkCLetIn ?loc x (mkCHole ~loc) b)) - | None -> a,(DAst.make ?loc @@ GLetIn (x, DAst.make ?loc @@ GHole (BinderType x, IntroAnonymous, None), None, g), None) in + let mkXLetIn ?loc x (a,(g,c),ist) = match c with + | Some b -> a,(g,Some (mkCLetIn ?loc x (mkCHole ~loc) b)), ist + | None -> a,(DAst.make ?loc @@ GLetIn (x, DAst.make ?loc @@ GHole (BinderType x, IntroAnonymous, None), None, g), None), ist in match red with - | T t -> let sigma, t = interp_term ist gl t in sigma, T t - | In_T t -> let sigma, t = interp_term ist gl t in sigma, In_T t + | T t -> let sigma, t = interp_term gl t in sigma, T t + | In_T t -> let sigma, t = interp_term gl t in sigma, In_T t | X_In_T (x, rp) | In_X_In_T (x, rp) -> let mk x p = match red with X_In_T _ -> X_In_T(x,p) | _ -> In_X_In_T(x,p) in let rp = mkXLetIn (Name x) rp in - let sigma, rp = interp_term ist gl rp in + let sigma, rp = interp_term gl rp in let _, h, _, rp = destLetIn rp in let sigma = cleanup_XinE h x rp sigma in let rp = subst1 h (nf_evar sigma rp) in @@ -1191,15 +1232,15 @@ let interp_pattern ?wit_ssrpatternarg ist gl red redty = let mk e x p = match red with E_In_X_In_T _ ->E_In_X_In_T(e,x,p)|_->E_As_X_In_T(e,x,p) in let rp = mkXLetIn (Name x) rp in - let sigma, rp = interp_term ist gl rp in + let sigma, rp = interp_term gl rp in let _, h, _, rp = destLetIn rp in let sigma = cleanup_XinE h x rp sigma in let rp = subst1 h (nf_evar sigma rp) in - let sigma, e = interp_term ist (re_sig (sig_it gl) sigma) e in + let sigma, e = interp_term (re_sig (sig_it gl) sigma) e in sigma, mk e h rp ;; -let interp_cpattern ist gl red redty = interp_pattern ist gl (T red) redty;; -let interp_rpattern ~wit_ssrpatternarg ist gl red = interp_pattern ~wit_ssrpatternarg ist gl red None;; +let interp_cpattern gl red redty = interp_pattern gl (T red) redty;; +let interp_rpattern ~wit_ssrpatternarg gl red = interp_pattern ~wit_ssrpatternarg gl red None;; let id_of_pattern = function | _, T t -> (match kind t with Var id -> Some id | _ -> None) @@ -1355,25 +1396,20 @@ let pf_fill_occ_term gl occ t = let cl,(_,t) = fill_occ_term env concl occ sigma0 t in cl, t -let cpattern_of_id id = ' ', (DAst.make @@ GRef (VarRef id, None), None) +let cpattern_of_id id = + ' ', (DAst.make @@ GRef (VarRef id, None), None), Some Geninterp.({ lfun = Id.Map.empty; extra = Tacinterp.TacStore.empty }) -let is_wildcard ((_, (l, r)) : cpattern) : bool = match DAst.get l, r with +let is_wildcard ((_, (l, r), _) : cpattern) : bool = match DAst.get l, r with | _, Some { CAst.v = CHole _ } | GHole _, None -> true | _ -> false (* "ssrpattern" *) -let pr_ssrpatternarg _ _ _ (_,cpat) = pr_rpattern cpat -let pr_ssrpatternarg_glob _ _ _ cpat = pr_rpattern cpat -let interp_ssrpatternarg ist gl p = project gl, (ist, p) -ARGUMENT EXTEND ssrpatternarg - PRINTED BY pr_ssrpatternarg - INTERPRETED BY interp_ssrpatternarg - GLOBALIZED BY glob_rpattern - RAW_PRINTED BY pr_ssrpatternarg_glob - GLOB_PRINTED BY pr_ssrpatternarg_glob +ARGUMENT EXTEND ssrpatternarg TYPED AS rpattern PRINTED BY pr_rpattern | [ rpattern(pat) ] -> [ pat ] END + +let pr_rpattern = pr_pattern let pf_merge_uc uc gl = re_sig (sig_it gl) (Evd.merge_universe_context (project gl) uc) @@ -1381,10 +1417,10 @@ let pf_merge_uc uc gl = let pf_unsafe_merge_uc uc gl = re_sig (sig_it gl) (Evd.set_universe_context (project gl) uc) -let interp_rpattern ist gl red = interp_rpattern ~wit_ssrpatternarg ist gl red +let interp_rpattern = interp_rpattern ~wit_ssrpatternarg -let ssrpatterntac _ist (arg_ist,arg) gl = - let pat = interp_rpattern arg_ist gl arg in +let ssrpatterntac _ist arg gl = + let pat = interp_rpattern gl arg in let sigma0 = project gl in let concl0 = pf_concl gl in let concl0 = EConstr.Unsafe.to_constr concl0 in @@ -1412,12 +1448,12 @@ let () = Tacenv.register_ltac true false (Id.of_string "ssrpattern") tac in Mltop.declare_cache_obj obj "ssrmatching_plugin" -let ssrinstancesof ist arg gl = +let ssrinstancesof arg gl = let ok rhs lhs ise = true in (* not (equal lhs (Evarutil.nf_evar ise rhs)) in *) let env, sigma, concl = pf_env gl, project gl, pf_concl gl in let concl = EConstr.Unsafe.to_constr concl in - let sigma0, cpat = interp_cpattern ist gl arg None in + let sigma0, cpat = interp_cpattern gl arg None in let pat = match cpat with T x -> x | _ -> errorstrm (str"Not supported") in let etpat, tpat = mk_tpattern env sigma (sigma0,pat) (ok pat) L2R pat in let find, conclude = @@ -1433,7 +1469,7 @@ let ssrinstancesof ist arg gl = with NoMatch -> ppnl (str"END INSTANCES"); tclIDTAC gl TACTIC EXTEND ssrinstoftpat -| [ "ssrinstancesoftpat" cpattern(arg) ] -> [ Proofview.V82.tactic (ssrinstancesof ist arg) ] +| [ "ssrinstancesoftpat" cpattern(arg) ] -> [ Proofview.V82.tactic (ssrinstancesof arg) ] END (* We wipe out all the keywords generated by the grammar rules we defined. *) diff --git a/plugins/ssrmatching/ssrmatching.mli b/plugins/ssrmatching/ssrmatching.mli index 8ab666f7e..cd5676f28 100644 --- a/plugins/ssrmatching/ssrmatching.mli +++ b/plugins/ssrmatching/ssrmatching.mli @@ -61,7 +61,7 @@ val redex_of_pattern : (** [interp_rpattern ise gl rpat] "internalizes" and "interprets" [rpat] in the current [Ltac] interpretation signature [ise] and tactic input [gl]*) val interp_rpattern : - Tacinterp.interp_sign -> goal sigma -> + goal sigma -> rpattern -> pattern @@ -69,8 +69,8 @@ val interp_rpattern : in the current [Ltac] interpretation signature [ise] and tactic input [gl]. [ty] is an optional type for the redex of [cpat] *) val interp_cpattern : - Tacinterp.interp_sign -> goal sigma -> - cpattern -> glob_constr_and_expr option -> + goal sigma -> + cpattern -> (glob_constr_and_expr * Geninterp.interp_sign) option -> pattern (** The set of occurrences to be matched. The boolean is set to true @@ -196,7 +196,7 @@ val mk_tpattern_matcher : val pf_fill_occ_term : goal sigma -> occ -> evar_map * EConstr.t -> EConstr.t * EConstr.t (* It may be handy to inject a simple term into the first form of cpattern *) -val cpattern_of_term : char * glob_constr_and_expr -> cpattern +val cpattern_of_term : char * glob_constr_and_expr -> Geninterp.interp_sign -> cpattern (** Helpers to make stateful closures. Example: a [find_P] function may be called many times, but the pattern instantiation phase is performed only the diff --git a/pretyping/inductiveops.ml b/pretyping/inductiveops.ml index d5baf9ff9..8e3c33ff7 100644 --- a/pretyping/inductiveops.ml +++ b/pretyping/inductiveops.ml @@ -645,8 +645,9 @@ let type_of_projection_knowing_arg env sigma p c ty = (* A function which checks that a term well typed verifies both syntactic conditions *) -let control_only_guard env c = - let check_fix_cofix e c = match kind c with +let control_only_guard env sigma c = + let check_fix_cofix e c = + match kind (EConstr.to_constr sigma c) with | CoFix (_,(_,_,_) as cofix) -> Inductive.check_cofix e cofix | Fix (_,(_,_,_) as fix) -> @@ -655,6 +656,6 @@ let control_only_guard env c = in let rec iter env c = check_fix_cofix env c; - iter_constr_with_full_binders push_rel iter env c + iter_constr_with_full_binders sigma EConstr.push_rel iter env c in iter env c diff --git a/pretyping/inductiveops.mli b/pretyping/inductiveops.mli index 367195724..296f25d3f 100644 --- a/pretyping/inductiveops.mli +++ b/pretyping/inductiveops.mli @@ -200,4 +200,4 @@ val type_of_inductive_knowing_conclusion : env -> evar_map -> Inductive.mind_specif Univ.puniverses -> EConstr.types -> evar_map * EConstr.types (********************) -val control_only_guard : env -> types -> unit +val control_only_guard : env -> Evd.evar_map -> EConstr.types -> unit diff --git a/pretyping/pretyping.ml b/pretyping/pretyping.ml index 1be759816..4bcb7e459 100644 --- a/pretyping/pretyping.ml +++ b/pretyping/pretyping.ml @@ -925,7 +925,7 @@ let rec pretype k0 resolve_tc (tycon : type_constraint) (env : ExtraEnv.t) evdre | [], [] -> [] | _ -> assert false in aux 1 1 (List.rev nal) cs.cs_args, true in - let fsign = if Flags.version_strictly_greater Flags.V8_6 || Flags.version_less_or_equal Flags.VOld + let fsign = if Flags.version_strictly_greater Flags.V8_6 then Context.Rel.map (whd_betaiota !evdref) fsign else fsign (* beta-iota-normalization regression in 8.5 and 8.6 *) in let obj ind p v f = @@ -1038,7 +1038,7 @@ let rec pretype k0 resolve_tc (tycon : type_constraint) (env : ExtraEnv.t) evdre let pi = beta_applist !evdref (pi, [EConstr.of_constr (build_dependent_constructor cs)]) in let cs_args = List.map (fun d -> map_rel_decl EConstr.of_constr d) cs.cs_args in let cs_args = - if Flags.version_strictly_greater Flags.V8_6 || Flags.version_less_or_equal Flags.VOld + if Flags.version_strictly_greater Flags.V8_6 then Context.Rel.map (whd_betaiota !evdref) cs_args else cs_args (* beta-iota-normalization regression in 8.5 and 8.6 *) in let csgn = @@ -1207,8 +1207,7 @@ let all_no_fail_flags = default_inference_flags false let ise_pretype_gen_ctx flags env sigma lvar kind c = let evd, c, _ = ise_pretype_gen flags env sigma lvar kind c in - let evd, f = Evarutil.nf_evars_and_universes evd in - f (EConstr.Unsafe.to_constr c), Evd.evar_universe_context evd + c, Evd.evar_universe_context evd (** Entry points of the high-level type synthesis algorithm *) diff --git a/pretyping/pretyping.mli b/pretyping/pretyping.mli index dfec13b8e..415c4e172 100644 --- a/pretyping/pretyping.mli +++ b/pretyping/pretyping.mli @@ -14,7 +14,6 @@ into elementary ones, insertion of coercions and resolution of implicit arguments. *) -open Constr open Environ open Evd open EConstr @@ -28,7 +27,7 @@ val interp_known_glob_level : ?loc:Loc.t -> Evd.evar_map -> (** An auxiliary function for searching for fixpoint guard indexes *) val search_guard : - ?loc:Loc.t -> env -> int list list -> rec_declaration -> int array + ?loc:Loc.t -> env -> int list list -> Constr.rec_declaration -> int array type typing_constraint = OfType of types | IsType | WithoutTypeConstraint @@ -87,9 +86,8 @@ val understand_ltac : inference_flags -> heuristics (but no external tactic solver hook), as well as to ensure that conversion problems are all solved and that no unresolved evar remains, expanding evars. *) - val understand : ?flags:inference_flags -> ?expected_type:typing_constraint -> - env -> evar_map -> glob_constr -> Constr.constr Evd.in_evar_universe_context + env -> evar_map -> glob_constr -> constr Evd.in_evar_universe_context (** Trying to solve remaining evars and remaining conversion problems possibly using type classes, heuristics, external tactic solver diff --git a/pretyping/reductionops.ml b/pretyping/reductionops.ml index 635b08545..e8b19f6bc 100644 --- a/pretyping/reductionops.ml +++ b/pretyping/reductionops.ml @@ -1486,16 +1486,12 @@ let hnf_lam_appvect env sigma t nl = let hnf_lam_applist env sigma t nl = List.fold_left (fun acc t -> hnf_lam_app env sigma acc t) t nl -let bind_assum (na, t) = - (na, t) - let splay_prod env sigma = let rec decrec env m c = let t = whd_all env sigma c in match EConstr.kind sigma t with | Prod (n,a,c0) -> - decrec (push_rel (LocalAssum (n,a)) env) - (bind_assum (n,a)::m) c0 + decrec (push_rel (LocalAssum (n,a)) env) ((n,a)::m) c0 | _ -> m,t in decrec env [] @@ -1505,8 +1501,7 @@ let splay_lam env sigma = let t = whd_all env sigma c in match EConstr.kind sigma t with | Lambda (n,a,c0) -> - decrec (push_rel (LocalAssum (n,a)) env) - (bind_assum (n,a)::m) c0 + decrec (push_rel (LocalAssum (n,a)) env) ((n,a)::m) c0 | _ -> m,t in decrec env [] diff --git a/pretyping/typeclasses.mli b/pretyping/typeclasses.mli index 541fbdf22..b80c28711 100644 --- a/pretyping/typeclasses.mli +++ b/pretyping/typeclasses.mli @@ -95,7 +95,12 @@ val no_goals : evar_filter val no_goals_or_obligations : evar_filter (** Resolvability. - Only undefined evars can be marked or checked for resolvability. *) + Only undefined evars can be marked or checked for resolvability. + They represent type-class search roots. + + A resolvable evar is an evar the type-class engine may try to solve + An unresolvable evar is an evar the type-class engine will NOT try to solve +*) val set_resolvable : Evd.Store.t -> bool -> Evd.Store.t val is_resolvable : evar_info -> bool diff --git a/pretyping/unification.ml b/pretyping/unification.ml index 936fb40a4..5bc93f1fa 100644 --- a/pretyping/unification.ml +++ b/pretyping/unification.ml @@ -195,7 +195,7 @@ let pose_all_metas_as_evars env evd t = let ty = EConstr.of_constr ty in let ty = if Evd.Metaset.is_empty mvs then ty else aux ty in let ty = - if Flags.version_strictly_greater Flags.V8_6 || Flags.version_less_or_equal Flags.VOld + if Flags.version_strictly_greater Flags.V8_6 then nf_betaiota env evd ty (* How it was in Coq <= 8.4 (but done in logic.ml at this time) *) else ty (* some beta-iota-normalization "regression" in 8.5 and 8.6 *) in let src = Evd.evar_source_of_meta mv !evdref in @@ -1306,12 +1306,7 @@ let solve_simple_evar_eqn ts env evd ev rhs = match solve_simple_eqn (Evarconv.evar_conv_x ts) env evd (None,ev,rhs) with | UnifFailure (evd,reason) -> error_cannot_unify env evd ~reason (mkEvar ev,rhs); - | Success evd -> - if Flags.version_less_or_equal Flags.V8_5 then - (* We used to force solving unrelated problems at arbitrary times *) - Evarconv.solve_unif_constraints_with_heuristics env evd - else (* solve_simple_eqn calls reconsider_unif_constraints itself *) - evd + | Success evd -> evd (* [w_merge env sigma b metas evars] merges common instances in metas or in evars, possibly generating new unification problems; if [b] diff --git a/pretyping/vnorm.ml b/pretyping/vnorm.ml index a8c9cf644..3c9b8bc33 100644 --- a/pretyping/vnorm.ml +++ b/pretyping/vnorm.ml @@ -143,7 +143,6 @@ and nf_vtype env sigma v = nf_val env sigma v crazy_type and nf_whd env sigma whd typ = match whd with - | Vsort s -> mkSort s | Vprod p -> let dom = nf_vtype env sigma (dom p) in let name = Name (Id.of_string "x") in @@ -184,7 +183,8 @@ and nf_whd env sigma whd typ = let pind = (ind, u) in (mkIndU pind, type_of_ind env pind) in nf_univ_args ~nb_univs mk env sigma stk - | Vatom_stk(Atype u, stk) -> assert false + | Vatom_stk(Asort s, stk) -> + assert (List.is_empty stk); mkSort s | Vuniv_level lvl -> assert false @@ -202,7 +202,26 @@ and nf_univ_args ~nb_univs mk env sigma stk = let (t,ty) = mk u in nf_stk ~from:nb_univs env sigma t ty stk -and constr_type_of_idkey env sigma (idkey : Vars.id_key) stk = +and nf_evar env sigma evk stk = + let evi = try Evd.find sigma evk with Not_found -> assert false in + let hyps = Environ.named_context_of_val (Evd.evar_filtered_hyps evi) in + let concl = Evd.evar_concl evi in + if List.is_empty hyps then + nf_stk env sigma (mkEvar (evk, [||])) concl stk + else match stk with + | Zapp args :: stk -> + (** We assume that there is no consecutive Zapp nodes in a VM stack. Is that + really an invariant? *) + let fold accu d = Term.mkNamedProd_or_LetIn d accu in + let t = List.fold_left fold concl hyps in + let t, args = nf_args env sigma args t in + let inst, args = Array.chop (List.length hyps) args in + let c = mkApp (mkEvar (evk, inst), args) in + nf_stk env sigma c t stk + | _ -> + CErrors.anomaly (Pp.str "Argument size mismatch when decompiling an evar") + +and constr_type_of_idkey env sigma (idkey : Vmvalues.id_key) stk = match idkey with | ConstKey cst -> let cbody = Environ.lookup_constant cst env in @@ -220,6 +239,8 @@ and constr_type_of_idkey env sigma (idkey : Vars.id_key) stk = let n = (nb_rel env - i) in let ty = RelDecl.get_type (lookup_rel n env) in nf_stk env sigma (mkRel n) (lift n ty) stk + | EvarKey evk -> + nf_evar env sigma evk stk and nf_stk ?from:(from=0) env sigma c t stk = match stk with @@ -357,8 +378,8 @@ and nf_cofix env sigma cf = mkCoFix (init,(name,cft,cfb)) let cbv_vm env sigma c t = - if Termops.occur_meta_or_existential sigma c then - CErrors.user_err Pp.(str "vm_compute does not support existential variables."); + if Termops.occur_meta sigma c then + CErrors.user_err Pp.(str "vm_compute does not support metas."); (** This evar-normalizes terms beforehand *) let c = EConstr.to_constr sigma c in let t = EConstr.to_constr sigma t in diff --git a/printing/ppconstr.ml b/printing/ppconstr.ml index 3ab41c62b..8854ff898 100644 --- a/printing/ppconstr.ml +++ b/printing/ppconstr.ml @@ -151,7 +151,7 @@ let tag_var = tag Tag.variable str "`" ++ str hd ++ c ++ str tl let pr_com_at n = - if !Flags.beautify && not (Int.equal n 0) then comment (CLexer.extract_comments n) + if !Flags.beautify && not (Int.equal n 0) then comment (Pputils.extract_comments n) else mt() let pr_with_comments ?loc pp = pr_located (fun x -> x) (loc, pp) @@ -703,13 +703,16 @@ let tag_var = tag Tag.variable | { CAst.v = CAppExpl ((None,f,us),[]) } -> str "@" ++ pr_cref f us | c -> pr prec c - let transf env c = + let transf env sigma c = if !Flags.beautify_file then - let r = Constrintern.for_grammar (Constrintern.intern_constr env) c in + let r = Constrintern.for_grammar (Constrintern.intern_constr env sigma) c in Constrextern.extern_glob_constr (Termops.vars_of_env env) r else c - let pr_expr prec c = pr prec (transf (Global.env()) c) + let pr_expr prec c = + let env = Global.env () in + let sigma = Evd.from_env env in + pr prec (transf env sigma c) let pr_simpleconstr = pr_expr lsimpleconstr diff --git a/printing/pputils.ml b/printing/pputils.ml index 6b23b7fe9..010b92f3e 100644 --- a/printing/pputils.ml +++ b/printing/pputils.ml @@ -15,14 +15,26 @@ open Misctypes open Locus open Genredexpr +let beautify_comments = ref [] + +let rec split_comments comacc acc pos = function + | [] -> beautify_comments := List.rev acc; comacc + | ((b,e),c as com)::coms -> + (* Take all comments that terminates before pos, or begin exactly + at pos (used to print comments attached after an expression) *) + if e<=pos || pos=b then split_comments (c::comacc) acc pos coms + else split_comments comacc (com::acc) pos coms + +let extract_comments pos = split_comments [] [] pos !beautify_comments + let pr_located pr (loc, x) = match loc with | Some loc when !Flags.beautify -> let (b, e) = Loc.unloc loc in (* Side-effect: order matters *) - let before = Pp.comment (CLexer.extract_comments b) in + let before = Pp.comment (extract_comments b) in let x = pr x in - let after = Pp.comment (CLexer.extract_comments e) in + let after = Pp.comment (extract_comments e) in before ++ x ++ after | _ -> pr x diff --git a/printing/pputils.mli b/printing/pputils.mli index 06123362a..6039168f8 100644 --- a/printing/pputils.mli +++ b/printing/pputils.mli @@ -39,3 +39,9 @@ val pr_red_expr_env : Environ.env -> Evd.evar_map -> val pr_raw_generic : Environ.env -> rlevel generic_argument -> Pp.t val pr_glb_generic : Environ.env -> glevel generic_argument -> Pp.t + +(* The comments interface is imperative due to the printer not + threading it, this could be solved using a better data + structure. *) +val beautify_comments : ((int * int) * string) list ref +val extract_comments : int -> string list diff --git a/proofs/proof.ml b/proofs/proof.ml index 78fe850bc..24f570f01 100644 --- a/proofs/proof.ml +++ b/proofs/proof.ml @@ -434,7 +434,7 @@ module V82 = struct CList.nth evl (n-1) in let env = Evd.evar_filtered_env evi in - let rawc = Constrintern.intern_constr env com in + let rawc = Constrintern.intern_constr env sigma com in let ltac_vars = Glob_ops.empty_lvar in let sigma = Evar_refiner.w_refine (evk, evi) (ltac_vars, rawc) sigma in Proofview.Unsafe.tclEVARS sigma diff --git a/proofs/refine.ml b/proofs/refine.ml index 4469f2772..50fd1c472 100644 --- a/proofs/refine.ml +++ b/proofs/refine.ml @@ -75,6 +75,7 @@ let generic_refine ~typecheck f gl = let sigma = Proofview.Goal.sigma gl in let env = Proofview.Goal.env gl in let concl = Proofview.Goal.concl gl in + let state = Proofview.Goal.state gl in (** Save the [future_goals] state to restore them after the refinement. *) let prev_future_goals = Evd.future_goals sigma in @@ -122,6 +123,7 @@ let generic_refine ~typecheck f gl = (** Select the goals *) let comb = CList.map_filter (Proofview.Unsafe.advance sigma) (CList.rev evs) in let sigma = CList.fold_left Proofview.Unsafe.mark_as_goal sigma comb in + let comb = CList.map (fun x -> Proofview.goal_with_state x state) comb in let trace () = Pp.(hov 2 (str"simple refine"++spc()++ Hook.get pr_constrv env sigma c)) in Proofview.Trace.name_tactic trace (Proofview.tclUNIT v) >>= fun v -> Proofview.Unsafe.tclSETENV (Environ.reset_context env) <*> diff --git a/stm/stm.ml b/stm/stm.ml index b74aee863..d878bbb30 100644 --- a/stm/stm.ml +++ b/stm/stm.ml @@ -2951,6 +2951,7 @@ let get_ast ~doc id = match VCS.visit id with | { step = `Cmd { cast = { loc; expr } } } | { step = `Fork (({ loc; expr }, _, _, _), _) } + | { step = `Sideff ((ReplayCommand {loc; expr}) , _) } | { step = `Qed ({ qast = { loc; expr } }, _) } -> Some (Loc.tag ?loc expr) | _ -> None diff --git a/tactics/class_tactics.ml b/tactics/class_tactics.ml index 34f659653..4c91f3f61 100644 --- a/tactics/class_tactics.ml +++ b/tactics/class_tactics.ml @@ -583,7 +583,7 @@ let make_resolve_hyp env sigma st flags only_classes pri decl = (fun (path,info,c) -> let info = { info with Vernacexpr.hint_pattern = - Option.map (Constrintern.intern_constr_pattern env) + Option.map (Constrintern.intern_constr_pattern env sigma) info.Vernacexpr.hint_pattern } in make_resolves env sigma ~name:(PathHints path) @@ -1133,6 +1133,7 @@ module Search = struct let rec result (shelf, ()) i k = foundone := true; Proofview.Unsafe.tclGETGOALS >>= fun gls -> + let gls = CList.map Proofview.drop_state gls in let j = List.length gls in (if !typeclasses_debug > 0 then Feedback.msg_debug @@ -1181,7 +1182,7 @@ module Search = struct (if List.is_empty goals then tclUNIT () else let sigma' = mark_unresolvables sigma goals in - with_shelf (Unsafe.tclEVARS sigma' <*> Unsafe.tclNEWGOALS goals) >>= + with_shelf (Unsafe.tclEVARS sigma' <*> Unsafe.tclNEWGOALS (CList.map Proofview.with_empty_state goals)) >>= fun s -> result s i (Some (Option.default 0 k + j))) end in with_shelf res >>= fun (sh, ()) -> @@ -1274,6 +1275,7 @@ module Search = struct search_tac_gl ~st only_classes dep hints depth (succ i) sigma gls gl end in Proofview.Unsafe.tclGETGOALS >>= fun gls -> + let gls = CList.map Proofview.drop_state gls in Proofview.tclEVARMAP >>= fun sigma -> let j = List.length gls in (tclDISPATCH (List.init j (fun i -> tac sigma gls i))) diff --git a/tactics/contradiction.ml b/tactics/contradiction.ml index a4a18aca2..c285f21e7 100644 --- a/tactics/contradiction.ml +++ b/tactics/contradiction.ml @@ -46,8 +46,6 @@ let absurd c = absurd c (* Contradiction *) -let use_negated_unit_or_eq_type () = Flags.version_strictly_greater Flags.V8_5 - (** [f] does not assume its argument to be [nf_evar]-ed. *) let filter_hyp f tac = let rec seek = function @@ -73,9 +71,7 @@ let contradiction_context = simplest_elim (mkVar id) else match EConstr.kind sigma typ with | Prod (na,t,u) when is_empty_type sigma u -> - let is_unit_or_eq = - if use_negated_unit_or_eq_type () then match_with_unit_or_eq_type sigma t - else None in + let is_unit_or_eq = match_with_unit_or_eq_type sigma t in Tacticals.New.tclORELSE (match is_unit_or_eq with | Some _ -> diff --git a/tactics/equality.ml b/tactics/equality.ml index b07c05011..f15a64fc8 100644 --- a/tactics/equality.ml +++ b/tactics/equality.ml @@ -86,7 +86,7 @@ let _ = let injection_in_context = ref false let use_injection_in_context = function - | None -> !injection_in_context && Flags.version_strictly_greater Flags.V8_5 + | None -> !injection_in_context | Some flags -> flags.injection_in_context let _ = @@ -535,7 +535,7 @@ let general_rewrite_clause l2r with_evars ?tac c cl = let rec do_hyps_atleastonce = function | [] -> tclZEROMSG (Pp.str"Nothing to rewrite.") | id :: l -> - tclIFTHENTRYELSEMUST + tclIFTHENFIRSTTRYELSEMUST (general_rewrite_ebindings_in l2r AllOccurrences false true ?tac id c with_evars) (do_hyps_atleastonce l) in @@ -551,7 +551,7 @@ let general_rewrite_clause l2r with_evars ?tac c cl = end in if cl.concl_occs == NoOccurrences then do_hyps else - tclIFTHENTRYELSEMUST + tclIFTHENFIRSTTRYELSEMUST (general_rewrite_ebindings l2r (occs_of cl.concl_occs) false true ?tac c with_evars) do_hyps diff --git a/tactics/hints.ml b/tactics/hints.ml index 4be2053f9..f3e0619a2 100644 --- a/tactics/hints.ml +++ b/tactics/hints.ml @@ -1272,7 +1272,7 @@ let prepare_hint check (poly,local) env init (sigma,c) = let interp_hints poly = fun h -> - let env = (Global.env()) in + let env = Global.env () in let sigma = Evd.from_env env in let f poly c = let evd,c = Constrintern.interp_open_constr env sigma c in @@ -1281,9 +1281,7 @@ let interp_hints poly = let gr = global_with_alias r in Dumpglob.add_glob ?loc:(loc_of_reference r) gr; gr in - let fr r = - evaluable_of_global_reference (Global.env()) (fref r) - in + let fr r = evaluable_of_global_reference env (fref r) in let fi c = match c with | HintsReference c -> @@ -1291,7 +1289,7 @@ let interp_hints poly = (PathHints [gr], poly, IsGlobRef gr) | HintsConstr c -> (PathAny, poly, f poly c) in - let fp = Constrintern.intern_constr_pattern (Global.env()) in + let fp = Constrintern.intern_constr_pattern env sigma in let fres (info, b, r) = let path, poly, gr = fi r in let info = { info with hint_pattern = Option.map fp info.hint_pattern } in diff --git a/tactics/tacticals.ml b/tactics/tacticals.ml index d0daeae09..789cc35ee 100644 --- a/tactics/tacticals.ml +++ b/tactics/tacticals.ml @@ -410,8 +410,14 @@ module New = struct Proofview.tclIFCATCH t1 (fun () -> tclDISPATCH (Array.to_list a)) (fun _ -> t3) + let tclIFTHENFIRSTELSE t1 t2 t3 = + Proofview.tclIFCATCH t1 + (fun () -> tclEXTEND [t2] (tclUNIT ()) []) + (fun _ -> t3) let tclIFTHENTRYELSEMUST t1 t2 = tclIFTHENELSE t1 (tclTRY t2) t2 + let tclIFTHENFIRSTTRYELSEMUST t1 t2 = + tclIFTHENFIRSTELSE t1 (tclTRY t2) t2 (* Try the first tactic that does not fail in a list of tactics *) let rec tclFIRST = function diff --git a/tactics/tacticals.mli b/tactics/tacticals.mli index 92d3d2598..f0ebac780 100644 --- a/tactics/tacticals.mli +++ b/tactics/tacticals.mli @@ -212,6 +212,7 @@ module New : sig val tclIFTHENELSE : unit tactic -> unit tactic -> unit tactic -> unit tactic val tclIFTHENSVELSE : unit tactic -> unit tactic array -> unit tactic -> unit tactic val tclIFTHENTRYELSEMUST : unit tactic -> unit tactic -> unit tactic + val tclIFTHENFIRSTTRYELSEMUST : unit tactic -> unit tactic -> unit tactic val tclDO : int -> unit tactic -> unit tactic val tclREPEAT : unit tactic -> unit tactic diff --git a/tactics/tactics.ml b/tactics/tactics.ml index a4da784a1..20519dd98 100644 --- a/tactics/tactics.ml +++ b/tactics/tactics.ml @@ -646,7 +646,8 @@ let cofix ido = match ido with (* Reduction and conversion tactics *) (**************************************************************) -type tactic_reduction = env -> evar_map -> constr -> constr +type tactic_reduction = Reductionops.reduction_function +type e_tactic_reduction = Reductionops.e_reduction_function let pf_reduce_decl redfun where decl gl = let open Context.Named.Declaration in @@ -1993,7 +1994,6 @@ let exact_proof c = Proofview.Goal.enter begin fun gl -> Refine.refine ~typecheck:false begin fun sigma -> let (c, ctx) = Constrintern.interp_casted_constr (pf_env gl) sigma c (pf_concl gl) in - let c = EConstr.of_constr c in let sigma = Evd.merge_universe_context sigma ctx in (sigma, c) end @@ -4664,30 +4664,6 @@ let destruct ev clr c l e = induction_gen clr false ev e ((Evd.empty,(c,NoBindings)),(None,l)) None -(* The registered tactic, which calls the default elimination - * if no elimination constant is provided. *) - -(* Induction tactics *) - -(* This was Induction before 6.3 (induction only in quantified premisses) *) -let simple_induct_id s = Tacticals.New.tclTHEN (intros_until_id s) (Tacticals.New.onLastHyp simplest_elim) -let simple_induct_nodep n = Tacticals.New.tclTHEN (intros_until_n n) (Tacticals.New.onLastHyp simplest_elim) - -let simple_induct = function - | NamedHyp id -> simple_induct_id id - | AnonHyp n -> simple_induct_nodep n - -(* Destruction tactics *) - -let simple_destruct_id s = - (Tacticals.New.tclTHEN (intros_until_id s) (Tacticals.New.onLastHyp simplest_case)) -let simple_destruct_nodep n = - (Tacticals.New.tclTHEN (intros_until_n n) (Tacticals.New.onLastHyp simplest_case)) - -let simple_destruct = function - | NamedHyp id -> simple_destruct_id id - | AnonHyp n -> simple_destruct_nodep n - (* * Eliminations giving the type instead of the proof. * These tactics use the default elimination constant and @@ -5148,16 +5124,10 @@ module New = struct open Locus let reduce_after_refine = - let onhyps = - (** We reduced everywhere in the hyps before 8.6 *) - if Flags.version_compare !Flags.compat_version Flags.V8_5 == 0 - then None - else Some [] - in reduce (Lazy {rBeta=true;rMatch=true;rFix=true;rCofix=true; rZeta=false;rDelta=false;rConst=[]}) - {onhyps; concl_occs=AllOccurrences } + {onhyps = Some []; concl_occs = AllOccurrences } let refine ~typecheck c = Refine.refine ~typecheck c <*> diff --git a/tactics/tactics.mli b/tactics/tactics.mli index fda7af223..1c3b75e91 100644 --- a/tactics/tactics.mli +++ b/tactics/tactics.mli @@ -132,7 +132,8 @@ val exact_proof : Constrexpr.constr_expr -> unit Proofview.tactic (** {6 Reduction tactics. } *) -type tactic_reduction = env -> evar_map -> constr -> constr +type tactic_reduction = Reductionops.reduction_function +type e_tactic_reduction = Reductionops.e_reduction_function type change_arg = patvar_map -> evar_map -> evar_map * constr @@ -140,6 +141,7 @@ val make_change_arg : constr -> change_arg val reduct_in_hyp : ?check:bool -> tactic_reduction -> hyp_location -> unit Proofview.tactic val reduct_option : ?check:bool -> tactic_reduction * cast_kind -> goal_location -> unit Proofview.tactic val reduct_in_concl : tactic_reduction * cast_kind -> unit Proofview.tactic +val e_reduct_in_concl : check:bool -> e_tactic_reduction * cast_kind -> unit Proofview.tactic val change_in_concl : (occurrences * constr_pattern) option -> change_arg -> unit Proofview.tactic val change_concl : constr -> unit Proofview.tactic val change_in_hyp : (occurrences * constr_pattern) option -> change_arg -> @@ -282,8 +284,6 @@ val simplest_elim : constr -> unit Proofview.tactic val elim : evars_flag -> clear_flag -> constr with_bindings -> constr with_bindings option -> unit Proofview.tactic -val simple_induct : quantified_hypothesis -> unit Proofview.tactic - val induction : evars_flag -> clear_flag -> constr -> or_and_intro_pattern option -> constr with_bindings option -> unit Proofview.tactic @@ -292,7 +292,6 @@ val induction : evars_flag -> clear_flag -> constr -> or_and_intro_pattern optio val general_case_analysis : evars_flag -> clear_flag -> constr with_bindings -> unit Proofview.tactic val simplest_case : constr -> unit Proofview.tactic -val simple_destruct : quantified_hypothesis -> unit Proofview.tactic val destruct : evars_flag -> clear_flag -> constr -> or_and_intro_pattern option -> constr with_bindings option -> unit Proofview.tactic diff --git a/test-suite/bugs/closed/2850.v b/test-suite/bugs/closed/2850.v deleted file mode 100644 index 64a93aeb0..000000000 --- a/test-suite/bugs/closed/2850.v +++ /dev/null @@ -1,2 +0,0 @@ -Definition id {A} (x : A) := x. -Fail Compute id. diff --git a/test-suite/bugs/closed/4785.v b/test-suite/bugs/closed/4785.v index c3c97d3f5..0d347b262 100644 --- a/test-suite/bugs/closed/4785.v +++ b/test-suite/bugs/closed/4785.v @@ -1,5 +1,4 @@ Require Coq.Lists.List Coq.Vectors.Vector. -Require Coq.Compat.Coq85. Module A. Import Coq.Lists.List Coq.Vectors.Vector. @@ -21,12 +20,10 @@ Delimit Scope mylist_scope with mylist. Bind Scope mylist_scope with mylist. Arguments mynil {_}, _. Arguments mycons {_} _ _. -Notation " [] " := mynil (compat "8.5") : mylist_scope. Notation " [ ] " := mynil (format "[ ]") : mylist_scope. Notation " [ x ] " := (mycons x nil) : mylist_scope. Notation " [ x ; y ; .. ; z ] " := (mycons x (mycons y .. (mycons z nil) ..)) : mylist_scope. -Import Coq.Compat.Coq85. Locate Module VectorNotations. Import VectorDef.VectorNotations. @@ -35,11 +32,3 @@ Check []%mylist : mylist _. Check [ ]%mylist : mylist _. Check [ ]%list : list _. End A. - -Module B. -Import Coq.Compat.Coq85. - -Goal True. - idtac; []. (* Check that importing the compat file doesn't break the [ | .. | ] syntax of Ltac *) -Abort. -End B. diff --git a/test-suite/bugs/closed/4785_compat_85.v b/test-suite/bugs/closed/4785_compat_85.v deleted file mode 100644 index bbb34f465..000000000 --- a/test-suite/bugs/closed/4785_compat_85.v +++ /dev/null @@ -1,46 +0,0 @@ -(* -*- coq-prog-args: ("-compat" "8.5") -*- *) -Require Coq.Lists.List Coq.Vectors.Vector. -Require Coq.Compat.Coq85. - -Module A. -Import Coq.Lists.List Coq.Vectors.Vector. -Import ListNotations. -Check [ ]%list : list _. -Import VectorNotations ListNotations. -Delimit Scope vector_scope with vector. -Check [ ]%vector : Vector.t _ _. -Check []%vector : Vector.t _ _. -Check [ ]%list : list _. -Fail Check []%list : list _. - -Goal True. - idtac; [ ]. (* Note that vector notations break the [ | .. | ] syntax of Ltac *) -Abort. - -Inductive mylist A := mynil | mycons (x : A) (xs : mylist A). -Delimit Scope mylist_scope with mylist. -Bind Scope mylist_scope with mylist. -Arguments mynil {_}, _. -Arguments mycons {_} _ _. -Notation " [] " := mynil (compat "8.5") : mylist_scope. -Notation " [ ] " := mynil (format "[ ]") : mylist_scope. -Notation " [ x ] " := (mycons x nil) : mylist_scope. -Notation " [ x ; y ; .. ; z ] " := (mycons x (mycons y .. (mycons z nil) ..)) : mylist_scope. - -Import Coq.Compat.Coq85. -Locate Module VectorNotations. -Import VectorDef.VectorNotations. - -Check []%vector : Vector.t _ _. -Check []%mylist : mylist _. -Check [ ]%mylist : mylist _. -Check [ ]%list : list _. -End A. - -Module B. -Import Coq.Compat.Coq85. - -Goal True. - idtac; []. (* Check that importing the compat file doesn't break the [ | .. | ] syntax of Ltac *) -Abort. -End B. diff --git a/test-suite/bugs/closed/4798.v b/test-suite/bugs/closed/4798.v index dbc3d46fc..6f2bcb968 100644 --- a/test-suite/bugs/closed/4798.v +++ b/test-suite/bugs/closed/4798.v @@ -1,3 +1,3 @@ Check match 2 with 0 => 0 | S n => n end. -Notation "|" := 1 (compat "8.4"). +Notation "|" := 1 (compat "8.6"). Check match 2 with 0 => 0 | S n => n end. (* fails *) diff --git a/test-suite/bugs/closed/4873.v b/test-suite/bugs/closed/4873.v index 3be36d847..39299883a 100644 --- a/test-suite/bugs/closed/4873.v +++ b/test-suite/bugs/closed/4873.v @@ -1,6 +1,5 @@ Require Import Coq.Classes.Morphisms. Require Import Relation_Definitions. -Require Import Coq.Compat.Coq85. Fixpoint tuple' T n : Type := match n with diff --git a/test-suite/bugs/closed/6878.v b/test-suite/bugs/closed/6878.v new file mode 100644 index 000000000..70f1b3127 --- /dev/null +++ b/test-suite/bugs/closed/6878.v @@ -0,0 +1,8 @@ + +Set Universe Polymorphism. +Module Type T. + Axiom foo : Prop. +End T. + +(** Used to anomaly *) +Fail Module M : T with Definition foo := Type. diff --git a/test-suite/coq-makefile/timing/run.sh b/test-suite/coq-makefile/timing/run.sh index 2439d3f37..aa6b0a9a4 100755 --- a/test-suite/coq-makefile/timing/run.sh +++ b/test-suite/coq-makefile/timing/run.sh @@ -38,9 +38,29 @@ make print-pretty-timed-diff TIMING_SORT_BY=diff || exit $? INFINITY="ā" INFINITY_REPLACEMENT="+.%" # assume that if the before time is zero, we expected the time to increase +TO_SED_IN_BOTH=( + -e s"/${INFINITY}/${INFINITY_REPLACEMENT}/g" # Whether or not something shows up as ā depends on whether a time registers as 0.s or as 0.001s, so we can't rely on this being consistent + -e s":|\s*N/A\s*$:| ${INFINITY_REPLACEMENT}:g" # Whether or not something shows up as N/A depends on whether a time registers as 0.s or as 0.001s, so we can't rely on this being consistent + -e s'/ *$//g' # the number of trailing spaces depends on how many digits percentages end up being; since this varies across runs, we remove trailing spaces + -e s'/[0-9]*\.[0-9]*//g' # the precise timing numbers vary, so we strip them out + -e s'/^-*$/------/g' # When none of the numbers get over 100 (or 1000, in per-file), the width of the table is different, so we normalize the number of dashes for table separators +) + +TO_SED_IN_PER_FILE=( + -e s'/[0-9]//g' # unclear whether this is actually needed above and beyond s'/[0-9]*\.[0-9]*//g'; it's been here from the start + -e s'/ */ /g' # unclear whether this is actually needed for per-file timing; it's been here from the start + -e s'/\(Total.*\)-\(.*\)-/\1+\2+/g' # Overall time in the per-file timing diff should be around 0; if it comes out negative, we remove the sign +) + +TO_SED_IN_PER_LINE=( + -e s'/0//g' # unclear whether this is actually needed above and beyond s'/[0-9]*\.[0-9]*//g'; it's been here from the start + -e s'/ */ /g' # Sometimes 0 will show up as 0m00.s, sometimes it'll end up being more like 0m00.001s; we must strip out the spaces that result from left-aligning numbers of different widths based on how many digits Coq's [-time] gives + -e s'/+/-/g' # some code lines don't really change, but this can show up as either -0m00.01s or +0m00.01s, so we need to normalize the signs + ) + for ext in "" .desired; do for file in time-of-build-before.log time-of-build-after.log time-of-build-both.log; do - cat ${file}${ext} | grep -v 'warning: undefined variable' | sed s"/${INFINITY}/${INFINITY_REPLACEMENT}/g" | sed s'/[0-9]//g' | sed s'/ *$//g' | sed s":|\s*N/A\s*$:| ${INFINITY_REPLACEMENT}:g" | sed s'/^-*$/------/g' | sed s'/ */ /g' | sed s'/\(Total.*\)-\(.*\)-/\1+\2+/g' > ${file}${ext}.processed + cat ${file}${ext} | grep -v 'warning: undefined variable' | sed "${TO_SED_IN_BOTH[@]}" "${TO_SED_IN_PER_FILE[@]}" > ${file}${ext}.processed done done for file in time-of-build-before.log time-of-build-after.log time-of-build-both.log; do @@ -74,7 +94,7 @@ echo for ext in "" .desired; do for file in A.v.timing.diff; do - cat ${file}${ext} | sed s"/${INFINITY}/${INFINITY_REPLACEMENT}/g" | sed s":|\s*N/A\s*$:| ${INFINITY_REPLACEMENT}:g" | sed s'/[0-9]*\.[0-9]*//g' | sed s'/0//g' | sed s'/ */ /g' | sed s'/ *$//g' | sed s'/+/-/g' | sort > ${file}${ext}.processed + cat ${file}${ext} | sed "${TO_SED_IN_BOTH[@]}" "${TO_SED_IN_PER_LINE[@]}" | sort > ${file}${ext}.processed done done for file in A.v.timing.diff; do diff --git a/test-suite/output/Load.out b/test-suite/output/Load.out new file mode 100644 index 000000000..0904d5540 --- /dev/null +++ b/test-suite/output/Load.out @@ -0,0 +1,6 @@ +f = 2 + : nat +u = I + : True +The command has indeed failed with message: +Files processed by Load cannot leave open proofs. diff --git a/test-suite/output/Load.v b/test-suite/output/Load.v new file mode 100644 index 000000000..967507415 --- /dev/null +++ b/test-suite/output/Load.v @@ -0,0 +1,7 @@ +Load "output/load/Load_noproof.v". +Print f. + +Load "output/load/Load_proof.v". +Print u. + +Fail Load "output/load/Load_openproof.v". diff --git a/test-suite/output/PrintInfos.v b/test-suite/output/PrintInfos.v index 08918981a..a498db3e8 100644 --- a/test-suite/output/PrintInfos.v +++ b/test-suite/output/PrintInfos.v @@ -26,6 +26,7 @@ About bar. Print bar. About Peano. (* Module *) +Set Warnings "-deprecated". About existS2. (* Notation *) Arguments eq_refl {A} {x}, {A} x. diff --git a/test-suite/output/bug6821.out b/test-suite/output/bug6821.out new file mode 100644 index 000000000..7b12b5320 --- /dev/null +++ b/test-suite/output/bug6821.out @@ -0,0 +1,2 @@ +forall f : nat -> Type, f x where x : nat := 1 + : Type diff --git a/test-suite/output/bug6821.v b/test-suite/output/bug6821.v new file mode 100644 index 000000000..40627e331 --- /dev/null +++ b/test-suite/output/bug6821.v @@ -0,0 +1,8 @@ +(* Was failing at printing time with stack overflow due to an infinite + eta-expansion *) + +Notation "x 'where' y .. z := v " := + ((fun y => .. ((fun z => x) v) ..) v) + (at level 11, v at next level, y binder, z binder). + +Check forall f, f x where x := 1. diff --git a/test-suite/output/load/Load_noproof.v b/test-suite/output/load/Load_noproof.v new file mode 100644 index 000000000..aaf1ffe26 --- /dev/null +++ b/test-suite/output/load/Load_noproof.v @@ -0,0 +1 @@ +Definition f := 2. diff --git a/test-suite/output/load/Load_openproof.v b/test-suite/output/load/Load_openproof.v new file mode 100644 index 000000000..204d4ecbf --- /dev/null +++ b/test-suite/output/load/Load_openproof.v @@ -0,0 +1 @@ +Lemma k : True. diff --git a/test-suite/output/load/Load_proof.v b/test-suite/output/load/Load_proof.v new file mode 100644 index 000000000..e47f66a19 --- /dev/null +++ b/test-suite/output/load/Load_proof.v @@ -0,0 +1,2 @@ +Lemma u : True. +Proof. exact I. Qed. diff --git a/test-suite/success/rewrite.v b/test-suite/success/rewrite.v index 62249666b..448d0082d 100644 --- a/test-suite/success/rewrite.v +++ b/test-suite/success/rewrite.v @@ -151,10 +151,25 @@ Abort. (* Check that rewriting within evars still work (was broken in 8.5beta1) *) - Goal forall (a: unit) (H: a = tt), exists x y:nat, x = y. intros; eexists; eexists. rewrite H. Undo. subst. Abort. + +(* Check that iterated rewriting does not rewrite in the side conditions *) +(* Example from Sigurd Schneider, extracted from contrib containers *) + +Lemma EQ + : forall (e e' : nat), True -> e = e'. +Admitted. + +Lemma test (v1 v2 v3: nat) (v' : v1 = v2) : v2 = v1. +Proof. + rewrite <- (EQ v1 v2) in *. + exact v'. + (* There should be only two side conditions *) + exact I. + exact I. +Qed. diff --git a/test-suite/success/vm_evars.v b/test-suite/success/vm_evars.v new file mode 100644 index 000000000..2c8b099ef --- /dev/null +++ b/test-suite/success/vm_evars.v @@ -0,0 +1,23 @@ +Fixpoint iter {A} (n : nat) (f : A -> A) (x : A) := +match n with +| 0 => x +| S n => iter n f (f x) +end. + +Goal nat -> True. +Proof. +intros n. +evar (f : nat -> nat). +cut (iter 10 f 0 = 0). +vm_compute. +intros; constructor. +instantiate (f := (fun x => x)). +reflexivity. +Qed. + +Goal exists x, x = 5 + 5. +Proof. + eexists. + vm_compute. + reflexivity. +Qed. diff --git a/theories/Arith/Compare_dec.v b/theories/Arith/Compare_dec.v index 7ebeed5f0..713aef858 100644 --- a/theories/Arith/Compare_dec.v +++ b/theories/Arith/Compare_dec.v @@ -135,11 +135,11 @@ Qed. See now [Nat.compare] and its properties. In scope [nat_scope], the notation for [Nat.compare] is "?=" *) -Notation nat_compare := Nat.compare (compat "8.4"). +Notation nat_compare := Nat.compare (compat "8.6"). -Notation nat_compare_spec := Nat.compare_spec (compat "8.4"). -Notation nat_compare_eq_iff := Nat.compare_eq_iff (compat "8.4"). -Notation nat_compare_S := Nat.compare_succ (compat "8.4"). +Notation nat_compare_spec := Nat.compare_spec (compat "8.6"). +Notation nat_compare_eq_iff := Nat.compare_eq_iff (compat "8.6"). +Notation nat_compare_S := Nat.compare_succ (only parsing). Lemma nat_compare_lt n m : n<m <-> (n ?= m) = Lt. Proof. @@ -200,9 +200,9 @@ Qed. See now [Nat.leb] and its properties. In scope [nat_scope], the notation for [Nat.leb] is "<=?" *) -Notation leb := Nat.leb (compat "8.4"). +Notation leb := Nat.leb (only parsing). -Notation leb_iff := Nat.leb_le (compat "8.4"). +Notation leb_iff := Nat.leb_le (only parsing). Lemma leb_iff_conv m n : (n <=? m) = false <-> m < n. Proof. diff --git a/theories/Arith/Div2.v b/theories/Arith/Div2.v index 1f0c6c34b..42956c475 100644 --- a/theories/Arith/Div2.v +++ b/theories/Arith/Div2.v @@ -20,7 +20,7 @@ Implicit Type n : nat. (** Here we define [n/2] and prove some of its properties *) -Notation div2 := Nat.div2 (compat "8.4"). +Notation div2 := Nat.div2 (only parsing). (** Since [div2] is recursively defined on [0], [1] and [(S (S n))], it is useful to prove the corresponding induction principle *) @@ -86,7 +86,7 @@ Qed. (** Properties related to the double ([2n]) *) -Notation double := Nat.double (compat "8.4"). +Notation double := Nat.double (only parsing). Hint Unfold double Nat.double: arith. diff --git a/theories/Arith/EqNat.v b/theories/Arith/EqNat.v index b31dcd445..4b51dfc00 100644 --- a/theories/Arith/EqNat.v +++ b/theories/Arith/EqNat.v @@ -71,10 +71,10 @@ Defined. We reuse the one already defined in module [Nat]. In scope [nat_scope], the notation "=?" can be used. *) -Notation beq_nat := Nat.eqb (compat "8.4"). +Notation beq_nat := Nat.eqb (only parsing). -Notation beq_nat_true_iff := Nat.eqb_eq (compat "8.4"). -Notation beq_nat_false_iff := Nat.eqb_neq (compat "8.4"). +Notation beq_nat_true_iff := Nat.eqb_eq (only parsing). +Notation beq_nat_false_iff := Nat.eqb_neq (only parsing). Lemma beq_nat_refl n : true = (n =? n). Proof. diff --git a/theories/Arith/Le.v b/theories/Arith/Le.v index af64a29af..69626cc10 100644 --- a/theories/Arith/Le.v +++ b/theories/Arith/Le.v @@ -28,17 +28,17 @@ Local Open Scope nat_scope. (** * [le] is an order on [nat] *) -Notation le_refl := Nat.le_refl (compat "8.4"). -Notation le_trans := Nat.le_trans (compat "8.4"). -Notation le_antisym := Nat.le_antisymm (compat "8.4"). +Notation le_refl := Nat.le_refl (only parsing). +Notation le_trans := Nat.le_trans (only parsing). +Notation le_antisym := Nat.le_antisymm (only parsing). Hint Resolve le_trans: arith. Hint Immediate le_antisym: arith. (** * Properties of [le] w.r.t 0 *) -Notation le_0_n := Nat.le_0_l (compat "8.4"). (* 0 <= n *) -Notation le_Sn_0 := Nat.nle_succ_0 (compat "8.4"). (* ~ S n <= 0 *) +Notation le_0_n := Nat.le_0_l (only parsing). (* 0 <= n *) +Notation le_Sn_0 := Nat.nle_succ_0 (only parsing). (* ~ S n <= 0 *) Lemma le_n_0_eq n : n <= 0 -> 0 = n. Proof. @@ -55,8 +55,8 @@ Proof Peano.le_n_S. Theorem le_S_n : forall n m, S n <= S m -> n <= m. Proof Peano.le_S_n. -Notation le_n_Sn := Nat.le_succ_diag_r (compat "8.4"). (* n <= S n *) -Notation le_Sn_n := Nat.nle_succ_diag_l (compat "8.4"). (* ~ S n <= n *) +Notation le_n_Sn := Nat.le_succ_diag_r (only parsing). (* n <= S n *) +Notation le_Sn_n := Nat.nle_succ_diag_l (only parsing). (* ~ S n <= n *) Theorem le_Sn_le : forall n m, S n <= m -> n <= m. Proof Nat.lt_le_incl. @@ -67,8 +67,8 @@ Hint Immediate le_n_0_eq le_Sn_le le_S_n : arith. (** * Properties of [le] w.r.t predecessor *) -Notation le_pred_n := Nat.le_pred_l (compat "8.4"). (* pred n <= n *) -Notation le_pred := Nat.pred_le_mono (compat "8.4"). (* n<=m -> pred n <= pred m *) +Notation le_pred_n := Nat.le_pred_l (only parsing). (* pred n <= n *) +Notation le_pred := Nat.pred_le_mono (only parsing). (* n<=m -> pred n <= pred m *) Hint Resolve le_pred_n: arith. diff --git a/theories/Arith/Lt.v b/theories/Arith/Lt.v index 07a93a9b6..0c7515c6f 100644 --- a/theories/Arith/Lt.v +++ b/theories/Arith/Lt.v @@ -25,7 +25,7 @@ Local Open Scope nat_scope. (** * Irreflexivity *) -Notation lt_irrefl := Nat.lt_irrefl (compat "8.4"). (* ~ x < x *) +Notation lt_irrefl := Nat.lt_irrefl (only parsing). (* ~ x < x *) Hint Resolve lt_irrefl: arith. @@ -64,12 +64,12 @@ Hint Immediate le_not_lt lt_not_le: arith. (** * Asymmetry *) -Notation lt_asym := Nat.lt_asymm (compat "8.4"). (* n<m -> ~m<n *) +Notation lt_asym := Nat.lt_asymm (only parsing). (* n<m -> ~m<n *) (** * Order and 0 *) -Notation lt_0_Sn := Nat.lt_0_succ (compat "8.4"). (* 0 < S n *) -Notation lt_n_0 := Nat.nlt_0_r (compat "8.4"). (* ~ n < 0 *) +Notation lt_0_Sn := Nat.lt_0_succ (only parsing). (* 0 < S n *) +Notation lt_n_0 := Nat.nlt_0_r (only parsing). (* ~ n < 0 *) Theorem neq_0_lt n : 0 <> n -> 0 < n. Proof. @@ -86,8 +86,8 @@ Hint Immediate neq_0_lt lt_0_neq: arith. (** * Order and successor *) -Notation lt_n_Sn := Nat.lt_succ_diag_r (compat "8.4"). (* n < S n *) -Notation lt_S := Nat.lt_lt_succ_r (compat "8.4"). (* n < m -> n < S m *) +Notation lt_n_Sn := Nat.lt_succ_diag_r (only parsing). (* n < S n *) +Notation lt_S := Nat.lt_lt_succ_r (only parsing). (* n < m -> n < S m *) Theorem lt_n_S n m : n < m -> S n < S m. Proof. @@ -129,28 +129,28 @@ Hint Resolve lt_pred_n_n: arith. (** * Transitivity properties *) -Notation lt_trans := Nat.lt_trans (compat "8.4"). -Notation lt_le_trans := Nat.lt_le_trans (compat "8.4"). -Notation le_lt_trans := Nat.le_lt_trans (compat "8.4"). +Notation lt_trans := Nat.lt_trans (only parsing). +Notation lt_le_trans := Nat.lt_le_trans (only parsing). +Notation le_lt_trans := Nat.le_lt_trans (only parsing). Hint Resolve lt_trans lt_le_trans le_lt_trans: arith. (** * Large = strict or equal *) -Notation le_lt_or_eq_iff := Nat.lt_eq_cases (compat "8.4"). +Notation le_lt_or_eq_iff := Nat.lt_eq_cases (only parsing). Theorem le_lt_or_eq n m : n <= m -> n < m \/ n = m. Proof. apply Nat.lt_eq_cases. Qed. -Notation lt_le_weak := Nat.lt_le_incl (compat "8.4"). +Notation lt_le_weak := Nat.lt_le_incl (only parsing). Hint Immediate lt_le_weak: arith. (** * Dichotomy *) -Notation le_or_lt := Nat.le_gt_cases (compat "8.4"). (* n <= m \/ m < n *) +Notation le_or_lt := Nat.le_gt_cases (only parsing). (* n <= m \/ m < n *) Theorem nat_total_order n m : n <> m -> n < m \/ m < n. Proof. diff --git a/theories/Arith/Minus.v b/theories/Arith/Minus.v index be0341cc3..3bf6cd952 100644 --- a/theories/Arith/Minus.v +++ b/theories/Arith/Minus.v @@ -48,7 +48,7 @@ Qed. (** * Diagonal *) -Notation minus_diag := Nat.sub_diag (compat "8.4"). (* n - n = 0 *) +Notation minus_diag := Nat.sub_diag (only parsing). (* n - n = 0 *) Lemma minus_diag_reverse n : 0 = n - n. Proof. @@ -89,13 +89,13 @@ Qed. (** * Relation with order *) Notation minus_le_compat_r := - Nat.sub_le_mono_r (compat "8.4"). (* n <= m -> n - p <= m - p. *) + Nat.sub_le_mono_r (only parsing). (* n <= m -> n - p <= m - p. *) Notation minus_le_compat_l := - Nat.sub_le_mono_l (compat "8.4"). (* n <= m -> p - m <= p - n. *) + Nat.sub_le_mono_l (only parsing). (* n <= m -> p - m <= p - n. *) -Notation le_minus := Nat.le_sub_l (compat "8.4"). (* n - m <= n *) -Notation lt_minus := Nat.sub_lt (compat "8.4"). (* m <= n -> 0 < m -> n-m < n *) +Notation le_minus := Nat.le_sub_l (only parsing). (* n - m <= n *) +Notation lt_minus := Nat.sub_lt (only parsing). (* m <= n -> 0 < m -> n-m < n *) Lemma lt_O_minus_lt n m : 0 < n - m -> m < n. Proof. diff --git a/theories/Arith/Mult.v b/theories/Arith/Mult.v index 1f680b6f8..4f4aa1837 100644 --- a/theories/Arith/Mult.v +++ b/theories/Arith/Mult.v @@ -25,35 +25,35 @@ Local Open Scope nat_scope. (** ** Zero property *) -Notation mult_0_l := Nat.mul_0_l (compat "8.4"). (* 0 * n = 0 *) -Notation mult_0_r := Nat.mul_0_r (compat "8.4"). (* n * 0 = 0 *) +Notation mult_0_l := Nat.mul_0_l (only parsing). (* 0 * n = 0 *) +Notation mult_0_r := Nat.mul_0_r (only parsing). (* n * 0 = 0 *) (** ** 1 is neutral *) -Notation mult_1_l := Nat.mul_1_l (compat "8.4"). (* 1 * n = n *) -Notation mult_1_r := Nat.mul_1_r (compat "8.4"). (* n * 1 = n *) +Notation mult_1_l := Nat.mul_1_l (only parsing). (* 1 * n = n *) +Notation mult_1_r := Nat.mul_1_r (only parsing). (* n * 1 = n *) Hint Resolve mult_1_l mult_1_r: arith. (** ** Commutativity *) -Notation mult_comm := Nat.mul_comm (compat "8.4"). (* n * m = m * n *) +Notation mult_comm := Nat.mul_comm (only parsing). (* n * m = m * n *) Hint Resolve mult_comm: arith. (** ** Distributivity *) Notation mult_plus_distr_r := - Nat.mul_add_distr_r (compat "8.4"). (* (n+m)*p = n*p + m*p *) + Nat.mul_add_distr_r (only parsing). (* (n+m)*p = n*p + m*p *) Notation mult_plus_distr_l := - Nat.mul_add_distr_l (compat "8.4"). (* n*(m+p) = n*m + n*p *) + Nat.mul_add_distr_l (only parsing). (* n*(m+p) = n*m + n*p *) Notation mult_minus_distr_r := - Nat.mul_sub_distr_r (compat "8.4"). (* (n-m)*p = n*p - m*p *) + Nat.mul_sub_distr_r (only parsing). (* (n-m)*p = n*p - m*p *) Notation mult_minus_distr_l := - Nat.mul_sub_distr_l (compat "8.4"). (* n*(m-p) = n*m - n*p *) + Nat.mul_sub_distr_l (only parsing). (* n*(m-p) = n*m - n*p *) Hint Resolve mult_plus_distr_r: arith. Hint Resolve mult_minus_distr_r: arith. @@ -61,7 +61,7 @@ Hint Resolve mult_minus_distr_l: arith. (** ** Associativity *) -Notation mult_assoc := Nat.mul_assoc (compat "8.4"). (* n*(m*p)=n*m*p *) +Notation mult_assoc := Nat.mul_assoc (only parsing). (* n*(m*p)=n*m*p *) Lemma mult_assoc_reverse n m p : n * m * p = n * (m * p). Proof. @@ -85,8 +85,8 @@ Qed. (** ** Multiplication and successor *) -Notation mult_succ_l := Nat.mul_succ_l (compat "8.4"). (* S n * m = n * m + m *) -Notation mult_succ_r := Nat.mul_succ_r (compat "8.4"). (* n * S m = n * m + n *) +Notation mult_succ_l := Nat.mul_succ_l (only parsing). (* S n * m = n * m + m *) +Notation mult_succ_r := Nat.mul_succ_r (only parsing). (* n * S m = n * m + n *) (** * Compatibility with orders *) diff --git a/theories/Arith/Peano_dec.v b/theories/Arith/Peano_dec.v index 38fe191c5..9a24c804a 100644 --- a/theories/Arith/Peano_dec.v +++ b/theories/Arith/Peano_dec.v @@ -21,7 +21,7 @@ Proof. - left; exists n; auto. Defined. -Notation eq_nat_dec := Nat.eq_dec (compat "8.4"). +Notation eq_nat_dec := Nat.eq_dec (only parsing). Hint Resolve O_or_S eq_nat_dec: arith. diff --git a/theories/Arith/Plus.v b/theories/Arith/Plus.v index a437e1dd2..b8297c2d8 100644 --- a/theories/Arith/Plus.v +++ b/theories/Arith/Plus.v @@ -29,12 +29,12 @@ Local Open Scope nat_scope. (** * Neutrality of 0, commutativity, associativity *) -Notation plus_0_l := Nat.add_0_l (compat "8.4"). -Notation plus_0_r := Nat.add_0_r (compat "8.4"). -Notation plus_comm := Nat.add_comm (compat "8.4"). -Notation plus_assoc := Nat.add_assoc (compat "8.4"). +Notation plus_0_l := Nat.add_0_l (only parsing). +Notation plus_0_r := Nat.add_0_r (only parsing). +Notation plus_comm := Nat.add_comm (only parsing). +Notation plus_assoc := Nat.add_assoc (only parsing). -Notation plus_permute := Nat.add_shuffle3 (compat "8.4"). +Notation plus_permute := Nat.add_shuffle3 (only parsing). Definition plus_Snm_nSm : forall n m, S n + m = n + S m := Peano.plus_n_Sm. @@ -140,7 +140,7 @@ Defined. (** * Derived properties *) -Notation plus_permute_2_in_4 := Nat.add_shuffle1 (compat "8.4"). +Notation plus_permute_2_in_4 := Nat.add_shuffle1 (only parsing). (** * Tail-recursive plus *) diff --git a/theories/Compat/Coq85.v b/theories/Compat/Coq85.v deleted file mode 100644 index e9f8b1eb3..000000000 --- a/theories/Compat/Coq85.v +++ /dev/null @@ -1,38 +0,0 @@ -(************************************************************************) -(* * The Coq Proof Assistant / The Coq Development Team *) -(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *) -(* <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.5 *) - -(** Any compatibility changes to make future versions of Coq behave like Coq 8.6 - are likely needed to make them behave like Coq 8.5. *) -Require Export Coq.Compat.Coq86. - -(** We use some deprecated options in this file, so we disable the - corresponding warning, to silence the build of this file. *) -Local Set Warnings "-deprecated-option". - -(* In 8.5, "intros [|]", taken e.g. on a goal "A\/B->C", does not - behave as "intros [H|H]" but leave instead hypotheses quantified in - the goal, here producing subgoals A->C and B->C. *) - -Global Unset Bracketing Last Introduction Pattern. -Global Unset Regular Subst Tactic. -Global Unset Structural Injection. -Global Unset Shrink Abstract. -Global Unset Shrink Obligations. -Global Set Refolding Reduction. - -(** The resolution algorithm for type classes has changed. *) -Global Set Typeclasses Legacy Resolution. -Global Set Typeclasses Limit Intros. -Global Unset Typeclasses Filtered Unification. - -(** Allow silently letting unification constraints float after a "." *) -Global Unset Solve Unification Constraints. diff --git a/theories/FSets/FMapFacts.v b/theories/FSets/FMapFacts.v index 0bade2ede..997059669 100644 --- a/theories/FSets/FMapFacts.v +++ b/theories/FSets/FMapFacts.v @@ -26,7 +26,7 @@ Hint Extern 1 (Equivalence _) => constructor; congruence. Module WFacts_fun (E:DecidableType)(Import M:WSfun E). -Notation option_map := option_map (compat "8.4"). +Notation option_map := option_map (compat "8.6"). Notation eq_dec := E.eq_dec. Definition eqb x y := if eq_dec x y then true else false. @@ -442,7 +442,7 @@ destruct (eq_dec x y); auto. Qed. Lemma map_o : forall m x (f:elt->elt'), - find x (map f m) = option_map f (find x m). + find x (map f m) = Datatypes.option_map f (find x m). Proof. intros. generalize (find_mapsto_iff (map f m) x) (find_mapsto_iff m x) @@ -475,7 +475,7 @@ Qed. Lemma mapi_o : forall m x (f:key->elt->elt'), (forall x y e, E.eq x y -> f x e = f y e) -> - find x (mapi f m) = option_map (f x) (find x m). + find x (mapi f m) = Datatypes.option_map (f x) (find x m). Proof. intros. generalize (find_mapsto_iff (mapi f m) x) (find_mapsto_iff m x) diff --git a/theories/Init/Datatypes.v b/theories/Init/Datatypes.v index faa4331e8..05b741f0a 100644 --- a/theories/Init/Datatypes.v +++ b/theories/Init/Datatypes.v @@ -361,14 +361,14 @@ Definition idProp : IDProp := fun A x => x. (* Compatibility *) -Notation prodT := prod (compat "8.2"). -Notation pairT := pair (compat "8.2"). -Notation prodT_rect := prod_rect (compat "8.2"). -Notation prodT_rec := prod_rec (compat "8.2"). -Notation prodT_ind := prod_ind (compat "8.2"). -Notation fstT := fst (compat "8.2"). -Notation sndT := snd (compat "8.2"). -Notation prodT_uncurry := prod_uncurry (compat "8.2"). -Notation prodT_curry := prod_curry (compat "8.2"). +Notation prodT := prod (only parsing). +Notation pairT := pair (only parsing). +Notation prodT_rect := prod_rect (only parsing). +Notation prodT_rec := prod_rec (only parsing). +Notation prodT_ind := prod_ind (only parsing). +Notation fstT := fst (only parsing). +Notation sndT := snd (only parsing). +Notation prodT_uncurry := prod_uncurry (only parsing). +Notation prodT_curry := prod_curry (only parsing). (* end hide *) diff --git a/theories/Init/Logic.v b/theories/Init/Logic.v index 0ceed0812..10ca9ecc9 100644 --- a/theories/Init/Logic.v +++ b/theories/Init/Logic.v @@ -551,14 +551,14 @@ Qed. (* Aliases *) -Notation sym_eq := eq_sym (compat "8.3"). -Notation trans_eq := eq_trans (compat "8.3"). -Notation sym_not_eq := not_eq_sym (compat "8.3"). - -Notation refl_equal := eq_refl (compat "8.3"). -Notation sym_equal := eq_sym (compat "8.3"). -Notation trans_equal := eq_trans (compat "8.3"). -Notation sym_not_equal := not_eq_sym (compat "8.3"). +Notation sym_eq := eq_sym (only parsing). +Notation trans_eq := eq_trans (only parsing). +Notation sym_not_eq := not_eq_sym (only parsing). + +Notation refl_equal := eq_refl (only parsing). +Notation sym_equal := eq_sym (only parsing). +Notation trans_equal := eq_trans (only parsing). +Notation sym_not_equal := not_eq_sym (only parsing). Hint Immediate eq_sym not_eq_sym: core. diff --git a/theories/Init/Logic_Type.v b/theories/Init/Logic_Type.v index 8b014aa30..6f10a9399 100644 --- a/theories/Init/Logic_Type.v +++ b/theories/Init/Logic_Type.v @@ -68,7 +68,7 @@ Defined. Hint Immediate identity_sym not_identity_sym: core. -Notation refl_id := identity_refl (compat "8.3"). -Notation sym_id := identity_sym (compat "8.3"). -Notation trans_id := identity_trans (compat "8.3"). -Notation sym_not_id := not_identity_sym (compat "8.3"). +Notation refl_id := identity_refl (only parsing). +Notation sym_id := identity_sym (only parsing). +Notation trans_id := identity_trans (only parsing). +Notation sym_not_id := not_identity_sym (only parsing). diff --git a/theories/Init/Peano.v b/theories/Init/Peano.v index 72cca2439..73c8c5ef4 100644 --- a/theories/Init/Peano.v +++ b/theories/Init/Peano.v @@ -39,7 +39,7 @@ Hint Resolve f_equal_nat: core. (** The predecessor function *) -Notation pred := Nat.pred (compat "8.4"). +Notation pred := Nat.pred (only parsing). Definition f_equal_pred := f_equal pred. @@ -81,7 +81,7 @@ Hint Resolve n_Sn: core. (** Addition *) -Notation plus := Nat.add (compat "8.4"). +Notation plus := Nat.add (only parsing). Infix "+" := Nat.add : nat_scope. Definition f_equal2_plus := f_equal2 plus. @@ -112,12 +112,12 @@ Qed. (** Standard associated names *) -Notation plus_0_r_reverse := plus_n_O (compat "8.2"). -Notation plus_succ_r_reverse := plus_n_Sm (compat "8.2"). +Notation plus_0_r_reverse := plus_n_O (only parsing). +Notation plus_succ_r_reverse := plus_n_Sm (only parsing). (** Multiplication *) -Notation mult := Nat.mul (compat "8.4"). +Notation mult := Nat.mul (only parsing). Infix "*" := Nat.mul : nat_scope. Definition f_equal2_mult := f_equal2 mult. @@ -139,12 +139,12 @@ Hint Resolve mult_n_Sm: core. (** Standard associated names *) -Notation mult_0_r_reverse := mult_n_O (compat "8.2"). -Notation mult_succ_r_reverse := mult_n_Sm (compat "8.2"). +Notation mult_0_r_reverse := mult_n_O (only parsing). +Notation mult_succ_r_reverse := mult_n_Sm (only parsing). (** Truncated subtraction: [m-n] is [0] if [n>=m] *) -Notation minus := Nat.sub (compat "8.4"). +Notation minus := Nat.sub (only parsing). Infix "-" := Nat.sub : nat_scope. (** Definition of the usual orders, the basic properties of [le] and [lt] @@ -221,8 +221,8 @@ Qed. (** Maximum and minimum : definitions and specifications *) -Notation max := Nat.max (compat "8.4"). -Notation min := Nat.min (compat "8.4"). +Notation max := Nat.max (only parsing). +Notation min := Nat.min (only parsing). Lemma max_l n m : m <= n -> Nat.max n m = n. Proof. diff --git a/theories/Init/Specif.v b/theories/Init/Specif.v index 673655431..137bd3a0f 100644 --- a/theories/Init/Specif.v +++ b/theories/Init/Specif.v @@ -744,16 +744,16 @@ Hint Resolve exist exist2 existT existT2: core. (* Compatibility *) -Notation sigS := sigT (compat "8.2"). -Notation existS := existT (compat "8.2"). -Notation sigS_rect := sigT_rect (compat "8.2"). -Notation sigS_rec := sigT_rec (compat "8.2"). -Notation sigS_ind := sigT_ind (compat "8.2"). -Notation projS1 := projT1 (compat "8.2"). -Notation projS2 := projT2 (compat "8.2"). - -Notation sigS2 := sigT2 (compat "8.2"). -Notation existS2 := existT2 (compat "8.2"). -Notation sigS2_rect := sigT2_rect (compat "8.2"). -Notation sigS2_rec := sigT2_rec (compat "8.2"). -Notation sigS2_ind := sigT2_ind (compat "8.2"). +Notation sigS := sigT (compat "8.6"). +Notation existS := existT (compat "8.6"). +Notation sigS_rect := sigT_rect (compat "8.6"). +Notation sigS_rec := sigT_rec (compat "8.6"). +Notation sigS_ind := sigT_ind (compat "8.6"). +Notation projS1 := projT1 (compat "8.6"). +Notation projS2 := projT2 (compat "8.6"). + +Notation sigS2 := sigT2 (compat "8.6"). +Notation existS2 := existT2 (compat "8.6"). +Notation sigS2_rect := sigT2_rect (compat "8.6"). +Notation sigS2_rec := sigT2_rec (compat "8.6"). +Notation sigS2_ind := sigT2_ind (compat "8.6"). diff --git a/theories/Lists/List.v b/theories/Lists/List.v index eba7eb943..ca5f154e9 100644 --- a/theories/Lists/List.v +++ b/theories/Lists/List.v @@ -29,7 +29,6 @@ Module ListNotations. Notation "[ ]" := nil (format "[ ]") : list_scope. Notation "[ x ]" := (cons x nil) : list_scope. Notation "[ x ; y ; .. ; z ]" := (cons x (cons y .. (cons z nil) ..)) : list_scope. -Notation "[ x ; .. ; y ]" := (cons x .. (cons y nil) ..) (compat "8.4") : list_scope. End ListNotations. Import ListNotations. diff --git a/theories/Logic/ChoiceFacts.v b/theories/Logic/ChoiceFacts.v index 8d7fa547a..9fd52866e 100644 --- a/theories/Logic/ChoiceFacts.v +++ b/theories/Logic/ChoiceFacts.v @@ -1310,11 +1310,11 @@ Qed. (**********************************************************************) (** * Compatibility notations *) Notation description_rel_choice_imp_funct_choice := - functional_rel_reification_and_rel_choice_imp_fun_choice (compat "8.6"). + functional_rel_reification_and_rel_choice_imp_fun_choice (only parsing). -Notation funct_choice_imp_rel_choice := fun_choice_imp_rel_choice (compat "8.6"). +Notation funct_choice_imp_rel_choice := fun_choice_imp_rel_choice (only parsing). Notation FunChoice_Equiv_RelChoice_and_ParamDefinDescr := - fun_choice_iff_rel_choice_and_functional_rel_reification (compat "8.6"). + fun_choice_iff_rel_choice_and_functional_rel_reification (only parsing). -Notation funct_choice_imp_description := fun_choice_imp_functional_rel_reification (compat "8.6"). +Notation funct_choice_imp_description := fun_choice_imp_functional_rel_reification (only parsing). diff --git a/theories/Logic/Diaconescu.v b/theories/Logic/Diaconescu.v index 72720b503..3317766c9 100644 --- a/theories/Logic/Diaconescu.v +++ b/theories/Logic/Diaconescu.v @@ -42,6 +42,7 @@ [[Carlstrƶm04]] Jesper Carlstrƶm, EM + Ext_ + AC_int is equivalent to AC_ext, Mathematical Logic Quaterly, vol 50(3), pp 236-240, 2004. *) +Require ClassicalFacts ChoiceFacts. (**********************************************************************) (** * Pred. Ext. + Rel. Axiom of Choice -> Excluded-Middle *) @@ -56,7 +57,7 @@ Definition PredicateExtensionality := (** From predicate extensionality we get propositional extensionality hence proof-irrelevance *) -Require Import ClassicalFacts. +Import ClassicalFacts. Variable pred_extensionality : PredicateExtensionality. @@ -78,7 +79,7 @@ Qed. (** From proof-irrelevance and relational choice, we get guarded relational choice *) -Require Import ChoiceFacts. +Import ChoiceFacts. Variable rel_choice : RelationalChoice. @@ -91,7 +92,7 @@ Qed. (** The form of choice we need: there is a functional relation which chooses an element in any non empty subset of bool *) -Require Import Bool. +Import Bool. Lemma AC_bool_subset_to_bool : exists R : (bool -> Prop) -> bool -> Prop, @@ -163,6 +164,8 @@ End PredExt_RelChoice_imp_EM. Section ProofIrrel_RelChoice_imp_EqEM. +Import ChoiceFacts. + Variable rel_choice : RelationalChoice. Variable proof_irrelevance : forall P:Prop , forall x y:P, x=y. diff --git a/theories/Logic/EqdepFacts.v b/theories/Logic/EqdepFacts.v index 309a98b6c..d938b315f 100644 --- a/theories/Logic/EqdepFacts.v +++ b/theories/Logic/EqdepFacts.v @@ -125,7 +125,7 @@ Proof. apply eq_dep_intro. Qed. -Notation eq_sigS_eq_dep := eq_sigT_eq_dep (compat "8.2"). (* Compatibility *) +Notation eq_sigS_eq_dep := eq_sigT_eq_dep (compat "8.6"). (* Compatibility *) Lemma eq_dep_eq_sigT : forall (U:Type) (P:U -> Type) (p q:U) (x:P p) (y:P q), diff --git a/theories/NArith/BinNat.v b/theories/NArith/BinNat.v index a4fc15037..5d3ec5abc 100644 --- a/theories/NArith/BinNat.v +++ b/theories/NArith/BinNat.v @@ -958,95 +958,94 @@ Notation "( p | q )" := (N.divide p q) (at level 0) : N_scope. (** Compatibility notations *) -(*Notation N := N (compat "8.3").*) (*hidden by module N above *) Notation N_rect := N_rect (only parsing). Notation N_rec := N_rec (only parsing). Notation N_ind := N_ind (only parsing). Notation N0 := N0 (only parsing). Notation Npos := N.pos (only parsing). -Notation Ndiscr := N.discr (compat "8.3"). -Notation Ndouble_plus_one := N.succ_double (compat "8.3"). -Notation Ndouble := N.double (compat "8.3"). -Notation Nsucc := N.succ (compat "8.3"). -Notation Npred := N.pred (compat "8.3"). -Notation Nsucc_pos := N.succ_pos (compat "8.3"). -Notation Ppred_N := Pos.pred_N (compat "8.3"). -Notation Nplus := N.add (compat "8.3"). -Notation Nminus := N.sub (compat "8.3"). -Notation Nmult := N.mul (compat "8.3"). -Notation Neqb := N.eqb (compat "8.3"). -Notation Ncompare := N.compare (compat "8.3"). -Notation Nlt := N.lt (compat "8.3"). -Notation Ngt := N.gt (compat "8.3"). -Notation Nle := N.le (compat "8.3"). -Notation Nge := N.ge (compat "8.3"). -Notation Nmin := N.min (compat "8.3"). -Notation Nmax := N.max (compat "8.3"). -Notation Ndiv2 := N.div2 (compat "8.3"). -Notation Neven := N.even (compat "8.3"). -Notation Nodd := N.odd (compat "8.3"). -Notation Npow := N.pow (compat "8.3"). -Notation Nlog2 := N.log2 (compat "8.3"). - -Notation nat_of_N := N.to_nat (compat "8.3"). -Notation N_of_nat := N.of_nat (compat "8.3"). -Notation N_eq_dec := N.eq_dec (compat "8.3"). -Notation Nrect := N.peano_rect (compat "8.3"). -Notation Nrect_base := N.peano_rect_base (compat "8.3"). -Notation Nrect_step := N.peano_rect_succ (compat "8.3"). -Notation Nind := N.peano_ind (compat "8.3"). -Notation Nrec := N.peano_rec (compat "8.3"). -Notation Nrec_base := N.peano_rec_base (compat "8.3"). -Notation Nrec_succ := N.peano_rec_succ (compat "8.3"). - -Notation Npred_succ := N.pred_succ (compat "8.3"). -Notation Npred_minus := N.pred_sub (compat "8.3"). -Notation Nsucc_pred := N.succ_pred (compat "8.3"). -Notation Ppred_N_spec := N.pos_pred_spec (compat "8.3"). -Notation Nsucc_pos_spec := N.succ_pos_spec (compat "8.3"). -Notation Ppred_Nsucc := N.pos_pred_succ (compat "8.3"). -Notation Nplus_0_l := N.add_0_l (compat "8.3"). -Notation Nplus_0_r := N.add_0_r (compat "8.3"). -Notation Nplus_comm := N.add_comm (compat "8.3"). -Notation Nplus_assoc := N.add_assoc (compat "8.3"). -Notation Nplus_succ := N.add_succ_l (compat "8.3"). -Notation Nsucc_0 := N.succ_0_discr (compat "8.3"). -Notation Nsucc_inj := N.succ_inj (compat "8.3"). -Notation Nminus_N0_Nle := N.sub_0_le (compat "8.3"). -Notation Nminus_0_r := N.sub_0_r (compat "8.3"). -Notation Nminus_succ_r:= N.sub_succ_r (compat "8.3"). -Notation Nmult_0_l := N.mul_0_l (compat "8.3"). -Notation Nmult_1_l := N.mul_1_l (compat "8.3"). -Notation Nmult_1_r := N.mul_1_r (compat "8.3"). -Notation Nmult_comm := N.mul_comm (compat "8.3"). -Notation Nmult_assoc := N.mul_assoc (compat "8.3"). -Notation Nmult_plus_distr_r := N.mul_add_distr_r (compat "8.3"). -Notation Neqb_eq := N.eqb_eq (compat "8.3"). -Notation Nle_0 := N.le_0_l (compat "8.3"). -Notation Ncompare_refl := N.compare_refl (compat "8.3"). -Notation Ncompare_Eq_eq := N.compare_eq (compat "8.3"). -Notation Ncompare_eq_correct := N.compare_eq_iff (compat "8.3"). -Notation Nlt_irrefl := N.lt_irrefl (compat "8.3"). -Notation Nlt_trans := N.lt_trans (compat "8.3"). -Notation Nle_lteq := N.lt_eq_cases (compat "8.3"). -Notation Nlt_succ_r := N.lt_succ_r (compat "8.3"). -Notation Nle_trans := N.le_trans (compat "8.3"). -Notation Nle_succ_l := N.le_succ_l (compat "8.3"). -Notation Ncompare_spec := N.compare_spec (compat "8.3"). -Notation Ncompare_0 := N.compare_0_r (compat "8.3"). -Notation Ndouble_div2 := N.div2_double (compat "8.3"). -Notation Ndouble_plus_one_div2 := N.div2_succ_double (compat "8.3"). -Notation Ndouble_inj := N.double_inj (compat "8.3"). -Notation Ndouble_plus_one_inj := N.succ_double_inj (compat "8.3"). -Notation Npow_0_r := N.pow_0_r (compat "8.3"). -Notation Npow_succ_r := N.pow_succ_r (compat "8.3"). -Notation Nlog2_spec := N.log2_spec (compat "8.3"). -Notation Nlog2_nonpos := N.log2_nonpos (compat "8.3"). -Notation Neven_spec := N.even_spec (compat "8.3"). -Notation Nodd_spec := N.odd_spec (compat "8.3"). -Notation Nlt_not_eq := N.lt_neq (compat "8.3"). -Notation Ngt_Nlt := N.gt_lt (compat "8.3"). +Notation Ndiscr := N.discr (compat "8.6"). +Notation Ndouble_plus_one := N.succ_double (only parsing). +Notation Ndouble := N.double (compat "8.6"). +Notation Nsucc := N.succ (compat "8.6"). +Notation Npred := N.pred (compat "8.6"). +Notation Nsucc_pos := N.succ_pos (compat "8.6"). +Notation Ppred_N := Pos.pred_N (compat "8.6"). +Notation Nplus := N.add (only parsing). +Notation Nminus := N.sub (only parsing). +Notation Nmult := N.mul (only parsing). +Notation Neqb := N.eqb (compat "8.6"). +Notation Ncompare := N.compare (compat "8.6"). +Notation Nlt := N.lt (compat "8.6"). +Notation Ngt := N.gt (compat "8.6"). +Notation Nle := N.le (compat "8.6"). +Notation Nge := N.ge (compat "8.6"). +Notation Nmin := N.min (compat "8.6"). +Notation Nmax := N.max (compat "8.6"). +Notation Ndiv2 := N.div2 (compat "8.6"). +Notation Neven := N.even (compat "8.6"). +Notation Nodd := N.odd (compat "8.6"). +Notation Npow := N.pow (compat "8.6"). +Notation Nlog2 := N.log2 (compat "8.6"). + +Notation nat_of_N := N.to_nat (only parsing). +Notation N_of_nat := N.of_nat (only parsing). +Notation N_eq_dec := N.eq_dec (compat "8.6"). +Notation Nrect := N.peano_rect (only parsing). +Notation Nrect_base := N.peano_rect_base (only parsing). +Notation Nrect_step := N.peano_rect_succ (only parsing). +Notation Nind := N.peano_ind (only parsing). +Notation Nrec := N.peano_rec (only parsing). +Notation Nrec_base := N.peano_rec_base (only parsing). +Notation Nrec_succ := N.peano_rec_succ (only parsing). + +Notation Npred_succ := N.pred_succ (compat "8.6"). +Notation Npred_minus := N.pred_sub (only parsing). +Notation Nsucc_pred := N.succ_pred (compat "8.6"). +Notation Ppred_N_spec := N.pos_pred_spec (only parsing). +Notation Nsucc_pos_spec := N.succ_pos_spec (compat "8.6"). +Notation Ppred_Nsucc := N.pos_pred_succ (only parsing). +Notation Nplus_0_l := N.add_0_l (only parsing). +Notation Nplus_0_r := N.add_0_r (only parsing). +Notation Nplus_comm := N.add_comm (only parsing). +Notation Nplus_assoc := N.add_assoc (only parsing). +Notation Nplus_succ := N.add_succ_l (only parsing). +Notation Nsucc_0 := N.succ_0_discr (only parsing). +Notation Nsucc_inj := N.succ_inj (compat "8.6"). +Notation Nminus_N0_Nle := N.sub_0_le (only parsing). +Notation Nminus_0_r := N.sub_0_r (only parsing). +Notation Nminus_succ_r:= N.sub_succ_r (only parsing). +Notation Nmult_0_l := N.mul_0_l (only parsing). +Notation Nmult_1_l := N.mul_1_l (only parsing). +Notation Nmult_1_r := N.mul_1_r (only parsing). +Notation Nmult_comm := N.mul_comm (only parsing). +Notation Nmult_assoc := N.mul_assoc (only parsing). +Notation Nmult_plus_distr_r := N.mul_add_distr_r (only parsing). +Notation Neqb_eq := N.eqb_eq (compat "8.6"). +Notation Nle_0 := N.le_0_l (only parsing). +Notation Ncompare_refl := N.compare_refl (compat "8.6"). +Notation Ncompare_Eq_eq := N.compare_eq (only parsing). +Notation Ncompare_eq_correct := N.compare_eq_iff (only parsing). +Notation Nlt_irrefl := N.lt_irrefl (compat "8.6"). +Notation Nlt_trans := N.lt_trans (compat "8.6"). +Notation Nle_lteq := N.lt_eq_cases (only parsing). +Notation Nlt_succ_r := N.lt_succ_r (compat "8.6"). +Notation Nle_trans := N.le_trans (compat "8.6"). +Notation Nle_succ_l := N.le_succ_l (compat "8.6"). +Notation Ncompare_spec := N.compare_spec (compat "8.6"). +Notation Ncompare_0 := N.compare_0_r (only parsing). +Notation Ndouble_div2 := N.div2_double (only parsing). +Notation Ndouble_plus_one_div2 := N.div2_succ_double (only parsing). +Notation Ndouble_inj := N.double_inj (compat "8.6"). +Notation Ndouble_plus_one_inj := N.succ_double_inj (only parsing). +Notation Npow_0_r := N.pow_0_r (compat "8.6"). +Notation Npow_succ_r := N.pow_succ_r (compat "8.6"). +Notation Nlog2_spec := N.log2_spec (compat "8.6"). +Notation Nlog2_nonpos := N.log2_nonpos (compat "8.6"). +Notation Neven_spec := N.even_spec (compat "8.6"). +Notation Nodd_spec := N.odd_spec (compat "8.6"). +Notation Nlt_not_eq := N.lt_neq (only parsing). +Notation Ngt_Nlt := N.gt_lt (only parsing). (** More complex compatibility facts, expressed as lemmas (to preserve scopes for instance) *) diff --git a/theories/NArith/Ndec.v b/theories/NArith/Ndec.v index 12e3efd55..67c30f225 100644 --- a/theories/NArith/Ndec.v +++ b/theories/NArith/Ndec.v @@ -22,11 +22,11 @@ Local Open Scope N_scope. (** Obsolete results about boolean comparisons over [N], kept for compatibility with IntMap and SMC. *) -Notation Peqb := Pos.eqb (compat "8.3"). -Notation Neqb := N.eqb (compat "8.3"). -Notation Peqb_correct := Pos.eqb_refl (compat "8.3"). -Notation Neqb_correct := N.eqb_refl (compat "8.3"). -Notation Neqb_comm := N.eqb_sym (compat "8.3"). +Notation Peqb := Pos.eqb (compat "8.6"). +Notation Neqb := N.eqb (compat "8.6"). +Notation Peqb_correct := Pos.eqb_refl (only parsing). +Notation Neqb_correct := N.eqb_refl (only parsing). +Notation Neqb_comm := N.eqb_sym (only parsing). Lemma Peqb_complete p p' : Pos.eqb p p' = true -> p = p'. Proof. now apply Pos.eqb_eq. Qed. @@ -276,7 +276,7 @@ Qed. (* Old results about [N.min] *) -Notation Nmin_choice := N.min_dec (compat "8.3"). +Notation Nmin_choice := N.min_dec (only parsing). Lemma Nmin_le_1 a b : Nleb (N.min a b) a = true. Proof. rewrite Nleb_Nle. apply N.le_min_l. Qed. diff --git a/theories/NArith/Ndigits.v b/theories/NArith/Ndigits.v index c6bad75ee..3ccaa7211 100644 --- a/theories/NArith/Ndigits.v +++ b/theories/NArith/Ndigits.v @@ -16,17 +16,17 @@ Local Open Scope N_scope. (** Compatibility names for some bitwise operations *) -Notation Pxor := Pos.lxor (compat "8.3"). -Notation Nxor := N.lxor (compat "8.3"). -Notation Pbit := Pos.testbit_nat (compat "8.3"). -Notation Nbit := N.testbit_nat (compat "8.3"). - -Notation Nxor_eq := N.lxor_eq (compat "8.3"). -Notation Nxor_comm := N.lxor_comm (compat "8.3"). -Notation Nxor_assoc := N.lxor_assoc (compat "8.3"). -Notation Nxor_neutral_left := N.lxor_0_l (compat "8.3"). -Notation Nxor_neutral_right := N.lxor_0_r (compat "8.3"). -Notation Nxor_nilpotent := N.lxor_nilpotent (compat "8.3"). +Notation Pxor := Pos.lxor (only parsing). +Notation Nxor := N.lxor (only parsing). +Notation Pbit := Pos.testbit_nat (only parsing). +Notation Nbit := N.testbit_nat (only parsing). + +Notation Nxor_eq := N.lxor_eq (only parsing). +Notation Nxor_comm := N.lxor_comm (only parsing). +Notation Nxor_assoc := N.lxor_assoc (only parsing). +Notation Nxor_neutral_left := N.lxor_0_l (only parsing). +Notation Nxor_neutral_right := N.lxor_0_r (only parsing). +Notation Nxor_nilpotent := N.lxor_nilpotent (only parsing). (** Equivalence of bit-testing functions, either with index in [N] or in [nat]. *) @@ -251,7 +251,7 @@ Local Close Scope N_scope. (** Checking whether a number is odd, i.e. if its lower bit is set. *) -Notation Nbit0 := N.odd (compat "8.3"). +Notation Nbit0 := N.odd (only parsing). Definition Nodd (n:N) := N.odd n = true. Definition Neven (n:N) := N.odd n = false. @@ -500,7 +500,7 @@ Qed. (** Number of digits in a number *) -Notation Nsize := N.size_nat (compat "8.3"). +Notation Nsize := N.size_nat (only parsing). (** conversions between N and bit vectors. *) diff --git a/theories/NArith/Ndiv_def.v b/theories/NArith/Ndiv_def.v index 6da93a1e2..7c9fd8695 100644 --- a/theories/NArith/Ndiv_def.v +++ b/theories/NArith/Ndiv_def.v @@ -24,10 +24,10 @@ Lemma Pdiv_eucl_remainder a b : snd (Pdiv_eucl a b) < Npos b. Proof. now apply (N.pos_div_eucl_remainder a (Npos b)). Qed. -Notation Ndiv_eucl := N.div_eucl (compat "8.3"). -Notation Ndiv := N.div (compat "8.3"). -Notation Nmod := N.modulo (compat "8.3"). +Notation Ndiv_eucl := N.div_eucl (compat "8.6"). +Notation Ndiv := N.div (compat "8.6"). +Notation Nmod := N.modulo (only parsing). -Notation Ndiv_eucl_correct := N.div_eucl_spec (compat "8.3"). -Notation Ndiv_mod_eq := N.div_mod' (compat "8.3"). -Notation Nmod_lt := N.mod_lt (compat "8.3"). +Notation Ndiv_eucl_correct := N.div_eucl_spec (only parsing). +Notation Ndiv_mod_eq := N.div_mod' (only parsing). +Notation Nmod_lt := N.mod_lt (compat "8.6"). diff --git a/theories/NArith/Nnat.v b/theories/NArith/Nnat.v index 3cb8117af..3488c8b43 100644 --- a/theories/NArith/Nnat.v +++ b/theories/NArith/Nnat.v @@ -210,30 +210,30 @@ Hint Rewrite Nat2N.id : Nnat. (** Compatibility notations *) -Notation nat_of_N_inj := N2Nat.inj (compat "8.3"). -Notation N_of_nat_of_N := N2Nat.id (compat "8.3"). -Notation nat_of_Ndouble := N2Nat.inj_double (compat "8.3"). -Notation nat_of_Ndouble_plus_one := N2Nat.inj_succ_double (compat "8.3"). -Notation nat_of_Nsucc := N2Nat.inj_succ (compat "8.3"). -Notation nat_of_Nplus := N2Nat.inj_add (compat "8.3"). -Notation nat_of_Nmult := N2Nat.inj_mul (compat "8.3"). -Notation nat_of_Nminus := N2Nat.inj_sub (compat "8.3"). -Notation nat_of_Npred := N2Nat.inj_pred (compat "8.3"). -Notation nat_of_Ndiv2 := N2Nat.inj_div2 (compat "8.3"). -Notation nat_of_Ncompare := N2Nat.inj_compare (compat "8.3"). -Notation nat_of_Nmax := N2Nat.inj_max (compat "8.3"). -Notation nat_of_Nmin := N2Nat.inj_min (compat "8.3"). - -Notation nat_of_N_of_nat := Nat2N.id (compat "8.3"). -Notation N_of_nat_inj := Nat2N.inj (compat "8.3"). -Notation N_of_double := Nat2N.inj_double (compat "8.3"). -Notation N_of_double_plus_one := Nat2N.inj_succ_double (compat "8.3"). -Notation N_of_S := Nat2N.inj_succ (compat "8.3"). -Notation N_of_pred := Nat2N.inj_pred (compat "8.3"). -Notation N_of_plus := Nat2N.inj_add (compat "8.3"). -Notation N_of_minus := Nat2N.inj_sub (compat "8.3"). -Notation N_of_mult := Nat2N.inj_mul (compat "8.3"). -Notation N_of_div2 := Nat2N.inj_div2 (compat "8.3"). -Notation N_of_nat_compare := Nat2N.inj_compare (compat "8.3"). -Notation N_of_min := Nat2N.inj_min (compat "8.3"). -Notation N_of_max := Nat2N.inj_max (compat "8.3"). +Notation nat_of_N_inj := N2Nat.inj (only parsing). +Notation N_of_nat_of_N := N2Nat.id (only parsing). +Notation nat_of_Ndouble := N2Nat.inj_double (only parsing). +Notation nat_of_Ndouble_plus_one := N2Nat.inj_succ_double (only parsing). +Notation nat_of_Nsucc := N2Nat.inj_succ (only parsing). +Notation nat_of_Nplus := N2Nat.inj_add (only parsing). +Notation nat_of_Nmult := N2Nat.inj_mul (only parsing). +Notation nat_of_Nminus := N2Nat.inj_sub (only parsing). +Notation nat_of_Npred := N2Nat.inj_pred (only parsing). +Notation nat_of_Ndiv2 := N2Nat.inj_div2 (only parsing). +Notation nat_of_Ncompare := N2Nat.inj_compare (only parsing). +Notation nat_of_Nmax := N2Nat.inj_max (only parsing). +Notation nat_of_Nmin := N2Nat.inj_min (only parsing). + +Notation nat_of_N_of_nat := Nat2N.id (only parsing). +Notation N_of_nat_inj := Nat2N.inj (only parsing). +Notation N_of_double := Nat2N.inj_double (only parsing). +Notation N_of_double_plus_one := Nat2N.inj_succ_double (only parsing). +Notation N_of_S := Nat2N.inj_succ (only parsing). +Notation N_of_pred := Nat2N.inj_pred (only parsing). +Notation N_of_plus := Nat2N.inj_add (only parsing). +Notation N_of_minus := Nat2N.inj_sub (only parsing). +Notation N_of_mult := Nat2N.inj_mul (only parsing). +Notation N_of_div2 := Nat2N.inj_div2 (only parsing). +Notation N_of_nat_compare := Nat2N.inj_compare (only parsing). +Notation N_of_min := Nat2N.inj_min (only parsing). +Notation N_of_max := Nat2N.inj_max (only parsing). diff --git a/theories/NArith/Nsqrt_def.v b/theories/NArith/Nsqrt_def.v index 97b41ae42..e771fe916 100644 --- a/theories/NArith/Nsqrt_def.v +++ b/theories/NArith/Nsqrt_def.v @@ -13,8 +13,8 @@ Require Import BinNat. (** Obsolete file, see [BinNat] now, only compatibility notations remain here. *) -Notation Nsqrtrem := N.sqrtrem (compat "8.3"). -Notation Nsqrt := N.sqrt (compat "8.3"). -Notation Nsqrtrem_spec := N.sqrtrem_spec (compat "8.3"). -Notation Nsqrt_spec := (fun n => N.sqrt_spec n (N.le_0_l n)) (compat "8.3"). -Notation Nsqrtrem_sqrt := N.sqrtrem_sqrt (compat "8.3"). +Notation Nsqrtrem := N.sqrtrem (compat "8.6"). +Notation Nsqrt := N.sqrt (compat "8.6"). +Notation Nsqrtrem_spec := N.sqrtrem_spec (compat "8.6"). +Notation Nsqrt_spec := (fun n => N.sqrt_spec n (N.le_0_l n)) (only parsing). +Notation Nsqrtrem_sqrt := N.sqrtrem_sqrt (compat "8.6"). diff --git a/theories/Numbers/Natural/Peano/NPeano.v b/theories/Numbers/Natural/Peano/NPeano.v index dfe167092..6000bdcf7 100644 --- a/theories/Numbers/Natural/Peano/NPeano.v +++ b/theories/Numbers/Natural/Peano/NPeano.v @@ -20,74 +20,74 @@ Module Nat <: NAxiomsSig := Nat. (** Compat notations for stuff that used to be at the beginning of NPeano. *) -Notation leb := Nat.leb (compat "8.4"). -Notation ltb := Nat.ltb (compat "8.4"). -Notation leb_le := Nat.leb_le (compat "8.4"). -Notation ltb_lt := Nat.ltb_lt (compat "8.4"). -Notation pow := Nat.pow (compat "8.4"). -Notation pow_0_r := Nat.pow_0_r (compat "8.4"). -Notation pow_succ_r := Nat.pow_succ_r (compat "8.4"). -Notation square := Nat.square (compat "8.4"). -Notation square_spec := Nat.square_spec (compat "8.4"). -Notation Even := Nat.Even (compat "8.4"). -Notation Odd := Nat.Odd (compat "8.4"). -Notation even := Nat.even (compat "8.4"). -Notation odd := Nat.odd (compat "8.4"). -Notation even_spec := Nat.even_spec (compat "8.4"). -Notation odd_spec := Nat.odd_spec (compat "8.4"). +Notation leb := Nat.leb (only parsing). +Notation ltb := Nat.ltb (only parsing). +Notation leb_le := Nat.leb_le (only parsing). +Notation ltb_lt := Nat.ltb_lt (only parsing). +Notation pow := Nat.pow (only parsing). +Notation pow_0_r := Nat.pow_0_r (only parsing). +Notation pow_succ_r := Nat.pow_succ_r (only parsing). +Notation square := Nat.square (only parsing). +Notation square_spec := Nat.square_spec (only parsing). +Notation Even := Nat.Even (only parsing). +Notation Odd := Nat.Odd (only parsing). +Notation even := Nat.even (only parsing). +Notation odd := Nat.odd (only parsing). +Notation even_spec := Nat.even_spec (only parsing). +Notation odd_spec := Nat.odd_spec (only parsing). Lemma Even_equiv n : Even n <-> Even.even n. Proof. symmetry. apply Even.even_equiv. Qed. Lemma Odd_equiv n : Odd n <-> Even.odd n. Proof. symmetry. apply Even.odd_equiv. Qed. -Notation divmod := Nat.divmod (compat "8.4"). -Notation div := Nat.div (compat "8.4"). -Notation modulo := Nat.modulo (compat "8.4"). -Notation divmod_spec := Nat.divmod_spec (compat "8.4"). -Notation div_mod := Nat.div_mod (compat "8.4"). -Notation mod_bound_pos := Nat.mod_bound_pos (compat "8.4"). -Notation sqrt_iter := Nat.sqrt_iter (compat "8.4"). -Notation sqrt := Nat.sqrt (compat "8.4"). -Notation sqrt_iter_spec := Nat.sqrt_iter_spec (compat "8.4"). -Notation sqrt_spec := Nat.sqrt_spec (compat "8.4"). -Notation log2_iter := Nat.log2_iter (compat "8.4"). -Notation log2 := Nat.log2 (compat "8.4"). -Notation log2_iter_spec := Nat.log2_iter_spec (compat "8.4"). -Notation log2_spec := Nat.log2_spec (compat "8.4"). -Notation log2_nonpos := Nat.log2_nonpos (compat "8.4"). -Notation gcd := Nat.gcd (compat "8.4"). -Notation divide := Nat.divide (compat "8.4"). -Notation gcd_divide := Nat.gcd_divide (compat "8.4"). -Notation gcd_divide_l := Nat.gcd_divide_l (compat "8.4"). -Notation gcd_divide_r := Nat.gcd_divide_r (compat "8.4"). -Notation gcd_greatest := Nat.gcd_greatest (compat "8.4"). -Notation testbit := Nat.testbit (compat "8.4"). -Notation shiftl := Nat.shiftl (compat "8.4"). -Notation shiftr := Nat.shiftr (compat "8.4"). -Notation bitwise := Nat.bitwise (compat "8.4"). -Notation land := Nat.land (compat "8.4"). -Notation lor := Nat.lor (compat "8.4"). -Notation ldiff := Nat.ldiff (compat "8.4"). -Notation lxor := Nat.lxor (compat "8.4"). -Notation double_twice := Nat.double_twice (compat "8.4"). -Notation testbit_0_l := Nat.testbit_0_l (compat "8.4"). -Notation testbit_odd_0 := Nat.testbit_odd_0 (compat "8.4"). -Notation testbit_even_0 := Nat.testbit_even_0 (compat "8.4"). -Notation testbit_odd_succ := Nat.testbit_odd_succ (compat "8.4"). -Notation testbit_even_succ := Nat.testbit_even_succ (compat "8.4"). -Notation shiftr_spec := Nat.shiftr_spec (compat "8.4"). -Notation shiftl_spec_high := Nat.shiftl_spec_high (compat "8.4"). -Notation shiftl_spec_low := Nat.shiftl_spec_low (compat "8.4"). -Notation div2_bitwise := Nat.div2_bitwise (compat "8.4"). -Notation odd_bitwise := Nat.odd_bitwise (compat "8.4"). -Notation div2_decr := Nat.div2_decr (compat "8.4"). -Notation testbit_bitwise_1 := Nat.testbit_bitwise_1 (compat "8.4"). -Notation testbit_bitwise_2 := Nat.testbit_bitwise_2 (compat "8.4"). -Notation land_spec := Nat.land_spec (compat "8.4"). -Notation ldiff_spec := Nat.ldiff_spec (compat "8.4"). -Notation lor_spec := Nat.lor_spec (compat "8.4"). -Notation lxor_spec := Nat.lxor_spec (compat "8.4"). +Notation divmod := Nat.divmod (only parsing). +Notation div := Nat.div (only parsing). +Notation modulo := Nat.modulo (only parsing). +Notation divmod_spec := Nat.divmod_spec (only parsing). +Notation div_mod := Nat.div_mod (only parsing). +Notation mod_bound_pos := Nat.mod_bound_pos (only parsing). +Notation sqrt_iter := Nat.sqrt_iter (only parsing). +Notation sqrt := Nat.sqrt (only parsing). +Notation sqrt_iter_spec := Nat.sqrt_iter_spec (only parsing). +Notation sqrt_spec := Nat.sqrt_spec (only parsing). +Notation log2_iter := Nat.log2_iter (only parsing). +Notation log2 := Nat.log2 (only parsing). +Notation log2_iter_spec := Nat.log2_iter_spec (only parsing). +Notation log2_spec := Nat.log2_spec (only parsing). +Notation log2_nonpos := Nat.log2_nonpos (only parsing). +Notation gcd := Nat.gcd (only parsing). +Notation divide := Nat.divide (only parsing). +Notation gcd_divide := Nat.gcd_divide (only parsing). +Notation gcd_divide_l := Nat.gcd_divide_l (only parsing). +Notation gcd_divide_r := Nat.gcd_divide_r (only parsing). +Notation gcd_greatest := Nat.gcd_greatest (only parsing). +Notation testbit := Nat.testbit (only parsing). +Notation shiftl := Nat.shiftl (only parsing). +Notation shiftr := Nat.shiftr (only parsing). +Notation bitwise := Nat.bitwise (only parsing). +Notation land := Nat.land (only parsing). +Notation lor := Nat.lor (only parsing). +Notation ldiff := Nat.ldiff (only parsing). +Notation lxor := Nat.lxor (only parsing). +Notation double_twice := Nat.double_twice (only parsing). +Notation testbit_0_l := Nat.testbit_0_l (only parsing). +Notation testbit_odd_0 := Nat.testbit_odd_0 (only parsing). +Notation testbit_even_0 := Nat.testbit_even_0 (only parsing). +Notation testbit_odd_succ := Nat.testbit_odd_succ (only parsing). +Notation testbit_even_succ := Nat.testbit_even_succ (only parsing). +Notation shiftr_spec := Nat.shiftr_spec (only parsing). +Notation shiftl_spec_high := Nat.shiftl_spec_high (only parsing). +Notation shiftl_spec_low := Nat.shiftl_spec_low (only parsing). +Notation div2_bitwise := Nat.div2_bitwise (only parsing). +Notation odd_bitwise := Nat.odd_bitwise (only parsing). +Notation div2_decr := Nat.div2_decr (only parsing). +Notation testbit_bitwise_1 := Nat.testbit_bitwise_1 (only parsing). +Notation testbit_bitwise_2 := Nat.testbit_bitwise_2 (only parsing). +Notation land_spec := Nat.land_spec (only parsing). +Notation ldiff_spec := Nat.ldiff_spec (only parsing). +Notation lor_spec := Nat.lor_spec (only parsing). +Notation lxor_spec := Nat.lxor_spec (only parsing). Infix "<=?" := Nat.leb (at level 70) : nat_scope. Infix "<?" := Nat.ltb (at level 70) : nat_scope. diff --git a/theories/PArith/BinPos.v b/theories/PArith/BinPos.v index 1de61d0b2..8d0896db7 100644 --- a/theories/PArith/BinPos.v +++ b/theories/PArith/BinPos.v @@ -1905,180 +1905,180 @@ Notation IsNul := Pos.IsNul (only parsing). Notation IsPos := Pos.IsPos (only parsing). Notation IsNeg := Pos.IsNeg (only parsing). -Notation Psucc := Pos.succ (compat "8.3"). -Notation Pplus := Pos.add (compat "8.3"). -Notation Pplus_carry := Pos.add_carry (compat "8.3"). -Notation Ppred := Pos.pred (compat "8.3"). -Notation Piter_op := Pos.iter_op (compat "8.3"). -Notation Piter_op_succ := Pos.iter_op_succ (compat "8.3"). -Notation Pmult_nat := (Pos.iter_op plus) (compat "8.3"). -Notation nat_of_P := Pos.to_nat (compat "8.3"). -Notation P_of_succ_nat := Pos.of_succ_nat (compat "8.3"). -Notation Pdouble_minus_one := Pos.pred_double (compat "8.3"). -Notation positive_mask := Pos.mask (compat "8.3"). -Notation positive_mask_rect := Pos.mask_rect (compat "8.3"). -Notation positive_mask_ind := Pos.mask_ind (compat "8.3"). -Notation positive_mask_rec := Pos.mask_rec (compat "8.3"). -Notation Pdouble_plus_one_mask := Pos.succ_double_mask (compat "8.3"). -Notation Pdouble_mask := Pos.double_mask (compat "8.3"). -Notation Pdouble_minus_two := Pos.double_pred_mask (compat "8.3"). -Notation Pminus_mask := Pos.sub_mask (compat "8.3"). -Notation Pminus_mask_carry := Pos.sub_mask_carry (compat "8.3"). -Notation Pminus := Pos.sub (compat "8.3"). -Notation Pmult := Pos.mul (compat "8.3"). -Notation iter_pos := @Pos.iter (compat "8.3"). -Notation Ppow := Pos.pow (compat "8.3"). -Notation Pdiv2 := Pos.div2 (compat "8.3"). -Notation Pdiv2_up := Pos.div2_up (compat "8.3"). -Notation Psize := Pos.size_nat (compat "8.3"). -Notation Psize_pos := Pos.size (compat "8.3"). -Notation Pcompare x y m := (Pos.compare_cont m x y) (compat "8.3"). -Notation Plt := Pos.lt (compat "8.3"). -Notation Pgt := Pos.gt (compat "8.3"). -Notation Ple := Pos.le (compat "8.3"). -Notation Pge := Pos.ge (compat "8.3"). -Notation Pmin := Pos.min (compat "8.3"). -Notation Pmax := Pos.max (compat "8.3"). -Notation Peqb := Pos.eqb (compat "8.3"). -Notation positive_eq_dec := Pos.eq_dec (compat "8.3"). -Notation xI_succ_xO := Pos.xI_succ_xO (compat "8.3"). -Notation Psucc_discr := Pos.succ_discr (compat "8.3"). +Notation Psucc := Pos.succ (compat "8.6"). +Notation Pplus := Pos.add (only parsing). +Notation Pplus_carry := Pos.add_carry (only parsing). +Notation Ppred := Pos.pred (compat "8.6"). +Notation Piter_op := Pos.iter_op (compat "8.6"). +Notation Piter_op_succ := Pos.iter_op_succ (compat "8.6"). +Notation Pmult_nat := (Pos.iter_op plus) (only parsing). +Notation nat_of_P := Pos.to_nat (only parsing). +Notation P_of_succ_nat := Pos.of_succ_nat (only parsing). +Notation Pdouble_minus_one := Pos.pred_double (only parsing). +Notation positive_mask := Pos.mask (only parsing). +Notation positive_mask_rect := Pos.mask_rect (only parsing). +Notation positive_mask_ind := Pos.mask_ind (only parsing). +Notation positive_mask_rec := Pos.mask_rec (only parsing). +Notation Pdouble_plus_one_mask := Pos.succ_double_mask (only parsing). +Notation Pdouble_mask := Pos.double_mask (compat "8.6"). +Notation Pdouble_minus_two := Pos.double_pred_mask (only parsing). +Notation Pminus_mask := Pos.sub_mask (only parsing). +Notation Pminus_mask_carry := Pos.sub_mask_carry (only parsing). +Notation Pminus := Pos.sub (only parsing). +Notation Pmult := Pos.mul (only parsing). +Notation iter_pos := @Pos.iter (only parsing). +Notation Ppow := Pos.pow (compat "8.6"). +Notation Pdiv2 := Pos.div2 (compat "8.6"). +Notation Pdiv2_up := Pos.div2_up (compat "8.6"). +Notation Psize := Pos.size_nat (only parsing). +Notation Psize_pos := Pos.size (only parsing). +Notation Pcompare x y m := (Pos.compare_cont m x y) (only parsing). +Notation Plt := Pos.lt (compat "8.6"). +Notation Pgt := Pos.gt (compat "8.6"). +Notation Ple := Pos.le (compat "8.6"). +Notation Pge := Pos.ge (compat "8.6"). +Notation Pmin := Pos.min (compat "8.6"). +Notation Pmax := Pos.max (compat "8.6"). +Notation Peqb := Pos.eqb (compat "8.6"). +Notation positive_eq_dec := Pos.eq_dec (only parsing). +Notation xI_succ_xO := Pos.xI_succ_xO (only parsing). +Notation Psucc_discr := Pos.succ_discr (compat "8.6"). Notation Psucc_o_double_minus_one_eq_xO := - Pos.succ_pred_double (compat "8.3"). + Pos.succ_pred_double (only parsing). Notation Pdouble_minus_one_o_succ_eq_xI := - Pos.pred_double_succ (compat "8.3"). -Notation xO_succ_permute := Pos.double_succ (compat "8.3"). + Pos.pred_double_succ (only parsing). +Notation xO_succ_permute := Pos.double_succ (only parsing). Notation double_moins_un_xO_discr := - Pos.pred_double_xO_discr (compat "8.3"). -Notation Psucc_not_one := Pos.succ_not_1 (compat "8.3"). -Notation Ppred_succ := Pos.pred_succ (compat "8.3"). -Notation Psucc_pred := Pos.succ_pred_or (compat "8.3"). -Notation Psucc_inj := Pos.succ_inj (compat "8.3"). -Notation Pplus_carry_spec := Pos.add_carry_spec (compat "8.3"). -Notation Pplus_comm := Pos.add_comm (compat "8.3"). -Notation Pplus_succ_permute_r := Pos.add_succ_r (compat "8.3"). -Notation Pplus_succ_permute_l := Pos.add_succ_l (compat "8.3"). -Notation Pplus_no_neutral := Pos.add_no_neutral (compat "8.3"). -Notation Pplus_carry_plus := Pos.add_carry_add (compat "8.3"). -Notation Pplus_reg_r := Pos.add_reg_r (compat "8.3"). -Notation Pplus_reg_l := Pos.add_reg_l (compat "8.3"). -Notation Pplus_carry_reg_r := Pos.add_carry_reg_r (compat "8.3"). -Notation Pplus_carry_reg_l := Pos.add_carry_reg_l (compat "8.3"). -Notation Pplus_assoc := Pos.add_assoc (compat "8.3"). -Notation Pplus_xO := Pos.add_xO (compat "8.3"). -Notation Pplus_xI_double_minus_one := Pos.add_xI_pred_double (compat "8.3"). -Notation Pplus_xO_double_minus_one := Pos.add_xO_pred_double (compat "8.3"). -Notation Pplus_diag := Pos.add_diag (compat "8.3"). -Notation PeanoView := Pos.PeanoView (compat "8.3"). -Notation PeanoOne := Pos.PeanoOne (compat "8.3"). -Notation PeanoSucc := Pos.PeanoSucc (compat "8.3"). -Notation PeanoView_rect := Pos.PeanoView_rect (compat "8.3"). -Notation PeanoView_ind := Pos.PeanoView_ind (compat "8.3"). -Notation PeanoView_rec := Pos.PeanoView_rec (compat "8.3"). -Notation peanoView_xO := Pos.peanoView_xO (compat "8.3"). -Notation peanoView_xI := Pos.peanoView_xI (compat "8.3"). -Notation peanoView := Pos.peanoView (compat "8.3"). -Notation PeanoView_iter := Pos.PeanoView_iter (compat "8.3"). -Notation eq_dep_eq_positive := Pos.eq_dep_eq_positive (compat "8.3"). -Notation PeanoViewUnique := Pos.PeanoViewUnique (compat "8.3"). -Notation Prect := Pos.peano_rect (compat "8.3"). -Notation Prect_succ := Pos.peano_rect_succ (compat "8.3"). -Notation Prect_base := Pos.peano_rect_base (compat "8.3"). -Notation Prec := Pos.peano_rec (compat "8.3"). -Notation Pind := Pos.peano_ind (compat "8.3"). -Notation Pcase := Pos.peano_case (compat "8.3"). -Notation Pmult_1_r := Pos.mul_1_r (compat "8.3"). -Notation Pmult_Sn_m := Pos.mul_succ_l (compat "8.3"). -Notation Pmult_xO_permute_r := Pos.mul_xO_r (compat "8.3"). -Notation Pmult_xI_permute_r := Pos.mul_xI_r (compat "8.3"). -Notation Pmult_comm := Pos.mul_comm (compat "8.3"). -Notation Pmult_plus_distr_l := Pos.mul_add_distr_l (compat "8.3"). -Notation Pmult_plus_distr_r := Pos.mul_add_distr_r (compat "8.3"). -Notation Pmult_assoc := Pos.mul_assoc (compat "8.3"). -Notation Pmult_xI_mult_xO_discr := Pos.mul_xI_mul_xO_discr (compat "8.3"). -Notation Pmult_xO_discr := Pos.mul_xO_discr (compat "8.3"). -Notation Pmult_reg_r := Pos.mul_reg_r (compat "8.3"). -Notation Pmult_reg_l := Pos.mul_reg_l (compat "8.3"). -Notation Pmult_1_inversion_l := Pos.mul_eq_1_l (compat "8.3"). -Notation Psquare_xO := Pos.square_xO (compat "8.3"). -Notation Psquare_xI := Pos.square_xI (compat "8.3"). -Notation iter_pos_swap_gen := Pos.iter_swap_gen (compat "8.3"). -Notation iter_pos_swap := Pos.iter_swap (compat "8.3"). -Notation iter_pos_succ := Pos.iter_succ (compat "8.3"). -Notation iter_pos_plus := Pos.iter_add (compat "8.3"). -Notation iter_pos_invariant := Pos.iter_invariant (compat "8.3"). -Notation Ppow_1_r := Pos.pow_1_r (compat "8.3"). -Notation Ppow_succ_r := Pos.pow_succ_r (compat "8.3"). -Notation Peqb_refl := Pos.eqb_refl (compat "8.3"). -Notation Peqb_eq := Pos.eqb_eq (compat "8.3"). -Notation Pcompare_refl_id := Pos.compare_cont_refl (compat "8.3"). -Notation Pcompare_eq_iff := Pos.compare_eq_iff (compat "8.3"). -Notation Pcompare_Gt_Lt := Pos.compare_cont_Gt_Lt (compat "8.3"). -Notation Pcompare_eq_Lt := Pos.compare_lt_iff (compat "8.3"). -Notation Pcompare_Lt_Gt := Pos.compare_cont_Lt_Gt (compat "8.3"). - -Notation Pcompare_antisym := Pos.compare_cont_antisym (compat "8.3"). -Notation ZC1 := Pos.gt_lt (compat "8.3"). -Notation ZC2 := Pos.lt_gt (compat "8.3"). -Notation Pcompare_spec := Pos.compare_spec (compat "8.3"). -Notation Pcompare_p_Sp := Pos.lt_succ_diag_r (compat "8.3"). -Notation Pcompare_succ_succ := Pos.compare_succ_succ (compat "8.3"). -Notation Pcompare_1 := Pos.nlt_1_r (compat "8.3"). -Notation Plt_1 := Pos.nlt_1_r (compat "8.3"). -Notation Plt_1_succ := Pos.lt_1_succ (compat "8.3"). -Notation Plt_lt_succ := Pos.lt_lt_succ (compat "8.3"). -Notation Plt_irrefl := Pos.lt_irrefl (compat "8.3"). -Notation Plt_trans := Pos.lt_trans (compat "8.3"). -Notation Plt_ind := Pos.lt_ind (compat "8.3"). -Notation Ple_lteq := Pos.le_lteq (compat "8.3"). -Notation Ple_refl := Pos.le_refl (compat "8.3"). -Notation Ple_lt_trans := Pos.le_lt_trans (compat "8.3"). -Notation Plt_le_trans := Pos.lt_le_trans (compat "8.3"). -Notation Ple_trans := Pos.le_trans (compat "8.3"). -Notation Plt_succ_r := Pos.lt_succ_r (compat "8.3"). -Notation Ple_succ_l := Pos.le_succ_l (compat "8.3"). -Notation Pplus_compare_mono_l := Pos.add_compare_mono_l (compat "8.3"). -Notation Pplus_compare_mono_r := Pos.add_compare_mono_r (compat "8.3"). -Notation Pplus_lt_mono_l := Pos.add_lt_mono_l (compat "8.3"). -Notation Pplus_lt_mono_r := Pos.add_lt_mono_r (compat "8.3"). -Notation Pplus_lt_mono := Pos.add_lt_mono (compat "8.3"). -Notation Pplus_le_mono_l := Pos.add_le_mono_l (compat "8.3"). -Notation Pplus_le_mono_r := Pos.add_le_mono_r (compat "8.3"). -Notation Pplus_le_mono := Pos.add_le_mono (compat "8.3"). -Notation Pmult_compare_mono_l := Pos.mul_compare_mono_l (compat "8.3"). -Notation Pmult_compare_mono_r := Pos.mul_compare_mono_r (compat "8.3"). -Notation Pmult_lt_mono_l := Pos.mul_lt_mono_l (compat "8.3"). -Notation Pmult_lt_mono_r := Pos.mul_lt_mono_r (compat "8.3"). -Notation Pmult_lt_mono := Pos.mul_lt_mono (compat "8.3"). -Notation Pmult_le_mono_l := Pos.mul_le_mono_l (compat "8.3"). -Notation Pmult_le_mono_r := Pos.mul_le_mono_r (compat "8.3"). -Notation Pmult_le_mono := Pos.mul_le_mono (compat "8.3"). -Notation Plt_plus_r := Pos.lt_add_r (compat "8.3"). -Notation Plt_not_plus_l := Pos.lt_not_add_l (compat "8.3"). -Notation Ppow_gt_1 := Pos.pow_gt_1 (compat "8.3"). -Notation Ppred_mask := Pos.pred_mask (compat "8.3"). -Notation Pminus_mask_succ_r := Pos.sub_mask_succ_r (compat "8.3"). -Notation Pminus_mask_carry_spec := Pos.sub_mask_carry_spec (compat "8.3"). -Notation Pminus_succ_r := Pos.sub_succ_r (compat "8.3"). -Notation Pminus_mask_diag := Pos.sub_mask_diag (compat "8.3"). - -Notation Pplus_minus_eq := Pos.add_sub (compat "8.3"). -Notation Pmult_minus_distr_l := Pos.mul_sub_distr_l (compat "8.3"). -Notation Pminus_lt_mono_l := Pos.sub_lt_mono_l (compat "8.3"). -Notation Pminus_compare_mono_l := Pos.sub_compare_mono_l (compat "8.3"). -Notation Pminus_compare_mono_r := Pos.sub_compare_mono_r (compat "8.3"). -Notation Pminus_lt_mono_r := Pos.sub_lt_mono_r (compat "8.3"). -Notation Pminus_decr := Pos.sub_decr (compat "8.3"). -Notation Pminus_xI_xI := Pos.sub_xI_xI (compat "8.3"). -Notation Pplus_minus_assoc := Pos.add_sub_assoc (compat "8.3"). -Notation Pminus_plus_distr := Pos.sub_add_distr (compat "8.3"). -Notation Pminus_minus_distr := Pos.sub_sub_distr (compat "8.3"). -Notation Pminus_mask_Lt := Pos.sub_mask_neg (compat "8.3"). -Notation Pminus_Lt := Pos.sub_lt (compat "8.3"). -Notation Pminus_Eq := Pos.sub_diag (compat "8.3"). -Notation Psize_monotone := Pos.size_nat_monotone (compat "8.3"). -Notation Psize_pos_gt := Pos.size_gt (compat "8.3"). -Notation Psize_pos_le := Pos.size_le (compat "8.3"). + Pos.pred_double_xO_discr (only parsing). +Notation Psucc_not_one := Pos.succ_not_1 (only parsing). +Notation Ppred_succ := Pos.pred_succ (compat "8.6"). +Notation Psucc_pred := Pos.succ_pred_or (only parsing). +Notation Psucc_inj := Pos.succ_inj (compat "8.6"). +Notation Pplus_carry_spec := Pos.add_carry_spec (only parsing). +Notation Pplus_comm := Pos.add_comm (only parsing). +Notation Pplus_succ_permute_r := Pos.add_succ_r (only parsing). +Notation Pplus_succ_permute_l := Pos.add_succ_l (only parsing). +Notation Pplus_no_neutral := Pos.add_no_neutral (only parsing). +Notation Pplus_carry_plus := Pos.add_carry_add (only parsing). +Notation Pplus_reg_r := Pos.add_reg_r (only parsing). +Notation Pplus_reg_l := Pos.add_reg_l (only parsing). +Notation Pplus_carry_reg_r := Pos.add_carry_reg_r (only parsing). +Notation Pplus_carry_reg_l := Pos.add_carry_reg_l (only parsing). +Notation Pplus_assoc := Pos.add_assoc (only parsing). +Notation Pplus_xO := Pos.add_xO (only parsing). +Notation Pplus_xI_double_minus_one := Pos.add_xI_pred_double (only parsing). +Notation Pplus_xO_double_minus_one := Pos.add_xO_pred_double (only parsing). +Notation Pplus_diag := Pos.add_diag (only parsing). +Notation PeanoView := Pos.PeanoView (only parsing). +Notation PeanoOne := Pos.PeanoOne (only parsing). +Notation PeanoSucc := Pos.PeanoSucc (only parsing). +Notation PeanoView_rect := Pos.PeanoView_rect (only parsing). +Notation PeanoView_ind := Pos.PeanoView_ind (only parsing). +Notation PeanoView_rec := Pos.PeanoView_rec (only parsing). +Notation peanoView_xO := Pos.peanoView_xO (only parsing). +Notation peanoView_xI := Pos.peanoView_xI (only parsing). +Notation peanoView := Pos.peanoView (only parsing). +Notation PeanoView_iter := Pos.PeanoView_iter (only parsing). +Notation eq_dep_eq_positive := Pos.eq_dep_eq_positive (only parsing). +Notation PeanoViewUnique := Pos.PeanoViewUnique (only parsing). +Notation Prect := Pos.peano_rect (only parsing). +Notation Prect_succ := Pos.peano_rect_succ (only parsing). +Notation Prect_base := Pos.peano_rect_base (only parsing). +Notation Prec := Pos.peano_rec (only parsing). +Notation Pind := Pos.peano_ind (only parsing). +Notation Pcase := Pos.peano_case (only parsing). +Notation Pmult_1_r := Pos.mul_1_r (only parsing). +Notation Pmult_Sn_m := Pos.mul_succ_l (only parsing). +Notation Pmult_xO_permute_r := Pos.mul_xO_r (only parsing). +Notation Pmult_xI_permute_r := Pos.mul_xI_r (only parsing). +Notation Pmult_comm := Pos.mul_comm (only parsing). +Notation Pmult_plus_distr_l := Pos.mul_add_distr_l (only parsing). +Notation Pmult_plus_distr_r := Pos.mul_add_distr_r (only parsing). +Notation Pmult_assoc := Pos.mul_assoc (only parsing). +Notation Pmult_xI_mult_xO_discr := Pos.mul_xI_mul_xO_discr (only parsing). +Notation Pmult_xO_discr := Pos.mul_xO_discr (only parsing). +Notation Pmult_reg_r := Pos.mul_reg_r (only parsing). +Notation Pmult_reg_l := Pos.mul_reg_l (only parsing). +Notation Pmult_1_inversion_l := Pos.mul_eq_1_l (only parsing). +Notation Psquare_xO := Pos.square_xO (compat "8.6"). +Notation Psquare_xI := Pos.square_xI (compat "8.6"). +Notation iter_pos_swap_gen := Pos.iter_swap_gen (only parsing). +Notation iter_pos_swap := Pos.iter_swap (only parsing). +Notation iter_pos_succ := Pos.iter_succ (only parsing). +Notation iter_pos_plus := Pos.iter_add (only parsing). +Notation iter_pos_invariant := Pos.iter_invariant (only parsing). +Notation Ppow_1_r := Pos.pow_1_r (compat "8.6"). +Notation Ppow_succ_r := Pos.pow_succ_r (compat "8.6"). +Notation Peqb_refl := Pos.eqb_refl (compat "8.6"). +Notation Peqb_eq := Pos.eqb_eq (compat "8.6"). +Notation Pcompare_refl_id := Pos.compare_cont_refl (only parsing). +Notation Pcompare_eq_iff := Pos.compare_eq_iff (only parsing). +Notation Pcompare_Gt_Lt := Pos.compare_cont_Gt_Lt (only parsing). +Notation Pcompare_eq_Lt := Pos.compare_lt_iff (only parsing). +Notation Pcompare_Lt_Gt := Pos.compare_cont_Lt_Gt (only parsing). + +Notation Pcompare_antisym := Pos.compare_cont_antisym (only parsing). +Notation ZC1 := Pos.gt_lt (only parsing). +Notation ZC2 := Pos.lt_gt (only parsing). +Notation Pcompare_spec := Pos.compare_spec (compat "8.6"). +Notation Pcompare_p_Sp := Pos.lt_succ_diag_r (only parsing). +Notation Pcompare_succ_succ := Pos.compare_succ_succ (compat "8.6"). +Notation Pcompare_1 := Pos.nlt_1_r (only parsing). +Notation Plt_1 := Pos.nlt_1_r (only parsing). +Notation Plt_1_succ := Pos.lt_1_succ (compat "8.6"). +Notation Plt_lt_succ := Pos.lt_lt_succ (compat "8.6"). +Notation Plt_irrefl := Pos.lt_irrefl (compat "8.6"). +Notation Plt_trans := Pos.lt_trans (compat "8.6"). +Notation Plt_ind := Pos.lt_ind (compat "8.6"). +Notation Ple_lteq := Pos.le_lteq (compat "8.6"). +Notation Ple_refl := Pos.le_refl (compat "8.6"). +Notation Ple_lt_trans := Pos.le_lt_trans (compat "8.6"). +Notation Plt_le_trans := Pos.lt_le_trans (compat "8.6"). +Notation Ple_trans := Pos.le_trans (compat "8.6"). +Notation Plt_succ_r := Pos.lt_succ_r (compat "8.6"). +Notation Ple_succ_l := Pos.le_succ_l (compat "8.6"). +Notation Pplus_compare_mono_l := Pos.add_compare_mono_l (only parsing). +Notation Pplus_compare_mono_r := Pos.add_compare_mono_r (only parsing). +Notation Pplus_lt_mono_l := Pos.add_lt_mono_l (only parsing). +Notation Pplus_lt_mono_r := Pos.add_lt_mono_r (only parsing). +Notation Pplus_lt_mono := Pos.add_lt_mono (only parsing). +Notation Pplus_le_mono_l := Pos.add_le_mono_l (only parsing). +Notation Pplus_le_mono_r := Pos.add_le_mono_r (only parsing). +Notation Pplus_le_mono := Pos.add_le_mono (only parsing). +Notation Pmult_compare_mono_l := Pos.mul_compare_mono_l (only parsing). +Notation Pmult_compare_mono_r := Pos.mul_compare_mono_r (only parsing). +Notation Pmult_lt_mono_l := Pos.mul_lt_mono_l (only parsing). +Notation Pmult_lt_mono_r := Pos.mul_lt_mono_r (only parsing). +Notation Pmult_lt_mono := Pos.mul_lt_mono (only parsing). +Notation Pmult_le_mono_l := Pos.mul_le_mono_l (only parsing). +Notation Pmult_le_mono_r := Pos.mul_le_mono_r (only parsing). +Notation Pmult_le_mono := Pos.mul_le_mono (only parsing). +Notation Plt_plus_r := Pos.lt_add_r (only parsing). +Notation Plt_not_plus_l := Pos.lt_not_add_l (only parsing). +Notation Ppow_gt_1 := Pos.pow_gt_1 (compat "8.6"). +Notation Ppred_mask := Pos.pred_mask (compat "8.6"). +Notation Pminus_mask_succ_r := Pos.sub_mask_succ_r (only parsing). +Notation Pminus_mask_carry_spec := Pos.sub_mask_carry_spec (only parsing). +Notation Pminus_succ_r := Pos.sub_succ_r (only parsing). +Notation Pminus_mask_diag := Pos.sub_mask_diag (only parsing). + +Notation Pplus_minus_eq := Pos.add_sub (only parsing). +Notation Pmult_minus_distr_l := Pos.mul_sub_distr_l (only parsing). +Notation Pminus_lt_mono_l := Pos.sub_lt_mono_l (only parsing). +Notation Pminus_compare_mono_l := Pos.sub_compare_mono_l (only parsing). +Notation Pminus_compare_mono_r := Pos.sub_compare_mono_r (only parsing). +Notation Pminus_lt_mono_r := Pos.sub_lt_mono_r (only parsing). +Notation Pminus_decr := Pos.sub_decr (only parsing). +Notation Pminus_xI_xI := Pos.sub_xI_xI (only parsing). +Notation Pplus_minus_assoc := Pos.add_sub_assoc (only parsing). +Notation Pminus_plus_distr := Pos.sub_add_distr (only parsing). +Notation Pminus_minus_distr := Pos.sub_sub_distr (only parsing). +Notation Pminus_mask_Lt := Pos.sub_mask_neg (only parsing). +Notation Pminus_Lt := Pos.sub_lt (only parsing). +Notation Pminus_Eq := Pos.sub_diag (only parsing). +Notation Psize_monotone := Pos.size_nat_monotone (only parsing). +Notation Psize_pos_gt := Pos.size_gt (only parsing). +Notation Psize_pos_le := Pos.size_le (only parsing). (** More complex compatibility facts, expressed as lemmas (to preserve scopes for instance) *) diff --git a/theories/PArith/Pnat.v b/theories/PArith/Pnat.v index d7880438d..26aba87fb 100644 --- a/theories/PArith/Pnat.v +++ b/theories/PArith/Pnat.v @@ -384,36 +384,36 @@ End SuccNat2Pos. (** For compatibility, old names and old-style lemmas *) -Notation Psucc_S := Pos2Nat.inj_succ (compat "8.3"). -Notation Pplus_plus := Pos2Nat.inj_add (compat "8.3"). -Notation Pmult_mult := Pos2Nat.inj_mul (compat "8.3"). -Notation Pcompare_nat_compare := Pos2Nat.inj_compare (compat "8.3"). -Notation nat_of_P_xH := Pos2Nat.inj_1 (compat "8.3"). -Notation nat_of_P_xO := Pos2Nat.inj_xO (compat "8.3"). -Notation nat_of_P_xI := Pos2Nat.inj_xI (compat "8.3"). -Notation nat_of_P_is_S := Pos2Nat.is_succ (compat "8.3"). -Notation nat_of_P_pos := Pos2Nat.is_pos (compat "8.3"). -Notation nat_of_P_inj_iff := Pos2Nat.inj_iff (compat "8.3"). -Notation nat_of_P_inj := Pos2Nat.inj (compat "8.3"). -Notation Plt_lt := Pos2Nat.inj_lt (compat "8.3"). -Notation Pgt_gt := Pos2Nat.inj_gt (compat "8.3"). -Notation Ple_le := Pos2Nat.inj_le (compat "8.3"). -Notation Pge_ge := Pos2Nat.inj_ge (compat "8.3"). -Notation Pminus_minus := Pos2Nat.inj_sub (compat "8.3"). -Notation iter_nat_of_P := @Pos2Nat.inj_iter (compat "8.3"). - -Notation nat_of_P_of_succ_nat := SuccNat2Pos.id_succ (compat "8.3"). -Notation P_of_succ_nat_of_P := Pos2SuccNat.id_succ (compat "8.3"). - -Notation nat_of_P_succ_morphism := Pos2Nat.inj_succ (compat "8.3"). -Notation nat_of_P_plus_morphism := Pos2Nat.inj_add (compat "8.3"). -Notation nat_of_P_mult_morphism := Pos2Nat.inj_mul (compat "8.3"). -Notation nat_of_P_compare_morphism := Pos2Nat.inj_compare (compat "8.3"). -Notation lt_O_nat_of_P := Pos2Nat.is_pos (compat "8.3"). -Notation ZL4 := Pos2Nat.is_succ (compat "8.3"). -Notation nat_of_P_o_P_of_succ_nat_eq_succ := SuccNat2Pos.id_succ (compat "8.3"). -Notation P_of_succ_nat_o_nat_of_P_eq_succ := Pos2SuccNat.id_succ (compat "8.3"). -Notation pred_o_P_of_succ_nat_o_nat_of_P_eq_id := Pos2SuccNat.pred_id (compat "8.3"). +Notation Psucc_S := Pos2Nat.inj_succ (only parsing). +Notation Pplus_plus := Pos2Nat.inj_add (only parsing). +Notation Pmult_mult := Pos2Nat.inj_mul (only parsing). +Notation Pcompare_nat_compare := Pos2Nat.inj_compare (only parsing). +Notation nat_of_P_xH := Pos2Nat.inj_1 (only parsing). +Notation nat_of_P_xO := Pos2Nat.inj_xO (only parsing). +Notation nat_of_P_xI := Pos2Nat.inj_xI (only parsing). +Notation nat_of_P_is_S := Pos2Nat.is_succ (only parsing). +Notation nat_of_P_pos := Pos2Nat.is_pos (only parsing). +Notation nat_of_P_inj_iff := Pos2Nat.inj_iff (only parsing). +Notation nat_of_P_inj := Pos2Nat.inj (only parsing). +Notation Plt_lt := Pos2Nat.inj_lt (only parsing). +Notation Pgt_gt := Pos2Nat.inj_gt (only parsing). +Notation Ple_le := Pos2Nat.inj_le (only parsing). +Notation Pge_ge := Pos2Nat.inj_ge (only parsing). +Notation Pminus_minus := Pos2Nat.inj_sub (only parsing). +Notation iter_nat_of_P := @Pos2Nat.inj_iter (only parsing). + +Notation nat_of_P_of_succ_nat := SuccNat2Pos.id_succ (only parsing). +Notation P_of_succ_nat_of_P := Pos2SuccNat.id_succ (only parsing). + +Notation nat_of_P_succ_morphism := Pos2Nat.inj_succ (only parsing). +Notation nat_of_P_plus_morphism := Pos2Nat.inj_add (only parsing). +Notation nat_of_P_mult_morphism := Pos2Nat.inj_mul (only parsing). +Notation nat_of_P_compare_morphism := Pos2Nat.inj_compare (only parsing). +Notation lt_O_nat_of_P := Pos2Nat.is_pos (only parsing). +Notation ZL4 := Pos2Nat.is_succ (only parsing). +Notation nat_of_P_o_P_of_succ_nat_eq_succ := SuccNat2Pos.id_succ (only parsing). +Notation P_of_succ_nat_o_nat_of_P_eq_succ := Pos2SuccNat.id_succ (only parsing). +Notation pred_o_P_of_succ_nat_o_nat_of_P_eq_id := Pos2SuccNat.pred_id (only parsing). Lemma nat_of_P_minus_morphism p q : Pos.compare_cont Eq p q = Gt -> diff --git a/theories/QArith/Qreduction.v b/theories/QArith/Qreduction.v index e8baccbc8..7b08515d2 100644 --- a/theories/QArith/Qreduction.v +++ b/theories/QArith/Qreduction.v @@ -13,8 +13,8 @@ Require Export QArith_base. Require Import Znumtheory. -Notation Z2P := Z.to_pos (compat "8.3"). -Notation Z2P_correct := Z2Pos.id (compat "8.3"). +Notation Z2P := Z.to_pos (only parsing). +Notation Z2P_correct := Z2Pos.id (only parsing). (** Simplification of fractions using [Z.gcd]. This version can compute within Coq. *) diff --git a/theories/Reals/RIneq.v b/theories/Reals/RIneq.v index ddf2d4ebf..59a104965 100644 --- a/theories/Reals/RIneq.v +++ b/theories/Reals/RIneq.v @@ -1613,6 +1613,9 @@ Proof. Qed. Hint Resolve mult_INR: real. +Lemma pow_INR (m n: nat) : INR (m ^ n) = pow (INR m) n. +Proof. now induction n as [|n IHn];[ | simpl; rewrite mult_INR, IHn]. Qed. + (*********) Lemma lt_0_INR : forall n:nat, (0 < n)%nat -> 0 < INR n. Proof. @@ -2026,7 +2029,7 @@ Qed. Lemma R_rm : ring_morph 0%R 1%R Rplus Rmult Rminus Ropp eq - 0%Z 1%Z Zplus Zmult Zminus Zopp Zeq_bool IZR. + 0%Z 1%Z Zplus Zmult Zminus Z.opp Zeq_bool IZR. Proof. constructor ; try easy. exact plus_IZR. diff --git a/theories/Reals/Rbasic_fun.v b/theories/Reals/Rbasic_fun.v index bceb4a6cd..aa886cee0 100644 --- a/theories/Reals/Rbasic_fun.v +++ b/theories/Reals/Rbasic_fun.v @@ -611,7 +611,7 @@ Qed. Lemma Rabs_Zabs : forall z:Z, Rabs (IZR z) = IZR (Z.abs z). Proof. - intros z; case z; unfold Zabs. + intros z; case z; unfold Z.abs. apply Rabs_R0. now intros p0; apply Rabs_pos_eq, (IZR_le 0). unfold IZR at 1. diff --git a/theories/Reals/Rlogic.v b/theories/Reals/Rlogic.v index 59604516f..04f13477c 100644 --- a/theories/Reals/Rlogic.v +++ b/theories/Reals/Rlogic.v @@ -65,7 +65,7 @@ destruct (Rle_lt_dec l 0) as [Hl|Hl]. now apply Rinv_0_lt_compat. now apply Hnp. left. -set (N := Zabs_nat (up (/l) - 2)). +set (N := Z.abs_nat (up (/l) - 2)). assert (H1l: (1 <= /l)%R). rewrite <- Rinv_1. apply Rinv_le_contravar with (1 := Hl). @@ -77,7 +77,7 @@ assert (HN: (INR N + 1 = IZR (up (/ l)) - 1)%R). rewrite inj_Zabs_nat. replace (IZR (up (/ l)) - 1)%R with (IZR (up (/ l) - 2) + 1)%R. apply (f_equal (fun v => IZR v + 1)%R). - apply Zabs_eq. + apply Z.abs_eq. apply Zle_minus_le_0. apply (Zlt_le_succ 1). apply lt_IZR. diff --git a/theories/Reals/Rpower.v b/theories/Reals/Rpower.v index ae2e7772b..c6fac951b 100644 --- a/theories/Reals/Rpower.v +++ b/theories/Reals/Rpower.v @@ -433,9 +433,9 @@ Proof. Qed. Theorem Rpower_lt : - forall x y z:R, 1 < x -> 0 <= y -> y < z -> x ^R y < x ^R z. + forall x y z:R, 1 < x -> y < z -> x ^R y < x ^R z. Proof. - intros x y z H H0 H1. + intros x y z H H1. unfold Rpower. apply exp_increasing. apply Rmult_lt_compat_r. @@ -490,11 +490,13 @@ Proof. Qed. Theorem Rle_Rpower : - forall e n m:R, 1 < e -> 0 <= n -> n <= m -> e ^R n <= e ^R m. + forall e n m:R, 1 <= e -> n <= m -> e ^R n <= e ^R m. Proof. - intros e n m H H0 H1; case H1. - intros H2; left; apply Rpower_lt; assumption. - intros H2; rewrite H2; right; reflexivity. + intros e n m [H | H]; intros H1. + case H1. + intros H2; left; apply Rpower_lt; assumption. + intros H2; rewrite H2; right; reflexivity. + now rewrite <- H; unfold Rpower; rewrite ln_1, !Rmult_0_r; apply Rle_refl. Qed. Theorem ln_lt_2 : / 2 < ln 2. @@ -709,13 +711,18 @@ intros x y z x0 y0; unfold Rpower. rewrite <- exp_plus, ln_mult, Rmult_plus_distr_l; auto. Qed. -Lemma Rle_Rpower_l a b c: 0 <= c -> 0 < a <= b -> Rpower a c <= Rpower b c. +Lemma Rlt_Rpower_l a b c: 0 < c -> 0 < a < b -> a ^R c < b ^R c. +Proof. +intros c0 [a0 ab]; apply exp_increasing. +now apply Rmult_lt_compat_l; auto; apply ln_increasing; fourier. +Qed. + +Lemma Rle_Rpower_l a b c: 0 <= c -> 0 < a <= b -> a ^R c <= b ^R c. Proof. intros [c0 | c0]; [ | intros; rewrite <- c0, !Rpower_O; [apply Rle_refl | |] ]. intros [a0 [ab|ab]]. - left; apply exp_increasing. - now apply Rmult_lt_compat_l; auto; apply ln_increasing; fourier. + now apply Rlt_le, Rlt_Rpower_l;[ | split]; fourier. rewrite ab; apply Rle_refl. apply Rlt_le_trans with a; tauto. tauto. diff --git a/theories/Structures/OrderedTypeEx.v b/theories/Structures/OrderedTypeEx.v index 5f635847a..f2a9a5691 100644 --- a/theories/Structures/OrderedTypeEx.v +++ b/theories/Structures/OrderedTypeEx.v @@ -57,7 +57,7 @@ Module Nat_as_OT <: UsualOrderedType. Definition compare x y : Compare lt eq x y. Proof. - case_eq (nat_compare x y); intro. + case_eq (Nat.compare x y); intro. - apply EQ. now apply nat_compare_eq. - apply LT. now apply nat_compare_Lt_lt. - apply GT. now apply nat_compare_Gt_gt. diff --git a/theories/Vectors/VectorDef.v b/theories/Vectors/VectorDef.v index dffb640ba..f6f3cafa2 100644 --- a/theories/Vectors/VectorDef.v +++ b/theories/Vectors/VectorDef.v @@ -307,12 +307,10 @@ End VECTORLIST. Module VectorNotations. Delimit Scope vector_scope with vector. Notation "[ ]" := [] (format "[ ]") : vector_scope. -Notation "[]" := [] (compat "8.5") : vector_scope. Notation "h :: t" := (h :: t) (at level 60, right associativity) : vector_scope. Notation "[ x ]" := (x :: []) : vector_scope. Notation "[ x ; y ; .. ; z ]" := (cons _ x _ (cons _ y _ .. (cons _ z _ (nil _)) ..)) : vector_scope. -Notation "[ x ; .. ; y ]" := (cons _ x _ .. (cons _ y _ (nil _)) ..) (compat "8.4") : vector_scope. Notation "v [@ p ]" := (nth v p) (at level 1, format "v [@ p ]") : vector_scope. Open Scope vector_scope. End VectorNotations. diff --git a/theories/ZArith/BinInt.v b/theories/ZArith/BinInt.v index e14cc3572..cf7397b57 100644 --- a/theories/ZArith/BinInt.v +++ b/theories/ZArith/BinInt.v @@ -1567,94 +1567,94 @@ End Z2Pos. (** Compatibility Notations *) -Notation Zdouble_plus_one := Z.succ_double (compat "8.3"). -Notation Zdouble_minus_one := Z.pred_double (compat "8.3"). -Notation Zdouble := Z.double (compat "8.3"). -Notation ZPminus := Z.pos_sub (compat "8.3"). -Notation Zsucc' := Z.succ (compat "8.3"). -Notation Zpred' := Z.pred (compat "8.3"). -Notation Zplus' := Z.add (compat "8.3"). -Notation Zplus := Z.add (compat "8.3"). (* Slightly incompatible *) -Notation Zopp := Z.opp (compat "8.3"). -Notation Zsucc := Z.succ (compat "8.3"). -Notation Zpred := Z.pred (compat "8.3"). -Notation Zminus := Z.sub (compat "8.3"). -Notation Zmult := Z.mul (compat "8.3"). -Notation Zcompare := Z.compare (compat "8.3"). -Notation Zsgn := Z.sgn (compat "8.3"). -Notation Zle := Z.le (compat "8.3"). -Notation Zge := Z.ge (compat "8.3"). -Notation Zlt := Z.lt (compat "8.3"). -Notation Zgt := Z.gt (compat "8.3"). -Notation Zmax := Z.max (compat "8.3"). -Notation Zmin := Z.min (compat "8.3"). -Notation Zabs := Z.abs (compat "8.3"). -Notation Zabs_nat := Z.abs_nat (compat "8.3"). -Notation Zabs_N := Z.abs_N (compat "8.3"). -Notation Z_of_nat := Z.of_nat (compat "8.3"). -Notation Z_of_N := Z.of_N (compat "8.3"). - -Notation Zind := Z.peano_ind (compat "8.3"). -Notation Zopp_0 := Z.opp_0 (compat "8.3"). -Notation Zopp_involutive := Z.opp_involutive (compat "8.3"). -Notation Zopp_inj := Z.opp_inj (compat "8.3"). -Notation Zplus_0_l := Z.add_0_l (compat "8.3"). -Notation Zplus_0_r := Z.add_0_r (compat "8.3"). -Notation Zplus_comm := Z.add_comm (compat "8.3"). -Notation Zopp_plus_distr := Z.opp_add_distr (compat "8.3"). -Notation Zopp_succ := Z.opp_succ (compat "8.3"). -Notation Zplus_opp_r := Z.add_opp_diag_r (compat "8.3"). -Notation Zplus_opp_l := Z.add_opp_diag_l (compat "8.3"). -Notation Zplus_assoc := Z.add_assoc (compat "8.3"). -Notation Zplus_permute := Z.add_shuffle3 (compat "8.3"). -Notation Zplus_reg_l := Z.add_reg_l (compat "8.3"). -Notation Zplus_succ_l := Z.add_succ_l (compat "8.3"). -Notation Zplus_succ_comm := Z.add_succ_comm (compat "8.3"). -Notation Zsucc_discr := Z.neq_succ_diag_r (compat "8.3"). -Notation Zsucc_inj := Z.succ_inj (compat "8.3"). -Notation Zsucc'_inj := Z.succ_inj (compat "8.3"). -Notation Zsucc'_pred' := Z.succ_pred (compat "8.3"). -Notation Zpred'_succ' := Z.pred_succ (compat "8.3"). -Notation Zpred'_inj := Z.pred_inj (compat "8.3"). -Notation Zsucc'_discr := Z.neq_succ_diag_r (compat "8.3"). -Notation Zminus_0_r := Z.sub_0_r (compat "8.3"). -Notation Zminus_diag := Z.sub_diag (compat "8.3"). -Notation Zminus_plus_distr := Z.sub_add_distr (compat "8.3"). -Notation Zminus_succ_r := Z.sub_succ_r (compat "8.3"). -Notation Zminus_plus := Z.add_simpl_l (compat "8.3"). -Notation Zmult_0_l := Z.mul_0_l (compat "8.3"). -Notation Zmult_0_r := Z.mul_0_r (compat "8.3"). -Notation Zmult_1_l := Z.mul_1_l (compat "8.3"). -Notation Zmult_1_r := Z.mul_1_r (compat "8.3"). -Notation Zmult_comm := Z.mul_comm (compat "8.3"). -Notation Zmult_assoc := Z.mul_assoc (compat "8.3"). -Notation Zmult_permute := Z.mul_shuffle3 (compat "8.3"). -Notation Zmult_1_inversion_l := Z.mul_eq_1 (compat "8.3"). -Notation Zdouble_mult := Z.double_spec (compat "8.3"). -Notation Zdouble_plus_one_mult := Z.succ_double_spec (compat "8.3"). -Notation Zopp_mult_distr_l_reverse := Z.mul_opp_l (compat "8.3"). -Notation Zmult_opp_opp := Z.mul_opp_opp (compat "8.3"). -Notation Zmult_opp_comm := Z.mul_opp_comm (compat "8.3"). -Notation Zopp_eq_mult_neg_1 := Z.opp_eq_mul_m1 (compat "8.3"). -Notation Zmult_plus_distr_r := Z.mul_add_distr_l (compat "8.3"). -Notation Zmult_plus_distr_l := Z.mul_add_distr_r (compat "8.3"). -Notation Zmult_minus_distr_r := Z.mul_sub_distr_r (compat "8.3"). -Notation Zmult_reg_l := Z.mul_reg_l (compat "8.3"). -Notation Zmult_reg_r := Z.mul_reg_r (compat "8.3"). -Notation Zmult_succ_l := Z.mul_succ_l (compat "8.3"). -Notation Zmult_succ_r := Z.mul_succ_r (compat "8.3"). - -Notation Zpos_xI := Pos2Z.inj_xI (compat "8.3"). -Notation Zpos_xO := Pos2Z.inj_xO (compat "8.3"). -Notation Zneg_xI := Pos2Z.neg_xI (compat "8.3"). -Notation Zneg_xO := Pos2Z.neg_xO (compat "8.3"). -Notation Zopp_neg := Pos2Z.opp_neg (compat "8.3"). -Notation Zpos_succ_morphism := Pos2Z.inj_succ (compat "8.3"). -Notation Zpos_mult_morphism := Pos2Z.inj_mul (compat "8.3"). -Notation Zpos_minus_morphism := Pos2Z.inj_sub (compat "8.3"). -Notation Zpos_eq_rev := Pos2Z.inj (compat "8.3"). -Notation Zpos_plus_distr := Pos2Z.inj_add (compat "8.3"). -Notation Zneg_plus_distr := Pos2Z.add_neg_neg (compat "8.3"). +Notation Zdouble_plus_one := Z.succ_double (only parsing). +Notation Zdouble_minus_one := Z.pred_double (only parsing). +Notation Zdouble := Z.double (compat "8.6"). +Notation ZPminus := Z.pos_sub (only parsing). +Notation Zsucc' := Z.succ (compat "8.6"). +Notation Zpred' := Z.pred (compat "8.6"). +Notation Zplus' := Z.add (compat "8.6"). +Notation Zplus := Z.add (only parsing). (* Slightly incompatible *) +Notation Zopp := Z.opp (compat "8.6"). +Notation Zsucc := Z.succ (compat "8.6"). +Notation Zpred := Z.pred (compat "8.6"). +Notation Zminus := Z.sub (only parsing). +Notation Zmult := Z.mul (only parsing). +Notation Zcompare := Z.compare (compat "8.6"). +Notation Zsgn := Z.sgn (compat "8.6"). +Notation Zle := Z.le (compat "8.6"). +Notation Zge := Z.ge (compat "8.6"). +Notation Zlt := Z.lt (compat "8.6"). +Notation Zgt := Z.gt (compat "8.6"). +Notation Zmax := Z.max (compat "8.6"). +Notation Zmin := Z.min (compat "8.6"). +Notation Zabs := Z.abs (compat "8.6"). +Notation Zabs_nat := Z.abs_nat (compat "8.6"). +Notation Zabs_N := Z.abs_N (compat "8.6"). +Notation Z_of_nat := Z.of_nat (only parsing). +Notation Z_of_N := Z.of_N (only parsing). + +Notation Zind := Z.peano_ind (only parsing). +Notation Zopp_0 := Z.opp_0 (compat "8.6"). +Notation Zopp_involutive := Z.opp_involutive (compat "8.6"). +Notation Zopp_inj := Z.opp_inj (compat "8.6"). +Notation Zplus_0_l := Z.add_0_l (only parsing). +Notation Zplus_0_r := Z.add_0_r (only parsing). +Notation Zplus_comm := Z.add_comm (only parsing). +Notation Zopp_plus_distr := Z.opp_add_distr (only parsing). +Notation Zopp_succ := Z.opp_succ (compat "8.6"). +Notation Zplus_opp_r := Z.add_opp_diag_r (only parsing). +Notation Zplus_opp_l := Z.add_opp_diag_l (only parsing). +Notation Zplus_assoc := Z.add_assoc (only parsing). +Notation Zplus_permute := Z.add_shuffle3 (only parsing). +Notation Zplus_reg_l := Z.add_reg_l (only parsing). +Notation Zplus_succ_l := Z.add_succ_l (only parsing). +Notation Zplus_succ_comm := Z.add_succ_comm (only parsing). +Notation Zsucc_discr := Z.neq_succ_diag_r (only parsing). +Notation Zsucc_inj := Z.succ_inj (compat "8.6"). +Notation Zsucc'_inj := Z.succ_inj (compat "8.6"). +Notation Zsucc'_pred' := Z.succ_pred (compat "8.6"). +Notation Zpred'_succ' := Z.pred_succ (compat "8.6"). +Notation Zpred'_inj := Z.pred_inj (compat "8.6"). +Notation Zsucc'_discr := Z.neq_succ_diag_r (only parsing). +Notation Zminus_0_r := Z.sub_0_r (only parsing). +Notation Zminus_diag := Z.sub_diag (only parsing). +Notation Zminus_plus_distr := Z.sub_add_distr (only parsing). +Notation Zminus_succ_r := Z.sub_succ_r (only parsing). +Notation Zminus_plus := Z.add_simpl_l (only parsing). +Notation Zmult_0_l := Z.mul_0_l (only parsing). +Notation Zmult_0_r := Z.mul_0_r (only parsing). +Notation Zmult_1_l := Z.mul_1_l (only parsing). +Notation Zmult_1_r := Z.mul_1_r (only parsing). +Notation Zmult_comm := Z.mul_comm (only parsing). +Notation Zmult_assoc := Z.mul_assoc (only parsing). +Notation Zmult_permute := Z.mul_shuffle3 (only parsing). +Notation Zmult_1_inversion_l := Z.mul_eq_1 (only parsing). +Notation Zdouble_mult := Z.double_spec (only parsing). +Notation Zdouble_plus_one_mult := Z.succ_double_spec (only parsing). +Notation Zopp_mult_distr_l_reverse := Z.mul_opp_l (only parsing). +Notation Zmult_opp_opp := Z.mul_opp_opp (only parsing). +Notation Zmult_opp_comm := Z.mul_opp_comm (only parsing). +Notation Zopp_eq_mult_neg_1 := Z.opp_eq_mul_m1 (only parsing). +Notation Zmult_plus_distr_r := Z.mul_add_distr_l (only parsing). +Notation Zmult_plus_distr_l := Z.mul_add_distr_r (only parsing). +Notation Zmult_minus_distr_r := Z.mul_sub_distr_r (only parsing). +Notation Zmult_reg_l := Z.mul_reg_l (only parsing). +Notation Zmult_reg_r := Z.mul_reg_r (only parsing). +Notation Zmult_succ_l := Z.mul_succ_l (only parsing). +Notation Zmult_succ_r := Z.mul_succ_r (only parsing). + +Notation Zpos_xI := Pos2Z.inj_xI (only parsing). +Notation Zpos_xO := Pos2Z.inj_xO (only parsing). +Notation Zneg_xI := Pos2Z.neg_xI (only parsing). +Notation Zneg_xO := Pos2Z.neg_xO (only parsing). +Notation Zopp_neg := Pos2Z.opp_neg (only parsing). +Notation Zpos_succ_morphism := Pos2Z.inj_succ (only parsing). +Notation Zpos_mult_morphism := Pos2Z.inj_mul (only parsing). +Notation Zpos_minus_morphism := Pos2Z.inj_sub (only parsing). +Notation Zpos_eq_rev := Pos2Z.inj (only parsing). +Notation Zpos_plus_distr := Pos2Z.inj_add (only parsing). +Notation Zneg_plus_distr := Pos2Z.add_neg_neg (only parsing). Notation Z := Z (only parsing). Notation Z_rect := Z_rect (only parsing). diff --git a/theories/ZArith/Int.v b/theories/ZArith/Int.v index f4094f609..2f3bf9a32 100644 --- a/theories/ZArith/Int.v +++ b/theories/ZArith/Int.v @@ -454,7 +454,7 @@ Module Z_as_Int <: Int. Proof. reflexivity. Qed. (** Compatibility notations for Coq v8.4 *) - Notation plus := add (compat "8.4"). - Notation minus := sub (compat "8.4"). - Notation mult := mul (compat "8.4"). + Notation plus := add (only parsing). + Notation minus := sub (only parsing). + Notation mult := mul (only parsing). End Z_as_Int. diff --git a/theories/ZArith/ZArith_dec.v b/theories/ZArith/ZArith_dec.v index 23112abf9..9bcdb73af 100644 --- a/theories/ZArith/ZArith_dec.v +++ b/theories/ZArith/ZArith_dec.v @@ -34,7 +34,7 @@ Lemma Zcompare_rec (P:Set) (n m:Z) : ((n ?= m) = Eq -> P) -> ((n ?= m) = Lt -> P) -> ((n ?= m) = Gt -> P) -> P. Proof. apply Zcompare_rect. Defined. -Notation Z_eq_dec := Z.eq_dec (compat "8.3"). +Notation Z_eq_dec := Z.eq_dec (compat "8.6"). Section decidability. diff --git a/theories/ZArith/Zabs.v b/theories/ZArith/Zabs.v index 95620f810..0d8450e36 100644 --- a/theories/ZArith/Zabs.v +++ b/theories/ZArith/Zabs.v @@ -29,17 +29,17 @@ Local Open Scope Z_scope. (**********************************************************************) (** * Properties of absolute value *) -Notation Zabs_eq := Z.abs_eq (compat "8.3"). -Notation Zabs_non_eq := Z.abs_neq (compat "8.3"). -Notation Zabs_Zopp := Z.abs_opp (compat "8.3"). -Notation Zabs_pos := Z.abs_nonneg (compat "8.3"). -Notation Zabs_involutive := Z.abs_involutive (compat "8.3"). -Notation Zabs_eq_case := Z.abs_eq_cases (compat "8.3"). -Notation Zabs_triangle := Z.abs_triangle (compat "8.3"). -Notation Zsgn_Zabs := Z.sgn_abs (compat "8.3"). -Notation Zabs_Zsgn := Z.abs_sgn (compat "8.3"). -Notation Zabs_Zmult := Z.abs_mul (compat "8.3"). -Notation Zabs_square := Z.abs_square (compat "8.3"). +Notation Zabs_eq := Z.abs_eq (compat "8.6"). +Notation Zabs_non_eq := Z.abs_neq (only parsing). +Notation Zabs_Zopp := Z.abs_opp (only parsing). +Notation Zabs_pos := Z.abs_nonneg (only parsing). +Notation Zabs_involutive := Z.abs_involutive (compat "8.6"). +Notation Zabs_eq_case := Z.abs_eq_cases (only parsing). +Notation Zabs_triangle := Z.abs_triangle (compat "8.6"). +Notation Zsgn_Zabs := Z.sgn_abs (only parsing). +Notation Zabs_Zsgn := Z.abs_sgn (only parsing). +Notation Zabs_Zmult := Z.abs_mul (only parsing). +Notation Zabs_square := Z.abs_square (compat "8.6"). (** * Proving a property of the absolute value by cases *) @@ -70,11 +70,11 @@ Qed. (** * Some results about the sign function. *) -Notation Zsgn_Zmult := Z.sgn_mul (compat "8.3"). -Notation Zsgn_Zopp := Z.sgn_opp (compat "8.3"). -Notation Zsgn_pos := Z.sgn_pos_iff (compat "8.3"). -Notation Zsgn_neg := Z.sgn_neg_iff (compat "8.3"). -Notation Zsgn_null := Z.sgn_null_iff (compat "8.3"). +Notation Zsgn_Zmult := Z.sgn_mul (only parsing). +Notation Zsgn_Zopp := Z.sgn_opp (only parsing). +Notation Zsgn_pos := Z.sgn_pos_iff (only parsing). +Notation Zsgn_neg := Z.sgn_neg_iff (only parsing). +Notation Zsgn_null := Z.sgn_null_iff (only parsing). (** A characterization of the sign function: *) @@ -88,13 +88,13 @@ Qed. (** Compatibility *) -Notation inj_Zabs_nat := Zabs2Nat.id_abs (compat "8.3"). -Notation Zabs_nat_Z_of_nat := Zabs2Nat.id (compat "8.3"). -Notation Zabs_nat_mult := Zabs2Nat.inj_mul (compat "8.3"). -Notation Zabs_nat_Zsucc := Zabs2Nat.inj_succ (compat "8.3"). -Notation Zabs_nat_Zplus := Zabs2Nat.inj_add (compat "8.3"). -Notation Zabs_nat_Zminus := (fun n m => Zabs2Nat.inj_sub m n) (compat "8.3"). -Notation Zabs_nat_compare := Zabs2Nat.inj_compare (compat "8.3"). +Notation inj_Zabs_nat := Zabs2Nat.id_abs (only parsing). +Notation Zabs_nat_Z_of_nat := Zabs2Nat.id (only parsing). +Notation Zabs_nat_mult := Zabs2Nat.inj_mul (only parsing). +Notation Zabs_nat_Zsucc := Zabs2Nat.inj_succ (only parsing). +Notation Zabs_nat_Zplus := Zabs2Nat.inj_add (only parsing). +Notation Zabs_nat_Zminus := (fun n m => Zabs2Nat.inj_sub m n) (only parsing). +Notation Zabs_nat_compare := Zabs2Nat.inj_compare (only parsing). Lemma Zabs_nat_le n m : 0 <= n <= m -> (Z.abs_nat n <= Z.abs_nat m)%nat. Proof. diff --git a/theories/ZArith/Zbool.v b/theories/ZArith/Zbool.v index 89a681a58..632d41b6a 100644 --- a/theories/ZArith/Zbool.v +++ b/theories/ZArith/Zbool.v @@ -35,10 +35,10 @@ Definition Zeven_odd_bool (x:Z) := bool_of_sumbool (Zeven_odd_dec x). (**********************************************************************) (** * Boolean comparisons of binary integers *) -Notation Zle_bool := Z.leb (compat "8.3"). -Notation Zge_bool := Z.geb (compat "8.3"). -Notation Zlt_bool := Z.ltb (compat "8.3"). -Notation Zgt_bool := Z.gtb (compat "8.3"). +Notation Zle_bool := Z.leb (only parsing). +Notation Zge_bool := Z.geb (only parsing). +Notation Zlt_bool := Z.ltb (only parsing). +Notation Zgt_bool := Z.gtb (only parsing). (** We now provide a direct [Z.eqb] that doesn't refer to [Z.compare]. The old [Zeq_bool] is kept for compatibility. *) @@ -89,7 +89,7 @@ Proof. apply Z.leb_le. Qed. -Notation Zle_bool_refl := Z.leb_refl (compat "8.3"). +Notation Zle_bool_refl := Z.leb_refl (only parsing). Lemma Zle_bool_antisym n m : (n <=? m) = true -> (m <=? n) = true -> n = m. diff --git a/theories/ZArith/Zcompare.v b/theories/ZArith/Zcompare.v index dca53b29d..c8432e27b 100644 --- a/theories/ZArith/Zcompare.v +++ b/theories/ZArith/Zcompare.v @@ -183,18 +183,18 @@ Qed. (** Compatibility notations *) -Notation Zcompare_refl := Z.compare_refl (compat "8.3"). -Notation Zcompare_Eq_eq := Z.compare_eq (compat "8.3"). -Notation Zcompare_Eq_iff_eq := Z.compare_eq_iff (compat "8.3"). -Notation Zcompare_spec := Z.compare_spec (compat "8.3"). -Notation Zmin_l := Z.min_l (compat "8.3"). -Notation Zmin_r := Z.min_r (compat "8.3"). -Notation Zmax_l := Z.max_l (compat "8.3"). -Notation Zmax_r := Z.max_r (compat "8.3"). -Notation Zabs_eq := Z.abs_eq (compat "8.3"). -Notation Zabs_non_eq := Z.abs_neq (compat "8.3"). -Notation Zsgn_0 := Z.sgn_null (compat "8.3"). -Notation Zsgn_1 := Z.sgn_pos (compat "8.3"). -Notation Zsgn_m1 := Z.sgn_neg (compat "8.3"). +Notation Zcompare_refl := Z.compare_refl (compat "8.6"). +Notation Zcompare_Eq_eq := Z.compare_eq (only parsing). +Notation Zcompare_Eq_iff_eq := Z.compare_eq_iff (only parsing). +Notation Zcompare_spec := Z.compare_spec (compat "8.6"). +Notation Zmin_l := Z.min_l (compat "8.6"). +Notation Zmin_r := Z.min_r (compat "8.6"). +Notation Zmax_l := Z.max_l (compat "8.6"). +Notation Zmax_r := Z.max_r (compat "8.6"). +Notation Zabs_eq := Z.abs_eq (compat "8.6"). +Notation Zabs_non_eq := Z.abs_neq (only parsing). +Notation Zsgn_0 := Z.sgn_null (only parsing). +Notation Zsgn_1 := Z.sgn_pos (only parsing). +Notation Zsgn_m1 := Z.sgn_neg (only parsing). (** Not kept: Zcompare_egal_dec *) diff --git a/theories/ZArith/Zdiv.v b/theories/ZArith/Zdiv.v index 764608d76..15d0e4874 100644 --- a/theories/ZArith/Zdiv.v +++ b/theories/ZArith/Zdiv.v @@ -20,16 +20,16 @@ Local Open Scope Z_scope. (** The definition of the division is now in [BinIntDef], the initial specifications and properties are in [BinInt]. *) -Notation Zdiv_eucl_POS := Z.pos_div_eucl (compat "8.3"). -Notation Zdiv_eucl := Z.div_eucl (compat "8.3"). -Notation Zdiv := Z.div (compat "8.3"). -Notation Zmod := Z.modulo (compat "8.3"). - -Notation Zdiv_eucl_eq := Z.div_eucl_eq (compat "8.3"). -Notation Z_div_mod_eq_full := Z.div_mod (compat "8.3"). -Notation Zmod_POS_bound := Z.pos_div_eucl_bound (compat "8.3"). -Notation Zmod_pos_bound := Z.mod_pos_bound (compat "8.3"). -Notation Zmod_neg_bound := Z.mod_neg_bound (compat "8.3"). +Notation Zdiv_eucl_POS := Z.pos_div_eucl (only parsing). +Notation Zdiv_eucl := Z.div_eucl (compat "8.6"). +Notation Zdiv := Z.div (compat "8.6"). +Notation Zmod := Z.modulo (only parsing). + +Notation Zdiv_eucl_eq := Z.div_eucl_eq (compat "8.6"). +Notation Z_div_mod_eq_full := Z.div_mod (only parsing). +Notation Zmod_POS_bound := Z.pos_div_eucl_bound (only parsing). +Notation Zmod_pos_bound := Z.mod_pos_bound (only parsing). +Notation Zmod_neg_bound := Z.mod_neg_bound (only parsing). (** * Main division theorems *) diff --git a/theories/ZArith/Zeven.v b/theories/ZArith/Zeven.v index 6b43dfc68..00a58b517 100644 --- a/theories/ZArith/Zeven.v +++ b/theories/ZArith/Zeven.v @@ -60,8 +60,8 @@ Proof (Zodd_equiv n). (** Boolean tests of parity (now in BinInt.Z) *) -Notation Zeven_bool := Z.even (compat "8.3"). -Notation Zodd_bool := Z.odd (compat "8.3"). +Notation Zeven_bool := Z.even (only parsing). +Notation Zodd_bool := Z.odd (only parsing). Lemma Zeven_bool_iff n : Z.even n = true <-> Zeven n. Proof. @@ -132,17 +132,17 @@ Qed. Hint Unfold Zeven Zodd: zarith. -Notation Zeven_bool_succ := Z.even_succ (compat "8.3"). -Notation Zeven_bool_pred := Z.even_pred (compat "8.3"). -Notation Zodd_bool_succ := Z.odd_succ (compat "8.3"). -Notation Zodd_bool_pred := Z.odd_pred (compat "8.3"). +Notation Zeven_bool_succ := Z.even_succ (only parsing). +Notation Zeven_bool_pred := Z.even_pred (only parsing). +Notation Zodd_bool_succ := Z.odd_succ (only parsing). +Notation Zodd_bool_pred := Z.odd_pred (only parsing). (******************************************************************) (** * Definition of [Z.quot2], [Z.div2] and properties wrt [Zeven] and [Zodd] *) -Notation Zdiv2 := Z.div2 (compat "8.3"). -Notation Zquot2 := Z.quot2 (compat "8.3"). +Notation Zdiv2 := Z.div2 (compat "8.6"). +Notation Zquot2 := Z.quot2 (compat "8.6"). (** Properties of [Z.div2] *) diff --git a/theories/ZArith/Zmax.v b/theories/ZArith/Zmax.v index 38b875086..7f595fcfd 100644 --- a/theories/ZArith/Zmax.v +++ b/theories/ZArith/Zmax.v @@ -18,32 +18,32 @@ Local Open Scope Z_scope. (** Exact compatibility *) -Notation Zmax_case := Z.max_case (compat "8.3"). -Notation Zmax_case_strong := Z.max_case_strong (compat "8.3"). -Notation Zmax_right := Z.max_r (compat "8.3"). -Notation Zle_max_l := Z.le_max_l (compat "8.3"). -Notation Zle_max_r := Z.le_max_r (compat "8.3"). -Notation Zmax_lub := Z.max_lub (compat "8.3"). -Notation Zmax_lub_lt := Z.max_lub_lt (compat "8.3"). -Notation Zle_max_compat_r := Z.max_le_compat_r (compat "8.3"). -Notation Zle_max_compat_l := Z.max_le_compat_l (compat "8.3"). -Notation Zmax_idempotent := Z.max_id (compat "8.3"). -Notation Zmax_n_n := Z.max_id (compat "8.3"). -Notation Zmax_comm := Z.max_comm (compat "8.3"). -Notation Zmax_assoc := Z.max_assoc (compat "8.3"). -Notation Zmax_irreducible_dec := Z.max_dec (compat "8.3"). -Notation Zmax_le_prime := Z.max_le (compat "8.3"). -Notation Zsucc_max_distr := Z.succ_max_distr (compat "8.3"). -Notation Zmax_SS := Z.succ_max_distr (compat "8.3"). -Notation Zplus_max_distr_l := Z.add_max_distr_l (compat "8.3"). -Notation Zplus_max_distr_r := Z.add_max_distr_r (compat "8.3"). -Notation Zmax_plus := Z.add_max_distr_r (compat "8.3"). -Notation Zmax1 := Z.le_max_l (compat "8.3"). -Notation Zmax2 := Z.le_max_r (compat "8.3"). -Notation Zmax_irreducible_inf := Z.max_dec (compat "8.3"). -Notation Zmax_le_prime_inf := Z.max_le (compat "8.3"). -Notation Zpos_max := Pos2Z.inj_max (compat "8.3"). -Notation Zpos_minus := Pos2Z.inj_sub_max (compat "8.3"). +Notation Zmax_case := Z.max_case (compat "8.6"). +Notation Zmax_case_strong := Z.max_case_strong (compat "8.6"). +Notation Zmax_right := Z.max_r (only parsing). +Notation Zle_max_l := Z.le_max_l (compat "8.6"). +Notation Zle_max_r := Z.le_max_r (compat "8.6"). +Notation Zmax_lub := Z.max_lub (compat "8.6"). +Notation Zmax_lub_lt := Z.max_lub_lt (compat "8.6"). +Notation Zle_max_compat_r := Z.max_le_compat_r (only parsing). +Notation Zle_max_compat_l := Z.max_le_compat_l (only parsing). +Notation Zmax_idempotent := Z.max_id (only parsing). +Notation Zmax_n_n := Z.max_id (only parsing). +Notation Zmax_comm := Z.max_comm (compat "8.6"). +Notation Zmax_assoc := Z.max_assoc (compat "8.6"). +Notation Zmax_irreducible_dec := Z.max_dec (only parsing). +Notation Zmax_le_prime := Z.max_le (only parsing). +Notation Zsucc_max_distr := Z.succ_max_distr (compat "8.6"). +Notation Zmax_SS := Z.succ_max_distr (only parsing). +Notation Zplus_max_distr_l := Z.add_max_distr_l (only parsing). +Notation Zplus_max_distr_r := Z.add_max_distr_r (only parsing). +Notation Zmax_plus := Z.add_max_distr_r (only parsing). +Notation Zmax1 := Z.le_max_l (only parsing). +Notation Zmax2 := Z.le_max_r (only parsing). +Notation Zmax_irreducible_inf := Z.max_dec (only parsing). +Notation Zmax_le_prime_inf := Z.max_le (only parsing). +Notation Zpos_max := Pos2Z.inj_max (only parsing). +Notation Zpos_minus := Pos2Z.inj_sub_max (only parsing). (** Slightly different lemmas *) diff --git a/theories/ZArith/Zmin.v b/theories/ZArith/Zmin.v index c6d7355d2..6bc72227b 100644 --- a/theories/ZArith/Zmin.v +++ b/theories/ZArith/Zmin.v @@ -18,24 +18,24 @@ Local Open Scope Z_scope. (** Exact compatibility *) -Notation Zmin_case := Z.min_case (compat "8.3"). -Notation Zmin_case_strong := Z.min_case_strong (compat "8.3"). -Notation Zle_min_l := Z.le_min_l (compat "8.3"). -Notation Zle_min_r := Z.le_min_r (compat "8.3"). -Notation Zmin_glb := Z.min_glb (compat "8.3"). -Notation Zmin_glb_lt := Z.min_glb_lt (compat "8.3"). -Notation Zle_min_compat_r := Z.min_le_compat_r (compat "8.3"). -Notation Zle_min_compat_l := Z.min_le_compat_l (compat "8.3"). -Notation Zmin_idempotent := Z.min_id (compat "8.3"). -Notation Zmin_n_n := Z.min_id (compat "8.3"). -Notation Zmin_comm := Z.min_comm (compat "8.3"). -Notation Zmin_assoc := Z.min_assoc (compat "8.3"). -Notation Zmin_irreducible_inf := Z.min_dec (compat "8.3"). -Notation Zsucc_min_distr := Z.succ_min_distr (compat "8.3"). -Notation Zmin_SS := Z.succ_min_distr (compat "8.3"). -Notation Zplus_min_distr_r := Z.add_min_distr_r (compat "8.3"). -Notation Zmin_plus := Z.add_min_distr_r (compat "8.3"). -Notation Zpos_min := Pos2Z.inj_min (compat "8.3"). +Notation Zmin_case := Z.min_case (compat "8.6"). +Notation Zmin_case_strong := Z.min_case_strong (compat "8.6"). +Notation Zle_min_l := Z.le_min_l (compat "8.6"). +Notation Zle_min_r := Z.le_min_r (compat "8.6"). +Notation Zmin_glb := Z.min_glb (compat "8.6"). +Notation Zmin_glb_lt := Z.min_glb_lt (compat "8.6"). +Notation Zle_min_compat_r := Z.min_le_compat_r (only parsing). +Notation Zle_min_compat_l := Z.min_le_compat_l (only parsing). +Notation Zmin_idempotent := Z.min_id (only parsing). +Notation Zmin_n_n := Z.min_id (only parsing). +Notation Zmin_comm := Z.min_comm (compat "8.6"). +Notation Zmin_assoc := Z.min_assoc (compat "8.6"). +Notation Zmin_irreducible_inf := Z.min_dec (only parsing). +Notation Zsucc_min_distr := Z.succ_min_distr (compat "8.6"). +Notation Zmin_SS := Z.succ_min_distr (only parsing). +Notation Zplus_min_distr_r := Z.add_min_distr_r (only parsing). +Notation Zmin_plus := Z.add_min_distr_r (only parsing). +Notation Zpos_min := Pos2Z.inj_min (only parsing). (** Slightly different lemmas *) @@ -48,7 +48,7 @@ Qed. Lemma Zmin_irreducible n m : Z.min n m = n \/ Z.min n m = m. Proof. destruct (Z.min_dec n m); auto. Qed. -Notation Zmin_or := Zmin_irreducible (compat "8.3"). +Notation Zmin_or := Zmin_irreducible (only parsing). Lemma Zmin_le_prime_inf n m p : Z.min n m <= p -> {n <= p} + {m <= p}. Proof. apply Z.min_case; auto. Qed. diff --git a/theories/ZArith/Zminmax.v b/theories/ZArith/Zminmax.v index ca5d1fa8f..06919642f 100644 --- a/theories/ZArith/Zminmax.v +++ b/theories/ZArith/Zminmax.v @@ -14,11 +14,11 @@ Require Import Orders BinInt Zcompare Zorder. (*begin hide*) (* Compatibility with names of the old Zminmax file *) -Notation Zmin_max_absorption_r_r := Z.min_max_absorption (compat "8.3"). -Notation Zmax_min_absorption_r_r := Z.max_min_absorption (compat "8.3"). -Notation Zmax_min_distr_r := Z.max_min_distr (compat "8.3"). -Notation Zmin_max_distr_r := Z.min_max_distr (compat "8.3"). -Notation Zmax_min_modular_r := Z.max_min_modular (compat "8.3"). -Notation Zmin_max_modular_r := Z.min_max_modular (compat "8.3"). -Notation max_min_disassoc := Z.max_min_disassoc (compat "8.3"). +Notation Zmin_max_absorption_r_r := Z.min_max_absorption (only parsing). +Notation Zmax_min_absorption_r_r := Z.max_min_absorption (only parsing). +Notation Zmax_min_distr_r := Z.max_min_distr (only parsing). +Notation Zmin_max_distr_r := Z.min_max_distr (only parsing). +Notation Zmax_min_modular_r := Z.max_min_modular (only parsing). +Notation Zmin_max_modular_r := Z.min_max_modular (only parsing). +Notation max_min_disassoc := Z.max_min_disassoc (only parsing). (*end hide*) diff --git a/theories/ZArith/Zmisc.v b/theories/ZArith/Zmisc.v index 635064722..c46241cee 100644 --- a/theories/ZArith/Zmisc.v +++ b/theories/ZArith/Zmisc.v @@ -20,7 +20,7 @@ Local Open Scope Z_scope. (** [n]th iteration of the function [f] *) -Notation iter := @Z.iter (compat "8.3"). +Notation iter := @Z.iter (only parsing). Lemma iter_nat_of_Z : forall n A f x, 0 <= n -> Z.iter n f x = iter_nat (Z.abs_nat n) A f x. diff --git a/theories/ZArith/Znat.v b/theories/ZArith/Znat.v index 70daca0e2..5c960da1f 100644 --- a/theories/ZArith/Znat.v +++ b/theories/ZArith/Znat.v @@ -953,65 +953,65 @@ Definition inj_gt n m := proj1 (Nat2Z.inj_gt n m). (** For the others, a Notation is fine *) -Notation inj_0 := Nat2Z.inj_0 (compat "8.3"). -Notation inj_S := Nat2Z.inj_succ (compat "8.3"). -Notation inj_compare := Nat2Z.inj_compare (compat "8.3"). -Notation inj_eq_rev := Nat2Z.inj (compat "8.3"). -Notation inj_eq_iff := (fun n m => iff_sym (Nat2Z.inj_iff n m)) (compat "8.3"). -Notation inj_le_iff := Nat2Z.inj_le (compat "8.3"). -Notation inj_lt_iff := Nat2Z.inj_lt (compat "8.3"). -Notation inj_ge_iff := Nat2Z.inj_ge (compat "8.3"). -Notation inj_gt_iff := Nat2Z.inj_gt (compat "8.3"). -Notation inj_le_rev := (fun n m => proj2 (Nat2Z.inj_le n m)) (compat "8.3"). -Notation inj_lt_rev := (fun n m => proj2 (Nat2Z.inj_lt n m)) (compat "8.3"). -Notation inj_ge_rev := (fun n m => proj2 (Nat2Z.inj_ge n m)) (compat "8.3"). -Notation inj_gt_rev := (fun n m => proj2 (Nat2Z.inj_gt n m)) (compat "8.3"). -Notation inj_plus := Nat2Z.inj_add (compat "8.3"). -Notation inj_mult := Nat2Z.inj_mul (compat "8.3"). -Notation inj_minus1 := Nat2Z.inj_sub (compat "8.3"). -Notation inj_minus := Nat2Z.inj_sub_max (compat "8.3"). -Notation inj_min := Nat2Z.inj_min (compat "8.3"). -Notation inj_max := Nat2Z.inj_max (compat "8.3"). - -Notation Z_of_nat_of_P := positive_nat_Z (compat "8.3"). +Notation inj_0 := Nat2Z.inj_0 (only parsing). +Notation inj_S := Nat2Z.inj_succ (only parsing). +Notation inj_compare := Nat2Z.inj_compare (only parsing). +Notation inj_eq_rev := Nat2Z.inj (only parsing). +Notation inj_eq_iff := (fun n m => iff_sym (Nat2Z.inj_iff n m)) (only parsing). +Notation inj_le_iff := Nat2Z.inj_le (only parsing). +Notation inj_lt_iff := Nat2Z.inj_lt (only parsing). +Notation inj_ge_iff := Nat2Z.inj_ge (only parsing). +Notation inj_gt_iff := Nat2Z.inj_gt (only parsing). +Notation inj_le_rev := (fun n m => proj2 (Nat2Z.inj_le n m)) (only parsing). +Notation inj_lt_rev := (fun n m => proj2 (Nat2Z.inj_lt n m)) (only parsing). +Notation inj_ge_rev := (fun n m => proj2 (Nat2Z.inj_ge n m)) (only parsing). +Notation inj_gt_rev := (fun n m => proj2 (Nat2Z.inj_gt n m)) (only parsing). +Notation inj_plus := Nat2Z.inj_add (only parsing). +Notation inj_mult := Nat2Z.inj_mul (only parsing). +Notation inj_minus1 := Nat2Z.inj_sub (only parsing). +Notation inj_minus := Nat2Z.inj_sub_max (only parsing). +Notation inj_min := Nat2Z.inj_min (only parsing). +Notation inj_max := Nat2Z.inj_max (only parsing). + +Notation Z_of_nat_of_P := positive_nat_Z (only parsing). Notation Zpos_eq_Z_of_nat_o_nat_of_P := - (fun p => eq_sym (positive_nat_Z p)) (compat "8.3"). - -Notation Z_of_nat_of_N := N_nat_Z (compat "8.3"). -Notation Z_of_N_of_nat := nat_N_Z (compat "8.3"). - -Notation Z_of_N_eq := (f_equal Z.of_N) (compat "8.3"). -Notation Z_of_N_eq_rev := N2Z.inj (compat "8.3"). -Notation Z_of_N_eq_iff := (fun n m => iff_sym (N2Z.inj_iff n m)) (compat "8.3"). -Notation Z_of_N_compare := N2Z.inj_compare (compat "8.3"). -Notation Z_of_N_le_iff := N2Z.inj_le (compat "8.3"). -Notation Z_of_N_lt_iff := N2Z.inj_lt (compat "8.3"). -Notation Z_of_N_ge_iff := N2Z.inj_ge (compat "8.3"). -Notation Z_of_N_gt_iff := N2Z.inj_gt (compat "8.3"). -Notation Z_of_N_le := (fun n m => proj1 (N2Z.inj_le n m)) (compat "8.3"). -Notation Z_of_N_lt := (fun n m => proj1 (N2Z.inj_lt n m)) (compat "8.3"). -Notation Z_of_N_ge := (fun n m => proj1 (N2Z.inj_ge n m)) (compat "8.3"). -Notation Z_of_N_gt := (fun n m => proj1 (N2Z.inj_gt n m)) (compat "8.3"). -Notation Z_of_N_le_rev := (fun n m => proj2 (N2Z.inj_le n m)) (compat "8.3"). -Notation Z_of_N_lt_rev := (fun n m => proj2 (N2Z.inj_lt n m)) (compat "8.3"). -Notation Z_of_N_ge_rev := (fun n m => proj2 (N2Z.inj_ge n m)) (compat "8.3"). -Notation Z_of_N_gt_rev := (fun n m => proj2 (N2Z.inj_gt n m)) (compat "8.3"). -Notation Z_of_N_pos := N2Z.inj_pos (compat "8.3"). -Notation Z_of_N_abs := N2Z.inj_abs_N (compat "8.3"). -Notation Z_of_N_le_0 := N2Z.is_nonneg (compat "8.3"). -Notation Z_of_N_plus := N2Z.inj_add (compat "8.3"). -Notation Z_of_N_mult := N2Z.inj_mul (compat "8.3"). -Notation Z_of_N_minus := N2Z.inj_sub_max (compat "8.3"). -Notation Z_of_N_succ := N2Z.inj_succ (compat "8.3"). -Notation Z_of_N_min := N2Z.inj_min (compat "8.3"). -Notation Z_of_N_max := N2Z.inj_max (compat "8.3"). -Notation Zabs_of_N := Zabs2N.id (compat "8.3"). -Notation Zabs_N_succ_abs := Zabs2N.inj_succ_abs (compat "8.3"). -Notation Zabs_N_succ := Zabs2N.inj_succ (compat "8.3"). -Notation Zabs_N_plus_abs := Zabs2N.inj_add_abs (compat "8.3"). -Notation Zabs_N_plus := Zabs2N.inj_add (compat "8.3"). -Notation Zabs_N_mult_abs := Zabs2N.inj_mul_abs (compat "8.3"). -Notation Zabs_N_mult := Zabs2N.inj_mul (compat "8.3"). + (fun p => eq_sym (positive_nat_Z p)) (only parsing). + +Notation Z_of_nat_of_N := N_nat_Z (only parsing). +Notation Z_of_N_of_nat := nat_N_Z (only parsing). + +Notation Z_of_N_eq := (f_equal Z.of_N) (only parsing). +Notation Z_of_N_eq_rev := N2Z.inj (only parsing). +Notation Z_of_N_eq_iff := (fun n m => iff_sym (N2Z.inj_iff n m)) (only parsing). +Notation Z_of_N_compare := N2Z.inj_compare (only parsing). +Notation Z_of_N_le_iff := N2Z.inj_le (only parsing). +Notation Z_of_N_lt_iff := N2Z.inj_lt (only parsing). +Notation Z_of_N_ge_iff := N2Z.inj_ge (only parsing). +Notation Z_of_N_gt_iff := N2Z.inj_gt (only parsing). +Notation Z_of_N_le := (fun n m => proj1 (N2Z.inj_le n m)) (only parsing). +Notation Z_of_N_lt := (fun n m => proj1 (N2Z.inj_lt n m)) (only parsing). +Notation Z_of_N_ge := (fun n m => proj1 (N2Z.inj_ge n m)) (only parsing). +Notation Z_of_N_gt := (fun n m => proj1 (N2Z.inj_gt n m)) (only parsing). +Notation Z_of_N_le_rev := (fun n m => proj2 (N2Z.inj_le n m)) (only parsing). +Notation Z_of_N_lt_rev := (fun n m => proj2 (N2Z.inj_lt n m)) (only parsing). +Notation Z_of_N_ge_rev := (fun n m => proj2 (N2Z.inj_ge n m)) (only parsing). +Notation Z_of_N_gt_rev := (fun n m => proj2 (N2Z.inj_gt n m)) (only parsing). +Notation Z_of_N_pos := N2Z.inj_pos (only parsing). +Notation Z_of_N_abs := N2Z.inj_abs_N (only parsing). +Notation Z_of_N_le_0 := N2Z.is_nonneg (only parsing). +Notation Z_of_N_plus := N2Z.inj_add (only parsing). +Notation Z_of_N_mult := N2Z.inj_mul (only parsing). +Notation Z_of_N_minus := N2Z.inj_sub_max (only parsing). +Notation Z_of_N_succ := N2Z.inj_succ (only parsing). +Notation Z_of_N_min := N2Z.inj_min (only parsing). +Notation Z_of_N_max := N2Z.inj_max (only parsing). +Notation Zabs_of_N := Zabs2N.id (only parsing). +Notation Zabs_N_succ_abs := Zabs2N.inj_succ_abs (only parsing). +Notation Zabs_N_succ := Zabs2N.inj_succ (only parsing). +Notation Zabs_N_plus_abs := Zabs2N.inj_add_abs (only parsing). +Notation Zabs_N_plus := Zabs2N.inj_add (only parsing). +Notation Zabs_N_mult_abs := Zabs2N.inj_mul_abs (only parsing). +Notation Zabs_N_mult := Zabs2N.inj_mul (only parsing). Theorem inj_minus2 : forall n m:nat, (m > n)%nat -> Z.of_nat (n - m) = 0. Proof. diff --git a/theories/ZArith/Znumtheory.v b/theories/ZArith/Znumtheory.v index 93fb723b0..f5444c31d 100644 --- a/theories/ZArith/Znumtheory.v +++ b/theories/ZArith/Znumtheory.v @@ -27,20 +27,20 @@ Open Scope Z_scope. - properties of the efficient [Z.gcd] function *) -Notation Zgcd := Z.gcd (compat "8.3"). -Notation Zggcd := Z.ggcd (compat "8.3"). -Notation Zggcd_gcd := Z.ggcd_gcd (compat "8.3"). -Notation Zggcd_correct_divisors := Z.ggcd_correct_divisors (compat "8.3"). -Notation Zgcd_divide_l := Z.gcd_divide_l (compat "8.3"). -Notation Zgcd_divide_r := Z.gcd_divide_r (compat "8.3"). -Notation Zgcd_greatest := Z.gcd_greatest (compat "8.3"). -Notation Zgcd_nonneg := Z.gcd_nonneg (compat "8.3"). -Notation Zggcd_opp := Z.ggcd_opp (compat "8.3"). +Notation Zgcd := Z.gcd (compat "8.6"). +Notation Zggcd := Z.ggcd (compat "8.6"). +Notation Zggcd_gcd := Z.ggcd_gcd (compat "8.6"). +Notation Zggcd_correct_divisors := Z.ggcd_correct_divisors (compat "8.6"). +Notation Zgcd_divide_l := Z.gcd_divide_l (compat "8.6"). +Notation Zgcd_divide_r := Z.gcd_divide_r (compat "8.6"). +Notation Zgcd_greatest := Z.gcd_greatest (compat "8.6"). +Notation Zgcd_nonneg := Z.gcd_nonneg (compat "8.6"). +Notation Zggcd_opp := Z.ggcd_opp (compat "8.6"). (** The former specialized inductive predicate [Z.divide] is now a generic existential predicate. *) -Notation Zdivide := Z.divide (compat "8.3"). +Notation Zdivide := Z.divide (compat "8.6"). (** Its former constructor is now a pseudo-constructor. *) @@ -48,17 +48,17 @@ Definition Zdivide_intro a b q (H:b=q*a) : Z.divide a b := ex_intro _ q H. (** Results concerning divisibility*) -Notation Zdivide_refl := Z.divide_refl (compat "8.3"). -Notation Zone_divide := Z.divide_1_l (compat "8.3"). -Notation Zdivide_0 := Z.divide_0_r (compat "8.3"). -Notation Zmult_divide_compat_l := Z.mul_divide_mono_l (compat "8.3"). -Notation Zmult_divide_compat_r := Z.mul_divide_mono_r (compat "8.3"). -Notation Zdivide_plus_r := Z.divide_add_r (compat "8.3"). -Notation Zdivide_minus_l := Z.divide_sub_r (compat "8.3"). -Notation Zdivide_mult_l := Z.divide_mul_l (compat "8.3"). -Notation Zdivide_mult_r := Z.divide_mul_r (compat "8.3"). -Notation Zdivide_factor_r := Z.divide_factor_l (compat "8.3"). -Notation Zdivide_factor_l := Z.divide_factor_r (compat "8.3"). +Notation Zdivide_refl := Z.divide_refl (compat "8.6"). +Notation Zone_divide := Z.divide_1_l (only parsing). +Notation Zdivide_0 := Z.divide_0_r (only parsing). +Notation Zmult_divide_compat_l := Z.mul_divide_mono_l (only parsing). +Notation Zmult_divide_compat_r := Z.mul_divide_mono_r (only parsing). +Notation Zdivide_plus_r := Z.divide_add_r (only parsing). +Notation Zdivide_minus_l := Z.divide_sub_r (only parsing). +Notation Zdivide_mult_l := Z.divide_mul_l (only parsing). +Notation Zdivide_mult_r := Z.divide_mul_r (only parsing). +Notation Zdivide_factor_r := Z.divide_factor_l (only parsing). +Notation Zdivide_factor_l := Z.divide_factor_r (only parsing). Lemma Zdivide_opp_r a b : (a | b) -> (a | - b). Proof. apply Z.divide_opp_r. Qed. @@ -93,12 +93,12 @@ Qed. (** Only [1] and [-1] divide [1]. *) -Notation Zdivide_1 := Z.divide_1_r (compat "8.3"). +Notation Zdivide_1 := Z.divide_1_r (only parsing). (** If [a] divides [b] and [b] divides [a] then [a] is [b] or [-b]. *) -Notation Zdivide_antisym := Z.divide_antisym (compat "8.3"). -Notation Zdivide_trans := Z.divide_trans (compat "8.3"). +Notation Zdivide_antisym := Z.divide_antisym (compat "8.6"). +Notation Zdivide_trans := Z.divide_trans (compat "8.6"). (** If [a] divides [b] and [b<>0] then [|a| <= |b|]. *) @@ -736,7 +736,7 @@ Qed. (** we now prove that [Z.gcd] is indeed a gcd in the sense of [Zis_gcd]. *) -Notation Zgcd_is_pos := Z.gcd_nonneg (compat "8.3"). +Notation Zgcd_is_pos := Z.gcd_nonneg (only parsing). Lemma Zgcd_is_gcd : forall a b, Zis_gcd a b (Z.gcd a b). Proof. @@ -769,8 +769,8 @@ Proof. - subst. now case (Z.gcd a b). Qed. -Notation Zgcd_inv_0_l := Z.gcd_eq_0_l (compat "8.3"). -Notation Zgcd_inv_0_r := Z.gcd_eq_0_r (compat "8.3"). +Notation Zgcd_inv_0_l := Z.gcd_eq_0_l (only parsing). +Notation Zgcd_inv_0_r := Z.gcd_eq_0_r (only parsing). Theorem Zgcd_div_swap0 : forall a b : Z, 0 < Z.gcd a b -> @@ -800,16 +800,16 @@ Proof. rewrite <- Zdivide_Zdiv_eq; auto. Qed. -Notation Zgcd_comm := Z.gcd_comm (compat "8.3"). +Notation Zgcd_comm := Z.gcd_comm (compat "8.6"). Lemma Zgcd_ass a b c : Z.gcd (Z.gcd a b) c = Z.gcd a (Z.gcd b c). Proof. symmetry. apply Z.gcd_assoc. Qed. -Notation Zgcd_Zabs := Z.gcd_abs_l (compat "8.3"). -Notation Zgcd_0 := Z.gcd_0_r (compat "8.3"). -Notation Zgcd_1 := Z.gcd_1_r (compat "8.3"). +Notation Zgcd_Zabs := Z.gcd_abs_l (only parsing). +Notation Zgcd_0 := Z.gcd_0_r (only parsing). +Notation Zgcd_1 := Z.gcd_1_r (only parsing). Hint Resolve Z.gcd_0_r Z.gcd_1_r : zarith. diff --git a/theories/ZArith/Zorder.v b/theories/ZArith/Zorder.v index f6289f213..a1ec4b35e 100644 --- a/theories/ZArith/Zorder.v +++ b/theories/ZArith/Zorder.v @@ -40,9 +40,9 @@ Qed. (**********************************************************************) (** * Decidability of equality and order on Z *) -Notation dec_eq := Z.eq_decidable (compat "8.3"). -Notation dec_Zle := Z.le_decidable (compat "8.3"). -Notation dec_Zlt := Z.lt_decidable (compat "8.3"). +Notation dec_eq := Z.eq_decidable (only parsing). +Notation dec_Zle := Z.le_decidable (only parsing). +Notation dec_Zlt := Z.lt_decidable (only parsing). Theorem dec_Zne n m : decidable (Zne n m). Proof. @@ -66,12 +66,12 @@ Qed. (** * Relating strict and large orders *) -Notation Zgt_lt := Z.gt_lt (compat "8.3"). -Notation Zlt_gt := Z.lt_gt (compat "8.3"). -Notation Zge_le := Z.ge_le (compat "8.3"). -Notation Zle_ge := Z.le_ge (compat "8.3"). -Notation Zgt_iff_lt := Z.gt_lt_iff (compat "8.3"). -Notation Zge_iff_le := Z.ge_le_iff (compat "8.3"). +Notation Zgt_lt := Z.gt_lt (compat "8.6"). +Notation Zlt_gt := Z.lt_gt (compat "8.6"). +Notation Zge_le := Z.ge_le (compat "8.6"). +Notation Zle_ge := Z.le_ge (compat "8.6"). +Notation Zgt_iff_lt := Z.gt_lt_iff (only parsing). +Notation Zge_iff_le := Z.ge_le_iff (only parsing). Lemma Zle_not_lt n m : n <= m -> ~ m < n. Proof. @@ -123,18 +123,18 @@ Qed. (** Reflexivity *) -Notation Zle_refl := Z.le_refl (compat "8.3"). -Notation Zeq_le := Z.eq_le_incl (compat "8.3"). +Notation Zle_refl := Z.le_refl (compat "8.6"). +Notation Zeq_le := Z.eq_le_incl (only parsing). Hint Resolve Z.le_refl: zarith. (** Antisymmetry *) -Notation Zle_antisym := Z.le_antisymm (compat "8.3"). +Notation Zle_antisym := Z.le_antisymm (only parsing). (** Asymmetry *) -Notation Zlt_asym := Z.lt_asymm (compat "8.3"). +Notation Zlt_asym := Z.lt_asymm (only parsing). Lemma Zgt_asym n m : n > m -> ~ m > n. Proof. @@ -143,8 +143,8 @@ Qed. (** Irreflexivity *) -Notation Zlt_irrefl := Z.lt_irrefl (compat "8.3"). -Notation Zlt_not_eq := Z.lt_neq (compat "8.3"). +Notation Zlt_irrefl := Z.lt_irrefl (compat "8.6"). +Notation Zlt_not_eq := Z.lt_neq (only parsing). Lemma Zgt_irrefl n : ~ n > n. Proof. @@ -153,8 +153,8 @@ Qed. (** Large = strict or equal *) -Notation Zlt_le_weak := Z.lt_le_incl (compat "8.3"). -Notation Zle_lt_or_eq_iff := Z.lt_eq_cases (compat "8.3"). +Notation Zlt_le_weak := Z.lt_le_incl (only parsing). +Notation Zle_lt_or_eq_iff := Z.lt_eq_cases (only parsing). Lemma Zle_lt_or_eq n m : n <= m -> n < m \/ n = m. Proof. @@ -163,11 +163,11 @@ Qed. (** Dichotomy *) -Notation Zle_or_lt := Z.le_gt_cases (compat "8.3"). +Notation Zle_or_lt := Z.le_gt_cases (only parsing). (** Transitivity of strict orders *) -Notation Zlt_trans := Z.lt_trans (compat "8.3"). +Notation Zlt_trans := Z.lt_trans (compat "8.6"). Lemma Zgt_trans n m p : n > m -> m > p -> n > p. Proof. @@ -176,8 +176,8 @@ Qed. (** Mixed transitivity *) -Notation Zlt_le_trans := Z.lt_le_trans (compat "8.3"). -Notation Zle_lt_trans := Z.le_lt_trans (compat "8.3"). +Notation Zlt_le_trans := Z.lt_le_trans (compat "8.6"). +Notation Zle_lt_trans := Z.le_lt_trans (compat "8.6"). Lemma Zle_gt_trans n m p : m <= n -> m > p -> n > p. Proof. @@ -191,7 +191,7 @@ Qed. (** Transitivity of large orders *) -Notation Zle_trans := Z.le_trans (compat "8.3"). +Notation Zle_trans := Z.le_trans (compat "8.6"). Lemma Zge_trans n m p : n >= m -> m >= p -> n >= p. Proof. @@ -242,8 +242,8 @@ Qed. (** Special base instances of order *) -Notation Zlt_succ := Z.lt_succ_diag_r (compat "8.3"). -Notation Zlt_pred := Z.lt_pred_l (compat "8.3"). +Notation Zlt_succ := Z.lt_succ_diag_r (only parsing). +Notation Zlt_pred := Z.lt_pred_l (only parsing). Lemma Zgt_succ n : Z.succ n > n. Proof. @@ -257,8 +257,8 @@ Qed. (** Relating strict and large order using successor or predecessor *) -Notation Zlt_succ_r := Z.lt_succ_r (compat "8.3"). -Notation Zle_succ_l := Z.le_succ_l (compat "8.3"). +Notation Zlt_succ_r := Z.lt_succ_r (compat "8.6"). +Notation Zle_succ_l := Z.le_succ_l (compat "8.6"). Lemma Zgt_le_succ n m : m > n -> Z.succ n <= m. Proof. @@ -297,10 +297,10 @@ Qed. (** Weakening order *) -Notation Zle_succ := Z.le_succ_diag_r (compat "8.3"). -Notation Zle_pred := Z.le_pred_l (compat "8.3"). -Notation Zlt_lt_succ := Z.lt_lt_succ_r (compat "8.3"). -Notation Zle_le_succ := Z.le_le_succ_r (compat "8.3"). +Notation Zle_succ := Z.le_succ_diag_r (only parsing). +Notation Zle_pred := Z.le_pred_l (only parsing). +Notation Zlt_lt_succ := Z.lt_lt_succ_r (only parsing). +Notation Zle_le_succ := Z.le_le_succ_r (only parsing). Lemma Zle_succ_le n m : Z.succ n <= m -> n <= m. Proof. @@ -336,8 +336,8 @@ Qed. (** Special cases of ordered integers *) -Notation Zlt_0_1 := Z.lt_0_1 (compat "8.3"). -Notation Zle_0_1 := Z.le_0_1 (compat "8.3"). +Notation Zlt_0_1 := Z.lt_0_1 (compat "8.6"). +Notation Zle_0_1 := Z.le_0_1 (compat "8.6"). Lemma Zle_neg_pos : forall p q:positive, Zneg p <= Zpos q. Proof. @@ -377,10 +377,10 @@ Qed. (** ** Addition *) (** Compatibility of addition wrt to order *) -Notation Zplus_lt_le_compat := Z.add_lt_le_mono (compat "8.3"). -Notation Zplus_le_lt_compat := Z.add_le_lt_mono (compat "8.3"). -Notation Zplus_le_compat := Z.add_le_mono (compat "8.3"). -Notation Zplus_lt_compat := Z.add_lt_mono (compat "8.3"). +Notation Zplus_lt_le_compat := Z.add_lt_le_mono (only parsing). +Notation Zplus_le_lt_compat := Z.add_le_lt_mono (only parsing). +Notation Zplus_le_compat := Z.add_le_mono (only parsing). +Notation Zplus_lt_compat := Z.add_lt_mono (only parsing). Lemma Zplus_gt_compat_l n m p : n > m -> p + n > p + m. Proof. @@ -414,7 +414,7 @@ Qed. (** Compatibility of addition wrt to being positive *) -Notation Zplus_le_0_compat := Z.add_nonneg_nonneg (compat "8.3"). +Notation Zplus_le_0_compat := Z.add_nonneg_nonneg (only parsing). (** Simplification of addition wrt to order *) @@ -572,9 +572,9 @@ Qed. (** Compatibility of multiplication by a positive wrt to being positive *) -Notation Zmult_le_0_compat := Z.mul_nonneg_nonneg (compat "8.3"). -Notation Zmult_lt_0_compat := Z.mul_pos_pos (compat "8.3"). -Notation Zmult_lt_O_compat := Z.mul_pos_pos (compat "8.3"). +Notation Zmult_le_0_compat := Z.mul_nonneg_nonneg (only parsing). +Notation Zmult_lt_0_compat := Z.mul_pos_pos (only parsing). +Notation Zmult_lt_O_compat := Z.mul_pos_pos (only parsing). Lemma Zmult_gt_0_compat n m : n > 0 -> m > 0 -> n * m > 0. Proof. @@ -626,9 +626,9 @@ Qed. (** * Equivalence between inequalities *) -Notation Zle_plus_swap := Z.le_add_le_sub_r (compat "8.3"). -Notation Zlt_plus_swap := Z.lt_add_lt_sub_r (compat "8.3"). -Notation Zlt_minus_simpl_swap := Z.lt_sub_pos (compat "8.3"). +Notation Zle_plus_swap := Z.le_add_le_sub_r (only parsing). +Notation Zlt_plus_swap := Z.lt_add_lt_sub_r (only parsing). +Notation Zlt_minus_simpl_swap := Z.lt_sub_pos (only parsing). Lemma Zeq_plus_swap n m p : n + p = m <-> n = m - p. Proof. diff --git a/theories/ZArith/Zpow_def.v b/theories/ZArith/Zpow_def.v index 0b0c5c221..2b099671f 100644 --- a/theories/ZArith/Zpow_def.v +++ b/theories/ZArith/Zpow_def.v @@ -16,12 +16,12 @@ Local Open Scope Z_scope. (** Nota : this file is mostly deprecated. The definition of [Z.pow] and its usual properties are now provided by module [BinInt.Z]. *) -Notation Zpower_pos := Z.pow_pos (compat "8.3"). -Notation Zpower := Z.pow (compat "8.3"). -Notation Zpower_0_r := Z.pow_0_r (compat "8.3"). -Notation Zpower_succ_r := Z.pow_succ_r (compat "8.3"). -Notation Zpower_neg_r := Z.pow_neg_r (compat "8.3"). -Notation Zpower_Ppow := Pos2Z.inj_pow (compat "8.3"). +Notation Zpower_pos := Z.pow_pos (only parsing). +Notation Zpower := Z.pow (only parsing). +Notation Zpower_0_r := Z.pow_0_r (only parsing). +Notation Zpower_succ_r := Z.pow_succ_r (only parsing). +Notation Zpower_neg_r := Z.pow_neg_r (only parsing). +Notation Zpower_Ppow := Pos2Z.inj_pow (only parsing). Lemma Zpower_theory : power_theory 1 Z.mul (@eq Z) Z.of_N Z.pow. Proof. diff --git a/theories/ZArith/Zpow_facts.v b/theories/ZArith/Zpow_facts.v index dc3d1a507..a9bc5bd09 100644 --- a/theories/ZArith/Zpow_facts.v +++ b/theories/ZArith/Zpow_facts.v @@ -31,17 +31,17 @@ Proof. now apply (Z.pow_0_l (Zpos p)). Qed. Lemma Zpower_pos_pos x p : 0 < x -> 0 < Z.pow_pos x p. Proof. intros. now apply (Z.pow_pos_nonneg x (Zpos p)). Qed. -Notation Zpower_1_r := Z.pow_1_r (compat "8.3"). -Notation Zpower_1_l := Z.pow_1_l (compat "8.3"). -Notation Zpower_0_l := Z.pow_0_l' (compat "8.3"). -Notation Zpower_0_r := Z.pow_0_r (compat "8.3"). -Notation Zpower_2 := Z.pow_2_r (compat "8.3"). -Notation Zpower_gt_0 := Z.pow_pos_nonneg (compat "8.3"). -Notation Zpower_ge_0 := Z.pow_nonneg (compat "8.3"). -Notation Zpower_Zabs := Z.abs_pow (compat "8.3"). -Notation Zpower_Zsucc := Z.pow_succ_r (compat "8.3"). -Notation Zpower_mult := Z.pow_mul_r (compat "8.3"). -Notation Zpower_le_monotone2 := Z.pow_le_mono_r (compat "8.3"). +Notation Zpower_1_r := Z.pow_1_r (only parsing). +Notation Zpower_1_l := Z.pow_1_l (only parsing). +Notation Zpower_0_l := Z.pow_0_l' (only parsing). +Notation Zpower_0_r := Z.pow_0_r (only parsing). +Notation Zpower_2 := Z.pow_2_r (only parsing). +Notation Zpower_gt_0 := Z.pow_pos_nonneg (only parsing). +Notation Zpower_ge_0 := Z.pow_nonneg (only parsing). +Notation Zpower_Zabs := Z.abs_pow (only parsing). +Notation Zpower_Zsucc := Z.pow_succ_r (only parsing). +Notation Zpower_mult := Z.pow_mul_r (only parsing). +Notation Zpower_le_monotone2 := Z.pow_le_mono_r (only parsing). Theorem Zpower_le_monotone a b c : 0 < a -> 0 <= b <= c -> a^b <= a^c. @@ -233,7 +233,7 @@ Qed. (** * Z.square: a direct definition of [z^2] *) -Notation Psquare := Pos.square (compat "8.3"). -Notation Zsquare := Z.square (compat "8.3"). -Notation Psquare_correct := Pos.square_spec (compat "8.3"). -Notation Zsquare_correct := Z.square_spec (compat "8.3"). +Notation Psquare := Pos.square (compat "8.6"). +Notation Zsquare := Z.square (compat "8.6"). +Notation Psquare_correct := Pos.square_spec (only parsing). +Notation Zsquare_correct := Z.square_spec (only parsing). diff --git a/theories/ZArith/Zquot.v b/theories/ZArith/Zquot.v index 6eab79c43..e93ebb1ad 100644 --- a/theories/ZArith/Zquot.v +++ b/theories/ZArith/Zquot.v @@ -33,21 +33,21 @@ Local Open Scope Z_scope. exploiting the arbitrary value of division by 0). *) -Notation Ndiv_Zquot := N2Z.inj_quot (compat "8.3"). -Notation Nmod_Zrem := N2Z.inj_rem (compat "8.3"). -Notation Z_quot_rem_eq := Z.quot_rem' (compat "8.3"). -Notation Zrem_lt := Z.rem_bound_abs (compat "8.3"). -Notation Zquot_unique := Z.quot_unique (compat "8.3"). -Notation Zrem_unique := Z.rem_unique (compat "8.3"). -Notation Zrem_1_r := Z.rem_1_r (compat "8.3"). -Notation Zquot_1_r := Z.quot_1_r (compat "8.3"). -Notation Zrem_1_l := Z.rem_1_l (compat "8.3"). -Notation Zquot_1_l := Z.quot_1_l (compat "8.3"). -Notation Z_quot_same := Z.quot_same (compat "8.3"). -Notation Z_quot_mult := Z.quot_mul (compat "8.3"). -Notation Zquot_small := Z.quot_small (compat "8.3"). -Notation Zrem_small := Z.rem_small (compat "8.3"). -Notation Zquot2_quot := Zquot2_quot (compat "8.3"). +Notation Ndiv_Zquot := N2Z.inj_quot (only parsing). +Notation Nmod_Zrem := N2Z.inj_rem (only parsing). +Notation Z_quot_rem_eq := Z.quot_rem' (only parsing). +Notation Zrem_lt := Z.rem_bound_abs (only parsing). +Notation Zquot_unique := Z.quot_unique (compat "8.6"). +Notation Zrem_unique := Z.rem_unique (compat "8.6"). +Notation Zrem_1_r := Z.rem_1_r (compat "8.6"). +Notation Zquot_1_r := Z.quot_1_r (compat "8.6"). +Notation Zrem_1_l := Z.rem_1_l (compat "8.6"). +Notation Zquot_1_l := Z.quot_1_l (compat "8.6"). +Notation Z_quot_same := Z.quot_same (compat "8.6"). +Notation Z_quot_mult := Z.quot_mul (only parsing). +Notation Zquot_small := Z.quot_small (compat "8.6"). +Notation Zrem_small := Z.rem_small (compat "8.6"). +Notation Zquot2_quot := Zquot2_quot (compat "8.6"). (** Particular values taken for [aĆ·0] and [(Z.rem a 0)]. We avise to not rely on these arbitrary values. *) diff --git a/toplevel/coqargs.ml b/toplevel/coqargs.ml index 310e297de..06b2ba41b 100644 --- a/toplevel/coqargs.ml +++ b/toplevel/coqargs.ml @@ -148,14 +148,13 @@ let add_vo_require opts d p export = let add_compat_require opts v = match v with - | Flags.V8_5 -> add_vo_require opts "Coq.Compat.Coq85" None (Some false) | Flags.V8_6 -> add_vo_require opts "Coq.Compat.Coq86" None (Some false) | Flags.V8_7 -> add_vo_require opts "Coq.Compat.Coq87" None (Some false) - | Flags.VOld | Flags.Current -> opts + | Flags.Current -> opts let set_batch_mode opts = Flags.quiet := true; - System.trust_file_cache := false; + System.trust_file_cache := true; { opts with batch_mode = true } let add_compile opts verbose s = diff --git a/toplevel/coqinit.ml b/toplevel/coqinit.ml index 237c3d097..96a0bd5ec 100644 --- a/toplevel/coqinit.ml +++ b/toplevel/coqinit.ml @@ -28,7 +28,7 @@ let load_rcfile ~rcfile ~time ~state = match rcfile with | Some rcfile -> if CUnix.file_readable_p rcfile then - Vernac.load_vernac ~time ~verbosely:false ~interactive:false ~check:true ~state rcfile + Vernac.load_vernac ~time ~echo:false ~interactive:false ~check:true ~state rcfile else raise (Sys_error ("Cannot read rcfile: "^ rcfile)) | None -> try @@ -39,7 +39,7 @@ let load_rcfile ~rcfile ~time ~state = Envars.home ~warn / "."^rcdefaultname^"."^Coq_config.version; Envars.home ~warn / "."^rcdefaultname ] in - Vernac.load_vernac ~time ~verbosely:false ~interactive:false ~check:true ~state inferedrc + Vernac.load_vernac ~time ~echo:false ~interactive:false ~check:true ~state inferedrc with Not_found -> state (* Flags.if_verbose diff --git a/toplevel/coqloop.ml b/toplevel/coqloop.ml index 652ed92c6..1da46e8ce 100644 --- a/toplevel/coqloop.ml +++ b/toplevel/coqloop.ml @@ -341,6 +341,8 @@ let loop_flush_all () = Format.pp_print_flush !Topfmt.std_ft (); Format.pp_print_flush !Topfmt.err_ft () +let drop_last_doc = ref None + let rec loop ~time ~state = let open Vernac.State in Sys.catch_break true; @@ -355,7 +357,14 @@ let rec loop ~time ~state = not possible due exceptions. *) in vernac_loop ~state with - | CErrors.Drop -> state + | CErrors.Drop -> + (* Due to using exceptions as a form of control, state here goes + out of sync as [do_vernac] will never return. We must thus do + this hack until we make `Drop` a toplevel-only command. See + bug #6872. *) + let state = { state with sid = Stm.get_current_state ~doc:state.doc } in + drop_last_doc := Some state; + state | CErrors.Quit -> exit 0 | any -> top_stderr (str "Anomaly: main loop exited with exception: " ++ diff --git a/toplevel/coqloop.mli b/toplevel/coqloop.mli index 516780ef9..bbb9b1383 100644 --- a/toplevel/coqloop.mli +++ b/toplevel/coqloop.mli @@ -37,3 +37,6 @@ val do_vernac : time:bool -> state:Vernac.State.t -> Vernac.State.t (** Main entry point of Coq: read and execute vernac commands. *) val loop : time:bool -> state:Vernac.State.t -> Vernac.State.t + +(** Last document seen after `Drop` *) +val drop_last_doc : Vernac.State.t option ref diff --git a/toplevel/coqtop.ml b/toplevel/coqtop.ml index 52e78302f..341888d09 100644 --- a/toplevel/coqtop.ml +++ b/toplevel/coqtop.ml @@ -36,7 +36,6 @@ let warning s = Flags.(with_option warn Feedback.msg_warning (strbrk s)) will not be generally be initialized, thus stateid, etc... may be bogus. For now we just print to the console too *) let coqtop_init_feed = Coqloop.coqloop_feed -let drop_last_doc = ref None (* Default toplevel loop *) let console_toploop_run opts ~state = @@ -46,9 +45,8 @@ let console_toploop_run opts ~state = Flags.if_verbose warning "Dumpglob cannot be used in interactive mode."; Dumpglob.noglob () end; - let state = Coqloop.loop ~time:opts.time ~state in + let _ = Coqloop.loop ~time:opts.time ~state in (* Initialise and launch the Ocaml toplevel *) - drop_last_doc := Some state; Coqinit.init_ocaml_path(); Mltop.ocaml_toploop(); (* We let the feeder in place for users of Drop *) @@ -94,10 +92,10 @@ let outputstate opts = (******************************************************************************) let load_vernacular opts ~state = List.fold_left - (fun state (f_in, verbosely) -> + (fun state (f_in, echo) -> let s = Loadpath.locate_file f_in in (* Should make the beautify logic clearer *) - let load_vernac f = Vernac.load_vernac ~time:opts.time ~verbosely ~interactive:false ~check:true ~state f in + let load_vernac f = Vernac.load_vernac ~time:opts.time ~echo ~interactive:false ~check:true ~state f in if !Flags.beautify then Flags.with_option Flags.beautify_file load_vernac f_in else load_vernac s @@ -196,7 +194,7 @@ let ensure_exists f = fatal_error (hov 0 (str "Can't find file" ++ spc () ++ str f)) (* Compile a vernac file *) -let compile opts ~verbosely ~f_in ~f_out = +let compile opts ~echo ~f_in ~f_out = let open Vernac.State in let check_pending_proofs () = let pfs = Proof_global.get_all_proof_names () in @@ -234,7 +232,7 @@ let compile opts ~verbosely ~f_in ~f_out = Dumpglob.start_dump_glob ~vfile:long_f_dot_v ~vofile:long_f_dot_vo; Dumpglob.dump_string ("F" ^ Names.DirPath.to_string ldir ^ "\n"); let wall_clock1 = Unix.gettimeofday () in - let state = Vernac.load_vernac ~time:opts.time ~verbosely ~check:true ~interactive:false ~state long_f_dot_v in + let state = Vernac.load_vernac ~time:opts.time ~echo ~check:true ~interactive:false ~state long_f_dot_v in let _doc = Stm.join ~doc:state.doc in let wall_clock2 = Unix.gettimeofday () in check_pending_proofs (); @@ -275,7 +273,7 @@ let compile opts ~verbosely ~f_in ~f_out = let state = { doc; sid; proof = None } in let state = load_init_vernaculars opts ~state in let ldir = Stm.get_ldir ~doc:state.doc in - let state = Vernac.load_vernac ~time:opts.time ~verbosely ~check:false ~interactive:false ~state long_f_dot_v in + let state = Vernac.load_vernac ~time:opts.time ~echo ~check:false ~interactive:false ~state long_f_dot_v in let doc = Stm.finish ~doc:state.doc in check_pending_proofs (); let _doc = Stm.snapshot_vio ~doc ldir long_f_dot_vio in @@ -290,17 +288,17 @@ let compile opts ~verbosely ~f_in ~f_out = let univs, proofs = Stm.finish_tasks lfdv univs disch proofs tasks in Library.save_library_raw lfdv sum lib univs proofs -let compile opts ~verbosely ~f_in ~f_out = +let compile opts ~echo ~f_in ~f_out = ignore(CoqworkmgrApi.get 1); - compile opts ~verbosely ~f_in ~f_out; + compile opts ~echo ~f_in ~f_out; CoqworkmgrApi.giveback 1 -let compile_file opts (f_in, verbosely) = +let compile_file opts (f_in, echo) = if !Flags.beautify then Flags.with_option Flags.beautify_file - (fun f_in -> compile opts ~verbosely ~f_in ~f_out:None) f_in + (fun f_in -> compile opts ~echo ~f_in ~f_out:None) f_in else - compile opts ~verbosely ~f_in ~f_out:None + compile opts ~echo ~f_in ~f_out:None let compile_files opts = let compile_list = List.rev opts.compile_list in diff --git a/toplevel/coqtop.mli b/toplevel/coqtop.mli index 0888ea4fd..056279bbd 100644 --- a/toplevel/coqtop.mli +++ b/toplevel/coqtop.mli @@ -17,9 +17,6 @@ val init_toplevel : string list -> Vernac.State.t option * Coqargs.coq_cmdopts val start : unit -> unit -(* Last document seen after `Drop` *) -val drop_last_doc : Vernac.State.t option ref - (* For other toploops *) val toploop_init : (Coqargs.coq_cmdopts -> string list -> string list) ref val toploop_run : (Coqargs.coq_cmdopts -> state:Vernac.State.t -> unit) ref diff --git a/toplevel/vernac.ml b/toplevel/vernac.ml index 5f0aa3bea..7c889500a 100644 --- a/toplevel/vernac.ml +++ b/toplevel/vernac.ml @@ -42,37 +42,6 @@ let vernac_echo ?loc in_chan = let open Loc in Feedback.msg_notice @@ str @@ really_input_string in_chan len ) loc -(* vernac parses the given stream, executes interpfun on the syntax tree it - * parses, and is verbose on "primitives" commands if verbosely is true *) - -let beautify_suffix = ".beautified" - -let set_formatter_translator ch = - let out s b e = output_substring ch s b e in - let ft = Format.make_formatter out (fun () -> flush ch) in - Format.pp_set_max_boxes ft max_int; - ft - -let pr_new_syntax_in_context ?loc ft_beautify ocom = - let loc = Option.cata Loc.unloc (0,0) loc in - let fs = States.freeze ~marshallable:`No in - (* Side-effect: order matters *) - let before = comment (CLexer.extract_comments (fst loc)) in - let com = match ocom with - | Some com -> Ppvernac.pr_vernac com - | None -> mt() in - let after = comment (CLexer.extract_comments (snd loc)) in - if !Flags.beautify_file then - (Pp.pp_with ft_beautify (hov 0 (before ++ com ++ after)); - Format.pp_print_flush ft_beautify ()) - else - Feedback.msg_info (hov 4 (str"New Syntax:" ++ fnl() ++ (hov 0 com))); - States.unfreeze fs - -let pr_new_syntax ?loc po ft_beautify ocom = - (* Reinstall the context of parsing which includes the bindings of comments to locations *) - Pcoq.Gram.with_parsable po (pr_new_syntax_in_context ?loc ft_beautify) ocom - (* For coqtop -time, we display the position in the file, and a glimpse of the executed command *) @@ -122,16 +91,9 @@ module State = struct end -let rec interp_vernac ~time ~check ~interactive ~state (loc,com) = +let interp_vernac ~time ~check ~interactive ~state (loc,com) = let open State in - let interp v = - match under_control v with - | VernacLoad (verbosely, fname) -> - let fname = Envars.expand_path_macros ~warn:(fun x -> Feedback.msg_warning (str x)) fname in - let fname = CUnix.make_suffix fname ".v" in - let f = Loadpath.locate_file fname in - load_vernac ~time ~verbosely ~check ~interactive ~state f - | _ -> + try (* XXX: We need to run this before add as the classification is highly dynamic and depends on the structure of the document. Hopefully this is fixed when VtMeta can be removed @@ -141,13 +103,17 @@ let rec interp_vernac ~time ~check ~interactive ~state (loc,com) = against that... *) let wflags = CWarnings.get_flags () in CWarnings.set_flags "none"; - let is_proof_step = match fst (Vernac_classifier.classify_vernac v) with + let is_proof_step = match fst (Vernac_classifier.classify_vernac com) with | VtProofStep _ | VtMeta | VtStartProof _ -> true | _ -> false in CWarnings.set_flags wflags; - let doc, nsid, ntip = Stm.add ~doc:state.doc ~ontop:state.sid (not !Flags.quiet) (loc,v) in + (* The -time option is only supported from console-based + clients due to the way it prints. *) + if time then print_cmd_header ?loc com; + let com = if time then VernacTime(time,(CAst.make ?loc com)) else com in + let doc, nsid, ntip = Stm.add ~doc:state.doc ~ontop:state.sid (not !Flags.quiet) (loc,com) in (* Main STM interaction *) if ntip <> `NewTip then @@ -167,13 +133,6 @@ let rec interp_vernac ~time ~check ~interactive ~state (loc,com) = if print_goals then Feedback.msg_notice (pr_open_cur_subgoals ()); let new_proof = Proof_global.give_me_the_proof_opt () in { doc = ndoc; sid = nsid; proof = new_proof } - in - try - (* The -time option is only supported from console-based - clients due to the way it prints. *) - if time then print_cmd_header ?loc com; - let com = if time then VernacTime(time, CAst.make ?loc com) else com in - interp com with reraise -> (* XXX: In non-interactive mode edit_at seems to do very weird things, so we better avoid it while we investigate *) @@ -186,18 +145,16 @@ let rec interp_vernac ~time ~check ~interactive ~state (loc,com) = end in iraise (reraise, info) (* Load a vernac file. CErrors are annotated with file and location *) -and load_vernac ~time ~verbosely ~check ~interactive ~state file = - let ft_beautify, close_beautify = - if !Flags.beautify_file then - let chan_beautify = open_out (file^beautify_suffix) in - set_formatter_translator chan_beautify, fun () -> close_out chan_beautify; - else - !Topfmt.std_ft, fun () -> () - in +let load_vernac_core ~time ~echo ~check ~interactive ~state file = + (* Keep in sync *) let in_chan = open_utf8_file_in file in - let in_echo = if verbosely then Some (open_utf8_file_in file) else None in + let in_echo = if echo then Some (open_utf8_file_in file) else None in + let input_cleanup () = close_in in_chan; Option.iter close_in in_echo in + let in_pa = Pcoq.Gram.parsable ~file:(Loc.InFile file) (Stream.of_channel in_chan) in let rstate = ref state in + (* For beautify, list of parsed sids *) + let rids = ref [] in let open State in try (* we go out of the following infinite loop when a End_of_input is @@ -224,36 +181,78 @@ and load_vernac ~time ~verbosely ~check ~interactive ~state file = *) in (* Printing of vernacs *) - if !Flags.beautify then pr_new_syntax ?loc in_pa ft_beautify (Some ast); Option.iter (vernac_echo ?loc) in_echo; checknav_simple (loc, ast); let state = Flags.silently (interp_vernac ~time ~check ~interactive ~state:!rstate) (loc, ast) in + rids := state.sid :: !rids; rstate := state; done; - !rstate + input_cleanup (); + !rstate, !rids, Pcoq.Gram.comment_state in_pa with any -> (* whatever the exception *) let (e, info) = CErrors.push any in - close_in in_chan; - Option.iter close_in in_echo; + input_cleanup (); match e with - | Stm.End_of_input -> - (* Is this called so comments at EOF are printed? *) - if !Flags.beautify then - pr_new_syntax ~loc:(Loc.make_loc (max_int,max_int)) in_pa ft_beautify None; - if !Flags.beautify_file then close_beautify (); - !rstate - | reraise -> - if !Flags.beautify_file then close_beautify (); - iraise (disable_drop e, info) - -(** [eval_expr : ?preserving:bool -> Loc.t * Vernacexpr.vernac_expr -> unit] - It executes one vernacular command. By default the command is - considered as non-state-preserving, in which case we add it to the - Backtrack stack (triggering a save of a frozen state and the generation - of a new state label). An example of state-preserving command is one coming - from the query panel of Coqide. *) + | Stm.End_of_input -> !rstate, !rids, Pcoq.Gram.comment_state in_pa + | reraise -> iraise (disable_drop e, info) let process_expr ~time ~state loc_ast = checknav_deep loc_ast; interp_vernac ~time ~interactive:true ~check:true ~state loc_ast + +(******************************************************************************) +(* Beautify-specific code *) +(******************************************************************************) + +(* vernac parses the given stream, executes interpfun on the syntax tree it + * parses, and is verbose on "primitives" commands if verbosely is true *) +let beautify_suffix = ".beautified" + +let set_formatter_translator ch = + let out s b e = output_substring ch s b e in + let ft = Format.make_formatter out (fun () -> flush ch) in + Format.pp_set_max_boxes ft max_int; + ft + +let pr_new_syntax ?loc ft_beautify ocom = + let loc = Option.cata Loc.unloc (0,0) loc in + let before = comment (Pputils.extract_comments (fst loc)) in + let com = Option.cata Ppvernac.pr_vernac (mt ()) ocom in + let after = comment (Pputils.extract_comments (snd loc)) in + if !Flags.beautify_file then + (Pp.pp_with ft_beautify (hov 0 (before ++ com ++ after)); + Format.pp_print_flush ft_beautify ()) + else + Feedback.msg_info (hov 4 (str"New Syntax:" ++ fnl() ++ (hov 0 com))) + +(* load_vernac with beautify *) +let beautify_pass ~doc ~comments ~ids ~filename = + let ft_beautify, close_beautify = + if !Flags.beautify_file then + let chan_beautify = open_out (filename^beautify_suffix) in + set_formatter_translator chan_beautify, fun () -> close_out chan_beautify; + else + !Topfmt.std_ft, fun () -> () + in + (* The interface to the comment printer is imperative, so we first + set the comments, then we call print. This has to be done for + each file. *) + Pputils.beautify_comments := comments; + List.iter (fun id -> + Option.iter (fun (loc,ast) -> + pr_new_syntax ?loc ft_beautify (Some ast)) + (Stm.get_ast ~doc id)) ids; + + (* Is this called so comments at EOF are printed? *) + pr_new_syntax ~loc:(Loc.make_loc (max_int,max_int)) ft_beautify None; + close_beautify () + +(* Main driver for file loading. For now, we only do one beautify + pass. *) +let load_vernac ~time ~echo ~check ~interactive ~state filename = + let ostate, ids, comments = load_vernac_core ~time ~echo ~check ~interactive ~state filename in + (* Pass for beautify *) + if !Flags.beautify then beautify_pass ~doc:ostate.State.doc ~comments ~ids:List.(rev ids) ~filename; + (* End pass *) + ostate diff --git a/toplevel/vernac.mli b/toplevel/vernac.mli index c7b8ebf44..19bac45c3 100644 --- a/toplevel/vernac.mli +++ b/toplevel/vernac.mli @@ -28,5 +28,5 @@ val process_expr : time:bool -> state:State.t -> Vernacexpr.vernac_control Loc.l (** [load_vernac echo sid file] Loads [file] on top of [sid], will echo the commands if [echo] is set. Callers are expected to handle and print errors in form of exceptions. *) -val load_vernac : time:bool -> verbosely:bool -> check:bool -> interactive:bool -> +val load_vernac : time:bool -> echo:bool -> check:bool -> interactive:bool -> state:State.t -> string -> State.t diff --git a/vernac/classes.ml b/vernac/classes.ml index a580fd25d..25d893bfb 100644 --- a/vernac/classes.ml +++ b/vernac/classes.ml @@ -54,7 +54,7 @@ let _ = let open Vernacexpr in { info with hint_pattern = Option.map - (Constrintern.intern_constr_pattern (Global.env())) + (Constrintern.intern_constr_pattern (Global.env()) Evd.(from_env Global.(env()))) info.hint_pattern } in Flags.silently (fun () -> Hints.add_hints local [typeclasses_db] @@ -336,7 +336,7 @@ let new_instance ?(abstract=false) ?(global=false) ?(refine= !refine_instance) let init_refine = Tacticals.New.tclTHENLIST [ Refine.refine ~typecheck:false (fun sigma -> (sigma,EConstr.of_constr (Option.get term))); - Proofview.Unsafe.tclNEWGOALS gls; + Proofview.Unsafe.tclNEWGOALS (CList.map Proofview.with_empty_state gls); Tactics.New.reduce_after_refine; ] in diff --git a/vernac/comAssumption.ml b/vernac/comAssumption.ml index 08ee197b2..1712634da 100644 --- a/vernac/comAssumption.ml +++ b/vernac/comAssumption.ml @@ -12,7 +12,6 @@ open Pp open CErrors open Util open Vars -open Environ open Declare open Names open Globnames @@ -89,7 +88,6 @@ match local with let interp_assumption sigma env impls bl c = let c = mkCProdN ?loc:(local_binders_loc bl) bl c in let sigma, (ty, impls) = interp_type_evars_impls env sigma ~impls c in - let ty = EConstr.Unsafe.to_constr ty in sigma, (ty, impls) (* When monomorphic the universe constraints are declared with the first declaration only. *) @@ -153,9 +151,9 @@ let do_assumptions kind nl l = let (sigma,_,_),l = List.fold_left_map (fun (sigma,env,ienv) (is_coe,(idl,c)) -> let sigma,(t,imps) = interp_assumption sigma env ienv [] c in let env = - push_named_context (List.map (fun {CAst.v=id} -> LocalAssum (id,t)) idl) env in + EConstr.push_named_context (List.map (fun {CAst.v=id} -> LocalAssum (id,t)) idl) env in let ienv = List.fold_right (fun {CAst.v=id} ienv -> - let impls = compute_internalization_data env Variable t imps in + let impls = compute_internalization_data env sigma Variable t imps in Id.Map.add id impls ienv) idl ienv in ((sigma,env,ienv),((is_coe,idl),t,imps))) (sigma,env,empty_internalization_env) l @@ -163,7 +161,7 @@ let do_assumptions kind nl l = let sigma = solve_remaining_evars all_and_fail_flags env sigma Evd.empty in (* The universe constraints come from the whole telescope. *) let sigma = Evd.nf_constraints sigma in - let nf_evar c = EConstr.to_constr sigma (EConstr.of_constr c) in + let nf_evar c = EConstr.to_constr sigma c in let uvars, l = List.fold_left_map (fun uvars (coe,t,imps) -> let t = nf_evar t in let uvars = Univ.LSet.union uvars (Univops.universes_of_constr env t) in diff --git a/vernac/comFixpoint.ml b/vernac/comFixpoint.ml index 489f299a2..edfe7aa81 100644 --- a/vernac/comFixpoint.ml +++ b/vernac/comFixpoint.ml @@ -212,8 +212,7 @@ let interp_recursive ~program_mode ~cofix fixl notations = let env_rec = push_named_context rec_sign env in (* Get interpretation metadatas *) - let fixtypes = List.map EConstr.Unsafe.to_constr fixtypes in - let impls = compute_internalization_env env Recursive fixnames fixtypes fiximps in + let impls = compute_internalization_env env sigma Recursive fixnames fixtypes fiximps in (* Interp bodies with rollback because temp use of notations/implicit *) let sigma, fixdefs = @@ -226,10 +225,9 @@ let interp_recursive ~program_mode ~cofix fixl notations = (* Instantiate evars and check all are resolved *) let sigma = solve_unif_constraints_with_heuristics env_rec sigma in - let sigma, nf = nf_evars_and_universes sigma in - let fixdefs = List.map (fun c -> Option.map EConstr.Unsafe.to_constr c) fixdefs in - let fixdefs = List.map (Option.map nf) fixdefs in - let fixtypes = List.map nf fixtypes in + let sigma, _ = nf_evars_and_universes sigma in + let fixdefs = List.map (fun c -> Option.map EConstr.(to_constr sigma) c) fixdefs in + let fixtypes = List.map EConstr.(to_constr sigma) fixtypes in let fixctxs = List.map (fun (_,ctx) -> ctx) fixctxs in (* Build the fix declaration block *) diff --git a/vernac/comInductive.ml b/vernac/comInductive.ml index 6444bbc5f..457a1da05 100644 --- a/vernac/comInductive.ml +++ b/vernac/comInductive.ml @@ -13,7 +13,6 @@ open CErrors open Sorts open Util open Constr -open Termops open Environ open Declare open Names @@ -53,7 +52,7 @@ let rec complete_conclusion a cs = CAst.map_with_loc (fun ?loc -> function ) let push_types env idl tl = - List.fold_left2 (fun env id t -> Environ.push_rel (LocalAssum (Name id,t)) env) + List.fold_left2 (fun env id t -> EConstr.push_rel (LocalAssum (Name id,t)) env) env idl tl type structured_one_inductive_expr = { @@ -92,7 +91,7 @@ let check_all_names_different indl = | _ -> raise (InductiveError (SameNamesOverlap l)) let mk_mltype_data sigma env assums arity indname = - let is_ml_type = is_sort env sigma (EConstr.of_constr arity) in + let is_ml_type = is_sort env sigma arity in (is_ml_type,indname,assums) let prepare_param = function @@ -132,14 +131,13 @@ let is_impredicative env u = u = Prop Null || (is_impredicative_set env && u = Prop Pos) let interp_ind_arity env sigma ind = - let c = intern_gen IsType env ind.ind_arity in + let c = intern_gen IsType env sigma ind.ind_arity in let impls = Implicit_quantifiers.implicits_of_glob_constr ~with_products:true c in let sigma,t = understand_tcc env sigma ~expected_type:IsType c in let pseudo_poly = check_anonymous_type c in let () = if not (Reductionops.is_arity env sigma t) then user_err ?loc:(constr_loc ind.ind_arity) (str "Not an arity") in - let t = EConstr.Unsafe.to_constr t in sigma, (t, pseudo_poly, impls) let interp_cstrs env sigma impls mldata arity ind = @@ -274,7 +272,6 @@ let interp_mutual_inductive (paramsl,indl) notations cum poly prv finite = let sigma, (impls, ((env_params, ctx_params), userimpls)) = interp_context_evars env0 sigma paramsl in - let ctx_params = List.map (fun d -> map_rel_decl EConstr.Unsafe.to_constr d) ctx_params in let indnames = List.map (fun ind -> ind.ind_name) indl in (* Names of parameters as arguments of the inductive type (defs removed) *) @@ -284,16 +281,16 @@ let interp_mutual_inductive (paramsl,indl) notations cum poly prv finite = (* Interpret the arities *) let sigma, arities = List.fold_left_map (fun sigma -> interp_ind_arity env_params sigma) sigma indl in - let fullarities = List.map (fun (c, _, _) -> Term.it_mkProd_or_LetIn c ctx_params) arities in + let fullarities = List.map (fun (c, _, _) -> EConstr.it_mkProd_or_LetIn c ctx_params) arities in let env_ar = push_types env0 indnames fullarities in - let env_ar_params = push_rel_context ctx_params env_ar in + let env_ar_params = EConstr.push_rel_context ctx_params env_ar in (* Compute interpretation metadatas *) let indimpls = List.map (fun (_, _, impls) -> userimpls @ lift_implicits (Context.Rel.nhyps ctx_params) impls) arities in let arities = List.map pi1 arities and aritypoly = List.map pi2 arities in - let impls = compute_internalization_env env0 ~impls (Inductive (params,true)) indnames fullarities indimpls in - let ntn_impls = compute_internalization_env env0 (Inductive (params,true)) indnames fullarities indimpls in + let impls = compute_internalization_env env0 sigma ~impls (Inductive (params,true)) indnames fullarities indimpls in + let ntn_impls = compute_internalization_env env0 sigma (Inductive (params,true)) indnames fullarities indimpls in let mldatas = List.map2 (mk_mltype_data sigma env_params params) arities indnames in let sigma, constructors = @@ -308,15 +305,14 @@ let interp_mutual_inductive (paramsl,indl) notations cum poly prv finite = let sigma = solve_remaining_evars all_and_fail_flags env_params sigma Evd.empty in (* Compute renewed arities *) let sigma, nf = nf_evars_and_universes sigma in - let arities = List.map nf arities in let constructors = List.map (fun (idl,cl,impsl) -> (idl,List.map nf cl,impsl)) constructors in + let arities = List.map EConstr.(to_constr sigma) arities in let sigma = List.fold_left2 (fun sigma ty poly -> make_conclusion_flexible sigma ty poly) sigma arities aritypoly in let sigma, arities = inductive_levels env_ar_params sigma poly arities constructors in let sigma, nf' = nf_evars_and_universes sigma in - let nf x = nf' (nf x) in let arities = List.map nf' arities in let constructors = List.map (fun (idl,cl,impsl) -> (idl,List.map nf' cl,impsl)) constructors in - let ctx_params = Context.Rel.map nf ctx_params in + let ctx_params = List.map Termops.(map_rel_decl (EConstr.to_constr sigma)) ctx_params in let uctx = Evd.check_univ_decl ~poly sigma decl in List.iter (fun c -> check_evars env_params Evd.empty sigma (EConstr.of_constr c)) arities; Context.Rel.iter (fun c -> check_evars env0 Evd.empty sigma (EConstr.of_constr c)) ctx_params; diff --git a/vernac/comProgramFixpoint.ml b/vernac/comProgramFixpoint.ml index af34f8b29..bd7ee0978 100644 --- a/vernac/comProgramFixpoint.ml +++ b/vernac/comProgramFixpoint.ml @@ -171,8 +171,8 @@ let build_wellfounded (recname,pl,n,bl,arityc,body) poly r measure notation = let sigma, intern_body = let ctx = LocalAssum (Name recname, get_type curry_fun) :: binders_rel in let (r, l, impls, scopes) = - Constrintern.compute_internalization_data env - Constrintern.Recursive (EConstr.Unsafe.to_constr full_arity) impls + Constrintern.compute_internalization_data env sigma + Constrintern.Recursive full_arity impls in let newimpls = Id.Map.singleton recname (r, l, impls @ [(Some (Id.of_string "recproof", Impargs.Manual, (true, false)))], diff --git a/vernac/obligations.ml b/vernac/obligations.ml index e4bcbc4bb..6447fc350 100644 --- a/vernac/obligations.ml +++ b/vernac/obligations.ml @@ -816,13 +816,13 @@ let solve_by_tac name evi t poly ctx = let id = name in let concl = EConstr.of_constr evi.evar_concl in (* spiwack: the status is dropped. *) - let (entry,_,ctx') = Pfedit.build_constant_by_tactic + let (entry,_,ctx') = Pfedit.build_constant_by_tactic id ~goal_kind:(goal_kind poly) ctx evi.evar_hyps concl (Tacticals.New.tclCOMPLETE t) in let env = Global.env () in let entry = Safe_typing.inline_private_constants_in_definition_entry env entry in let body, () = Future.force entry.const_entry_body in let ctx' = Evd.merge_context_set ~sideff:true Evd.univ_rigid (Evd.from_ctx ctx') (snd body) in - Inductiveops.control_only_guard (Global.env ()) (fst body); + Inductiveops.control_only_guard env ctx' (EConstr.of_constr (fst body)); (fst body), entry.const_entry_type, Evd.evar_universe_context ctx' let obligation_terminator name num guard hook auto pf = @@ -838,7 +838,7 @@ let obligation_terminator name num guard hook auto pf = let (body, cstr), () = Future.force entry.Entries.const_entry_body in let sigma = Evd.from_ctx uctx in let sigma = Evd.merge_context_set ~sideff:true Evd.univ_rigid sigma cstr in - Inductiveops.control_only_guard (Global.env ()) body; + Inductiveops.control_only_guard (Global.env ()) sigma (EConstr.of_constr body); (** Declare the obligation ourselves and drop the hook *) let prg = get_info (ProgMap.find name !from_prg) in (** Ensure universes are substituted properly in body and type *) diff --git a/vernac/record.ml b/vernac/record.ml index fa6c87f28..1991a8640 100644 --- a/vernac/record.ml +++ b/vernac/record.ml @@ -72,7 +72,7 @@ let interp_fields_evars env sigma impls_env nots l = let impls = match i with | Anonymous -> impls - | Name id -> Id.Map.add id (compute_internalization_data env Constrintern.Method (EConstr.to_constr sigma t') impl) impls + | Name id -> Id.Map.add id (compute_internalization_data env sigma Constrintern.Method t' impl) impls in let d = match b' with | None -> LocalAssum (i,t') @@ -147,7 +147,7 @@ let typecheck_params_and_fields finite def id poly pl t ps nots fs = let assums = List.filter is_local_assum newps in let params = List.map (RelDecl.get_name %> Name.get_id) assums in let ty = Inductive (params,(finite != Declarations.BiFinite)) in - let impls_env = compute_internalization_env env0 ~impls:impls_env ty [id] [EConstr.to_constr sigma arity] [imps] in + let impls_env = compute_internalization_env env0 sigma ~impls:impls_env ty [id] [arity] [imps] in let env2,sigma,impls,newfs,data = interp_fields_evars env_ar sigma impls_env nots (binders_of_decls fs) in diff --git a/vernac/vernacentries.ml b/vernac/vernacentries.ml index 8630bf27a..0ff6d9c17 100644 --- a/vernac/vernacentries.ml +++ b/vernac/vernacentries.ml @@ -1027,7 +1027,9 @@ let vernac_arguments ~atts reference args more_implicits nargs_for_red flags = let sr = smart_global reference in let inf_names = let ty, _ = Global.type_of_global_in_context (Global.env ()) sr in - Impargs.compute_implicits_names (Global.env ()) ty + let env = Global.env () in + let sigma = Evd.from_env env in + Impargs.compute_implicits_names env sigma (EConstr.of_constr ty) in let prev_names = try Arguments_renaming.arguments_names sr with Not_found -> inf_names @@ -1255,7 +1257,7 @@ let vernac_reserve bl = let env = Global.env() in let sigma = Evd.from_env env in let t,ctx = Constrintern.interp_type env sigma c in - let t = Detyping.detype Detyping.Now false Id.Set.empty env (Evd.from_ctx ctx) (EConstr.of_constr t) in + let t = Detyping.detype Detyping.Now false Id.Set.empty env (Evd.from_ctx ctx) t in let t,_ = Notation_ops.notation_constr_of_glob_constr (default_env ()) t in Reserve.declare_reserved_type idl t) in List.iter sb_decl bl @@ -1629,6 +1631,7 @@ let vernac_global_check c = let senv = Global.safe_env() in let uctx = UState.context_set uctx in let senv = Safe_typing.push_context_set false uctx senv in + let c = EConstr.to_constr sigma c in let j = Safe_typing.typing senv c in let env = Safe_typing.env_of_safe_env senv in print_safe_judgment env sigma j ++ @@ -1749,10 +1752,10 @@ let interp_search_restriction = function open Search -let interp_search_about_item env = +let interp_search_about_item env sigma = function | SearchSubPattern pat -> - let _,pat = intern_constr_pattern env pat in + let _,pat = intern_constr_pattern env sigma pat in GlobSearchSubPattern pat | SearchString (s,None) when Id.is_valid s -> GlobSearchString s @@ -1798,13 +1801,13 @@ let vernac_search ~atts s gopt r = (* if goal selector is given and wrong, then let exceptions be raised. *) | Some g -> snd (Pfedit.get_goal_context g) , Some g in - let get_pattern c = snd (intern_constr_pattern env c) in + let get_pattern c = snd (intern_constr_pattern env Evd.(from_env env) c) in let pr_search ref env c = let pr = pr_global ref in let pp = if !search_output_name_only then pr else begin - let pc = pr_lconstr_env env Evd.empty c in + let pc = pr_lconstr_env env Evd.(from_env env) c in hov 2 (pr ++ str":" ++ spc () ++ pc) end in Feedback.msg_notice pp @@ -1817,7 +1820,8 @@ let vernac_search ~atts s gopt r = | SearchHead c -> (Search.search_by_head gopt (get_pattern c) r |> Search.prioritize_search) pr_search | SearchAbout sl -> - (Search.search_about gopt (List.map (on_snd (interp_search_about_item env)) sl) r |> Search.prioritize_search) pr_search + (Search.search_about gopt (List.map (on_snd (interp_search_about_item env Evd.(from_env env))) sl) r |> + Search.prioritize_search) pr_search let vernac_locate = function | LocateAny (AN qid) -> print_located_qualid qid @@ -1912,8 +1916,7 @@ let vernac_check_guard () = let message = try let { Evd.it=gl ; sigma=sigma } = Proof.V82.top_goal pts in - Inductiveops.control_only_guard (Goal.V82.env sigma gl) - (EConstr.Unsafe.to_constr pfterm); + Inductiveops.control_only_guard (Goal.V82.env sigma gl) sigma pfterm; (str "The condition holds up to here") with UserError(_,s) -> (str ("Condition violated: ") ++s) @@ -1928,6 +1931,8 @@ exception End_of_input without a considerable amount of refactoring. *) let vernac_load interp fname = + if Proof_global.there_are_pending_proofs () then + CErrors.user_err Pp.(str "Load is not supported inside proofs."); let interp x = let proof_mode = Proof_global.get_default_proof_mode_name () [@ocaml.warning "-3"] in Proof_global.activate_proof_mode proof_mode [@ocaml.warning "-3"]; @@ -1944,8 +1949,13 @@ let vernac_load interp fname = let longfname = Loadpath.locate_file fname in let in_chan = open_utf8_file_in longfname in Pcoq.Gram.parsable ~file:(Loc.InFile longfname) (Stream.of_channel in_chan) in - try while true do interp (snd (parse_sentence input)) done - with End_of_input -> () + begin + try while true do interp (snd (parse_sentence input)) done + with End_of_input -> () + end; + (* If Load left a proof open, we fail too. *) + if Proof_global.there_are_pending_proofs () then + CErrors.user_err Pp.(str "Files processed by Load cannot leave open proofs.") (* "locality" is the prefix "Local" attribute, while the "local" component * is the outdated/deprecated "Local" attribute of some vernacular commands @@ -1956,6 +1966,7 @@ let interp ?proof ~atts ~st c = vernac_pperr_endline (fun () -> str "interpreting: " ++ Ppvernac.pr_vernac_expr c); match c with + (* Loading a file requires access to the control interpreter *) | VernacLoad _ -> assert false (* The STM should handle that, but LOAD bypasses the STM... *) |