aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.circleci/config.yml13
-rw-r--r--.travis.yml100
-rw-r--r--CHANGES3
-rw-r--r--README.md1
-rw-r--r--checker/checker.ml3
-rw-r--r--checker/closure.ml45
-rw-r--r--checker/closure.mli12
-rw-r--r--checker/declarations.ml4
-rw-r--r--checker/environ.ml24
-rw-r--r--checker/environ.mli2
-rw-r--r--checker/indtypes.ml28
-rw-r--r--checker/inductive.ml16
-rw-r--r--checker/reduction.ml30
-rw-r--r--checker/univ.ml34
-rw-r--r--checker/univ.mli15
-rw-r--r--checker/values.ml4
-rw-r--r--dev/ci/ci-basic-overlay.sh104
-rw-r--r--dev/ci/ci-common.sh45
-rwxr-xr-xdev/ci/ci-compcert.sh2
-rwxr-xr-xdev/ci/ci-iris-lambda-rust.sh4
-rw-r--r--dev/ci/user-overlays/06535-fix-push-rel-to-named.sh4
-rw-r--r--dev/ci/user-overlays/06686-ccnv-no-proj.sh4
-rw-r--r--dev/doc/COMPATIBILITY (renamed from COMPATIBILITY)7
-rw-r--r--dev/doc/changes.md11
-rwxr-xr-xdev/lint-repository.sh13
-rwxr-xr-xdev/tools/check-eof-newline.sh19
-rwxr-xr-xdev/tools/merge-pr.sh20
-rwxr-xr-xdev/tools/should-check-whitespace.sh6
-rwxr-xr-xdev/tools/sudo-apt-get-update.sh4
-rw-r--r--dev/vm_printers.ml2
-rw-r--r--doc/refman/RefMan-oth.tex9
-rw-r--r--doc/refman/Universes.tex39
-rw-r--r--engine/evarutil.ml119
-rw-r--r--engine/evarutil.mli5
-rw-r--r--engine/proofview.ml5
-rw-r--r--engine/proofview.mli2
-rw-r--r--engine/universes.ml11
-rw-r--r--engine/universes.mli6
-rw-r--r--ide/coq_lex.mll6
-rwxr-xr-xinstall.sh8
-rw-r--r--interp/constrexpr_ops.ml8
-rw-r--r--interp/constrextern.ml3
-rw-r--r--interp/constrintern.ml8
-rw-r--r--interp/declare.ml7
-rw-r--r--interp/discharge.ml2
-rw-r--r--interp/notation_ops.ml19
-rw-r--r--intf/constrexpr.ml1
-rw-r--r--intf/glob_term.ml1
-rw-r--r--intf/notation_term.ml1
-rw-r--r--intf/pattern.ml2
-rw-r--r--intf/vernacexpr.ml8
-rw-r--r--kernel/cClosure.ml23
-rw-r--r--kernel/cClosure.mli4
-rw-r--r--kernel/constr.ml5
-rw-r--r--kernel/constr.mli4
-rw-r--r--kernel/csymtable.ml2
-rw-r--r--kernel/csymtable.mli2
-rw-r--r--kernel/environ.ml23
-rw-r--r--kernel/environ.mli4
-rw-r--r--kernel/indtypes.ml22
-rw-r--r--kernel/inductive.ml24
-rw-r--r--kernel/kernel.mllib1
-rw-r--r--kernel/nativecode.ml23
-rw-r--r--kernel/nativecode.mli2
-rw-r--r--kernel/nativeconv.ml11
-rw-r--r--kernel/nativeinstr.mli2
-rw-r--r--kernel/nativelambda.ml5
-rw-r--r--kernel/nativelib.ml5
-rw-r--r--kernel/nativevalues.ml18
-rw-r--r--kernel/nativevalues.mli6
-rw-r--r--kernel/pre_env.ml3
-rw-r--r--kernel/pre_env.mli4
-rw-r--r--kernel/reduction.ml296
-rw-r--r--kernel/reduction.mli16
-rw-r--r--kernel/term.ml2
-rw-r--r--kernel/term.mli4
-rw-r--r--kernel/univ.ml136
-rw-r--r--kernel/univ.mli58
-rw-r--r--kernel/vconv.ml1
-rw-r--r--kernel/vconv.mli2
-rw-r--r--kernel/vm.ml546
-rw-r--r--kernel/vm.mli106
-rw-r--r--kernel/vmvalues.ml525
-rw-r--r--kernel/vmvalues.mli144
-rw-r--r--lib/flags.ml18
-rw-r--r--library/globnames.ml2
-rw-r--r--parsing/g_proofs.ml43
-rw-r--r--parsing/g_vernac.ml418
-rw-r--r--plugins/funind/functional_principles_proofs.ml15
-rw-r--r--plugins/funind/functional_principles_types.mli4
-rw-r--r--plugins/funind/glob_term_to_relation.ml4
-rw-r--r--plugins/funind/glob_termops.ml166
-rw-r--r--plugins/funind/glob_termops.mli30
-rw-r--r--plugins/funind/indfun.ml3
-rw-r--r--plugins/funind/indfun_common.ml1
-rw-r--r--plugins/funind/invfun.ml22
-rw-r--r--plugins/funind/invfun.mli17
-rw-r--r--plugins/funind/merge.ml1013
-rw-r--r--plugins/funind/recdef.mli1
-rw-r--r--plugins/funind/recdef_plugin.mlpack1
-rw-r--r--plugins/ltac/rewrite.ml13
-rw-r--r--plugins/omega/coq_omega.ml2
-rw-r--r--plugins/ssr/ssrcommon.ml4
-rw-r--r--plugins/ssr/ssrvernac.ml42
-rw-r--r--pretyping/cases.ml6
-rw-r--r--pretyping/cbv.ml2
-rw-r--r--pretyping/detyping.ml14
-rw-r--r--pretyping/evarconv.ml14
-rw-r--r--pretyping/evardefine.ml4
-rw-r--r--pretyping/glob_ops.ml10
-rw-r--r--pretyping/inductiveops.ml146
-rw-r--r--pretyping/inductiveops.mli9
-rw-r--r--pretyping/inferCumulativity.ml224
-rw-r--r--pretyping/inferCumulativity.mli10
-rw-r--r--pretyping/nativenorm.ml28
-rw-r--r--pretyping/patternops.ml6
-rw-r--r--pretyping/pretyping.ml12
-rw-r--r--pretyping/pretyping.mllib1
-rw-r--r--pretyping/recordops.ml27
-rw-r--r--pretyping/reductionops.ml86
-rw-r--r--pretyping/reductionops.mli6
-rw-r--r--pretyping/tacred.ml16
-rw-r--r--pretyping/typing.mli1
-rw-r--r--pretyping/unification.ml4
-rw-r--r--pretyping/vnorm.ml15
-rw-r--r--printing/ppconstr.ml3
-rw-r--r--printing/ppvernac.ml25
-rw-r--r--printing/prettyp.ml11
-rw-r--r--printing/printer.ml4
-rw-r--r--printing/printer.mli3
-rw-r--r--printing/printmod.ml3
-rw-r--r--proofs/clenv.ml2
-rw-r--r--proofs/logic.ml4
-rw-r--r--proofs/proof_global.ml7
-rw-r--r--proofs/tacmach.ml2
-rw-r--r--stm/stm.ml151
-rw-r--r--stm/stm.mli73
-rw-r--r--stm/vernac_classifier.ml17
-rw-r--r--tactics/class_tactics.ml2
-rw-r--r--tactics/equality.ml2
-rw-r--r--tactics/tactics.ml8
-rw-r--r--test-suite/bugs/closed/5286.v9
-rw-r--r--test-suite/bugs/closed/6534.v7
-rw-r--r--test-suite/coqchk/include.v11
-rw-r--r--test-suite/coqchk/primproj2.v10
-rw-r--r--test-suite/output/ErrorInCanonicalStructures.out5
-rw-r--r--test-suite/output/ErrorInCanonicalStructures.v3
-rw-r--r--test-suite/output/ErrorInCanonicalStructures2.out5
-rw-r--r--test-suite/output/ErrorInCanonicalStructures2.v3
-rw-r--r--test-suite/output/UnivBinders.out2
-rw-r--r--test-suite/success/cumulativity.v26
-rw-r--r--theories/Lists/List.v27
-rw-r--r--toplevel/coqinit.ml114
-rw-r--r--toplevel/coqinit.mli7
-rw-r--r--toplevel/coqtop.ml106
-rw-r--r--vernac/comInductive.ml4
-rw-r--r--vernac/explainErr.ml1
-rw-r--r--vernac/himsg.ml22
-rw-r--r--vernac/lemmas.ml32
-rw-r--r--vernac/lemmas.mli2
-rw-r--r--vernac/mltop.ml34
-rw-r--r--vernac/mltop.mli24
-rw-r--r--vernac/record.ml15
-rw-r--r--vernac/vernacentries.ml39
164 files changed, 2557 insertions, 3126 deletions
diff --git a/.circleci/config.yml b/.circleci/config.yml
index c49bc3b08b..9b0cc21197 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -54,10 +54,17 @@ opam-switch: &opam-switch
steps:
- checkout
- run: *before_script
+ - run:
+ name: Cache selection
+ command: |
+ source ~/.profile
+ # We can't use environment variables in cache names
+ # So put it in a file and use the checksum
+ echo "$COMPILER" > COMPILER
- restore_cache:
keys:
- - coq-opam-cache-v1-{{ arch }}-{{ .Environment.COMPILER }}-{{ checksum ".circleci/config.yml" }}-
- - coq-opam-cache-v1-{{ arch }}-{{ .Environment.COMPILER }}- # this grabs old cache if checksum doesn't match
+ - coq-opam-cache-v1-{{ arch }}-{{ checksum "COMPILER" }}-{{ checksum ".circleci/config.yml" }}-
+ - coq-opam-cache-v1-{{ arch }}-{{ checksum "COMPILER" }}- # this grabs old cache if checksum doesn't match
- run:
name: Update opam lists
command: |
@@ -76,7 +83,7 @@ opam-switch: &opam-switch
source ~/.profile
rm -rf ~/.opam/log/
- save_cache:
- key: coq-opam-cache-v1-{{ arch }}-{{ .Environment.COMPILER }}-{{ checksum ".circleci/config.yml" }}-
+ key: coq-opam-cache-v1-{{ arch }}-{{ checksum "COMPILER" }}-{{ checksum ".circleci/config.yml" }}-
paths:
- ~/.opam
- persist_to_workspace:
diff --git a/.travis.yml b/.travis.yml
index 8f1f1e699b..19e7075f22 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -20,10 +20,19 @@ addons:
apt:
sources:
- avsm
- packages:
- - opam
- - aspcud
- - gcc-multilib
+## Due to issues like
+## https://github.com/travis-ci/travis-ci/issues/8507 ,
+## https://github.com/travis-ci/travis-ci/issues/9000 ,
+## https://github.com/travis-ci/travis-ci/issues/9081 , and
+## https://github.com/travis-ci/travis-ci/issues/9126 , we get frequent
+## failures with using `packages`. Therefore, for most targets, we
+## instead invoke `apt-get update` manually with `travis_retry` before
+## invoking `apt-get install`, manually, below in the `install:`
+## target.
+# packages:
+# - opam
+# - aspcud
+# - gcc-multilib
env:
global:
@@ -46,33 +55,68 @@ env:
- TEST_TARGET="validate" TW="travis_wait"
- TEST_TARGET="validate" COMPILER="4.02.3+32bit" TW="travis_wait"
- TEST_TARGET="validate" COMPILER="${COMPILER_BE}+flambda" CAMLP5_VER="${CAMLP5_VER_BE}" NATIVE_COMP="no" EXTRA_CONF="-flambda-opts -O3" EXTRA_OPAM="num" FINDLIB_VER="${FINDLIB_VER_BE}"
- - TEST_TARGET="ci-bignums"
- - TEST_TARGET="ci-color"
- - TEST_TARGET="ci-compcert"
- - TEST_TARGET="ci-coq-dpdgraph" EXTRA_OPAM="ocamlgraph"
- - TEST_TARGET="ci-coquelicot"
- - TEST_TARGET="ci-equations"
- - TEST_TARGET="ci-geocoq"
- - TEST_TARGET="ci-fiat-crypto"
- - TEST_TARGET="ci-fiat-parsers"
- - TEST_TARGET="ci-flocq"
- - TEST_TARGET="ci-formal-topology"
- - TEST_TARGET="ci-hott"
- - TEST_TARGET="ci-iris-lambda-rust"
- - TEST_TARGET="ci-ltac2"
- - TEST_TARGET="ci-math-classes"
- - TEST_TARGET="ci-math-comp"
- - TEST_TARGET="ci-sf"
- - TEST_TARGET="ci-unimath"
- - TEST_TARGET="ci-vst"
- # Not ready yet for 8.7
- # - TEST_TARGET="ci-cpdt"
- # - TEST_TARGET="ci-metacoq"
- # - TEST_TARGET="ci-tlc"
matrix:
include:
+ - if: NOT (type = pull_request)
+ env:
+ - TEST_TARGET="ci-bignums"
+ - if: NOT (type = pull_request)
+ env:
+ - TEST_TARGET="ci-color"
+ - if: NOT (type = pull_request)
+ env:
+ - TEST_TARGET="ci-compcert"
+ - if: NOT (type = pull_request)
+ env:
+ - TEST_TARGET="ci-coq-dpdgraph" EXTRA_OPAM="ocamlgraph"
+ - if: NOT (type = pull_request)
+ env:
+ - TEST_TARGET="ci-coquelicot"
+ - if: NOT (type = pull_request)
+ env:
+ - TEST_TARGET="ci-equations"
+ - if: NOT (type = pull_request)
+ env:
+ - TEST_TARGET="ci-geocoq"
+ - if: NOT (type = pull_request)
+ env:
+ - TEST_TARGET="ci-fiat-crypto"
+ - if: NOT (type = pull_request)
+ env:
+ - TEST_TARGET="ci-fiat-parsers"
+ - if: NOT (type = pull_request)
+ env:
+ - TEST_TARGET="ci-flocq"
+ - if: NOT (type = pull_request)
+ env:
+ - TEST_TARGET="ci-formal-topology"
+ - if: NOT (type = pull_request)
+ env:
+ - TEST_TARGET="ci-hott"
+ - if: NOT (type = pull_request)
+ env:
+ - TEST_TARGET="ci-iris-lambda-rust"
+ - if: NOT (type = pull_request)
+ env:
+ - TEST_TARGET="ci-ltac2"
+ - if: NOT (type = pull_request)
+ env:
+ - TEST_TARGET="ci-math-classes"
+ - if: NOT (type = pull_request)
+ env:
+ - TEST_TARGET="ci-math-comp"
+ - if: NOT (type = pull_request)
+ env:
+ - TEST_TARGET="ci-sf"
+ - if: NOT (type = pull_request)
+ env:
+ - TEST_TARGET="ci-unimath"
+ - if: NOT (type = pull_request)
+ env:
+ - TEST_TARGET="ci-vst"
+
- env:
- TEST_TARGET="lint"
install: []
@@ -212,6 +256,8 @@ before_install:
- if [ "${TRAVIS_PULL_REQUEST}" != "false" ]; then echo "Tested commit (followed by parent commits):"; git log -1; for commit in `git log -1 --format="%P"`; do echo; git log -1 $commit; done; fi
install:
+- if [ "${TRAVIS_OS_NAME}" == "linux" ]; then travis_retry ./dev/tools/sudo-apt-get-update.sh -q; fi
+- if [ "${TRAVIS_OS_NAME}" == "linux" ]; then sudo apt-get install -y opam aspcud gcc-multilib; fi
- opam init -j ${NJOBS} --compiler=${COMPILER} -n -y
- eval $(opam config env)
- opam config list
diff --git a/CHANGES b/CHANGES
index 8c9b51b86b..cb4b966b08 100644
--- a/CHANGES
+++ b/CHANGES
@@ -53,6 +53,9 @@ Focusing
Vernacular Commands
+- Proofs ending in "Qed exporting ident, .., ident" are not supported
+ anymore. Constants generated during `abstract` are kept private to the
+ local environment.
- The deprecated Coercion Local, Open Local Scope, Notation Local syntax
was removed. Use Local as a prefix instead.
- For the Extraction Language command, "OCaml" is spelled correctly.
diff --git a/README.md b/README.md
index fae83e02cf..883630acf1 100644
--- a/README.md
+++ b/README.md
@@ -4,6 +4,7 @@
[![Appveyor](https://ci.appveyor.com/api/projects/status/eln43k05pa2vm908/branch/master?svg=true)](https://ci.appveyor.com/project/coq/coq/branch/master)
[![Circle CI](https://circleci.com/gh/coq/coq/tree/master.svg?style=shield)](https://circleci.com/gh/coq/workflows/coq/tree/master)
[![Gitter](https://badges.gitter.im/coq/coq.svg)](https://gitter.im/coq/coq)
+[![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.1003420.svg)](https://doi.org/10.5281/zenodo.1003420)
Coq is a formal proof management system. It provides a formal language to write
mathematical definitions, executable algorithms and theorems together with an
diff --git a/checker/checker.ml b/checker/checker.ml
index fee31b6675..b8b4d5dc2c 100644
--- a/checker/checker.ml
+++ b/checker/checker.ml
@@ -208,8 +208,7 @@ let usage () =
open Type_errors
let anomaly_string () = str "Anomaly: "
-let report () = (str "." ++ spc () ++ str "Please report" ++
- strbrk "at " ++ str Coq_config.wwwbugtracker ++ str ".")
+let report () = strbrk (". Please report at " ^ Coq_config.wwwbugtracker ^ ".")
let guill s = str "\"" ++ str s ++ str "\""
diff --git a/checker/closure.ml b/checker/closure.ml
index 98f8c4a826..14b31e09d6 100644
--- a/checker/closure.ml
+++ b/checker/closure.ml
@@ -49,13 +49,6 @@ let with_stats c =
end else
Lazy.force c
-type transparent_state = Id.Pred.t * Cpred.t
-let all_opaque = (Id.Pred.empty, Cpred.empty)
-let all_transparent = (Id.Pred.full, Cpred.full)
-
-let is_transparent_variable (ids, _) id = Id.Pred.mem id ids
-let is_transparent_constant (_, csts) cst = Cpred.mem cst csts
-
module type RedFlagsSig = sig
type reds
type red_kind
@@ -63,8 +56,6 @@ module type RedFlagsSig = sig
val fDELTA : red_kind
val fIOTA : red_kind
val fZETA : red_kind
- val fCONST : Constant.t -> red_kind
- val fVAR : Id.t -> red_kind
val no_red : reds
val red_add : reds -> red_kind -> reds
val mkflags : red_kind list -> reds
@@ -80,51 +71,33 @@ module RedFlags = (struct
type reds = {
r_beta : bool;
r_delta : bool;
- r_const : transparent_state;
r_zeta : bool;
r_evar : bool;
r_iota : bool }
type red_kind = BETA | DELTA | IOTA | ZETA
- | CONST of Constant.t | VAR of Id.t
+
let fBETA = BETA
let fDELTA = DELTA
let fIOTA = IOTA
let fZETA = ZETA
- let fCONST kn = CONST kn
- let fVAR id = VAR id
let no_red = {
r_beta = false;
r_delta = false;
- r_const = all_opaque;
r_zeta = false;
r_evar = false;
r_iota = false }
let red_add red = function
| BETA -> { red with r_beta = true }
- | DELTA -> { red with r_delta = true; r_const = all_transparent }
- | CONST kn ->
- let (l1,l2) = red.r_const in
- { red with r_const = l1, Cpred.add kn l2 }
+ | DELTA -> { red with r_delta = true}
| IOTA -> { red with r_iota = true }
| ZETA -> { red with r_zeta = true }
- | VAR id ->
- let (l1,l2) = red.r_const in
- { red with r_const = Id.Pred.add id l1, l2 }
let mkflags = List.fold_left red_add no_red
let red_set red = function
| BETA -> incr_cnt red.r_beta beta
- | CONST kn ->
- let (_,l) = red.r_const in
- let c = Cpred.mem kn l in
- incr_cnt c delta
- | VAR id -> (* En attendant d'avoir des kn pour les Var *)
- let (l,_) = red.r_const in
- let c = Id.Pred.mem id l in
- incr_cnt c delta
| ZETA -> incr_cnt red.r_zeta zeta
| IOTA -> incr_cnt red.r_iota iota
| DELTA -> (* Used for Rel/Var defined in context *)
@@ -700,6 +673,9 @@ let contract_fix_vect fix =
in
(subs_cons(Array.init nfix make_body, env), thisbody)
+let unfold_projection env p =
+ let pb = lookup_projection p env in
+ Zproj (pb.proj_npars, pb.proj_arg, p)
(*********************************************************************)
(* A machine that inspects the head of a term until it finds an
@@ -720,10 +696,9 @@ let rec knh info m stk =
| FCast(t,_,_) -> knh info t stk
| FProj (p,c) ->
- if red_set info.i_flags (fCONST (Projection.constant p)) then
- (let pb = lookup_projection p (info.i_env) in
- knh info c (Zproj (pb.proj_npars, pb.proj_arg, p)
- :: zupdate m stk))
+ if red_set info.i_flags fDELTA then
+ let s = unfold_projection info.i_env p in
+ knh info c (s :: zupdate m stk)
else (m,stk)
(* cases where knh stops *)
@@ -755,11 +730,11 @@ let rec knr info m stk =
(match get_args n tys f e stk with
Inl e', s -> knit info e' f s
| Inr lam, s -> (lam,s))
- | FFlex(ConstKey kn) when red_set info.i_flags (fCONST (fst kn)) ->
+ | FFlex(ConstKey kn) when red_set info.i_flags fDELTA ->
(match ref_value_cache info (ConstKey kn) with
Some v -> kni info v stk
| None -> (set_norm m; (m,stk)))
- | FFlex(VarKey id) when red_set info.i_flags (fVAR id) ->
+ | FFlex(VarKey id) when red_set info.i_flags fDELTA ->
(match ref_value_cache info (VarKey id) with
Some v -> kni info v stk
| None -> (set_norm m; (m,stk)))
diff --git a/checker/closure.mli b/checker/closure.mli
index ce8c64e307..7bdc21b605 100644
--- a/checker/closure.mli
+++ b/checker/closure.mli
@@ -24,14 +24,6 @@ val with_stats: 'a Lazy.t -> 'a
Rem: reduction of a Rel/Var bound to a term is Delta, but reduction of
a LetIn expression is Letin reduction *)
-type transparent_state = Id.Pred.t * Cpred.t
-
-val all_opaque : transparent_state
-val all_transparent : transparent_state
-
-val is_transparent_variable : transparent_state -> variable -> bool
-val is_transparent_constant : transparent_state -> Constant.t -> bool
-
(* Sets of reduction kinds. *)
module type RedFlagsSig = sig
type reds
@@ -42,8 +34,6 @@ module type RedFlagsSig = sig
val fDELTA : red_kind
val fIOTA : red_kind
val fZETA : red_kind
- val fCONST : Constant.t -> red_kind
- val fVAR : Id.t -> red_kind
(* No reduction at all *)
val no_red : reds
@@ -131,6 +121,8 @@ val eta_expand_stack : stack -> stack
val eta_expand_ind_stack : env -> inductive -> fconstr -> stack ->
(fconstr * stack) -> stack * stack
+val unfold_projection : env -> Projection.t -> stack_member
+
(* To lazy reduce a constr, create a [clos_infos] with
[create_clos_infos], inject the term to reduce with [inject]; then use
a reduction function *)
diff --git a/checker/declarations.ml b/checker/declarations.ml
index 884a1ef18c..15b1f0a0c6 100644
--- a/checker/declarations.ml
+++ b/checker/declarations.ml
@@ -484,8 +484,8 @@ let subst_wf_paths sub p = Rtree.smartmap (subst_recarg sub) p
let eq_recarg r1 r2 = match r1, r2 with
| Norec, Norec -> true
- | Mrec i1, Mrec i2 -> Names.eq_ind i1 i2
- | Imbr i1, Imbr i2 -> Names.eq_ind i1 i2
+ | Mrec i1, Mrec i2 -> Names.eq_ind_chk i1 i2
+ | Imbr i1, Imbr i2 -> Names.eq_ind_chk i1 i2
| _ -> false
let eq_wf_paths = Rtree.equal eq_recarg
diff --git a/checker/environ.ml b/checker/environ.ml
index 3830cd0dc2..bbd043c8e9 100644
--- a/checker/environ.ml
+++ b/checker/environ.ml
@@ -126,7 +126,7 @@ let add_constant kn cs env =
env_constants = new_constants } in
{ env with env_globals = new_globals }
-type const_evaluation_result = NoBody | Opaque | IsProj
+type const_evaluation_result = NoBody | Opaque
(* Constant types *)
@@ -148,18 +148,16 @@ exception NotEvaluableConst of const_evaluation_result
let constant_value env (kn,u) =
let cb = lookup_constant kn env in
- if cb.const_proj = None then
- match cb.const_body with
- | Def l_body ->
- let b = force_constr l_body in
- begin
- match cb.const_universes with
- | Monomorphic_const _ -> b
- | Polymorphic_const _ -> subst_instance_constr u (force_constr l_body)
- end
- | OpaqueDef _ -> raise (NotEvaluableConst Opaque)
- | Undef _ -> raise (NotEvaluableConst NoBody)
- else raise (NotEvaluableConst IsProj)
+ match cb.const_body with
+ | Def l_body ->
+ let b = force_constr l_body in
+ begin
+ match cb.const_universes with
+ | Monomorphic_const _ -> b
+ | Polymorphic_const _ -> subst_instance_constr u (force_constr l_body)
+ end
+ | OpaqueDef _ -> raise (NotEvaluableConst Opaque)
+ | Undef _ -> raise (NotEvaluableConst NoBody)
(* A global const is evaluable if it is defined and not opaque *)
let evaluable_constant cst env =
diff --git a/checker/environ.mli b/checker/environ.mli
index ba62ed519b..36e0ea0274 100644
--- a/checker/environ.mli
+++ b/checker/environ.mli
@@ -52,7 +52,7 @@ val check_constraints : Univ.constraints -> env -> bool
val lookup_constant : Constant.t -> env -> Cic.constant_body
val add_constant : Constant.t -> Cic.constant_body -> env -> env
val constant_type : env -> Constant.t puniverses -> constr Univ.constrained
-type const_evaluation_result = NoBody | Opaque | IsProj
+type const_evaluation_result = NoBody | Opaque
exception NotEvaluableConst of const_evaluation_result
val constant_value : env -> Constant.t puniverses -> constr
val evaluable_constant : Constant.t -> env -> bool
diff --git a/checker/indtypes.ml b/checker/indtypes.ml
index bb0db8cfe9..1807ae0ecd 100644
--- a/checker/indtypes.ml
+++ b/checker/indtypes.ml
@@ -502,10 +502,19 @@ let check_positivity_one (env, _,ntypes,_ as ienv) hyps nrecp (_,i as ind) indlc
indlc
in mk_paths (Mrec ind) irecargs
+let prrecarg = function
+ | Norec -> str "Norec"
+ | Mrec (mind,i) ->
+ str "Mrec[" ++ MutInd.debug_print mind ++ pr_comma () ++ int i ++ str "]"
+ | Imbr (mind,i) ->
+ str "Imbr[" ++ MutInd.debug_print mind ++ pr_comma () ++ int i ++ str "]"
+
let check_subtree t1 t2 =
let cmp_labels l1 l2 = l1 == Norec || eq_recarg l1 l2 in
if not (Rtree.equiv eq_recarg cmp_labels t1 t2)
- then failwith "bad recursive trees"
+ then user_err Pp.(str "Bad recursive tree: found " ++ fnl ()
+ ++ Rtree.pp_tree prrecarg t1 ++ fnl () ++ str " when expected " ++ fnl ()
+ ++ Rtree.pp_tree prrecarg t2)
(* if t1=t2 then () else msg_warning (str"TODO: check recursive positions")*)
let check_positivity env_ar mind params nrecp inds =
@@ -555,14 +564,23 @@ let check_subtyping cumi paramsctxt env inds =
We must produce the substitution σ : [ Var(i) -> Var (i + n) | 0 <= i < n]
and push the constraints [ Var(n) ... Var(2n - 1) |- cst{σ} ], together
with the cumulativity constraints [ cumul_cst ]. *)
- let len = AUContext.size (ACumulativityInfo.univ_context cumi) in
- let inst = Instance.of_array (Array.init len (fun i -> Level.var (i + len))) in
+ let uctx = ACumulativityInfo.univ_context cumi in
+ let len = AUContext.size uctx in
+ let inst = Instance.of_array @@ Array.init len (fun i -> Level.var (i + len)) in
+
let other_context = ACumulativityInfo.univ_context cumi in
let uctx_other = UContext.make (inst, AUContext.instantiate inst other_context) in
- let cumul_context = AUContext.repr (ACumulativityInfo.subtyp_context cumi) in
- let cumul_cst = UContext.constraints cumul_context in
+ let cumul_cst =
+ Array.fold_left_i (fun i csts var ->
+ match var with
+ | Variance.Irrelevant -> csts
+ | Variance.Covariant -> Constraint.add (Level.var i,Le,Level.var (i+len)) csts
+ | Variance.Invariant -> Constraint.add (Level.var i,Eq,Level.var (i+len)) csts)
+ Constraint.empty (ACumulativityInfo.variance cumi)
+ in
let env = Environ.push_context uctx_other env in
let env = Environ.add_constraints cumul_cst env in
+
(* process individual inductive types: *)
Array.iter (fun { mind_user_lc = lc; mind_arity = arity } ->
match arity with
diff --git a/checker/inductive.ml b/checker/inductive.ml
index 22353ec168..8d426a3c05 100644
--- a/checker/inductive.ml
+++ b/checker/inductive.ml
@@ -381,7 +381,7 @@ let type_case_branches env (pind,largs) (p,pj) c =
let check_case_info env indsp ci =
let (mib,mip) = lookup_mind_specif env indsp in
if
- not (eq_ind indsp ci.ci_ind) ||
+ not (eq_ind_chk indsp ci.ci_ind) ||
(mib.mind_nparams <> ci.ci_npar) ||
(mip.mind_consnrealdecls <> ci.ci_cstr_ndecls) ||
(mip.mind_consnrealargs <> ci.ci_cstr_nargs)
@@ -435,20 +435,14 @@ type subterm_spec =
| Dead_code
| Not_subterm
-let eq_recarg r1 r2 = match r1, r2 with
-| Norec, Norec -> true
-| Mrec i1, Mrec i2 -> Names.eq_ind i1 i2
-| Imbr i1, Imbr i2 -> Names.eq_ind i1 i2
-| _ -> false
-
let eq_wf_paths = Rtree.equal eq_recarg
let inter_recarg r1 r2 = match r1, r2 with
| Norec, Norec -> Some r1
| Mrec i1, Mrec i2
| Imbr i1, Imbr i2
-| Mrec i1, Imbr i2 -> if Names.eq_ind i1 i2 then Some r1 else None
-| Imbr i1, Mrec i2 -> if Names.eq_ind i1 i2 then Some r2 else None
+| Mrec i1, Imbr i2 -> if Names.eq_ind_chk i1 i2 then Some r1 else None
+| Imbr i1, Mrec i2 -> if Names.eq_ind_chk i1 i2 then Some r2 else None
| _ -> None
let inter_wf_paths = Rtree.inter eq_recarg inter_recarg Norec
@@ -544,7 +538,7 @@ let lookup_subterms env ind =
let match_inductive ind ra =
match ra with
- | (Mrec i | Imbr i) -> eq_ind ind i
+ | (Mrec i | Imbr i) -> eq_ind_chk ind i
| Norec -> false
(* In {match c as z in ci y_s return P with |C_i x_s => t end}
@@ -645,7 +639,7 @@ let get_recargs_approx env tree ind args =
(* When the inferred tree allows it, we consider that we have a potential
nested inductive type *)
begin match dest_recarg tree with
- | Imbr kn' | Mrec kn' when eq_ind (fst ind_kn) kn' ->
+ | Imbr kn' | Mrec kn' when eq_ind_chk (fst ind_kn) kn' ->
build_recargs_nested ienv tree (ind_kn, largs)
| _ -> mk_norec
end
diff --git a/checker/reduction.ml b/checker/reduction.ml
index d4b258f588..2297c90b3f 100644
--- a/checker/reduction.ml
+++ b/checker/reduction.ml
@@ -158,24 +158,17 @@ let compare_stacks f fmind lft1 stk1 lft2 stk2 =
let convert_inductive_instances cv_pb cumi u u' univs =
let len_instance =
Univ.AUContext.size (Univ.ACumulativityInfo.univ_context cumi) in
- let ind_subtypctx = Univ.ACumulativityInfo.subtyp_context cumi in
if not ((len_instance = Univ.Instance.length u) &&
(len_instance = Univ.Instance.length u')) then
anomaly (Pp.str "Invalid inductive subtyping encountered!")
else
- let comp_cst =
- let comp_subst = (Univ.Instance.append u u') in
- Univ.AUContext.instantiate comp_subst ind_subtypctx
- in
+ let variance = Univ.ACumulativityInfo.variance cumi in
let comp_cst =
match cv_pb with
- CONV ->
- let comp_cst' =
- let comp_subst = (Univ.Instance.append u' u) in
- Univ.AUContext.instantiate comp_subst ind_subtypctx
- in
- Univ.Constraint.union comp_cst comp_cst'
- | CUMUL -> comp_cst
+ | CONV ->
+ Univ.Variance.eq_constraints variance u u' Univ.Constraint.empty
+ | CUMUL ->
+ Univ.Variance.leq_constraints variance u u' Univ.Constraint.empty
in
if (Univ.check_constraints comp_cst univs) then () else raise NotConvertible
@@ -300,11 +293,6 @@ let oracle_order infos l2r k1 k2 =
if Int.equal n1 n2 then l2r
else n1 < n2
-let unfold_projection infos p c =
- let pb = lookup_projection p (infos_env infos) in
- let s = Zproj (pb.proj_npars, pb.proj_arg, p) in
- (c, s)
-
(* Conversion between [lft1]term1 and [lft2]term2 *)
let rec ccnv univ cv_pb infos lft1 lft2 term1 term2 =
eqappr univ cv_pb infos (lft1, (term1,[])) (lft2, (term2,[]))
@@ -374,12 +362,12 @@ and eqappr univ cv_pb infos (lft1,st1) (lft2,st2) =
eqappr univ cv_pb infos app1 app2)
| (FProj (p1,c1), _) ->
- let (def1, s1) = unfold_projection infos p1 c1 in
- eqappr univ cv_pb infos (lft1, whd_stack infos def1 (s1 :: v1)) appr2
+ let s1 = unfold_projection (infos_env infos) p1 in
+ eqappr univ cv_pb infos (lft1, whd_stack infos c1 (s1 :: v1)) appr2
| (_, FProj (p2,c2)) ->
- let (def2, s2) = unfold_projection infos p2 c2 in
- eqappr univ cv_pb infos appr1 (lft2, whd_stack infos def2 (s2 :: v2))
+ let s2 = unfold_projection (infos_env infos) p2 in
+ eqappr univ cv_pb infos appr1 (lft2, whd_stack infos c2 (s2 :: v2))
(* other constructors *)
| (FLambda _, FLambda _) ->
diff --git a/checker/univ.ml b/checker/univ.ml
index 7d01657df7..46b3ce6808 100644
--- a/checker/univ.ml
+++ b/checker/univ.ml
@@ -1003,12 +1003,42 @@ end
type abstract_universe_context = AUContext.t
+module Variance =
+struct
+ (** A universe position in the instance given to a cumulative
+ inductive can be the following. Note there is no Contravariant
+ case because [forall x : A, B <= forall x : A', B'] requires [A =
+ A'] as opposed to [A' <= A]. *)
+ type t = Irrelevant | Covariant | Invariant
+
+ let leq_constraint csts variance u u' =
+ match variance with
+ | Irrelevant -> csts
+ | Covariant -> Constraint.add (u, Le, u') csts
+ | Invariant -> Constraint.add (u, Eq, u') csts
+
+ let eq_constraint csts variance u u' =
+ match variance with
+ | Irrelevant -> csts
+ | Covariant | Invariant -> Constraint.add (u, Eq, u') csts
+
+ let leq_constraints variance u u' csts =
+ let len = Array.length u in
+ assert (len = Array.length u' && len = Array.length variance);
+ Array.fold_left3 leq_constraint csts variance u u'
+
+ let eq_constraints variance u u' csts =
+ let len = Array.length u in
+ assert (len = Array.length u' && len = Array.length variance);
+ Array.fold_left3 eq_constraint csts variance u u'
+end
+
module CumulativityInfo =
struct
- type t = universe_context * universe_context
+ type t = universe_context * Variance.t array
let univ_context (univcst, subtypcst) = univcst
- let subtyp_context (univcst, subtypcst) = subtypcst
+ let variance (univs, variance) = variance
end
diff --git a/checker/univ.mli b/checker/univ.mli
index 21c94d9529..8c0685e0b2 100644
--- a/checker/univ.mli
+++ b/checker/univ.mli
@@ -218,12 +218,25 @@ end
type abstract_universe_context = AUContext.t
+module Variance :
+sig
+ (** A universe position in the instance given to a cumulative
+ inductive can be the following. Note there is no Contravariant
+ case because [forall x : A, B <= forall x : A', B'] requires [A =
+ A'] as opposed to [A' <= A]. *)
+ type t = Irrelevant | Covariant | Invariant
+
+ val leq_constraints : t array -> Instance.t constraint_function
+ val eq_constraints : t array -> Instance.t constraint_function
+end
+
+
module ACumulativityInfo :
sig
type t
val univ_context : t -> abstract_universe_context
- val subtyp_context : t -> abstract_universe_context
+ val variance : t -> Variance.t array
end
diff --git a/checker/values.ml b/checker/values.ml
index 313067cb6b..55e1cdb6f7 100644
--- a/checker/values.ml
+++ b/checker/values.ml
@@ -110,10 +110,12 @@ let v_cstrs =
(v_tuple "univ_constraint"
[|v_level;v_enum "order_request" 3;v_level|]))
+let v_variance = v_enum "variance" 3
+
let v_instance = Annot ("instance", Array v_level)
let v_context = v_tuple "universe_context" [|v_instance;v_cstrs|]
let v_abs_context = v_context (* only for clarity *)
-let v_abs_cum_info = v_tuple "cumulativity_info" [|v_abs_context; v_context|]
+let v_abs_cum_info = v_tuple "cumulativity_info" [|v_abs_context; Array v_variance|]
let v_context_set = v_tuple "universe_context_set" [|v_hset v_level;v_cstrs|]
(** kernel/term *)
diff --git a/dev/ci/ci-basic-overlay.sh b/dev/ci/ci-basic-overlay.sh
index 232b8a56e4..784da6f971 100644
--- a/dev/ci/ci-basic-overlay.sh
+++ b/dev/ci/ci-basic-overlay.sh
@@ -4,141 +4,143 @@
# Maybe we should just use Ruby to have real objects...
+# : "${foo:=bar}" sets foo to "bar" if it is unset or null
+
########################################################################
# MathComp
########################################################################
-: ${mathcomp_CI_BRANCH:=master}
-: ${mathcomp_CI_GITURL:=https://github.com/math-comp/math-comp.git}
+: "${mathcomp_CI_BRANCH:=master}"
+: "${mathcomp_CI_GITURL:=https://github.com/math-comp/math-comp.git}"
########################################################################
# UniMath
########################################################################
-: ${UniMath_CI_BRANCH:=master}
-: ${UniMath_CI_GITURL:=https://github.com/UniMath/UniMath.git}
+: "${UniMath_CI_BRANCH:=master}"
+: "${UniMath_CI_GITURL:=https://github.com/UniMath/UniMath.git}"
########################################################################
# Unicoq + Metacoq
########################################################################
-: ${unicoq_CI_BRANCH:=master}
-: ${unicoq_CI_GITURL:=https://github.com/unicoq/unicoq.git}
+: "${unicoq_CI_BRANCH:=master}"
+: "${unicoq_CI_GITURL:=https://github.com/unicoq/unicoq.git}"
-: ${metacoq_CI_BRANCH:=master}
-: ${metacoq_CI_GITURL:=https://github.com/MetaCoq/MetaCoq.git}
+: "${metacoq_CI_BRANCH:=master}"
+: "${metacoq_CI_GITURL:=https://github.com/MetaCoq/MetaCoq.git}"
########################################################################
# Mathclasses + Corn
########################################################################
-: ${math_classes_CI_BRANCH:=master}
-: ${math_classes_CI_GITURL:=https://github.com/math-classes/math-classes.git}
+: "${math_classes_CI_BRANCH:=master}"
+: "${math_classes_CI_GITURL:=https://github.com/math-classes/math-classes.git}"
-: ${Corn_CI_BRANCH:=master}
-: ${Corn_CI_GITURL:=https://github.com/c-corn/corn.git}
+: "${Corn_CI_BRANCH:=master}"
+: "${Corn_CI_GITURL:=https://github.com/c-corn/corn.git}"
########################################################################
# Iris
########################################################################
-: ${stdpp_CI_BRANCH:=master}
-: ${stdpp_CI_GITURL:=https://gitlab.mpi-sws.org/robbertkrebbers/coq-stdpp.git}
+: "${stdpp_CI_BRANCH:=master}"
+: "${stdpp_CI_GITURL:=https://gitlab.mpi-sws.org/robbertkrebbers/coq-stdpp.git}"
-: ${Iris_CI_BRANCH:=master}
-: ${Iris_CI_GITURL:=https://gitlab.mpi-sws.org/FP/iris-coq.git}
+: "${Iris_CI_BRANCH:=master}"
+: "${Iris_CI_GITURL:=https://gitlab.mpi-sws.org/FP/iris-coq.git}"
-: ${lambdaRust_CI_BRANCH:=master}
-: ${lambdaRust_CI_GITURL:=https://gitlab.mpi-sws.org/FP/LambdaRust-coq.git}
+: "${lambdaRust_CI_BRANCH:=master}"
+: "${lambdaRust_CI_GITURL:=https://gitlab.mpi-sws.org/FP/LambdaRust-coq.git}"
########################################################################
# HoTT
########################################################################
-: ${HoTT_CI_BRANCH:=master}
-: ${HoTT_CI_GITURL:=https://github.com/HoTT/HoTT.git}
+: "${HoTT_CI_BRANCH:=master}"
+: "${HoTT_CI_GITURL:=https://github.com/HoTT/HoTT.git}"
########################################################################
# Ltac2
########################################################################
-: ${ltac2_CI_BRANCH:=master}
-: ${ltac2_CI_GITURL:=https://github.com/ppedrot/ltac2.git}
+: "${ltac2_CI_BRANCH:=master}"
+: "${ltac2_CI_GITURL:=https://github.com/ppedrot/ltac2.git}"
########################################################################
# GeoCoq
########################################################################
-: ${GeoCoq_CI_BRANCH:=master}
-: ${GeoCoq_CI_GITURL:=https://github.com/GeoCoq/GeoCoq.git}
+: "${GeoCoq_CI_BRANCH:=master}"
+: "${GeoCoq_CI_GITURL:=https://github.com/GeoCoq/GeoCoq.git}"
########################################################################
# Flocq
########################################################################
-: ${Flocq_CI_BRANCH:=master}
-: ${Flocq_CI_GITURL:=https://scm.gforge.inria.fr/anonscm/git/flocq/flocq.git}
+: "${Flocq_CI_BRANCH:=master}"
+: "${Flocq_CI_GITURL:=https://gitlab.inria.fr/flocq/flocq.git}"
########################################################################
# Coquelicot
########################################################################
-: ${Coquelicot_CI_BRANCH:=master}
-: ${Coquelicot_CI_GITURL:=https://scm.gforge.inria.fr/anonscm/git/coquelicot/coquelicot.git}
+: "${Coquelicot_CI_BRANCH:=master}"
+: "${Coquelicot_CI_GITURL:=https://scm.gforge.inria.fr/anonscm/git/coquelicot/coquelicot.git}"
########################################################################
# CompCert
########################################################################
-: ${CompCert_CI_BRANCH:=master}
-: ${CompCert_CI_GITURL:=https://github.com/AbsInt/CompCert.git}
+: "${CompCert_CI_BRANCH:=master}"
+: "${CompCert_CI_GITURL:=https://github.com/AbsInt/CompCert.git}"
########################################################################
# VST
########################################################################
-: ${VST_CI_BRANCH:=master}
-: ${VST_CI_GITURL:=https://github.com/PrincetonUniversity/VST.git}
+: "${VST_CI_BRANCH:=master}"
+: "${VST_CI_GITURL:=https://github.com/PrincetonUniversity/VST.git}"
########################################################################
# fiat_parsers
########################################################################
-: ${fiat_parsers_CI_BRANCH:=master}
-: ${fiat_parsers_CI_GITURL:=https://github.com/mit-plv/fiat.git}
+: "${fiat_parsers_CI_BRANCH:=master}"
+: "${fiat_parsers_CI_GITURL:=https://github.com/mit-plv/fiat.git}"
########################################################################
# fiat_crypto
########################################################################
-: ${fiat_crypto_CI_BRANCH:=master}
-: ${fiat_crypto_CI_GITURL:=https://github.com/mit-plv/fiat-crypto.git}
+: "${fiat_crypto_CI_BRANCH:=master}"
+: "${fiat_crypto_CI_GITURL:=https://github.com/mit-plv/fiat-crypto.git}"
########################################################################
# formal-topology
########################################################################
-: ${formal_topology_CI_BRANCH:=ci}
-: ${formal_topology_CI_GITURL:=https://github.com/bmsherman/topology.git}
+: "${formal_topology_CI_BRANCH:=ci}"
+: "${formal_topology_CI_GITURL:=https://github.com/bmsherman/topology.git}"
########################################################################
# coq-dpdgraph
########################################################################
-: ${coq_dpdgraph_CI_BRANCH:=coq-trunk}
-: ${coq_dpdgraph_CI_GITURL:=https://github.com/Karmaki/coq-dpdgraph.git}
+: "${coq_dpdgraph_CI_BRANCH:=coq-trunk}"
+: "${coq_dpdgraph_CI_GITURL:=https://github.com/Karmaki/coq-dpdgraph.git}"
########################################################################
# CoLoR
########################################################################
-: ${CoLoR_CI_BRANCH:=master}
-: ${CoLoR_CI_GITURL:=https://github.com/fblanqui/color.git}
+: "${CoLoR_CI_BRANCH:=master}"
+: "${CoLoR_CI_GITURL:=https://github.com/fblanqui/color.git}"
########################################################################
# SF
########################################################################
-: ${sf_lf_CI_TARURL:=https://www.cis.upenn.edu/~bcpierce/sf/lf-current/lf.tgz}
-: ${sf_plf_CI_TARURL:=https://www.cis.upenn.edu/~bcpierce/sf/plf-current/plf.tgz}
-: ${sf_vfa_CI_TARURL:=https://www.cis.upenn.edu/~bcpierce/sf/vfa-current/vfa.tgz}
+: "${sf_lf_CI_TARURL:=https://www.cis.upenn.edu/~bcpierce/sf/lf-current/lf.tgz}"
+: "${sf_plf_CI_TARURL:=https://www.cis.upenn.edu/~bcpierce/sf/plf-current/plf.tgz}"
+: "${sf_vfa_CI_TARURL:=https://www.cis.upenn.edu/~bcpierce/sf/vfa-current/vfa.tgz}"
########################################################################
# TLC
########################################################################
-: ${tlc_CI_BRANCH:=master}
-: ${tlc_CI_GITURL:=https://gforge.inria.fr/git/tlc/tlc.git}
+: "${tlc_CI_BRANCH:=master}"
+: "${tlc_CI_GITURL:=https://gforge.inria.fr/git/tlc/tlc.git}"
########################################################################
# Bignums
########################################################################
-: ${bignums_CI_BRANCH:=master}
-: ${bignums_CI_GITURL:=https://github.com/coq/bignums.git}
+: "${bignums_CI_BRANCH:=master}"
+: "${bignums_CI_GITURL:=https://github.com/coq/bignums.git}"
########################################################################
# Equations
########################################################################
-: ${Equations_CI_BRANCH:=8.8+alpha}
-: ${Equations_CI_GITURL:=https://github.com/mattam82/Coq-Equations.git}
+: "${Equations_CI_BRANCH:=8.8+alpha}"
+: "${Equations_CI_GITURL:=https://github.com/mattam82/Coq-Equations.git}"
diff --git a/dev/ci/ci-common.sh b/dev/ci/ci-common.sh
index 58c90ff11d..d7a356930e 100644
--- a/dev/ci/ci-common.sh
+++ b/dev/ci/ci-common.sh
@@ -2,9 +2,13 @@
set -xe
+# default value for NJOBS
+: "${NJOBS:=1}"
+export NJOBS
+
if [ -n "${GITLAB_CI}" ];
then
- export COQBIN=`pwd`/_install_ci/bin
+ export COQBIN="$PWD/_install_ci/bin"
export CI_BRANCH="$CI_COMMIT_REF_NAME"
else
if [ -n "${TRAVIS}" ];
@@ -15,8 +19,10 @@ else
then
export CI_PULL_REQUEST="$CIRCLE_PR_NUMBER"
export CI_BRANCH="$CIRCLE_BRANCH"
+ else # assume local
+ export CI_BRANCH="$(git rev-parse --abbrev-ref HEAD)"
fi
- export COQBIN=`pwd`/bin
+ export COQBIN="$PWD/bin"
fi
export PATH="$COQBIN:$PATH"
@@ -26,14 +32,16 @@ export COQBIN="$COQBIN/"
ls "$COQBIN"
# Where we clone and build external developments
-CI_BUILD_DIR=`pwd`/_build_ci
+CI_BUILD_DIR="$PWD/_build_ci"
-for overlay in ${ci_dir}/user-overlays/*.sh; do
- source ${overlay}
+# shellcheck source=ci-basic-overlay.sh
+source "${ci_dir}/ci-basic-overlay.sh"
+for overlay in "${ci_dir}"/user-overlays/*.sh; do
+ # shellcheck source=/dev/null
+ source "${overlay}"
done
-source ${ci_dir}/ci-basic-overlay.sh
-mathcomp_CI_DIR=${CI_BUILD_DIR}/math-comp
+mathcomp_CI_DIR="${CI_BUILD_DIR}/math-comp"
# git_checkout branch url dest will create a git repository
# in <dest> (if it does not exist already) and checkout the
@@ -46,15 +54,16 @@ git_checkout()
# Allow an optional 4th argument for the commit
local _COMMIT=${4:-FETCH_HEAD}
- local _DEPTH=$(if [ -z "${4}" ]; then echo "--depth 1"; fi)
-
- mkdir -p ${_DEST}
- ( cd ${_DEST} && \
- if [ ! -d .git ] ; then git clone ${_DEPTH} ${_URL} . ; fi && \
- echo "Checking out ${_DEST}" && \
- git fetch ${_URL} ${_BRANCH} && \
- git checkout ${_COMMIT} && \
- echo "${_DEST}: `git log -1 --format='%s | %H | %cd | %aN'`" )
+ local _DEPTH=()
+ if [ -z "${4}" ]; then _DEPTH=(--depth 1); fi
+
+ mkdir -p "${_DEST}"
+ ( cd "${_DEST}" && \
+ if [ ! -d .git ] ; then git clone "${_DEPTH[@]}" "${_URL}" . ; fi && \
+ echo "Checking out ${_DEST}" && \
+ git fetch "${_URL}" "${_BRANCH}" && \
+ git checkout "${_COMMIT}" && \
+ echo "${_DEST}: $(git log -1 --format='%s | %H | %cd | %aN')" )
}
checkout_mathcomp()
@@ -79,8 +88,8 @@ install_ssreflect()
{
echo 'Installing ssreflect' && echo -en 'travis_fold:start:ssr.install\\r'
- checkout_mathcomp ${mathcomp_CI_DIR}
- ( cd ${mathcomp_CI_DIR}/mathcomp && \
+ checkout_mathcomp "${mathcomp_CI_DIR}"
+ ( cd "${mathcomp_CI_DIR}/mathcomp" && \
sed -i.bak '/ssrtest/d' Make && \
sed -i.bak '/odd_order/d' Make && \
sed -i.bak '/all\/all.v/d' Make && \
diff --git a/dev/ci/ci-compcert.sh b/dev/ci/ci-compcert.sh
index fc3cef3426..6a0ce2aefa 100755
--- a/dev/ci/ci-compcert.sh
+++ b/dev/ci/ci-compcert.sh
@@ -5,7 +5,7 @@ source ${ci_dir}/ci-common.sh
CompCert_CI_DIR=${CI_BUILD_DIR}/CompCert
-opam install -j ${NJOBS} -y menhir
+opam install -j "$NJOBS" -y menhir
git_checkout ${CompCert_CI_BRANCH} ${CompCert_CI_GITURL} ${CompCert_CI_DIR}
( cd ${CompCert_CI_DIR} && ./configure -ignore-coq-version x86_32-linux && make && make check-proof )
diff --git a/dev/ci/ci-iris-lambda-rust.sh b/dev/ci/ci-iris-lambda-rust.sh
index cf24d202d9..267e13359b 100755
--- a/dev/ci/ci-iris-lambda-rust.sh
+++ b/dev/ci/ci-iris-lambda-rust.sh
@@ -34,8 +34,8 @@ git_checkout ${stdpp_CI_BRANCH} ${stdpp_URL_PARTS[0]} ${stdpp_CI_DIR} ${stdpp_UR
# Build std++
( cd ${stdpp_CI_DIR} && make && make install )
-# Build iris
-( cd ${Iris_CI_DIR} && make && make install )
+# Build and validate (except on Travis, i.e., skip if TRAVIS is non-empty) Iris
+( cd ${Iris_CI_DIR} && make && (test -n "${TRAVIS}" || make validate) && make install )
# Build lambdaRust
( cd ${lambdaRust_CI_DIR} && make && make install )
diff --git a/dev/ci/user-overlays/06535-fix-push-rel-to-named.sh b/dev/ci/user-overlays/06535-fix-push-rel-to-named.sh
new file mode 100644
index 0000000000..8a50fb1111
--- /dev/null
+++ b/dev/ci/user-overlays/06535-fix-push-rel-to-named.sh
@@ -0,0 +1,4 @@
+if [ "$CI_PULL_REQUEST" = "6535" ] || [ "$CI_BRANCH" = "fix-push-rel-to-named" ]; then
+ Equations_CI_BRANCH=fix-6535
+ Equations_CI_GITURL=https://github.com/ppedrot/Coq-Equations
+fi
diff --git a/dev/ci/user-overlays/06686-ccnv-no-proj.sh b/dev/ci/user-overlays/06686-ccnv-no-proj.sh
new file mode 100644
index 0000000000..3a3ab44e03
--- /dev/null
+++ b/dev/ci/user-overlays/06686-ccnv-no-proj.sh
@@ -0,0 +1,4 @@
+if [ "$CI_PULL_REQUEST" = "6686" ] || [ "$CI_BRANCH" = "ccnv-no-proj" ]; then
+ Equations_CI_BRANCH=ccnv-fixes
+ Equations_CI_GITURL=https://github.com/SkySkimmer/Coq-Equations
+fi
diff --git a/COMPATIBILITY b/dev/doc/COMPATIBILITY
index b5fed7f018..a81afca32d 100644
--- a/COMPATIBILITY
+++ b/dev/doc/COMPATIBILITY
@@ -1,3 +1,6 @@
+Note: this file isn't used anymore. Incompatibilities are documented
+as part of CHANGES.
+
Potential sources of incompatibilities between Coq V8.6 and V8.7
----------------------------------------------------------------
@@ -5,10 +8,6 @@ Potential sources of incompatibilities between Coq V8.6 and V8.7
error rather than a warning when the superfluous name is already in
use. The easy fix is to remove the superfluous name.
-- Proofs ending in "Qed exporting ident, .., ident" are not supported
- anymore. Constants generated during `abstract` are kept private to the
- local environment.
-
Potential sources of incompatibilities between Coq V8.5 and V8.6
----------------------------------------------------------------
diff --git a/dev/doc/changes.md b/dev/doc/changes.md
index e616bd5663..aef62b0092 100644
--- a/dev/doc/changes.md
+++ b/dev/doc/changes.md
@@ -58,6 +58,17 @@ Declaration of printers for arguments used only in vernac command
happen. An alternative is to register the corresponding argument as
a value, using "Geninterp.register_val0 wit None".
+### STM API
+
+The STM API has seen a general overhaul. The main change is the
+introduction of a "Coq document" type, which all operations now take
+as a parameter. This effectively functionalize the STM API and will
+allow in the future to handle several documents simultaneously.
+
+The main remarkable point is that key implicit global parameters such
+as load-paths and required modules are now arguments to the document
+creation function. This helps enforcing some key invariants.
+
### XML IDE Protocol
- Before 8.8, `Query` only executed the first command present in the
diff --git a/dev/lint-repository.sh b/dev/lint-repository.sh
index 87a8297461..ee9c8777a3 100755
--- a/dev/lint-repository.sh
+++ b/dev/lint-repository.sh
@@ -9,12 +9,12 @@
CODE=0
-if [ "(" "-n" "${TRAVIS_PULL_REQUEST}" ")" "-a" "(" "${TRAVIS_PULL_REQUEST}" "!=" "false" ")" ];
+if [ -n "${TRAVIS_PULL_REQUEST}" ] && [ "${TRAVIS_PULL_REQUEST}" != false ];
then
# skip PRs from before the linter existed
if [ -z "$(git ls-tree --name-only "${TRAVIS_PULL_REQUEST_SHA}" dev/lint-commits.sh)" ];
then
- 2>&1 echo "Linting skipped: pull request older than the linter."
+ 1>&2 echo "Linting skipped: pull request older than the linter."
exit 0
fi
@@ -22,14 +22,13 @@ then
# can still check that they don't worsen.
CUR_HEAD=${TRAVIS_COMMIT_RANGE%%...*}
PR_HEAD=${TRAVIS_COMMIT_RANGE##*...}
- MERGE_BASE=$(git merge-base $CUR_HEAD $PR_HEAD)
- dev/lint-commits.sh $MERGE_BASE $PR_HEAD || CODE=1
+ MERGE_BASE=$(git merge-base "$CUR_HEAD" "$PR_HEAD")
+ dev/lint-commits.sh "$MERGE_BASE" "$PR_HEAD" || CODE=1
fi
# Check that the files with 'whitespace' gitattribute end in a newline.
# xargs exit status is 123 if any file failed the test
-find . "(" -path ./.git -prune ")" -type f \
--o "(" -exec dev/tools/should-check-whitespace.sh '{}' ';' ")" \
--print0 | xargs -0 -L 1 dev/tools/check-eof-newline.sh || CODE=1
+find . "(" -path ./.git -prune ")" -o -type f -print0 |
+ xargs -0 dev/tools/check-eof-newline.sh || CODE=1
exit $CODE
diff --git a/dev/tools/check-eof-newline.sh b/dev/tools/check-eof-newline.sh
index 1c578c05ce..9e4c8661dc 100755
--- a/dev/tools/check-eof-newline.sh
+++ b/dev/tools/check-eof-newline.sh
@@ -1,9 +1,14 @@
#!/usr/bin/env bash
-if [ -z "$(tail -c 1 "$1")" ]
-then
- exit 0
-else
- echo "No newline at end of file $1!"
- exit 1
-fi
+CODE=0
+for f in "$@"; do
+ if git ls-files --error-unmatch "$f" >/dev/null 2>&1 && \
+ git check-attr whitespace -- "$f" | grep -q -v -e 'unset$' -e 'unspecified$' && \
+ [ -n "$(tail -c 1 "$f")" ]
+ then
+ echo "No newline at end of file $f!"
+ CODE=1
+ fi
+done
+
+exit "$CODE"
diff --git a/dev/tools/merge-pr.sh b/dev/tools/merge-pr.sh
index 0c4a79bfd3..9f24960fff 100755
--- a/dev/tools/merge-pr.sh
+++ b/dev/tools/merge-pr.sh
@@ -9,18 +9,18 @@ set -e
PR=$1
-CURRENT_LOCAL_BRANCH=`git rev-parse --abbrev-ref HEAD`
-REMOTE=`git config --get branch.$CURRENT_LOCAL_BRANCH.remote`
-git fetch $REMOTE refs/pull/$PR/head
+CURRENT_LOCAL_BRANCH=$(git rev-parse --abbrev-ref HEAD)
+REMOTE=$(git config --get "branch.$CURRENT_LOCAL_BRANCH.remote")
+git fetch "$REMOTE" "refs/pull/$PR/head"
API=https://api.github.com/repos/coq/coq
-BASE_BRANCH=`curl -s $API/pulls/$PR | jq -r '.base.label'`
+BASE_BRANCH=$(curl -s "$API/pulls/$PR" | jq -r '.base.label')
-COMMIT=`git rev-parse FETCH_HEAD`
-STATUS=`curl -s $API/commits/$COMMIT/status | jq -r '.state'`
+COMMIT=$(git rev-parse FETCH_HEAD)
+STATUS=$(curl -s "$API/commits/$COMMIT/status" | jq -r '.state')
-if [ $BASE_BRANCH != "coq:$CURRENT_LOCAL_BRANCH" ]; then
+if [ "$BASE_BRANCH" != "coq:$CURRENT_LOCAL_BRANCH" ]; then
echo "Wrong base branch"
read -p "Bypass? [y/N] " -n 1 -r
echo
@@ -30,7 +30,7 @@ if [ $BASE_BRANCH != "coq:$CURRENT_LOCAL_BRANCH" ]; then
fi
fi;
-if [ $STATUS != "success" ]; then
+if [ "$STATUS" != "success" ]; then
echo "CI status is \"$STATUS\""
read -p "Bypass? [y/N] " -n 1 -r
echo
@@ -40,10 +40,10 @@ if [ $STATUS != "success" ]; then
fi
fi;
-git merge -S --no-ff FETCH_HEAD -m "Merge PR #$PR: `curl -s $API/pulls/$PR | jq -r '.title'`" -e
+git merge -S --no-ff FETCH_HEAD -m "Merge PR #$PR: $(curl -s "$API/pulls/$PR" | jq -r '.title')" -e
# TODO: improve this check
-if [[ `git diff $REMOTE/$CURRENT_LOCAL_BRANCH dev/ci` ]]; then
+if ! git diff --quiet "$REMOTE/$CURRENT_LOCAL_BRANCH" -- dev/ci; then
echo "******************************************"
echo "** WARNING: does this PR have overlays? **"
echo "******************************************"
diff --git a/dev/tools/should-check-whitespace.sh b/dev/tools/should-check-whitespace.sh
deleted file mode 100755
index d85d651070..0000000000
--- a/dev/tools/should-check-whitespace.sh
+++ /dev/null
@@ -1,6 +0,0 @@
-#!/usr/bin/env bash
-
-# determine if a file has whitespace checking enabled in .gitattributes
-
-git ls-files --error-unmatch "$1" >/dev/null 2>&1 &&
-git check-attr whitespace -- "$1" | grep -q -v -e 'unset$' -e 'unspecified$'
diff --git a/dev/tools/sudo-apt-get-update.sh b/dev/tools/sudo-apt-get-update.sh
new file mode 100755
index 0000000000..f8bf6bed41
--- /dev/null
+++ b/dev/tools/sudo-apt-get-update.sh
@@ -0,0 +1,4 @@
+#!/usr/bin/env bash
+
+(sudo apt-get update "$@" 2>&1 || echo 'E: update failed') | tee /tmp/apt.err
+! grep -q '^\(E:\|W: Failed to fetch\)' /tmp/apt.err || exit $?
diff --git a/dev/vm_printers.ml b/dev/vm_printers.ml
index 8e43bf6ed0..f819d2e6a9 100644
--- a/dev/vm_printers.ml
+++ b/dev/vm_printers.ml
@@ -3,7 +3,7 @@ open Term
open Names
open Cbytecodes
open Cemitcodes
-open Vm
+open Vmvalues
let ppripos (ri,pos) =
(match ri with
diff --git a/doc/refman/RefMan-oth.tex b/doc/refman/RefMan-oth.tex
index 3ebeba178a..1cd23c9297 100644
--- a/doc/refman/RefMan-oth.tex
+++ b/doc/refman/RefMan-oth.tex
@@ -912,6 +912,15 @@ This command turns off the use of a default timeout.
This command displays whether some default timeout has be set or not.
+\subsection[\tt Fail \textrm{\textsl{command-or-tactic}}.]{\tt Fail \textrm{\textsl{command-or-tactic}}.\comindex{Fail}\label{Fail}}
+
+For debugging {\Coq} scripts, sometimes it is desirable to know
+whether a command or a tactic fails. If the given command or tactic
+fails, the {\tt Fail} statement succeeds, without changing the proof
+state, and in interactive mode, {\Coq} prints a message confirming the failure.
+If the command or tactic succeeds, the statement is an error, and
+{\Coq} prints a message indicating that the failure did not occur.
+
\section{Controlling display}
\subsection[\tt Set Silent.]{\tt Set Silent.\optindex{Silent}
diff --git a/doc/refman/Universes.tex b/doc/refman/Universes.tex
index a1a6a43918..6c84a1818c 100644
--- a/doc/refman/Universes.tex
+++ b/doc/refman/Universes.tex
@@ -68,6 +68,13 @@ is only valid as long as \texttt{Top.4} is strictly smaller than
monomorphic (not universe polymorphic), so the two universes
(in this case \texttt{Top.3} and \texttt{Top.4}) are actually global levels.
+When printing \texttt{pidentity}, we can see the universes it binds in
+the annotation \texttt{@\{Top.2\}}. Additionally, when \texttt{Set
+ Printing Universes} is on we print the ``universe context'' of
+\texttt{pidentity} consisting of the bound universes and the
+constraints they must verify (for \texttt{pidentity} there are no
+constraints).
+
Inductive types can also be declared universes polymorphic on universes
appearing in their parameters or fields. A typical example is given by
monoids:
@@ -138,7 +145,7 @@ producing global universe constraints, one can use the
\optindex{Polymorphic Inductive Cumulativity}
Polymorphic inductive types, coinductive types, variants and records can be
-declared cumulative using the \texttt{Cumulative}. Alternatively,
+declared cumulative using the \texttt{Cumulative} prefix. Alternatively,
there is an option \texttt{Set Polymorphic Inductive Cumulativity} which when set,
makes all subsequent \emph{polymorphic} inductive definitions cumulative. When set,
inductive types and the like can be enforced to be
@@ -151,15 +158,22 @@ Polymorphic Cumulative Inductive list {A : Type} :=
\begin{coq_example}
Print list.
\end{coq_example}
-When printing \texttt{list}, the part of the output of the form
-\texttt{$\mathtt{\sim}$@\{i\} <= $\mathtt{\sim}$@\{j\} iff }
-indicates the universe constraints in order to have the subtyping
-$\WTEGLECONV{\mathtt{list@\{i\}} A}{\mathtt{list@\{j\}} B}$
-(for fully applied instances of \texttt{list}) whenever $\WTEGCONV{A}{B}$.
-In the case of \texttt{list} there is no constraint!
-This also means that any two instances of \texttt{list} are convertible:
-$\WTEGCONV{\mathtt{list@\{i\}} A}{\mathtt{list@\{j\}} B}$ whenever $\WTEGCONV{A}{B}$ and
-furthermore their corresponding (when fully applied to convertible arguments) constructors.
+When printing \texttt{list}, the universe context indicates the
+subtyping constraints by prefixing the level names with symbols.
+
+Because inductive subtypings are only produced by comparing inductives
+to themselves with universes changed, they amount to variance
+information: each universe is either invariant, covariant or
+irrelevant (there are no contravariant subtypings in Coq),
+respectively represented by the symbols \texttt{=}, \texttt{+} and
+\texttt{*}.
+
+Here we see that \texttt{list} binds an irrelevant universe, so any
+two instances of \texttt{list} are convertible:
+$\WTEGCONV{\mathtt{list@\{i\}} A}{\mathtt{list@\{j\}} B}$ whenever
+$\WTEGCONV{A}{B}$ and furthermore their corresponding (when fully
+applied to convertible arguments) constructors.
+
See Chapter~\ref{Cic} for more details on convertibility and subtyping.
The following is an example of a record with non-trivial subtyping relation:
\begin{coq_example*}
@@ -168,8 +182,9 @@ Polymorphic Cumulative Record packType := {pk : Type}.
\begin{coq_example}
Print packType.
\end{coq_example}
-Notice that as expected, \texttt{packType@\{i\}} and \texttt{packType@\{j\}} are
-convertible if and only if \texttt{i $=$ j}.
+\texttt{packType} binds a covariant universe, i.e.
+$\WTEGCONV{\mathtt{packType@\{i\}}}{\mathtt{packType@\{j\}}}$ whenever
+\texttt{i $\leq$ j}.
Cumulative inductive types, coninductive types, variants and records
only make sense when they are universe polymorphic. Therefore, an
diff --git a/engine/evarutil.ml b/engine/evarutil.ml
index 374fdce722..f82ffccdc3 100644
--- a/engine/evarutil.ml
+++ b/engine/evarutil.ml
@@ -257,22 +257,6 @@ let make_pure_subst evi args =
* we have the property that u and phi(t) are convertible in env.
*)
-let csubst_subst (k, s) c =
- (** Safe because this is a substitution *)
- let c = EConstr.Unsafe.to_constr c in
- let rec subst n c = match Constr.kind c with
- | Rel m ->
- if m <= n then c
- else if m - n <= k then EConstr.Unsafe.to_constr (Int.Map.find (k - m + n) s)
- else mkRel (m - k)
- | _ -> Constr.map_with_binders succ subst n c
- in
- let c = if k = 0 then c else subst 0 c in
- EConstr.of_constr c
-
-let subst2 subst vsubst c =
- csubst_subst subst (EConstr.Vars.replace_vars vsubst c)
-
let next_ident_away id avoid =
let avoid id = Id.Set.mem id avoid in
next_ident_away_from id avoid
@@ -282,19 +266,79 @@ let next_name_away na avoid =
let id = match na with Name id -> id | Anonymous -> default_non_dependent_ident in
next_ident_away_from id avoid
-type csubst = int * EConstr.t Int.Map.t
+type subst_val =
+| SRel of int
+| SVar of Id.t
+
+type csubst = {
+ csubst_len : int;
+ (** Cardinal of [csubst_rel] *)
+ csubst_var : Constr.t Id.Map.t;
+ (** A mapping of variables to variables. We use the more general
+ [Constr.t] to share allocations, but all values are of shape [Var _]. *)
+ csubst_rel : Constr.t Int.Map.t;
+ (** A contiguous mapping of integers to variables. Same remark for values. *)
+ csubst_rev : subst_val Id.Map.t;
+ (** Reverse mapping of the substitution *)
+}
+(** This type represent a name substitution for the named and De Bruijn parts of
+ a environment. For efficiency we also store the reverse substitution.
+ Invariant: all identifiers in the codomain of [csubst_var] and [csubst_rel]
+ must be pairwise distinct. *)
+
+let empty_csubst = {
+ csubst_len = 0;
+ csubst_rel = Int.Map.empty;
+ csubst_var = Id.Map.empty;
+ csubst_rev = Id.Map.empty;
+}
-let empty_csubst = (0, Int.Map.empty)
+let csubst_subst { csubst_len = k; csubst_var = v; csubst_rel = s } c =
+ (** Safe because this is a substitution *)
+ let c = EConstr.Unsafe.to_constr c in
+ let rec subst n c = match Constr.kind c with
+ | Rel m ->
+ if m <= n then c
+ else if m - n <= k then Int.Map.find (k - m + n) s
+ else mkRel (m - k)
+ | Var id ->
+ begin try Id.Map.find id v with Not_found -> c end
+ | _ -> Constr.map_with_binders succ subst n c
+ in
+ let c = if k = 0 && Id.Map.is_empty v then c else subst 0 c in
+ EConstr.of_constr c
type ext_named_context =
- csubst * (Id.t * EConstr.constr) list *
- Id.Set.t * EConstr.named_context
-
-let push_var id (n, s) =
- let s = Int.Map.add n (EConstr.mkVar id) s in
- (succ n, s)
-
-let push_rel_decl_to_named_context sigma decl (subst, vsubst, avoid, nc) =
+ csubst * Id.Set.t * EConstr.named_context
+
+let push_var id { csubst_len = n; csubst_var = v; csubst_rel = s; csubst_rev = r } =
+ let s = Int.Map.add n (Constr.mkVar id) s in
+ let r = Id.Map.add id (SRel n) r in
+ { csubst_len = succ n; csubst_var = v; csubst_rel = s; csubst_rev = r }
+
+(** Post-compose the substitution with the generator [src ↦ tgt] *)
+let update_var src tgt subst =
+ let cur =
+ try Some (Id.Map.find src subst.csubst_rev)
+ with Not_found -> None
+ in
+ match cur with
+ | None ->
+ (** Missing keys stand for identity substitution [src ↦ src] *)
+ let csubst_var = Id.Map.add src (Constr.mkVar tgt) subst.csubst_var in
+ let csubst_rev = Id.Map.add tgt (SVar src) subst.csubst_rev in
+ { subst with csubst_var; csubst_rev }
+ | Some bnd ->
+ let csubst_rev = Id.Map.add tgt bnd (Id.Map.remove src subst.csubst_rev) in
+ match bnd with
+ | SRel m ->
+ let csubst_rel = Int.Map.add m (Constr.mkVar tgt) subst.csubst_rel in
+ { subst with csubst_rel; csubst_rev }
+ | SVar id ->
+ let csubst_var = Id.Map.add id (Constr.mkVar tgt) subst.csubst_var in
+ { subst with csubst_var; csubst_rev }
+
+let push_rel_decl_to_named_context sigma decl (subst, avoid, nc) =
let open EConstr in
let open Vars in
let map_decl f d =
@@ -330,18 +374,17 @@ let push_rel_decl_to_named_context sigma decl (subst, vsubst, avoid, nc) =
binding named [id], we will keep [id0] (the name given
by the user) and rename [id0] into [id] in the named
context. Unless [id] is a section variable. *)
- let subst = (fst subst, Int.Map.map (replace_vars [id0,mkVar id]) (snd subst)) in
- let vsubst = (id0,mkVar id)::vsubst in
- let d = decl |> NamedDecl.of_rel_decl (fun _ -> id0) |> map_decl (subst2 subst vsubst) in
+ let subst = update_var id0 id subst in
+ let d = decl |> NamedDecl.of_rel_decl (fun _ -> id0) |> map_decl (csubst_subst subst) in
let nc = List.map (replace_var_named_declaration id0 id) nc in
- (push_var id0 subst, vsubst, Id.Set.add id avoid, d :: nc)
+ (push_var id0 subst, Id.Set.add id avoid, d :: nc)
| _ ->
(* spiwack: if [id0] is a section variable renaming it is
incorrect. We revert to a less robust behaviour where
the new binder has name [id]. Which amounts to the same
behaviour than when [id=id0]. *)
- let d = decl |> NamedDecl.of_rel_decl (fun _ -> id) |> map_decl (subst2 subst vsubst) in
- (push_var id subst, vsubst, Id.Set.add id avoid, d :: nc)
+ let d = decl |> NamedDecl.of_rel_decl (fun _ -> id) |> map_decl (csubst_subst subst) in
+ (push_var id subst, Id.Set.add id avoid, d :: nc)
let push_rel_context_to_named_context env sigma typ =
(* compute the instances relative to the named context and rel_context *)
@@ -350,17 +393,17 @@ let push_rel_context_to_named_context env sigma typ =
let ids = List.map get_id (named_context env) in
let inst_vars = List.map mkVar ids in
if List.is_empty (Environ.rel_context env) then
- (named_context_val env, typ, inst_vars, empty_csubst, [])
+ (named_context_val env, typ, inst_vars, empty_csubst)
else
let avoid = List.fold_right Id.Set.add ids Id.Set.empty in
let inst_rels = List.rev (rel_list 0 (nb_rel env)) in
(* move the rel context to a named context and extend the named instance *)
(* with vars of the rel context *)
(* We do keep the instances corresponding to local definition (see above) *)
- let (subst, vsubst, _, env) =
+ let (subst, _, env) =
Context.Rel.fold_outside (fun d acc -> push_rel_decl_to_named_context sigma d acc)
- (rel_context env) ~init:(empty_csubst, [], avoid, named_context env) in
- (val_of_named_context env, subst2 subst vsubst typ, inst_rels@inst_vars, subst, vsubst)
+ (rel_context env) ~init:(empty_csubst, avoid, named_context env) in
+ (val_of_named_context env, csubst_subst subst typ, inst_rels@inst_vars, subst)
(*------------------------------------*
* Entry points to define new evars *
@@ -425,8 +468,8 @@ let new_evar_from_context sign evd ?src ?filter ?candidates ?store ?naming ?prin
(* [new_evar] declares a new existential in an env env with type typ *)
(* Converting the env into the sign of the evar to define *)
let new_evar env evd ?src ?filter ?candidates ?store ?naming ?principal typ =
- let sign,typ',instance,subst,vsubst = push_rel_context_to_named_context env evd typ in
- let map c = subst2 subst vsubst c in
+ let sign,typ',instance,subst = push_rel_context_to_named_context env evd typ in
+ let map c = csubst_subst subst c in
let candidates = Option.map (fun l -> List.map map l) candidates in
let instance =
match filter with
diff --git a/engine/evarutil.mli b/engine/evarutil.mli
index 37f5968ad8..923bf49a9c 100644
--- a/engine/evarutil.mli
+++ b/engine/evarutil.mli
@@ -222,14 +222,13 @@ val empty_csubst : csubst
val csubst_subst : csubst -> constr -> constr
type ext_named_context =
- csubst * (Id.t * constr) list *
- Id.Set.t * named_context
+ csubst * Id.Set.t * named_context
val push_rel_decl_to_named_context :
evar_map -> rel_declaration -> ext_named_context -> ext_named_context
val push_rel_context_to_named_context : Environ.env -> evar_map -> types ->
- named_context_val * types * constr list * csubst * (Id.t*constr) list
+ named_context_val * types * constr list * csubst
val generalize_evar_over_rels : evar_map -> existential -> types * constr list
diff --git a/engine/proofview.ml b/engine/proofview.ml
index 0a64351950..47b9b406d8 100644
--- a/engine/proofview.ml
+++ b/engine/proofview.ml
@@ -1086,7 +1086,7 @@ module Goal = struct
end
end
- let enter_one f =
+ let enter_one ?(__LOC__=__LOC__) f =
let open Proof in
Comb.get >>= function
| [goal] -> begin
@@ -1097,7 +1097,8 @@ module Goal = struct
let (e, info) = CErrors.push e in
tclZERO ~info e
end
- | _ -> assert false (* unsatisfied not-exactly-one-goal precondition *)
+ | _ ->
+ CErrors.anomaly Pp.(str __LOC__ ++ str " enter_one")
let goals =
Pv.get >>= fun step ->
diff --git a/engine/proofview.mli b/engine/proofview.mli
index 59728a2fd1..b02fde3a80 100644
--- a/engine/proofview.mli
+++ b/engine/proofview.mli
@@ -499,7 +499,7 @@ module Goal : sig
(** Like {!enter}, but assumes exactly one goal under focus, raising *)
(** a fatal error otherwise. *)
- val enter_one : ([ `LZ ] t -> 'a tactic) -> 'a tactic
+ val enter_one : ?__LOC__:string -> ([ `LZ ] t -> 'a tactic) -> 'a tactic
(** Recover the list of current goals under focus, without evar-normalization.
FIXME: encapsulate the level in an existential type. *)
diff --git a/engine/universes.ml b/engine/universes.ml
index eaddf98a83..3a00f0fd1d 100644
--- a/engine/universes.ml
+++ b/engine/universes.ml
@@ -1103,14 +1103,3 @@ let solve_constraints_system levels level_bounds level_min =
done;
done;
v
-
-
-(** Operations for universe_info_ind *)
-
-(** Given a universe context representing constraints of an inductive
- this function produces a UInfoInd.t that with the trivial subtyping relation. *)
-let univ_inf_ind_from_universe_context univcst =
- let freshunivs = Instance.of_array
- (Array.map (fun _ -> new_univ_level ())
- (Instance.to_array (UContext.instance univcst)))
- in CumulativityInfo.from_universe_context univcst freshunivs
diff --git a/engine/universes.mli b/engine/universes.mli
index 130dcf8bb8..cb6e2ba1b6 100644
--- a/engine/universes.mli
+++ b/engine/universes.mli
@@ -221,9 +221,3 @@ val pr_universe_opt_subst : universe_opt_subst -> Pp.t
val solve_constraints_system : Universe.t option array -> Universe.t array -> Universe.t array ->
Universe.t array
-
-(** Operations for universe_info_ind *)
-
-(** Given a universe context representing constraints of an inductive
- this function produces a UInfoInd.t that with the trivial subtyping relation. *)
-val univ_inf_ind_from_universe_context : UContext.t -> CumulativityInfo.t
diff --git a/ide/coq_lex.mll b/ide/coq_lex.mll
index a7e9003dbe..fcc242e074 100644
--- a/ide/coq_lex.mll
+++ b/ide/coq_lex.mll
@@ -19,8 +19,12 @@ let space = [' ' '\n' '\r' '\t' '\012'] (* '\012' is form-feed *)
let number = [ '0'-'9' ]+
+let string = "\"" _+ "\""
+
let undotted_sep = (number space* ':' space*)? '{' | '}' | '-'+ | '+'+ | '*'+
+let vernac_control = "Fail" | "Time" | "Redirect" space+ string | "Timeout" space+ number
+
let dot_sep = '.' (space | eof)
let utf8_extra_byte = [ '\x80' - '\xBF' ]
@@ -67,7 +71,7 @@ and sentence initial stamp = parse
stamp (utf8_lexeme_start lexbuf) Tags.Script.sentence;
sentence true stamp lexbuf
}
- | undotted_sep {
+ | (vernac_control space+)* undotted_sep {
(* Separators like { or } and bullets * - + are only active
at the start of a sentence *)
if initial then stamp (utf8_lexeme_start lexbuf + String.length (Lexing.lexeme lexbuf) - 1) Tags.Script.sentence;
diff --git a/install.sh b/install.sh
index f8589a3c71..4f60080a14 100755
--- a/install.sh
+++ b/install.sh
@@ -4,13 +4,13 @@ dest="$1"
shift
for f; do
- bn=`basename $f`
- dn=`dirname $f`
+ bn=$(basename "$f")
+ dn=$(dirname "$f")
install -d "$dest/$dn"
case $bn in
- *.cmxs|*.py) install -m 755 $f "$dest/$dn/$bn"
+ *.cmxs|*.py) install -m 755 "$f" "$dest/$dn/$bn"
;;
- *) install -m 644 $f "$dest/$dn/$bn"
+ *) install -m 644 "$f" "$dest/$dn/$bn"
;;
esac
done
diff --git a/interp/constrexpr_ops.ml b/interp/constrexpr_ops.ml
index 7cc8de85d2..da04d8786b 100644
--- a/interp/constrexpr_ops.ml
+++ b/interp/constrexpr_ops.ml
@@ -173,10 +173,12 @@ let rec constr_expr_eq e1 e2 =
| CDelimiters(s1,e1), CDelimiters(s2,e2) ->
String.equal s1 s2 &&
constr_expr_eq e1 e2
+ | CProj(p1,c1), CProj(p2,c2) ->
+ eq_reference p1 p2 && constr_expr_eq c1 c2
| (CRef _ | CFix _ | CCoFix _ | CProdN _ | CLambdaN _ | CLetIn _ | CAppExpl _
| CApp _ | CRecord _ | CCases _ | CLetTuple _ | CIf _ | CHole _
| CPatVar _ | CEvar _ | CSort _ | CCast _ | CNotation _ | CPrim _
- | CGeneralization _ | CDelimiters _), _ -> false
+ | CGeneralization _ | CDelimiters _ | CProj _), _ -> false
and args_eq (a1,e1) (a2,e2) =
Option.equal (eq_located explicitation_eq) e1 e2 &&
@@ -365,6 +367,8 @@ let fold_constr_expr_with_binders g f n acc = CAst.with_val (function
(fold_local_binders g f n acc t lb) c lb) l acc
| CCoFix (_,_) ->
Feedback.msg_warning (strbrk "Capture check in multiple binders not done"); acc
+ | CProj (_,c) ->
+ f n acc c
)
let free_vars_of_constr_expr c =
@@ -446,6 +450,8 @@ let map_constr_expr_with_binders g f e = CAst.map (function
let e'' = List.fold_left (fun e ((_,id),_,_,_) -> g id e) e' dl in
let d' = f e'' d in
(id,bl',t',d')) dl)
+ | CProj (p,c) ->
+ CProj (p, f e c)
)
(* Used in constrintern *)
diff --git a/interp/constrextern.ml b/interp/constrextern.ml
index 1330b3741e..4f7d537d3f 100644
--- a/interp/constrextern.ml
+++ b/interp/constrextern.ml
@@ -908,6 +908,9 @@ let rec extern inctx scopes vars r =
| GCast (c, c') ->
CCast (sub_extern true scopes vars c,
Miscops.map_cast_type (extern_typ scopes vars) c')
+ | GProj (p, c) ->
+ let pr = extern_reference ?loc Id.Set.empty (ConstRef (Projection.constant p)) in
+ CProj (pr, sub_extern inctx scopes vars c)
) r'
and extern_typ (_,scopes) =
diff --git a/interp/constrintern.ml b/interp/constrintern.ml
index 1dc7f325fa..4afe301dd7 100644
--- a/interp/constrintern.ml
+++ b/interp/constrintern.ml
@@ -1885,7 +1885,13 @@ let internalize globalenv env pattern_mode (_, ntnvars as lvar) c =
| CCast (c1, c2) ->
DAst.make ?loc @@
GCast (intern env c1, Miscops.map_cast_type (intern_type env) c2)
- )
+ | CProj (pr, c) ->
+ match intern_reference pr with
+ | ConstRef p ->
+ DAst.make ?loc @@ GProj (Projection.make p false, intern env c)
+ | _ ->
+ raise (InternalizationError (loc,IllegalMetavariable)) (* FIXME *)
+ )
and intern_type env = intern (set_type_scope env)
and intern_local_binder env bind : intern_env * Glob_term.extended_glob_local_binder list =
diff --git a/interp/declare.ml b/interp/declare.ml
index 55f825c251..72cdabfd20 100644
--- a/interp/declare.ml
+++ b/interp/declare.ml
@@ -364,13 +364,8 @@ let infer_inductive_subtyping (pth, mind_ent) =
| Cumulative_ind_entry cumi ->
begin
let env = Global.env () in
- let env' =
- Environ.push_context
- (Univ.CumulativityInfo.univ_context cumi) env
- in
(* let (env'', typed_params) = Typeops.infer_local_decls env' (mind_ent.mind_entry_params) in *)
- let evd = Evd.from_env env' in
- (pth, Inductiveops.infer_inductive_subtyping env' evd mind_ent)
+ (pth, InferCumulativity.infer_inductive env mind_ent)
end
type inductive_obj = Dischargedhypsmap.discharged_hyps * mutual_inductive_entry
diff --git a/interp/discharge.ml b/interp/discharge.ml
index 75bfca3078..710f88c3ff 100644
--- a/interp/discharge.ml
+++ b/interp/discharge.ml
@@ -92,7 +92,7 @@ let process_inductive info modlist mib =
let auctx = Univ.ACumulativityInfo.univ_context cumi in
let subst, auctx = Lib.discharge_abstract_universe_context info auctx in
let auctx = Univ.AUContext.repr auctx in
- subst, Cumulative_ind_entry (Universes.univ_inf_ind_from_universe_context auctx)
+ subst, Cumulative_ind_entry (Univ.CumulativityInfo.from_universe_context auctx)
in
let discharge c = Vars.subst_univs_level_constr subst (expmod_constr modlist c) in
let inds =
diff --git a/interp/notation_ops.ml b/interp/notation_ops.ml
index 20492e38c8..326d05cba6 100644
--- a/interp/notation_ops.ml
+++ b/interp/notation_ops.ml
@@ -86,9 +86,11 @@ let rec eq_notation_constr (vars1,vars2 as vars) t1 t2 = match t1, t2 with
Miscops.glob_sort_eq s1 s2
| NCast (t1, c1), NCast (t2, c2) ->
(eq_notation_constr vars) t1 t2 && cast_type_eq (eq_notation_constr vars) c1 c2
+| NProj (p1, c1), NProj (p2, c2) ->
+ Projection.equal p1 p2 && eq_notation_constr vars c1 c2
| (NRef _ | NVar _ | NApp _ | NHole _ | NList _ | NLambda _ | NProd _
| NBinderList _ | NLetIn _ | NCases _ | NLetTuple _ | NIf _
- | NRec _ | NSort _ | NCast _), _ -> false
+ | NRec _ | NSort _ | NCast _ | NProj _), _ -> false
(**********************************************************************)
(* Re-interpret a notation as a glob_constr, taking care of binders *)
@@ -189,6 +191,7 @@ let glob_constr_of_notation_constr_with_binders ?loc g f e nc =
| NSort x -> GSort x
| NHole (x, naming, arg) -> GHole (x, naming, arg)
| NRef x -> GRef (x,None)
+ | NProj (p,c) -> GProj (p, f e c)
let glob_constr_of_notation_constr ?loc x =
let rec aux () x =
@@ -383,6 +386,7 @@ let notation_constr_and_vars_of_glob_constr a =
if arg != None then has_ltac := true;
NHole (w, naming, arg)
| GRef (r,_) -> NRef r
+ | GProj (p, c) -> NProj (p, aux c)
| GEvar _ | GPatVar _ ->
user_err Pp.(str "Existential variables not allowed in notations.")
) x
@@ -576,6 +580,14 @@ let rec subst_notation_constr subst bound raw =
let k' = Miscops.smartmap_cast_type (subst_notation_constr subst bound) k in
if r1' == r1 && k' == k then raw else NCast(r1',k')
+ | NProj (p, c) ->
+ let kn = Projection.constant p in
+ let b = Projection.unfolded p in
+ let kn' = subst_constant subst kn in
+ let c' = subst_notation_constr subst bound c in
+ if kn' == kn && c' == c then raw else NProj(Projection.make kn' b, c')
+
+
let subst_interpretation subst (metas,pat) =
let bound = List.fold_left (fun accu (id, _) -> Id.Set.add id accu) Id.Set.empty metas in
(metas,subst_notation_constr subst bound pat)
@@ -1167,9 +1179,12 @@ let rec match_ inner u alp metas sigma a1 a2 =
match_names metas (alp,sigma) (Name id') na in
match_in u alp metas sigma (mkGApp a1 (DAst.make @@ GVar id')) b2
+ | GProj(p1, t1), NProj(p2, t2) when Projection.equal p1 p2 ->
+ match_in u alp metas sigma t1 t2
+
| (GRef _ | GVar _ | GEvar _ | GPatVar _ | GApp _ | GLambda _ | GProd _
| GLetIn _ | GCases _ | GLetTuple _ | GIf _ | GRec _ | GSort _ | GHole _
- | GCast _), _ -> raise No_match
+ | GCast _ | GProj _ ), _ -> raise No_match
and match_in u = match_ true u
diff --git a/intf/constrexpr.ml b/intf/constrexpr.ml
index 8bcdbcc0ef..fbf9e248ab 100644
--- a/intf/constrexpr.ml
+++ b/intf/constrexpr.ml
@@ -97,6 +97,7 @@ and constr_expr_r =
| CGeneralization of binding_kind * abstraction_kind option * constr_expr
| CPrim of prim_token
| CDelimiters of string * constr_expr
+ | CProj of reference * constr_expr
and constr_expr = constr_expr_r CAst.t
and case_expr = constr_expr (* expression that is being matched *)
diff --git a/intf/glob_term.ml b/intf/glob_term.ml
index f311d33b8a..61bbe2c264 100644
--- a/intf/glob_term.ml
+++ b/intf/glob_term.ml
@@ -55,6 +55,7 @@ type 'a glob_constr_r =
| GSort of glob_sort
| GHole of Evar_kinds.t * intro_pattern_naming_expr * Genarg.glob_generic_argument option
| GCast of 'a glob_constr_g * 'a glob_constr_g cast_type
+ | GProj of Projection.t * 'a glob_constr_g
and 'a glob_constr_g = ('a glob_constr_r, 'a) DAst.t
and 'a glob_decl_g = Name.t * binding_kind * 'a glob_constr_g option * 'a glob_constr_g
diff --git a/intf/notation_term.ml b/intf/notation_term.ml
index 7823d3febb..cad6f4b821 100644
--- a/intf/notation_term.ml
+++ b/intf/notation_term.ml
@@ -43,6 +43,7 @@ type notation_constr =
notation_constr array * notation_constr array
| NSort of glob_sort
| NCast of notation_constr * notation_constr cast_type
+ | NProj of Projection.t * notation_constr
(** Note concerning NList: first constr is iterator, second is terminator;
first id is where each argument of the list has to be substituted
diff --git a/intf/pattern.ml b/intf/pattern.ml
index 20636accfa..64873a0394 100644
--- a/intf/pattern.ml
+++ b/intf/pattern.ml
@@ -26,7 +26,7 @@ type constr_pattern =
| PRel of int
| PApp of constr_pattern * constr_pattern array
| PSoApp of patvar * constr_pattern list
- | PProj of projection * constr_pattern
+ | PProj of Projection.t * constr_pattern
| PLambda of Name.t * constr_pattern * constr_pattern
| PProd of Name.t * constr_pattern * constr_pattern
| PLetIn of Name.t * constr_pattern * constr_pattern option * constr_pattern
diff --git a/intf/vernacexpr.ml b/intf/vernacexpr.ml
index 8bd2da2f11..8e0fe54c55 100644
--- a/intf/vernacexpr.ml
+++ b/intf/vernacexpr.ml
@@ -167,6 +167,7 @@ type option_ref_value =
type universe_decl_expr = (Id.t Loc.located list, glob_constraint list) gen_universe_decl
type ident_decl = lident * universe_decl_expr option
+type name_decl = lname * universe_decl_expr option
type sort_expr = Sorts.family
@@ -204,12 +205,12 @@ type inductive_expr =
type one_inductive_expr =
ident_decl * local_binder_expr list * constr_expr option * constructor_expr list
-type typeclass_constraint = (Name.t Loc.located * universe_decl_expr option) * binding_kind * constr_expr
+type typeclass_constraint = name_decl * binding_kind * constr_expr
and typeclass_context = typeclass_constraint list
type proof_expr =
- ident_decl option * (local_binder_expr list * constr_expr)
+ ident_decl * (local_binder_expr list * constr_expr)
type syntax_modifier =
| SetItemLevel of string list * Extend.production_level
@@ -339,7 +340,7 @@ type nonrec vernac_expr =
| VernacNotationAddFormat of string * string * string
(* Gallina *)
- | VernacDefinition of (discharge * definition_object_kind) * ident_decl * definition_expr
+ | VernacDefinition of (discharge * definition_object_kind) * name_decl * definition_expr
| VernacStartTheoremProof of theorem_kind * proof_expr list
| VernacEndProof of proof_end
| VernacExactProof of constr_expr
@@ -449,7 +450,6 @@ type nonrec vernac_expr =
| VernacComments of comment list
(* Proof management *)
- | VernacGoal of constr_expr
| VernacAbort of lident option
| VernacAbortAll
| VernacRestart
diff --git a/kernel/cClosure.ml b/kernel/cClosure.ml
index b1181157e1..219ea5b24a 100644
--- a/kernel/cClosure.ml
+++ b/kernel/cClosure.ml
@@ -91,6 +91,7 @@ module type RedFlagsSig = sig
val red_add : reds -> red_kind -> reds
val red_sub : reds -> red_kind -> reds
val red_add_transparent : reds -> transparent_state -> reds
+ val red_transparent : reds -> transparent_state
val mkflags : red_kind list -> reds
val red_set : reds -> red_kind -> bool
val red_projection : reds -> projection -> bool
@@ -164,6 +165,8 @@ module RedFlags = (struct
let (l1,l2) = red.r_const in
{ red with r_const = Id.Pred.remove id l1, l2 }
+ let red_transparent red = red.r_const
+
let red_add_transparent red tr =
{ red with r_const = tr }
@@ -847,6 +850,14 @@ let contract_fix_vect fix =
in
(subs_cons(Array.init nfix make_body, env), thisbody)
+let unfold_projection info p =
+ if red_projection info.i_flags p
+ then
+ let open Declarations in
+ let pb = lookup_projection p (info_env info) in
+ Some (Zproj (pb.proj_npars, pb.proj_arg, Projection.constant p))
+ else None
+
(*********************************************************************)
(* A machine that inspects the head of a term until it finds an
atom or a subterm that may produce a redex (abstraction,
@@ -865,15 +876,9 @@ let rec knh info m stk =
| (None, stk') -> (m,stk'))
| FCast(t,_,_) -> knh info t stk
| FProj (p,c) ->
- let unf = Projection.unfolded p in
- if unf || red_set info.i_flags (fCONST (Projection.constant p)) then
- (match try Some (lookup_projection p (info_env info)) with Not_found -> None with
- | None -> (m, stk)
- | Some pb ->
- knh info c (Zproj (pb.Declarations.proj_npars, pb.Declarations.proj_arg,
- Projection.constant p)
- :: zupdate m stk))
- else (m,stk)
+ (match unfold_projection info p with
+ | None -> (m, stk)
+ | Some s -> knh info c (s :: zupdate m stk))
(* cases where knh stops *)
| (FFlex _|FLetIn _|FConstruct _|FEvar _|
diff --git a/kernel/cClosure.mli b/kernel/cClosure.mli
index 119b70e301..c43fc46239 100644
--- a/kernel/cClosure.mli
+++ b/kernel/cClosure.mli
@@ -61,6 +61,9 @@ module type RedFlagsSig = sig
(** Adds a reduction kind to a set *)
val red_add_transparent : reds -> transparent_state -> reds
+ (** Retrieve the transparent state of the reduction flags *)
+ val red_transparent : reds -> transparent_state
+
(** Build a reduction set from scratch = iter [red_add] on [no_red] *)
val mkflags : red_kind list -> reds
@@ -163,6 +166,7 @@ val stack_tail : int -> stack -> stack
val stack_nth : stack -> int -> fconstr
val zip_term : (fconstr -> constr) -> constr -> stack -> constr
val eta_expand_stack : stack -> stack
+val unfold_projection : 'a infos -> Projection.t -> stack_member option
(** To lazy reduce a constr, create a [clos_infos] with
[create_clos_infos], inject the term to reduce with [inject]; then use
diff --git a/kernel/constr.ml b/kernel/constr.ml
index 5930cfadc6..1ff1fcc4c0 100644
--- a/kernel/constr.ml
+++ b/kernel/constr.ml
@@ -1178,8 +1178,3 @@ let hcons =
Id.hcons)
(* let hcons_types = hcons_constr *)
-
-(*******)
-(* Type of abstract machine values *)
-(** FIXME: nothing to do there *)
-type values
diff --git a/kernel/constr.mli b/kernel/constr.mli
index 98bf713082..19ffa8fe30 100644
--- a/kernel/constr.mli
+++ b/kernel/constr.mli
@@ -459,7 +459,3 @@ val case_info_hash : case_info -> int
(*********************************************************************)
val hcons : constr -> constr
-
-(**************************************)
-
-type values
diff --git a/kernel/csymtable.ml b/kernel/csymtable.ml
index 712c66f11d..2bbb867cd4 100644
--- a/kernel/csymtable.ml
+++ b/kernel/csymtable.ml
@@ -15,7 +15,7 @@
open Util
open Names
open Constr
-open Vm
+open Vmvalues
open Cemitcodes
open Cbytecodes
open Declarations
diff --git a/kernel/csymtable.mli b/kernel/csymtable.mli
index 91bb30e7ed..fc935f6ee9 100644
--- a/kernel/csymtable.mli
+++ b/kernel/csymtable.mli
@@ -12,7 +12,7 @@ open Names
open Constr
open Pre_env
-val val_of_constr : env -> constr -> values
+val val_of_constr : env -> constr -> Vmvalues.values
val set_opaque_const : Constant.t -> unit
val set_transparent_const : Constant.t -> unit
diff --git a/kernel/environ.ml b/kernel/environ.ml
index 93dc2f9a72..738ecc6e1f 100644
--- a/kernel/environ.ml
+++ b/kernel/environ.ml
@@ -254,31 +254,10 @@ let constant_context env kn =
| Monomorphic_const _ -> Univ.AUContext.empty
| Polymorphic_const ctx -> ctx
-type const_evaluation_result = NoBody | Opaque | IsProj
+type const_evaluation_result = NoBody | Opaque
exception NotEvaluableConst of const_evaluation_result
-let constant_value env (kn,u) =
- let cb = lookup_constant kn env in
- if cb.const_proj = None then
- match cb.const_body with
- | Def l_body ->
- begin
- match cb.const_universes with
- | Monomorphic_const _ ->
- (Mod_subst.force_constr l_body, Univ.Constraint.empty)
- | Polymorphic_const _ ->
- let csts = constraints_of cb u in
- (subst_instance_constr u (Mod_subst.force_constr l_body), csts)
- end
- | OpaqueDef _ -> raise (NotEvaluableConst Opaque)
- | Undef _ -> raise (NotEvaluableConst NoBody)
- else raise (NotEvaluableConst IsProj)
-
-let constant_opt_value env cst =
- try Some (constant_value env cst)
- with NotEvaluableConst _ -> None
-
let constant_value_and_type env (kn, u) =
let cb = lookup_constant kn env in
if Declareops.constant_is_polymorphic cb then
diff --git a/kernel/environ.mli b/kernel/environ.mli
index 7cc541258d..69d811a642 100644
--- a/kernel/environ.mli
+++ b/kernel/environ.mli
@@ -146,13 +146,11 @@ val type_in_type_constant : Constant.t -> env -> bool
body and [NotEvaluableConst IsProj] if [c] is a projection
and [Not_found] if it does not exist in [env] *)
-type const_evaluation_result = NoBody | Opaque | IsProj
+type const_evaluation_result = NoBody | Opaque
exception NotEvaluableConst of const_evaluation_result
-val constant_value : env -> Constant.t puniverses -> constr constrained
val constant_type : env -> Constant.t puniverses -> types constrained
-val constant_opt_value : env -> Constant.t puniverses -> (constr * Univ.Constraint.t) option
val constant_value_and_type : env -> Constant.t puniverses ->
constr option * types * Univ.Constraint.t
(** The universe context associated to the constant, empty if not
diff --git a/kernel/indtypes.ml b/kernel/indtypes.ml
index b117f8714b..cfca335d32 100644
--- a/kernel/indtypes.ml
+++ b/kernel/indtypes.ml
@@ -234,22 +234,32 @@ let check_subtyping_arity_constructor env (subst : constr -> constr) (arcn : typ
(* This check produces a value of the unit type if successful or raises an anomaly if check fails. *)
let check_subtyping cumi paramsctxt env_ar inds =
let numparams = Context.Rel.nhyps paramsctxt in
- let sbsubst = CumulativityInfo.subtyping_susbst cumi in
- let dosubst = subst_univs_level_constr sbsubst in
let uctx = CumulativityInfo.univ_context cumi in
- let instance_other = Univ.subst_univs_level_instance sbsubst (Univ.UContext.instance uctx) in
- let constraints_other = Univ.subst_univs_level_constraints sbsubst (Univ.UContext.constraints uctx) in
+ let new_levels = Array.init (UContext.size uctx) (Level.make DirPath.empty) in
+ let lmap = Array.fold_left2 (fun lmap u u' -> LMap.add u u' lmap)
+ LMap.empty (Instance.to_array @@ UContext.instance uctx) new_levels
+ in
+ let dosubst = subst_univs_level_constr lmap in
+ let instance_other = Instance.of_array new_levels in
+ let constraints_other = Univ.subst_univs_level_constraints lmap (Univ.UContext.constraints uctx) in
let uctx_other = Univ.UContext.make (instance_other, constraints_other) in
let env = Environ.push_context uctx env_ar in
let env = Environ.push_context uctx_other env in
- let env = push_context (CumulativityInfo.subtyp_context cumi) env in
+ let subtyp_constraints =
+ CumulativityInfo.leq_constraints cumi
+ (UContext.instance uctx) instance_other
+ Constraint.empty
+ in
+ let env = Environ.add_constraints subtyp_constraints env in
(* process individual inductive types: *)
Array.iter (fun (id,cn,lc,(sign,arity)) ->
match arity with
| RegularArity (_, full_arity, _) ->
check_subtyping_arity_constructor env dosubst full_arity numparams true;
Array.iter (fun cnt -> check_subtyping_arity_constructor env dosubst cnt numparams false) lc
- | TemplateArity _ -> ()
+ | TemplateArity _ ->
+ anomaly ~label:"check_subtyping"
+ Pp.(str "template polymorphism and cumulative polymorphism are not compatible")
) inds
(* Type-check an inductive definition. Does not check positivity
diff --git a/kernel/inductive.ml b/kernel/inductive.ml
index 28a09b81b0..722705bd70 100644
--- a/kernel/inductive.ml
+++ b/kernel/inductive.ml
@@ -796,18 +796,18 @@ let rec subterm_specif renv stack t =
| Proj (p, c) ->
let subt = subterm_specif renv stack c in
- (match subt with
- | Subterm (s, wf) ->
- (* We take the subterm specs of the constructor of the record *)
- let wf_args = (dest_subterms wf).(0) in
- (* We extract the tree of the projected argument *)
- let kn = Projection.constant p in
- let cb = lookup_constant kn renv.env in
- let pb = Option.get cb.const_proj in
- let n = pb.proj_arg in
- Subterm (Strict, List.nth wf_args n)
- | Dead_code -> Dead_code
- | Not_subterm -> Not_subterm)
+ (match subt with
+ | Subterm (s, wf) ->
+ (* We take the subterm specs of the constructor of the record *)
+ let wf_args = (dest_subterms wf).(0) in
+ (* We extract the tree of the projected argument *)
+ let kn = Projection.constant p in
+ let cb = lookup_constant kn renv.env in
+ let pb = Option.get cb.const_proj in
+ let n = pb.proj_arg in
+ spec_of_tree (List.nth wf_args n)
+ | Dead_code -> Dead_code
+ | Not_subterm -> Not_subterm)
| Var _ | Sort _ | Cast _ | Prod _ | LetIn _ | App _ | Const _ | Ind _
| Construct _ | CoFix _ -> Not_subterm
diff --git a/kernel/kernel.mllib b/kernel/kernel.mllib
index 917e4f6f14..749854b8cd 100644
--- a/kernel/kernel.mllib
+++ b/kernel/kernel.mllib
@@ -16,6 +16,7 @@ Cemitcodes
Opaqueproof
Declarations
Entries
+Vmvalues
Nativevalues
CPrimitives
Declareops
diff --git a/kernel/nativecode.ml b/kernel/nativecode.ml
index ffe19510a6..8fa2540536 100644
--- a/kernel/nativecode.ml
+++ b/kernel/nativecode.ml
@@ -148,7 +148,7 @@ type symbol =
| SymbMatch of annot_sw
| SymbInd of inductive
| SymbMeta of metavariable
- | SymbEvar of existential
+ | SymbEvar of Evar.t
| SymbLevel of Univ.Level.t
let dummy_symb = SymbValue (dummy_value ())
@@ -162,8 +162,7 @@ let eq_symbol sy1 sy2 =
| SymbMatch sw1, SymbMatch sw2 -> eq_annot_sw sw1 sw2
| SymbInd ind1, SymbInd ind2 -> eq_ind ind1 ind2
| SymbMeta m1, SymbMeta m2 -> Int.equal m1 m2
- | SymbEvar (evk1,args1), SymbEvar (evk2,args2) ->
- Evar.equal evk1 evk2 && Array.for_all2 Constr.equal args1 args2
+ | SymbEvar evk1, SymbEvar evk2 -> Evar.equal evk1 evk2
| SymbLevel l1, SymbLevel l2 -> Univ.Level.equal l1 l2
| _, _ -> false
@@ -176,10 +175,7 @@ let hash_symbol symb =
| SymbMatch sw -> combinesmall 5 (hash_annot_sw sw)
| SymbInd ind -> combinesmall 6 (ind_hash ind)
| SymbMeta m -> combinesmall 7 m
- | SymbEvar (evk,args) ->
- let evh = Evar.hash evk in
- let hl = Array.fold_left (fun h t -> combine h (Constr.hash t)) evh args in
- combinesmall 8 hl
+ | SymbEvar evk -> combinesmall 8 (Evar.hash evk)
| SymbLevel l -> combinesmall 9 (Univ.Level.hash l)
module HashedTypeSymbol = struct
@@ -1047,11 +1043,12 @@ let ml_of_instance instance u =
let tyn = fresh_lname Anonymous in
let i = push_symbol (SymbMeta mv) in
MLapp(MLprimitive Mk_meta, [|get_meta_code i; MLlocal tyn|])
- | Levar(ev,ty) ->
+ | Levar(evk,ty,args) ->
let tyn = fresh_lname Anonymous in
- let i = push_symbol (SymbEvar ev) in
+ let i = push_symbol (SymbEvar evk) in
+ let args = MLarray(Array.map (ml_of_lam env l) args) in
MLlet(tyn, ml_of_lam env l ty,
- MLapp(MLprimitive Mk_evar, [|get_evar_code i;MLlocal tyn|]))
+ MLapp(MLprimitive Mk_evar, [|get_evar_code i;MLlocal tyn; args|]))
| Lprod(dom,codom) ->
let dom = ml_of_lam env l dom in
let codom = ml_of_lam env l codom in
@@ -1919,15 +1916,17 @@ let compile_constant env sigma prefix ~interactive con cb =
let asw = { asw_ind = ind; asw_prefix = prefix; asw_ci = ci;
asw_reloc = tbl; asw_finite = true } in
let c_uid = fresh_lname Anonymous in
+ let cf_uid = fresh_lname Anonymous in
let _, arity = tbl.(0) in
let ci_uid = fresh_lname Anonymous in
let cargs = Array.init arity
(fun i -> if Int.equal i pb.proj_arg then Some ci_uid else None)
in
let i = push_symbol (SymbConst con) in
- let accu = MLapp (MLprimitive Cast_accu, [|MLlocal c_uid|]) in
+ let accu = MLapp (MLprimitive Cast_accu, [|MLlocal cf_uid|]) in
let accu_br = MLapp (MLprimitive Mk_proj, [|get_const_code i;accu|]) in
- let code = MLmatch(asw,MLlocal c_uid,accu_br,[|[((ind,1),cargs)],MLlocal ci_uid|]) in
+ let code = MLmatch(asw,MLlocal cf_uid,accu_br,[|[((ind,1),cargs)],MLlocal ci_uid|]) in
+ let code = MLlet(cf_uid, MLapp (MLprimitive Force_cofix, [|MLlocal c_uid|]), code) in
let gn = Gproj ("",con) in
let fargs = Array.init (pb.proj_npars + 1) (fun _ -> fresh_lname Anonymous) in
let arg = fargs.(pb.proj_npars) in
diff --git a/kernel/nativecode.mli b/kernel/nativecode.mli
index d08f49095e..7d20054f77 100644
--- a/kernel/nativecode.mli
+++ b/kernel/nativecode.mli
@@ -44,7 +44,7 @@ val get_ind : symbols -> int -> inductive
val get_meta : symbols -> int -> metavariable
-val get_evar : symbols -> int -> existential
+val get_evar : symbols -> int -> Evar.t
val get_level : symbols -> int -> Univ.Level.t
diff --git a/kernel/nativeconv.ml b/kernel/nativeconv.ml
index 9f9102f7d2..bfa9821360 100644
--- a/kernel/nativeconv.ml
+++ b/kernel/nativeconv.ml
@@ -54,13 +54,18 @@ and conv_accu env pb lvl k1 k2 cu =
conv_atom env pb lvl (atom_of_accu k1) (atom_of_accu k2) cu
else
let cu = conv_atom env pb lvl (atom_of_accu k1) (atom_of_accu k2) cu in
- List.fold_right2 (conv_val env CONV lvl) (args_of_accu k1) (args_of_accu k2) cu
+ Array.fold_right2 (conv_val env CONV lvl) (args_of_accu k1) (args_of_accu k2) cu
and conv_atom env pb lvl a1 a2 cu =
if a1 == a2 then cu
else
match a1, a2 with
- | Ameta _, _ | _, Ameta _ | Aevar _, _ | _, Aevar _ -> assert false
+ | Ameta (m1,_), Ameta (m2,_) ->
+ if Int.equal m1 m2 then cu else raise NotConvertible
+ | Aevar (ev1,_,args1), Aevar (ev2,_,args2) ->
+ if Evar.equal ev1 ev2 then
+ Array.fold_right2 (conv_val env CONV lvl) args1 args2 cu
+ else raise NotConvertible
| Arel i1, Arel i2 ->
if Int.equal i1 i2 then cu else raise NotConvertible
| Aind (ind1,u1), Aind (ind2,u2) ->
@@ -112,7 +117,7 @@ and conv_atom env pb lvl a1 a2 cu =
else conv_accu env CONV lvl ac1 ac2 cu
| Arel _, _ | Aind _, _ | Aconstant _, _ | Asort _, _ | Avar _, _
| Acase _, _ | Afix _, _ | Acofix _, _ | Acofixe _, _ | Aprod _, _
- | Aproj _, _ -> raise NotConvertible
+ | Aproj _, _ | Ameta _, _ | Aevar _, _ -> raise NotConvertible
(* Precondition length t1 = length f1 = length f2 = length t2 *)
and conv_fix env lvl t1 f1 t2 f2 cu =
diff --git a/kernel/nativeinstr.mli b/kernel/nativeinstr.mli
index 928283a4d8..48ad884440 100644
--- a/kernel/nativeinstr.mli
+++ b/kernel/nativeinstr.mli
@@ -23,7 +23,7 @@ and lambda =
| Lrel of Name.t * int
| Lvar of Id.t
| Lmeta of metavariable * lambda (* type *)
- | Levar of existential * lambda (* type *)
+ | Levar of Evar.t * lambda (* type *) * lambda array (* arguments *)
| Lprod of lambda * lambda
| Llam of Name.t array * lambda
| Llet of Name.t * lambda * lambda
diff --git a/kernel/nativelambda.ml b/kernel/nativelambda.ml
index b333b0fb9c..29b3e59da8 100644
--- a/kernel/nativelambda.ml
+++ b/kernel/nativelambda.ml
@@ -453,11 +453,12 @@ let rec lambda_of_constr env sigma c =
let ty = meta_type sigma mv in
Lmeta (mv, lambda_of_constr env sigma ty)
- | Evar ev ->
+ | Evar (evk,args as ev) ->
(match evar_value sigma ev with
| None ->
let ty = evar_type sigma ev in
- Levar(ev, lambda_of_constr env sigma ty)
+ let args = Array.map (lambda_of_constr env sigma) args in
+ Levar(evk, lambda_of_constr env sigma ty, args)
| Some t -> lambda_of_constr env sigma t)
| Cast (c, _, _) -> lambda_of_constr env sigma c
diff --git a/kernel/nativelib.ml b/kernel/nativelib.ml
index 4e7d6b218c..1e35f6c036 100644
--- a/kernel/nativelib.ml
+++ b/kernel/nativelib.ml
@@ -157,9 +157,8 @@ let call_linker ?(fatal=true) prefix f upds =
register_native_file prefix
with Dynlink.Error e as exn ->
let exn = CErrors.push exn in
- let msg = "Dynlink error, " ^ Dynlink.error_message e in
- if fatal then (Feedback.msg_error (Pp.str msg); iraise exn)
- else if !Flags.debug then Feedback.msg_debug (Pp.str msg));
+ if fatal then iraise exn
+ else if !Flags.debug then Feedback.msg_debug CErrors.(iprint exn));
match upds with Some upds -> update_locations upds | _ -> ()
let link_library ~prefix ~dirname ~basename =
diff --git a/kernel/nativevalues.ml b/kernel/nativevalues.ml
index ae66362ca3..3d47b1672e 100644
--- a/kernel/nativevalues.ml
+++ b/kernel/nativevalues.ml
@@ -61,7 +61,7 @@ type atom =
| Acofixe of t array * t array * int * t
| Aprod of Name.t * t * (t -> t)
| Ameta of metavariable * t
- | Aevar of existential * t
+ | Aevar of Evar.t * t * t array
| Aproj of Constant.t * accumulator
let accumulate_tag = 0
@@ -132,8 +132,8 @@ let mk_prod_accu s dom codom =
let mk_meta_accu mv ty =
mk_accu (Ameta (mv,ty))
-let mk_evar_accu ev ty =
- mk_accu (Aevar (ev,ty))
+let mk_evar_accu ev ty args =
+ mk_accu (Aevar (ev,ty,args))
let mk_proj_accu kn c =
mk_accu (Aproj (kn,c))
@@ -153,8 +153,7 @@ let accu_nargs (k:accumulator) =
let args_of_accu (k:accumulator) =
let nargs = accu_nargs k in
let f i = (Obj.magic (Obj.field (Obj.magic k) (nargs-i+2)) : t) in
- let t = Array.init nargs f in
- Array.to_list t
+ Array.init nargs f
let is_accu x =
let o = Obj.repr x in
@@ -179,11 +178,10 @@ let force_cofix (cofix : t) =
let atom = atom_of_accu accu in
match atom with
| Acofix(typ,norm,pos,f) ->
- let f = ref f in
- let args = List.rev (args_of_accu accu) in
- List.iter (fun x -> f := !f x) args;
- let v = !f (Obj.magic ()) in
- set_atom_of_accu accu (Acofixe(typ,norm,pos,v));
+ let args = args_of_accu accu in
+ let f = Array.fold_right (fun arg f -> f arg) args f in
+ let v = f (Obj.magic ()) in
+ set_atom_of_accu accu (Acofixe(typ,norm,pos,v));
v
| Acofixe(_,_,_,v) -> v
| _ -> cofix
diff --git a/kernel/nativevalues.mli b/kernel/nativevalues.mli
index 18b877745b..993842740b 100644
--- a/kernel/nativevalues.mli
+++ b/kernel/nativevalues.mli
@@ -51,7 +51,7 @@ type atom =
| Acofixe of t array * t array * int * t
| Aprod of Name.t * t * (t -> t)
| Ameta of metavariable * t
- | Aevar of existential * t
+ | Aevar of Evar.t * t (* type *) * t array (* arguments *)
| Aproj of Constant.t * accumulator
(* Constructors *)
@@ -68,7 +68,7 @@ val mk_prod_accu : Name.t -> t -> t -> t
val mk_fix_accu : rec_pos -> int -> t array -> t array -> t
val mk_cofix_accu : int -> t array -> t array -> t
val mk_meta_accu : metavariable -> t
-val mk_evar_accu : existential -> t -> t
+val mk_evar_accu : Evar.t -> t -> t array -> t
val mk_proj_accu : Constant.t -> accumulator -> t
val upd_cofix : t -> t -> unit
val force_cofix : t -> t
@@ -84,7 +84,7 @@ val napply : t -> t array -> t
val dummy_value : unit -> t
val atom_of_accu : accumulator -> atom
-val args_of_accu : accumulator -> t list
+val args_of_accu : accumulator -> t array
val accu_nargs : accumulator -> int
val cast_accu : t -> accumulator
diff --git a/kernel/pre_env.ml b/kernel/pre_env.ml
index 3ef15105ae..6c5e1cde5a 100644
--- a/kernel/pre_env.ml
+++ b/kernel/pre_env.ml
@@ -15,7 +15,6 @@
open Util
open Names
-open Constr
open Declarations
module NamedDecl = Context.Named.Declaration
@@ -50,7 +49,7 @@ type stratification = {
}
type val_kind =
- | VKvalue of (values * Id.Set.t) CEphemeron.key
+ | VKvalue of (Vmvalues.values * Id.Set.t) CEphemeron.key
| VKnone
type lazy_val = val_kind ref
diff --git a/kernel/pre_env.mli b/kernel/pre_env.mli
index 335ca1057f..a6b57bd1b3 100644
--- a/kernel/pre_env.mli
+++ b/kernel/pre_env.mli
@@ -36,9 +36,9 @@ type stratification = {
type lazy_val
-val force_lazy_val : lazy_val -> (values * Id.Set.t) option
+val force_lazy_val : lazy_val -> (Vmvalues.values * Id.Set.t) option
val dummy_lazy_val : unit -> lazy_val
-val build_lazy_val : lazy_val -> (values * Id.Set.t) -> unit
+val build_lazy_val : lazy_val -> (Vmvalues.values * Id.Set.t) -> unit
type named_context_val = private {
env_named_ctx : Context.Named.t;
diff --git a/kernel/reduction.ml b/kernel/reduction.ml
index c07ac973b8..159d2ea665 100644
--- a/kernel/reduction.ml
+++ b/kernel/reduction.ml
@@ -200,13 +200,9 @@ let is_cumul = function CUMUL -> true | CONV -> false
type 'a universe_compare =
{ (* Might raise NotConvertible *)
- compare : env -> conv_pb -> Sorts.t -> Sorts.t -> 'a -> 'a;
+ compare_sorts : env -> conv_pb -> Sorts.t -> Sorts.t -> 'a -> 'a;
compare_instances: flex:bool -> Univ.Instance.t -> Univ.Instance.t -> 'a -> 'a;
- conv_inductives : conv_pb -> (Declarations.mutual_inductive_body * int) -> Univ.Instance.t -> int ->
- Univ.Instance.t -> int -> 'a -> 'a;
- conv_constructors : (Declarations.mutual_inductive_body * int * int) ->
- Univ.Instance.t -> int -> Univ.Instance.t -> int -> 'a -> 'a;
- }
+ compare_cumul_instances : Univ.Constraint.t -> 'a -> 'a }
type 'a universe_state = 'a * 'a universe_compare
@@ -215,18 +211,68 @@ type ('a,'b) generic_conversion_function = env -> 'b universe_state -> 'a -> 'a
type 'a infer_conversion_function = env -> UGraph.t -> 'a -> 'a -> Univ.Constraint.t
let sort_cmp_universes env pb s0 s1 (u, check) =
- (check.compare env pb s0 s1 u, check)
+ (check.compare_sorts env pb s0 s1 u, check)
(* [flex] should be true for constants, false for inductive types and
constructors. *)
let convert_instances ~flex u u' (s, check) =
(check.compare_instances ~flex u u' s, check)
-
-let convert_inductives cv_pb ind u1 sv1 u2 sv2 (s, check) =
- (check.conv_inductives cv_pb ind u1 sv1 u2 sv2 s, check)
-let convert_constructors cons u1 sv1 u2 sv2 (s, check) =
- (check.conv_constructors cons u1 sv1 u2 sv2 s, check)
+let get_cumulativity_constraints cv_pb cumi u u' =
+ match cv_pb with
+ | CONV ->
+ Univ.ACumulativityInfo.eq_constraints cumi u u' Univ.Constraint.empty
+ | CUMUL ->
+ Univ.ACumulativityInfo.leq_constraints cumi u u' Univ.Constraint.empty
+
+let inductive_cumulativity_arguments (mind,ind) =
+ mind.Declarations.mind_nparams +
+ mind.Declarations.mind_packets.(ind).Declarations.mind_nrealargs
+
+let convert_inductives_gen cmp_instances cmp_cumul cv_pb (mind,ind) nargs u1 u2 s =
+ match mind.Declarations.mind_universes with
+ | Declarations.Monomorphic_ind _ ->
+ assert (Univ.Instance.length u1 = 0 && Univ.Instance.length u2 = 0);
+ s
+ | Declarations.Polymorphic_ind _ ->
+ cmp_instances u1 u2 s
+ | Declarations.Cumulative_ind cumi ->
+ let num_param_arity = inductive_cumulativity_arguments (mind,ind) in
+ if not (Int.equal num_param_arity nargs) then
+ cmp_instances u1 u2 s
+ else
+ let csts = get_cumulativity_constraints cv_pb cumi u1 u2 in
+ cmp_cumul csts s
+
+let convert_inductives cv_pb ind nargs u1 u2 (s, check) =
+ convert_inductives_gen (check.compare_instances ~flex:false) check.compare_cumul_instances
+ cv_pb ind nargs u1 u2 s, check
+
+let constructor_cumulativity_arguments (mind, ind, ctor) =
+ let nparamsctxt =
+ mind.Declarations.mind_nparams +
+ mind.Declarations.mind_packets.(ind).Declarations.mind_nrealargs
+ (* Context.Rel.length mind.Declarations.mind_params_ctxt *) in
+ nparamsctxt + mind.Declarations.mind_packets.(ind).Declarations.mind_consnrealargs.(ctor - 1)
+
+let convert_constructors_gen cmp_instances cmp_cumul (mind, ind, cns) nargs u1 u2 s =
+ match mind.Declarations.mind_universes with
+ | Declarations.Monomorphic_ind _ ->
+ assert (Univ.Instance.length u1 = 0 && Univ.Instance.length u2 = 0);
+ s
+ | Declarations.Polymorphic_ind _ ->
+ cmp_instances u1 u2 s
+ | Declarations.Cumulative_ind cumi ->
+ let num_cnstr_args = constructor_cumulativity_arguments (mind,ind,cns) in
+ if not (Int.equal num_cnstr_args nargs) then
+ cmp_instances u1 u2 s
+ else
+ let csts = get_cumulativity_constraints CONV cumi u1 u2 in
+ cmp_cumul csts s
+
+let convert_constructors ctor nargs u1 u2 (s, check) =
+ convert_constructors_gen (check.compare_instances ~flex:false) check.compare_cumul_instances
+ ctor nargs u1 u2 s, check
let conv_table_key infos k1 k2 cuniv =
if k1 == k2 then cuniv else
@@ -308,17 +354,6 @@ let in_whnf (t,stk) =
| (FFlex _ | FProd _ | FEvar _ | FInd _ | FAtom _ | FRel _ | FProj _) -> true
| FLOCKED -> assert false
-let unfold_projection infos p c =
- let unf = Projection.unfolded p in
- if unf || RedFlags.red_set infos.i_flags (RedFlags.fCONST (Projection.constant p)) then
- (match try Some (lookup_projection p (info_env infos)) with Not_found -> None with
- | Some pb ->
- let s = Zproj (pb.Declarations.proj_npars, pb.Declarations.proj_arg,
- Projection.constant p) in
- Some (c, s)
- | None -> None)
- else None
-
(* Conversion between [lft1]term1 and [lft2]term2 *)
let rec ccnv cv_pb l2r infos lft1 lft2 term1 term2 cuniv =
eqappr cv_pb l2r infos (lft1, (term1,[])) (lft2, (term2,[])) cuniv
@@ -336,9 +371,8 @@ and eqappr cv_pb l2r infos (lft1,st1) (lft2,st2) cuniv =
if in_whnf st1' then (st1',st2') else whd_both st1' st2' in
let ((hd1,v1),(hd2,v2)) = whd_both st1 st2 in
let appr1 = (lft1,(hd1,v1)) and appr2 = (lft2,(hd2,v2)) in
- (* compute the lifts that apply to the head of the term (hd1 and hd2) *)
- let el1 = el_stack lft1 v1 in
- let el2 = el_stack lft2 v2 in
+ (** We delay the computation of the lifts that apply to the head of the term
+ with [el_stack] inside the branches where they are actually used. *)
match (fterm_of hd1, fterm_of hd2) with
(* case of leaves *)
| (FAtom a1, FAtom a2) ->
@@ -354,6 +388,8 @@ and eqappr cv_pb l2r infos (lft1,st1) (lft2,st2) cuniv =
| _ -> raise NotConvertible)
| (FEvar ((ev1,args1),env1), FEvar ((ev2,args2),env2)) ->
if Evar.equal ev1 ev2 then
+ let el1 = el_stack lft1 v1 in
+ let el2 = el_stack lft2 v2 in
let cuniv = convert_stacks l2r infos lft1 lft2 v1 v2 cuniv in
convert_vect l2r infos el1 el2
(Array.map (mk_clos env1) args1)
@@ -362,6 +398,8 @@ and eqappr cv_pb l2r infos (lft1,st1) (lft2,st2) cuniv =
(* 2 index known to be bound to no constant *)
| (FRel n, FRel m) ->
+ let el1 = el_stack lft1 v1 in
+ let el2 = el_stack lft2 v2 in
if Int.equal (reloc_rel n el1) (reloc_rel m el2)
then convert_stacks l2r infos lft1 lft2 v1 v2 cuniv
else raise NotConvertible
@@ -396,25 +434,27 @@ and eqappr cv_pb l2r infos (lft1,st1) (lft2,st2) cuniv =
(* Projections: prefer unfolding to first-order unification,
which will happen naturally if the terms c1, c2 are not in constructor
form *)
- (match unfold_projection infos p1 c1 with
- | Some (def1,s1) ->
- eqappr cv_pb l2r infos (lft1, (def1, (s1 :: v1))) appr2 cuniv
+ (match unfold_projection infos p1 with
+ | Some s1 ->
+ eqappr cv_pb l2r infos (lft1, (c1, (s1 :: v1))) appr2 cuniv
| None ->
- match unfold_projection infos p2 c2 with
- | Some (def2,s2) ->
- eqappr cv_pb l2r infos appr1 (lft2, (def2, (s2 :: v2))) cuniv
+ match unfold_projection infos p2 with
+ | Some s2 ->
+ eqappr cv_pb l2r infos appr1 (lft2, (c2, (s2 :: v2))) cuniv
| None ->
if Constant.equal (Projection.constant p1) (Projection.constant p2)
&& compare_stack_shape v1 v2 then
+ let el1 = el_stack lft1 v1 in
+ let el2 = el_stack lft2 v2 in
let u1 = ccnv CONV l2r infos el1 el2 c1 c2 cuniv in
convert_stacks l2r infos lft1 lft2 v1 v2 u1
else (* Two projections in WHNF: unfold *)
raise NotConvertible)
| (FProj (p1,c1), t2) ->
- (match unfold_projection infos p1 c1 with
- | Some (def1,s1) ->
- eqappr cv_pb l2r infos (lft1, (def1, (s1 :: v1))) appr2 cuniv
+ (match unfold_projection infos p1 with
+ | Some s1 ->
+ eqappr cv_pb l2r infos (lft1, (c1, (s1 :: v1))) appr2 cuniv
| None ->
(match t2 with
| FFlex fl2 ->
@@ -425,9 +465,9 @@ and eqappr cv_pb l2r infos (lft1,st1) (lft2,st2) cuniv =
| _ -> raise NotConvertible))
| (t1, FProj (p2,c2)) ->
- (match unfold_projection infos p2 c2 with
- | Some (def2,s2) ->
- eqappr cv_pb l2r infos appr1 (lft2, (def2, (s2 :: v2))) cuniv
+ (match unfold_projection infos p2 with
+ | Some s2 ->
+ eqappr cv_pb l2r infos appr1 (lft2, (c2, (s2 :: v2))) cuniv
| None ->
(match t1 with
| FFlex fl1 ->
@@ -445,6 +485,8 @@ and eqappr cv_pb l2r infos (lft1,st1) (lft2,st2) cuniv =
anomaly (Pp.str "conversion was given ill-typed terms (FLambda).");
let (_,ty1,bd1) = destFLambda mk_clos hd1 in
let (_,ty2,bd2) = destFLambda mk_clos hd2 in
+ let el1 = el_stack lft1 v1 in
+ let el2 = el_stack lft2 v2 in
let cuniv = ccnv CONV l2r infos el1 el2 ty1 ty2 cuniv in
ccnv CONV l2r infos (el_lift el1) (el_lift el2) bd1 bd2 cuniv
@@ -452,6 +494,8 @@ and eqappr cv_pb l2r infos (lft1,st1) (lft2,st2) cuniv =
if not (is_empty_stack v1 && is_empty_stack v2) then
anomaly (Pp.str "conversion was given ill-typed terms (FProd).");
(* Luo's system *)
+ let el1 = el_stack lft1 v1 in
+ let el2 = el_stack lft2 v2 in
let cuniv = ccnv CONV l2r infos el1 el2 c1 c'1 cuniv in
ccnv cv_pb l2r infos (el_lift el1) (el_lift el2) c2 c'2 cuniv
@@ -479,7 +523,13 @@ and eqappr cv_pb l2r infos (lft1,st1) (lft2,st2) cuniv =
| (FFlex fl1, c2) ->
(match unfold_reference infos fl1 with
| Some def1 ->
- eqappr cv_pb l2r infos (lft1, (def1, v1)) appr2 cuniv
+ (** By virtue of the previous case analyses, we know [c2] is rigid.
+ Conversion check to rigid terms eventually implies full weak-head
+ reduction, so instead of repeatedly performing small-step
+ unfoldings, we perform reduction with all flags on. *)
+ let all = RedFlags.red_add_transparent all (RedFlags.red_transparent (info_flags infos)) in
+ let r1 = whd_stack (infos_with_reds infos all) def1 v1 in
+ eqappr cv_pb l2r infos (lft1, r1) appr2 cuniv
| None ->
match c2 with
| FConstruct ((ind2,j2),u2) ->
@@ -493,7 +543,10 @@ and eqappr cv_pb l2r infos (lft1,st1) (lft2,st2) cuniv =
| (c1, FFlex fl2) ->
(match unfold_reference infos fl2 with
| Some def2 ->
- eqappr cv_pb l2r infos appr1 (lft2, (def2, v2)) cuniv
+ (** Symmetrical case of above. *)
+ let all = RedFlags.red_add_transparent all (RedFlags.red_transparent (info_flags infos)) in
+ let r2 = whd_stack (infos_with_reds infos all) def2 v2 in
+ eqappr cv_pb l2r infos appr1 (lft2, r2) cuniv
| None ->
match c1 with
| FConstruct ((ind1,j1),u1) ->
@@ -511,15 +564,12 @@ and eqappr cv_pb l2r infos (lft1,st1) (lft2,st2) cuniv =
convert_stacks l2r infos lft1 lft2 v1 v2 cuniv
else
let mind = Environ.lookup_mind (fst ind1) (info_env infos) in
- let cuniv =
- match mind.Declarations.mind_universes with
- | Declarations.Monomorphic_ind _ | Declarations.Polymorphic_ind _ ->
- convert_instances ~flex:false u1 u2 cuniv
- | Declarations.Cumulative_ind cumi ->
- convert_inductives cv_pb (mind, snd ind1) u1 (CClosure.stack_args_size v1)
- u2 (CClosure.stack_args_size v2) cuniv
- in
- convert_stacks l2r infos lft1 lft2 v1 v2 cuniv
+ let nargs = CClosure.stack_args_size v1 in
+ if not (Int.equal nargs (CClosure.stack_args_size v2))
+ then raise NotConvertible
+ else
+ let cuniv = convert_inductives cv_pb (mind, snd ind1) nargs u1 u2 cuniv in
+ convert_stacks l2r infos lft1 lft2 v1 v2 cuniv
else raise NotConvertible
| (FConstruct ((ind1,j1),u1), FConstruct ((ind2,j2),u2)) ->
@@ -529,16 +579,12 @@ and eqappr cv_pb l2r infos (lft1,st1) (lft2,st2) cuniv =
convert_stacks l2r infos lft1 lft2 v1 v2 cuniv
else
let mind = Environ.lookup_mind (fst ind1) (info_env infos) in
- let cuniv =
- match mind.Declarations.mind_universes with
- | Declarations.Monomorphic_ind _ | Declarations.Polymorphic_ind _ ->
- convert_instances ~flex:false u1 u2 cuniv
- | Declarations.Cumulative_ind _ ->
- convert_constructors
- (mind, snd ind1, j1) u1 (CClosure.stack_args_size v1)
- u2 (CClosure.stack_args_size v2) cuniv
- in
- convert_stacks l2r infos lft1 lft2 v1 v2 cuniv
+ let nargs = CClosure.stack_args_size v1 in
+ if not (Int.equal nargs (CClosure.stack_args_size v2))
+ then raise NotConvertible
+ else
+ let cuniv = convert_constructors (mind, snd ind1, j1) nargs u1 u2 cuniv in
+ convert_stacks l2r infos lft1 lft2 v1 v2 cuniv
else raise NotConvertible
(* Eta expansion of records *)
@@ -564,6 +610,8 @@ and eqappr cv_pb l2r infos (lft1,st1) (lft2,st2) cuniv =
let fty2 = Array.map (mk_clos e2) tys2 in
let fcl1 = Array.map (mk_clos (subs_liftn n e1)) cl1 in
let fcl2 = Array.map (mk_clos (subs_liftn n e2)) cl2 in
+ let el1 = el_stack lft1 v1 in
+ let el2 = el_stack lft2 v2 in
let cuniv = convert_vect l2r infos el1 el2 fty1 fty2 cuniv in
let cuniv =
convert_vect l2r infos
@@ -579,6 +627,8 @@ and eqappr cv_pb l2r infos (lft1,st1) (lft2,st2) cuniv =
let fty2 = Array.map (mk_clos e2) tys2 in
let fcl1 = Array.map (mk_clos (subs_liftn n e1)) cl1 in
let fcl2 = Array.map (mk_clos (subs_liftn n e2)) cl2 in
+ let el1 = el_stack lft1 v1 in
+ let el2 = el_stack lft2 v2 in
let cuniv = convert_vect l2r infos el1 el2 fty1 fty2 cuniv in
let cuniv =
convert_vect l2r infos
@@ -655,84 +705,14 @@ let check_convert_instances ~flex u u' univs =
else raise NotConvertible
(* general conversion and inference functions *)
-let infer_check_conv_inductives
- infer_check_convert_instances
- infer_check_inductive_instances
- cv_pb (mind, ind) u1 sv1 u2 sv2 univs =
- match mind.Declarations.mind_universes with
- | Declarations.Monomorphic_ind _ | Declarations.Polymorphic_ind _ ->
- infer_check_convert_instances ~flex:false u1 u2 univs
- | Declarations.Cumulative_ind cumi ->
- let num_param_arity =
- mind.Declarations.mind_nparams + mind.Declarations.mind_packets.(ind).Declarations.mind_nrealargs
- in
- if not (num_param_arity = sv1 && num_param_arity = sv2) then
- infer_check_convert_instances ~flex:false u1 u2 univs
- else
- infer_check_inductive_instances cv_pb cumi u1 u2 univs
-
-let infer_check_conv_constructors
- infer_check_convert_instances
- infer_check_inductive_instances
- (mind, ind, cns) u1 sv1 u2 sv2 univs =
- match mind.Declarations.mind_universes with
- | Declarations.Monomorphic_ind _ | Declarations.Polymorphic_ind _ ->
- infer_check_convert_instances ~flex:false u1 u2 univs
- | Declarations.Cumulative_ind cumi ->
- let num_cnstr_args =
- let nparamsctxt =
- mind.Declarations.mind_nparams + mind.Declarations.mind_packets.(ind).Declarations.mind_nrealargs
- (* Context.Rel.length mind.Declarations.mind_params_ctxt *) in
- nparamsctxt + mind.Declarations.mind_packets.(ind).Declarations.mind_consnrealargs.(cns - 1)
- in
- if not (num_cnstr_args = sv1 && num_cnstr_args = sv2) then
- infer_check_convert_instances ~flex:false u1 u2 univs
- else
- infer_check_inductive_instances CONV cumi u1 u2 univs
-
-let check_inductive_instances cv_pb cumi u u' univs =
- let length_ind_instance =
- Univ.AUContext.size (Univ.ACumulativityInfo.univ_context cumi)
- in
- let ind_subtypctx = Univ.ACumulativityInfo.subtyp_context cumi in
- if not ((length_ind_instance = Univ.Instance.length u) &&
- (length_ind_instance = Univ.Instance.length u')) then
- anomaly (Pp.str "Invalid inductive subtyping encountered!")
- else
- let comp_cst =
- let comp_subst = (Univ.Instance.append u u') in
- Univ.AUContext.instantiate comp_subst ind_subtypctx
- in
- let comp_cst =
- match cv_pb with
- CONV ->
- let comp_cst' =
- let comp_subst = (Univ.Instance.append u' u) in
- Univ.AUContext.instantiate comp_subst ind_subtypctx
- in
- Univ.Constraint.union comp_cst comp_cst'
- | CUMUL -> comp_cst
- in
- if (UGraph.check_constraints comp_cst univs) then univs
- else raise NotConvertible
-
-let check_conv_inductives cv_pb ind u1 sv1 u2 sv2 univs =
- infer_check_conv_inductives
- check_convert_instances
- check_inductive_instances
- cv_pb ind u1 sv1 u2 sv2 univs
-
-let check_conv_constructors cns u1 sv1 u2 sv2 univs =
- infer_check_conv_constructors
- check_convert_instances
- check_inductive_instances
- cns u1 sv1 u2 sv2 univs
+let check_inductive_instances csts univs =
+ if (UGraph.check_constraints csts univs) then univs
+ else raise NotConvertible
let checked_universes =
- { compare = checked_sort_cmp_universes;
+ { compare_sorts = checked_sort_cmp_universes;
compare_instances = check_convert_instances;
- conv_inductives = check_conv_inductives;
- conv_constructors = check_conv_constructors}
+ compare_cumul_instances = check_inductive_instances; }
let infer_eq (univs, cstrs as cuniv) u u' =
if UGraph.check_eq univs u u' then cuniv
@@ -775,49 +755,13 @@ let infer_convert_instances ~flex u u' (univs,cstrs) =
else Univ.enforce_eq_instances u u' cstrs
in (univs, cstrs')
-let infer_inductive_instances cv_pb cumi u u' (univs, cstrs) =
- let length_ind_instance =
- Univ.AUContext.size (Univ.ACumulativityInfo.univ_context cumi)
- in
- let ind_subtypctx = Univ.ACumulativityInfo.subtyp_context cumi in
- if not ((length_ind_instance = Univ.Instance.length u) &&
- (length_ind_instance = Univ.Instance.length u')) then
- anomaly (Pp.str "Invalid inductive subtyping encountered!")
- else
- let comp_cst =
- let comp_subst = (Univ.Instance.append u u') in
- Univ.AUContext.instantiate comp_subst ind_subtypctx
- in
- let comp_cst =
- match cv_pb with
- CONV ->
- let comp_cst' =
- let comp_subst = (Univ.Instance.append u' u) in
- Univ.AUContext.instantiate comp_subst ind_subtypctx
- in
- Univ.Constraint.union comp_cst comp_cst'
- | CUMUL -> comp_cst
- in
- (univs, Univ.Constraint.union cstrs comp_cst)
-
-
-let infer_conv_inductives cv_pb ind u1 sv1 u2 sv2 univs =
- infer_check_conv_inductives
- infer_convert_instances
- infer_inductive_instances
- cv_pb ind u1 sv1 u2 sv2 univs
-
-let infer_conv_constructors cns u1 sv1 u2 sv2 univs =
- infer_check_conv_constructors
- infer_convert_instances
- infer_inductive_instances
- cns u1 sv1 u2 sv2 univs
-
-let inferred_universes : (UGraph.t * Univ.Constraint.t) universe_compare =
- { compare = infer_cmp_universes;
+let infer_inductive_instances csts (univs,csts') =
+ (univs, Univ.Constraint.union csts csts')
+
+let inferred_universes : (UGraph.t * Univ.Constraint.t) universe_compare =
+ { compare_sorts = infer_cmp_universes;
compare_instances = infer_convert_instances;
- conv_inductives = infer_conv_inductives;
- conv_constructors = infer_conv_constructors}
+ compare_cumul_instances = infer_inductive_instances; }
let gen_conv cv_pb l2r reds env evars univs t1 t2 =
let b =
diff --git a/kernel/reduction.mli b/kernel/reduction.mli
index 573e4c8bde..0e6a2b8199 100644
--- a/kernel/reduction.mli
+++ b/kernel/reduction.mli
@@ -35,15 +35,11 @@ type 'a extended_conversion_function =
type conv_pb = CONV | CUMUL
-type 'a universe_compare =
+type 'a universe_compare =
{ (* Might raise NotConvertible *)
- compare : env -> conv_pb -> Sorts.t -> Sorts.t -> 'a -> 'a;
+ compare_sorts : env -> conv_pb -> Sorts.t -> Sorts.t -> 'a -> 'a;
compare_instances: flex:bool -> Univ.Instance.t -> Univ.Instance.t -> 'a -> 'a;
- conv_inductives : conv_pb -> (Declarations.mutual_inductive_body * int) -> Univ.Instance.t -> int ->
- Univ.Instance.t -> int -> 'a -> 'a;
- conv_constructors : (Declarations.mutual_inductive_body * int * int) ->
- Univ.Instance.t -> int -> Univ.Instance.t -> int -> 'a -> 'a;
- }
+ compare_cumul_instances : Univ.Constraint.t -> 'a -> 'a }
type 'a universe_state = 'a * 'a universe_compare
@@ -51,6 +47,12 @@ type ('a,'b) generic_conversion_function = env -> 'b universe_state -> 'a -> 'a
type 'a infer_conversion_function = env -> UGraph.t -> 'a -> 'a -> Univ.Constraint.t
+val get_cumulativity_constraints : conv_pb -> Univ.ACumulativityInfo.t ->
+ Univ.Instance.t -> Univ.Instance.t -> Univ.Constraint.t
+
+val inductive_cumulativity_arguments : (Declarations.mutual_inductive_body * int) -> int
+val constructor_cumulativity_arguments : (Declarations.mutual_inductive_body * int * int) -> int
+
val sort_cmp_universes : env -> conv_pb -> Sorts.t -> Sorts.t ->
'a * 'a universe_compare -> 'a * 'a universe_compare
diff --git a/kernel/term.ml b/kernel/term.ml
index aa88059524..fae990d45f 100644
--- a/kernel/term.ml
+++ b/kernel/term.ml
@@ -92,7 +92,7 @@ type ('constr, 'types, 'sort, 'univs) kind_of_term =
| CoFix of ('constr, 'types) pcofixpoint
| Proj of projection * 'constr
-type values = Constr.values
+type values = Vmvalues.values
(**********************************************************************)
(** Redeclaration of functions from module Constr *)
diff --git a/kernel/term.mli b/kernel/term.mli
index f5cb72f4e8..c9a8cf6e1e 100644
--- a/kernel/term.mli
+++ b/kernel/term.mli
@@ -572,8 +572,8 @@ type ('constr, 'types, 'sort, 'univs) kind_of_term =
| Proj of projection * 'constr
[@@ocaml.deprecated "Alias for Constr.kind_of_term"]
-type values = Constr.values
-[@@ocaml.deprecated "Alias for Constr.values"]
+type values = Vmvalues.values
+[@@ocaml.deprecated "Alias for Vmvalues.values"]
val hash_constr : Constr.constr -> int
[@@ocaml.deprecated "Alias for Constr.hash"]
diff --git a/kernel/univ.ml b/kernel/univ.ml
index f72f6f26a9..080bb7ad48 100644
--- a/kernel/univ.ml
+++ b/kernel/univ.ml
@@ -712,7 +712,48 @@ type universe_level_subst = universe_level universe_map
(** A full substitution might involve algebraic universes *)
type universe_subst = universe universe_map
-module Instance : sig
+module Variance =
+struct
+ (** A universe position in the instance given to a cumulative
+ inductive can be the following. Note there is no Contravariant
+ case because [forall x : A, B <= forall x : A', B'] requires [A =
+ A'] as opposed to [A' <= A]. *)
+ type t = Irrelevant | Covariant | Invariant
+
+ let sup x y =
+ match x, y with
+ | Irrelevant, s | s, Irrelevant -> s
+ | Invariant, _ | _, Invariant -> Invariant
+ | Covariant, Covariant -> Covariant
+
+ let pr = function
+ | Irrelevant -> str "*"
+ | Covariant -> str "+"
+ | Invariant -> str "="
+
+ let leq_constraint csts variance u u' =
+ match variance with
+ | Irrelevant -> csts
+ | Covariant -> enforce_leq_level u u' csts
+ | Invariant -> enforce_eq_level u u' csts
+
+ let eq_constraint csts variance u u' =
+ match variance with
+ | Irrelevant -> csts
+ | Covariant | Invariant -> enforce_eq_level u u' csts
+
+ let leq_constraints variance u u' csts =
+ let len = Array.length u in
+ assert (len = Array.length u' && len = Array.length variance);
+ Array.fold_left3 leq_constraint csts variance u u'
+
+ let eq_constraints variance u u' csts =
+ let len = Array.length u in
+ assert (len = Array.length u' && len = Array.length variance);
+ Array.fold_left3 eq_constraint csts variance u u'
+end
+
+module Instance : sig
type t = Level.t array
val empty : t
@@ -732,7 +773,7 @@ module Instance : sig
val subst_fn : universe_level_subst_fn -> t -> t
- val pr : (Level.t -> Pp.t) -> t -> Pp.t
+ val pr : (Level.t -> Pp.t) -> ?variance:Variance.t array -> t -> Pp.t
val levels : t -> LSet.t
end =
struct
@@ -808,8 +849,12 @@ struct
let levels x = LSet.of_array x
- let pr =
- prvect_with_sep spc
+ let pr prl ?variance =
+ let ppu i u =
+ let v = Option.map (fun v -> v.(i)) variance in
+ pr_opt_no_spc Variance.pr v ++ prl u
+ in
+ prvecti_with_sep spc ppu
let equal t u =
t == u ||
@@ -873,9 +918,9 @@ struct
let empty = (Instance.empty, Constraint.empty)
let is_empty (univs, cst) = Instance.is_empty univs && Constraint.is_empty cst
- let pr prl (univs, cst as ctx) =
+ let pr prl ?variance (univs, cst as ctx) =
if is_empty ctx then mt() else
- h 0 (Instance.pr prl univs ++ str " |= ") ++ h 0 (v 0 (Constraint.pr prl cst))
+ h 0 (Instance.pr prl ?variance univs ++ str " |= ") ++ h 0 (v 0 (Constraint.pr prl cst))
let hcons (univs, cst) =
(Instance.hcons univs, hcons_constraints cst)
@@ -911,66 +956,42 @@ end
type abstract_universe_context = AUContext.t
let hcons_abstract_universe_context = AUContext.hcons
-(** Universe info for cumulative inductive types:
- A context of universe levels
- with universe constraints, representing local universe variables
- and constraints, together with a context of universe levels with
- universe constraints, representing conditions for subtyping used
- for inductive types.
+(** Universe info for cumulative inductive types: A context of
+ universe levels with universe constraints, representing local
+ universe variables and constraints, together with an array of
+ Variance.t.
- This data structure maintains the invariant that the context for
- subtyping constraints is exactly twice as big as the context for
- universe constraints. *)
+ This data structure maintains the invariant that the variance
+ array has the same length as the universe instance. *)
module CumulativityInfo =
struct
- type t = universe_context * universe_context
+ type t = universe_context * Variance.t array
let make x =
- if (Instance.length (UContext.instance (snd x))) =
- (Instance.length (UContext.instance (fst x))) * 2 then x
+ if (Instance.length (UContext.instance (fst x))) =
+ (Array.length (snd x)) then x
else anomaly (Pp.str "Invalid subtyping information encountered!")
- let empty = (UContext.empty, UContext.empty)
- let is_empty (univcst, subtypcst) = UContext.is_empty univcst && UContext.is_empty subtypcst
+ let empty = (UContext.empty, [||])
+ let is_empty (univs, variance) = UContext.is_empty univs && Array.is_empty variance
- let halve_context ctx =
- let len = Array.length (Instance.to_array ctx) in
- let halflen = len / 2 in
- (Instance.of_array (Array.sub (Instance.to_array ctx) 0 halflen),
- Instance.of_array (Array.sub (Instance.to_array ctx) halflen halflen))
+ let pr prl (univs, variance) =
+ UContext.pr prl ~variance univs
- let pr prl (univcst, subtypcst) =
- if UContext.is_empty univcst then mt() else
- let (ctx, ctx') = halve_context (UContext.instance subtypcst) in
- (UContext.pr prl univcst) ++ fnl () ++ fnl () ++
- h 0 (str "~@{" ++ Instance.pr prl ctx ++ str "} <= ~@{" ++ Instance.pr prl ctx' ++ str "} iff ")
- ++ fnl () ++ h 0 (v 0 (Constraint.pr prl (UContext.constraints subtypcst)))
+ let hcons (univs, variance) = (* should variance be hconsed? *)
+ (UContext.hcons univs, variance)
- let hcons (univcst, subtypcst) =
- (UContext.hcons univcst, UContext.hcons subtypcst)
-
- let univ_context (univcst, subtypcst) = univcst
- let subtyp_context (univcst, subtypcst) = subtypcst
-
- let create_trivial_subtyping ctx ctx' =
- CArray.fold_left_i
- (fun i cst l -> Constraint.add (l, Eq, Array.get ctx' i) cst)
- Constraint.empty (Instance.to_array ctx)
+ let univ_context (univs, subtypcst) = univs
+ let variance (univs, variance) = variance
(** This function takes a universe context representing constraints
- of an inductive and a Instance.t of fresh universe names for the
- subtyping (with the same length as the context in the given
- universe context) and produces a UInfoInd.t that with the
- trivial subtyping relation. *)
- let from_universe_context univcst freshunivs =
- let inst = (UContext.instance univcst) in
- assert (Instance.length freshunivs = Instance.length inst);
- (univcst, UContext.make (Instance.append inst freshunivs,
- create_trivial_subtyping inst freshunivs))
-
- let subtyping_susbst (univcst, subtypcst) =
- let (ctx, ctx') = (halve_context (UContext.instance subtypcst))in
- Array.fold_left2 (fun subst l1 l2 -> LMap.add l1 l2 subst) LMap.empty ctx ctx'
+ of an inductive and produces a CumulativityInfo.t with the
+ trivial subtyping relation. *)
+ let from_universe_context univs =
+ (univs, Array.init (UContext.size univs) (fun _ -> Variance.Invariant))
+
+ let leq_constraints (_,variance) u u' csts = Variance.leq_constraints variance u u' csts
+ let eq_constraints (_,variance) u u' csts = Variance.eq_constraints variance u u' csts
end
@@ -1138,10 +1159,9 @@ let abstract_universes ctx =
let ctx = UContext.make (instance, cstrs) in
instance, ctx
-let abstract_cumulativity_info (univcst, substcst) =
- let instance, univcst = abstract_universes univcst in
- let _, substcst = abstract_universes substcst in
- (instance, (univcst, substcst))
+let abstract_cumulativity_info (univs, variance) =
+ let subst, univs = abstract_universes univs in
+ subst, (univs, variance)
(** Pretty-printing *)
diff --git a/kernel/univ.mli b/kernel/univ.mli
index 63bef1b81b..77ebf5a11b 100644
--- a/kernel/univ.mli
+++ b/kernel/univ.mli
@@ -238,6 +238,20 @@ type universe_level_subst_fn = Level.t -> Level.t
type universe_subst = Universe.t universe_map
type universe_level_subst = Level.t universe_map
+module Variance :
+sig
+ (** A universe position in the instance given to a cumulative
+ inductive can be the following. Note there is no Contravariant
+ case because [forall x : A, B <= forall x : A', B'] requires [A =
+ A'] as opposed to [A' <= A]. *)
+ type t = Irrelevant | Covariant | Invariant
+
+ val sup : t -> t -> t
+
+ val pr : t -> Pp.t
+
+end
+
(** {6 Universe instances} *)
module Instance :
@@ -273,7 +287,7 @@ sig
val subst_fn : universe_level_subst_fn -> t -> t
(** Substitution by a level-to-level function. *)
- val pr : (Level.t -> Pp.t) -> t -> Pp.t
+ val pr : (Level.t -> Pp.t) -> ?variance:Variance.t array -> t -> Pp.t
(** Pretty-printing, no comments *)
val levels : t -> LSet.t
@@ -347,36 +361,32 @@ end
type abstract_universe_context = AUContext.t
[@@ocaml.deprecated "Use AUContext.t"]
-(** Universe info for inductive types: A context of universe levels
- with universe Constraint.t, representing local universe variables
- and Constraint.t, together with a context of universe levels with
- universe Constraint.t, representing conditions for subtyping used
- for inductive types.
+(** Universe info for cumulative inductive types: A context of
+ universe levels with universe constraints, representing local
+ universe variables and constraints, together with an array of
+ Variance.t.
- This data structure maintains the invariant that the context for
- subtyping Constraint.t is exactly twice as big as the context for
- universe Constraint.t. *)
+ This data structure maintains the invariant that the variance
+ array has the same length as the universe instance. *)
module CumulativityInfo :
sig
type t
- val make : UContext.t * UContext.t -> t
+ val make : UContext.t * Variance.t array -> t
val empty : t
val is_empty : t -> bool
val univ_context : t -> UContext.t
- val subtyp_context : t -> UContext.t
-
- (** This function takes a universe context representing Constraint.t
- of an inductive and a Instance.t of fresh universe names for the
- subtyping (with the same length as the context in the given
- universe context) and produces a UInfoInd.t that with the
- trivial subtyping relation. *)
- val from_universe_context : UContext.t -> Instance.t -> t
+ val variance : t -> Variance.t array
- val subtyping_susbst : t -> universe_level_subst
+ (** This function takes a universe context representing constraints
+ of an inductive and produces a CumulativityInfo.t with the
+ trivial subtyping relation. *)
+ val from_universe_context : UContext.t -> t
+ val leq_constraints : t -> Instance.t constraint_function
+ val eq_constraints : t -> Instance.t constraint_function
end
type cumulativity_info = CumulativityInfo.t
@@ -387,7 +397,9 @@ sig
type t
val univ_context : t -> AUContext.t
- val subtyp_context : t -> AUContext.t
+ val variance : t -> Variance.t array
+ val leq_constraints : t -> Instance.t constraint_function
+ val eq_constraints : t -> Instance.t constraint_function
end
type abstract_cumulativity_info = ACumulativityInfo.t
@@ -481,9 +493,11 @@ val make_abstract_instance : AUContext.t -> Instance.t
val pr_constraint_type : constraint_type -> Pp.t
val pr_constraints : (Level.t -> Pp.t) -> Constraint.t -> Pp.t
-val pr_universe_context : (Level.t -> Pp.t) -> UContext.t -> Pp.t
+val pr_universe_context : (Level.t -> Pp.t) -> ?variance:Variance.t array ->
+ UContext.t -> Pp.t
val pr_cumulativity_info : (Level.t -> Pp.t) -> CumulativityInfo.t -> Pp.t
-val pr_abstract_universe_context : (Level.t -> Pp.t) -> AUContext.t -> Pp.t
+val pr_abstract_universe_context : (Level.t -> Pp.t) -> ?variance:Variance.t array ->
+ AUContext.t -> Pp.t
val pr_abstract_cumulativity_info : (Level.t -> Pp.t) -> ACumulativityInfo.t -> Pp.t
val pr_universe_context_set : (Level.t -> Pp.t) -> ContextSet.t -> Pp.t
val explain_universe_inconsistency : (Level.t -> Pp.t) ->
diff --git a/kernel/vconv.ml b/kernel/vconv.ml
index 3ef297b1f4..8c76581478 100644
--- a/kernel/vconv.ml
+++ b/kernel/vconv.ml
@@ -3,6 +3,7 @@ open Names
open Environ
open Reduction
open Vm
+open Vmvalues
open Csymtable
let val_of_constr env c =
diff --git a/kernel/vconv.mli b/kernel/vconv.mli
index 7f727df475..c3c9636e89 100644
--- a/kernel/vconv.mli
+++ b/kernel/vconv.mli
@@ -19,4 +19,4 @@ val vm_conv : conv_pb -> types kernel_conversion_function
val vm_conv_gen : conv_pb -> (types, 'a) generic_conversion_function
(** Precompute a VM value from a constr *)
-val val_of_constr : env -> constr -> values
+val val_of_constr : env -> constr -> Vmvalues.values
diff --git a/kernel/vm.ml b/kernel/vm.ml
index 51101f88e4..352ea74a41 100644
--- a/kernel/vm.ml
+++ b/kernel/vm.ml
@@ -6,47 +6,13 @@
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
-open Names
-open Sorts
-open Constr
open Cbytecodes
+open Vmvalues
external set_drawinstr : unit -> unit = "coq_set_drawinstr"
-(******************************************)
-(* Utility Functions about Obj ************)
-(******************************************)
-
-external offset_closure : Obj.t -> int -> Obj.t = "coq_offset_closure"
-external offset : Obj.t -> int = "coq_offset"
-
-(*******************************************)
-(* Initalization of the abstract machine ***)
-(*******************************************)
-
-external init_vm : unit -> unit = "init_coq_vm"
-
-let _ = init_vm ()
-
-(*******************************************)
-(* Machine code *** ************************)
-(*******************************************)
-
-type tcode
-let tcode_of_obj v = ((Obj.obj v):tcode)
-let fun_code v = tcode_of_obj (Obj.field (Obj.repr v) 0)
-
-external mkAccuCode : int -> tcode = "coq_makeaccu"
external mkPopStopCode : int -> tcode = "coq_pushpop"
-external offset_tcode : tcode -> int -> tcode = "coq_offset_tcode"
-external int_tcode : tcode -> int -> int = "coq_int_tcode"
-
-external accumulate : unit -> tcode = "accumulate_code"
-let accumulate = accumulate ()
-
-external is_accumulate : tcode -> bool = "coq_is_accumulate_code"
-
let popstop_tbl = ref (Array.init 30 mkPopStopCode)
let popstop_code i =
@@ -62,106 +28,6 @@ let popstop_code i =
let stop = popstop_code 0
-(******************************************************)
-(* Abstract data types and utility functions **********)
-(******************************************************)
-
-(* Values of the abstract machine *)
-let val_of_obj v = ((Obj.obj v):values)
-let crazy_val = (val_of_obj (Obj.repr 0))
-
-(* Abstract data *)
-type vprod
-type vfun
-type vfix
-type vcofix
-type vblock
-type arguments
-
-type vm_env
-type vstack = values array
-
-type vswitch = {
- sw_type_code : tcode;
- sw_code : tcode;
- sw_annot : annot_switch;
- sw_stk : vstack;
- sw_env : vm_env
- }
-
-(* Representation of values *)
-(* + Products : *)
-(* - vprod = 0_[ dom | codom] *)
-(* dom : values, codom : vfun *)
-(* *)
-(* + Functions have two representations : *)
-(* - unapplied fun : vf = Ct_[ C | fv1 | ... | fvn] *)
-(* C:tcode, fvi : values *)
-(* Remark : a function and its environment is the same value. *)
-(* - partially applied fun : Ct_[Restart:C| vf | arg1 | ... argn] *)
-(* *)
-(* + Fixpoints : *)
-(* - Ct_[C1|Infix_t|C2|...|Infix_t|Cn|fv1|...|fvn] *)
-(* One single block to represent all of the fixpoints, each fixpoint *)
-(* is the pointer to the field holding the pointer to its code, and *)
-(* the infix tag is used to know where the block starts. *)
-(* - Partial application follows the scheme of partially applied *)
-(* functions. Note: only fixpoints not having been applied to its *)
-(* recursive argument are coded this way. When the rec. arg. is *)
-(* applied, either it's a constructor and the fix reduces, or it's *)
-(* and the fix is coded as an accumulator. *)
-(* *)
-(* + Cofixpoints : see cbytegen.ml *)
-(* *)
-(* + vblock's encode (non constant) constructors as in Ocaml, but *)
-(* starting from 0 up. tag 0 ( = accu_tag) is reserved for *)
-(* accumulators. *)
-(* *)
-(* + vm_env is the type of the machine environments (i.e. a function or *)
-(* a fixpoint) *)
-(* *)
-(* + Accumulators : At_[accumulate| accu | arg1 | ... | argn ] *)
-(* - representation of [accu] : tag_[....] *)
-(* -- tag <= 3 : encoding atom type (sorts, free vars, etc.) *)
-(* -- 10_[accu|proj name] : a projection blocked by an accu *)
-(* -- 11_[accu|fix_app] : a fixpoint blocked by an accu *)
-(* -- 12_[accu|vswitch] : a match blocked by an accu *)
-(* -- 13_[fcofix] : a cofix function *)
-(* -- 14_[fcofix|val] : a cofix function, val represent the value *)
-(* of the function applied to arg1 ... argn *)
-(* The [arguments] type, which is abstracted as an array, represents : *)
-(* tag[ _ | _ |v1|... | vn] *)
-(* Generally the first field is a code pointer. *)
-
-(* Do not edit this type without editing C code, especially "coq_values.h" *)
-
-type atom =
- | Aid of Vars.id_key
- | Aind of inductive
- | Atype of Univ.Universe.t
-
-(* Zippers *)
-
-type zipper =
- | Zapp of arguments
- | Zfix of vfix*arguments (* Possibly empty *)
- | Zswitch of vswitch
- | Zproj of Constant.t (* name of the projection *)
-
-type stack = zipper list
-
-type to_up = values
-
-type whd =
- | Vsort of Sorts.t
- | Vprod of vprod
- | Vfun of vfun
- | Vfix of vfix * arguments option
- | Vcofix of vcofix * to_up * arguments option
- | Vconstr_const of int
- | Vconstr_block of vblock
- | Vatom_stk of atom * stack
- | Vuniv_level of Univ.Level.t
(************************************************)
(* Abstract machine *****************************)
@@ -178,389 +44,72 @@ external push_vstack : vstack -> int -> unit = "coq_push_vstack"
external interprete : tcode -> values -> vm_env -> int -> values =
"coq_interprete_ml"
-
-
(* Functions over arguments *)
-let nargs : arguments -> int = fun args -> (Obj.size (Obj.repr args)) - 2
-let arg args i =
- if 0 <= i && i < (nargs args) then
- val_of_obj (Obj.field (Obj.repr args) (i+2))
- else invalid_arg
- ("Vm.arg size = "^(string_of_int (nargs args))^
- " acces "^(string_of_int i))
(* Apply a value to arguments contained in [vargs] *)
let apply_arguments vf vargs =
let n = nargs vargs in
- if Int.equal n 0 then vf
+ if Int.equal n 0 then fun_val vf
else
begin
push_ra stop;
push_arguments vargs;
- interprete (fun_code vf) vf (Obj.magic vf) (n - 1)
+ interprete (fun_code vf) (fun_val vf) (fun_env vf) (n - 1)
end
(* Apply value [vf] to an array of argument values [varray] *)
let apply_varray vf varray =
let n = Array.length varray in
- if Int.equal n 0 then vf
+ if Int.equal n 0 then fun_val vf
else
begin
push_ra stop;
(* The fun code of [vf] will make sure we have enough stack, so we put 0
here. *)
push_vstack varray 0;
- interprete (fun_code vf) vf (Obj.magic vf) (n - 1)
+ interprete (fun_code vf) (fun_val vf) (fun_env vf) (n - 1)
end
-(*************************************************)
-(* Destructors ***********************************)
-(*************************************************)
-
-let uni_lvl_val (v : values) : Univ.Level.t =
- let whd = Obj.magic v in
- match whd with
- | Vuniv_level lvl -> lvl
- | _ ->
- let pr =
- let open Pp in
- match whd with
- | Vsort _ -> str "Vsort"
- | Vprod _ -> str "Vprod"
- | Vfun _ -> str "Vfun"
- | Vfix _ -> str "Vfix"
- | Vcofix _ -> str "Vcofix"
- | Vconstr_const i -> str "Vconstr_const"
- | Vconstr_block b -> str "Vconstr_block"
- | Vatom_stk (a,stk) -> str "Vatom_stk"
- | _ -> assert false
- in
- CErrors.anomaly
- Pp.( strbrk "Parsing virtual machine value expected universe level, got "
- ++ pr ++ str ".")
-
-let rec whd_accu a stk =
- let stk =
- if Int.equal (Obj.size a) 2 then stk
- else Zapp (Obj.obj a) :: stk in
- let at = Obj.field a 1 in
- match Obj.tag at with
- | i when Int.equal i type_atom_tag ->
- begin match stk with
- | [Zapp args] ->
- let u = ref (Obj.obj (Obj.field at 0)) in
- for i = 0 to nargs args - 1 do
- u := Univ.Universe.sup !u (Univ.Universe.make (uni_lvl_val (arg args i)))
- done;
- Vsort (Type !u)
- | _ -> assert false
- end
- | i when i <= max_atom_tag ->
- Vatom_stk(Obj.magic at, stk)
- | i when Int.equal i proj_tag ->
- let zproj = Zproj (Obj.obj (Obj.field at 0)) in
- whd_accu (Obj.field at 1) (zproj :: stk)
- | i when Int.equal i fix_app_tag ->
- let fa = Obj.field at 1 in
- let zfix =
- Zfix (Obj.obj (Obj.field fa 1), Obj.obj fa) in
- whd_accu (Obj.field at 0) (zfix :: stk)
- | i when Int.equal i switch_tag ->
- let zswitch = Zswitch (Obj.obj (Obj.field at 1)) in
- whd_accu (Obj.field at 0) (zswitch :: stk)
- | i when Int.equal i cofix_tag ->
- let vcfx = Obj.obj (Obj.field at 0) in
- let to_up = Obj.obj a in
- begin match stk with
- | [] -> Vcofix(vcfx, to_up, None)
- | [Zapp args] -> Vcofix(vcfx, to_up, Some args)
- | _ -> assert false
- end
- | i when Int.equal i cofix_evaluated_tag ->
- let vcofix = Obj.obj (Obj.field at 0) in
- let res = Obj.obj a in
- begin match stk with
- | [] -> Vcofix(vcofix, res, None)
- | [Zapp args] -> Vcofix(vcofix, res, Some args)
- | _ -> assert false
- end
- | tg ->
- CErrors.anomaly
- Pp.(strbrk "Failed to parse VM value. Tag = " ++ int tg ++ str ".")
-
-external kind_of_closure : Obj.t -> int = "coq_kind_of_closure"
-
-let whd_val : values -> whd =
- fun v ->
- let o = Obj.repr v in
- if Obj.is_int o then Vconstr_const (Obj.obj o)
- 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))
- else
- if tag = Obj.closure_tag || tag = Obj.infix_tag then
- (match kind_of_closure o with
- | 0 -> Vfun(Obj.obj o)
- | 1 -> Vfix(Obj.obj o, None)
- | 2 -> Vfix(Obj.obj (Obj.field o 1), Some (Obj.obj o))
- | 3 -> Vatom_stk(Aid(RelKey(int_tcode (fun_code o) 1)), [])
- | _ -> CErrors.anomaly ~label:"Vm.whd " (Pp.str "kind_of_closure does not work."))
- else
- Vconstr_block(Obj.obj o)
-
-(**********************************************)
-(* Constructors *******************************)
-(**********************************************)
-
-let obj_of_atom : atom -> Obj.t =
- fun a ->
- let res = Obj.new_block accu_tag 2 in
- Obj.set_field res 0 (Obj.repr accumulate);
- Obj.set_field res 1 (Obj.repr a);
- res
-
-(* 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_ind ind -> obj_of_atom (Aind ind)
- | Const_proj p -> Obj.repr p
- | Const_b0 tag -> Obj.repr tag
- | Const_bn(tag, args) ->
- let len = Array.length args in
- let res = Obj.new_block tag len in
- for i = 0 to len - 1 do
- Obj.set_field res i (obj_of_str_const args.(i))
- 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)
-
-let val_of_str_const str = val_of_obj (obj_of_str_const str)
-
-let val_of_atom a = val_of_obj (obj_of_atom a)
-
-let atom_of_proj kn v =
- let r = Obj.new_block proj_tag 2 in
- Obj.set_field r 0 (Obj.repr kn);
- Obj.set_field r 1 (Obj.repr v);
- ((Obj.obj r) : atom)
-
-let val_of_proj kn v =
- val_of_atom (atom_of_proj kn v)
-
-module IdKeyHash =
-struct
- type t = Constant.t tableKey
- let equal = Names.eq_table_key Constant.equal
- 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)
-end
-
-module KeyTable = Hashtbl.Make(IdKeyHash)
-
-let idkey_tbl = KeyTable.create 31
-
-let val_of_idkey key =
- try KeyTable.find idkey_tbl key
- with Not_found ->
- let v = val_of_atom (Aid key) in
- KeyTable.add idkey_tbl key v;
- v
-
-let val_of_rel k = val_of_idkey (RelKey k)
-
-let val_of_named id = val_of_idkey (VarKey id)
-
-let val_of_constant c = val_of_idkey (ConstKey c)
-
-external val_of_annot_switch : annot_switch -> values = "%identity"
-
+(* Functions over vfun *)
let mkrel_vstack k arity =
let max = k + arity - 1 in
Array.init arity (fun i -> val_of_rel (max - i))
-
-(*************************************************)
-(** Operations manipulating data types ***********)
-(*************************************************)
-
-(* Functions over products *)
-
-let dom : vprod -> values = fun p -> val_of_obj (Obj.field (Obj.repr p) 0)
-let codom : vprod -> vfun = fun p -> (Obj.obj (Obj.field (Obj.repr p) 1))
-
-(* Functions over vfun *)
-
-external closure_arity : vfun -> int = "coq_closure_arity"
-
-let body_of_vfun k vf =
+let reduce_fun k vf =
let vargs = mkrel_vstack k 1 in
- apply_varray (Obj.magic vf) vargs
+ apply_varray vf vargs
let decompose_vfun2 k vf1 vf2 =
let arity = min (closure_arity vf1) (closure_arity vf2) in
assert (0 < arity && arity < Sys.max_array_length);
let vargs = mkrel_vstack k arity in
- let v1 = apply_varray (Obj.magic vf1) vargs in
- let v2 = apply_varray (Obj.magic vf2) vargs in
+ let v1 = apply_varray vf1 vargs in
+ let v2 = apply_varray vf2 vargs in
arity, v1, v2
-(* Functions over fixpoint *)
-
-let first o = (offset_closure o (offset o))
-let last o = (Obj.field o (Obj.size o - 1))
-
-let current_fix vf = - (offset (Obj.repr vf) / 2)
-
-let unsafe_fb_code fb i = tcode_of_obj (Obj.field (Obj.repr fb) (2 * i))
-
-let unsafe_rec_arg fb i = int_tcode (unsafe_fb_code fb i) 1
-
-let rec_args vf =
- let fb = first (Obj.repr vf) in
- let size = Obj.size (last fb) in
- Array.init size (unsafe_rec_arg fb)
-
-exception FALSE
-
-let check_fix f1 f2 =
- let i1, i2 = current_fix f1, current_fix f2 in
- (* Checking starting point *)
- if i1 = i2 then
- let fb1,fb2 = first (Obj.repr f1), first (Obj.repr f2) in
- let n = Obj.size (last fb1) in
- (* Checking number of definitions *)
- if n = Obj.size (last fb2) then
- (* Checking recursive arguments *)
- try
- for i = 0 to n - 1 do
- if unsafe_rec_arg fb1 i <> unsafe_rec_arg fb2 i
- then raise FALSE
- done;
- true
- with FALSE -> false
- else false
- else false
-
(* Functions over vfix *)
-external atom_rel : unit -> atom array = "get_coq_atom_tbl"
-external realloc_atom_rel : int -> unit = "realloc_coq_atom_tbl"
-
-let relaccu_tbl =
- let atom_rel = atom_rel() in
- let len = Array.length atom_rel in
- for i = 0 to len - 1 do atom_rel.(i) <- Aid (RelKey i) done;
- ref (Array.init len mkAccuCode)
-
-let relaccu_code i =
- let len = Array.length !relaccu_tbl in
- if i < len then !relaccu_tbl.(i)
- else
- begin
- realloc_atom_rel i;
- let atom_rel = atom_rel () in
- let nl = Array.length atom_rel in
- for j = len to nl - 1 do atom_rel.(j) <- Aid(RelKey j) done;
- relaccu_tbl :=
- Array.init nl
- (fun j -> if j < len then !relaccu_tbl.(j) else mkAccuCode j);
- !relaccu_tbl.(i)
- end
let reduce_fix k vf =
- let fb = first (Obj.repr vf) in
+ let fb = first_fix vf in
(* computing types *)
- let fc_typ = ((Obj.obj (last fb)) : tcode array) in
+ let fc_typ = fix_types fb in
let ndef = Array.length fc_typ in
- let et = offset_closure fb (2*(ndef - 1)) in
+ let et = offset_closure_fix fb (2*(ndef - 1)) in
let ftyp =
Array.map
- (fun c -> interprete c crazy_val (Obj.magic et) 0) fc_typ in
+ (fun c -> interprete c crazy_val et 0) fc_typ in
(* Construction of the environment of fix bodies *)
- let e = Obj.dup fb in
- for i = 0 to ndef - 1 do
- Obj.set_field e (2 * i) (Obj.repr (relaccu_code (k + i)))
- done;
- let fix_body i =
- let jump_grabrec c = offset_tcode c 2 in
- let c = jump_grabrec (unsafe_fb_code fb i) in
- let res = Obj.new_block Obj.closure_tag 2 in
- Obj.set_field res 0 (Obj.repr c);
- Obj.set_field res 1 (offset_closure e (2*i));
- ((Obj.obj res) : vfun) in
- (Array.init ndef fix_body, ftyp)
-
-(* Functions over vcofix *)
-
-let get_fcofix vcf i =
- match whd_val (Obj.obj (Obj.field (Obj.repr vcf) (i+1))) with
- | Vcofix(vcfi, _, _) -> vcfi
- | _ -> assert false
-
-let current_cofix vcf =
- let ndef = Obj.size (last (Obj.repr vcf)) in
- let rec find_cofix pos =
- if pos < ndef then
- if get_fcofix vcf pos == vcf then pos
- else find_cofix (pos+1)
- else raise Not_found in
- try find_cofix 0
- with Not_found -> assert false
-
-let check_cofix vcf1 vcf2 =
- (current_cofix vcf1 = current_cofix vcf2) &&
- (Obj.size (last (Obj.repr vcf1)) = Obj.size (last (Obj.repr vcf2)))
+ (mk_fix_body k ndef fb, ftyp)
let reduce_cofix k vcf =
- let fc_typ = ((Obj.obj (last (Obj.repr vcf))) : tcode array) in
+ let fc_typ = cofix_types vcf in
let ndef = Array.length fc_typ in
let ftyp =
(* Evaluate types *)
- Array.map (fun c -> interprete c crazy_val (Obj.magic vcf) 0) fc_typ in
+ Array.map (fun c -> interprete c crazy_val (cofix_env vcf) 0) fc_typ in
(* Construction of the environment of cofix bodies *)
- let e = Obj.dup (Obj.repr vcf) in
- for i = 0 to ndef - 1 do
- Obj.set_field e (i+1) (Obj.repr (val_of_rel (k+i)))
- done;
-
- let cofix_body i =
- let vcfi = get_fcofix vcf i in
- let c = Obj.field (Obj.repr vcfi) 0 in
- Obj.set_field e 0 c;
- let atom = Obj.new_block cofix_tag 1 in
- let self = Obj.new_block accu_tag 2 in
- Obj.set_field self 0 (Obj.repr accumulate);
- Obj.set_field self 1 (Obj.repr atom);
- apply_varray (Obj.obj e) [|Obj.obj self|] in
- (Array.init ndef cofix_body, ftyp)
-
-
-(* Functions over vblock *)
-
-let btag : vblock -> int = fun b -> Obj.tag (Obj.repr b)
-let bsize : vblock -> int = fun b -> Obj.size (Obj.repr b)
-let bfield b i =
- if 0 <= i && i < (bsize b) then val_of_obj (Obj.field (Obj.repr b) i)
- else invalid_arg "Vm.bfield"
-
-
-(* Functions over vswitch *)
-
-let check_switch sw1 sw2 = sw1.sw_annot.rtbl = sw2.sw_annot.rtbl
-
-let case_info sw = sw.sw_annot.ci
+ (mk_cofix_body apply_varray k ndef vcf, ftyp)
let type_of_switch sw =
(* The fun code of types will make sure we have enough stack, so we put 0
@@ -568,20 +117,6 @@ let type_of_switch sw =
push_vstack sw.sw_stk 0;
interprete sw.sw_type_code crazy_val sw.sw_env 0
-let branch_arg k (tag,arity) =
- if Int.equal arity 0 then ((Obj.magic tag):values)
- else
- let b, ofs =
- if tag < last_variant_tag then Obj.new_block tag arity, 0
- else
- let b = Obj.new_block last_variant_tag (arity+1) in
- Obj.set_field b 0 (Obj.repr (tag-last_variant_tag));
- b,1 in
- for i = ofs to ofs + arity - 1 do
- Obj.set_field b i (Obj.repr (val_of_rel (k+i)))
- done;
- val_of_obj b
-
let apply_switch sw arg =
let tc = sw.sw_annot.tailcall in
if tc then
@@ -603,8 +138,8 @@ let branch_of_switch k sw =
(* t = a stk --> t v *)
let rec apply_stack a stk v =
match stk with
- | [] -> apply_varray a [|v|]
- | Zapp args :: stk -> apply_stack (apply_arguments a args) stk v
+ | [] -> apply_varray (fun_of_val a) [|v|]
+ | Zapp args :: stk -> apply_stack (apply_arguments (fun_of_val a) args) stk v
| Zproj kn :: stk -> apply_stack (val_of_proj kn a) stk v
| Zfix(f,args) :: stk ->
let a,stk =
@@ -615,7 +150,7 @@ let rec apply_stack a stk v =
push_val a;
push_arguments args;
let a =
- interprete (fun_code f) (Obj.magic f) (Obj.magic f)
+ interprete (fix_code f) (fix_val f) (fix_env f)
(nargs args+ nargs args') in
a, stk
| _ ->
@@ -623,7 +158,7 @@ let rec apply_stack a stk v =
push_val a;
push_arguments args;
let a =
- interprete (fun_code f) (Obj.magic f) (Obj.magic f)
+ interprete (fix_code f) (fix_val f) (fix_env f)
(nargs args) in
a, stk in
apply_stack a stk v
@@ -634,50 +169,21 @@ let apply_whd k whd =
let v = val_of_rel k in
match whd with
| Vsort _ | Vprod _ | Vconstr_const _ | Vconstr_block _ -> assert false
- | Vfun f -> body_of_vfun k f
+ | Vfun f -> reduce_fun k f
| Vfix(f, None) ->
push_ra stop;
push_val v;
- interprete (fun_code f) (Obj.magic f) (Obj.magic f) 0
+ interprete (fix_code f) (fix_val f) (fix_env f) 0
| Vfix(f, Some args) ->
push_ra stop;
push_val v;
push_arguments args;
- interprete (fun_code f) (Obj.magic f) (Obj.magic f) (nargs args)
+ interprete (fix_code f) (fix_val f) (fix_env f) (nargs args)
| Vcofix(_,to_up,_) ->
push_ra stop;
push_val v;
- interprete (fun_code to_up) (Obj.magic to_up) (Obj.magic to_up) 0
+ interprete (cofix_upd_code to_up) (cofix_upd_val to_up) (cofix_upd_env to_up) 0
| Vatom_stk(a,stk) ->
apply_stack (val_of_atom a) stk v
| Vuniv_level lvl -> assert false
-let rec pr_atom a =
- Pp.(match a with
- | Aid c -> str "Aid(" ++ (match c with
- | ConstKey c -> Constant.print c
- | RelKey i -> str "#" ++ int i
- | _ -> str "...") ++ str ")"
- | Aind (mi,i) -> str "Aind(" ++ MutInd.print mi ++ str "#" ++ int i ++ str ")"
- | Atype _ -> str "Atype(")
-and pr_whd w =
- Pp.(match w with
- | Vsort _ -> str "Vsort"
- | Vprod _ -> str "Vprod"
- | Vfun _ -> str "Vfun"
- | Vfix _ -> str "Vfix"
- | Vcofix _ -> str "Vcofix"
- | Vconstr_const i -> str "Vconstr_const(" ++ int i ++ str ")"
- | Vconstr_block b -> str "Vconstr_block"
- | Vatom_stk (a,stk) -> str "Vatom_stk(" ++ pr_atom a ++ str ", " ++ pr_stack stk ++ str ")"
- | Vuniv_level _ -> assert false)
-and pr_stack stk =
- Pp.(match stk with
- | [] -> str "[]"
- | s :: stk -> pr_zipper s ++ str " :: " ++ pr_stack stk)
-and pr_zipper z =
- Pp.(match z with
- | Zapp args -> str "Zapp(len = " ++ int (nargs args) ++ str ")"
- | Zfix (f,args) -> str "Zfix(..., len=" ++ int (nargs args) ++ str ")"
- | Zswitch s -> str "Zswitch(...)"
- | Zproj c -> str "Zproj(" ++ Constant.print c ++ str ")")
diff --git a/kernel/vm.mli b/kernel/vm.mli
index bc38452d4f..c6d92ba266 100644
--- a/kernel/vm.mli
+++ b/kernel/vm.mli
@@ -6,118 +6,28 @@
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
-open Names
-open Constr
-open Cbytecodes
+open Vmvalues
(** Debug printing *)
val set_drawinstr : unit -> unit
-(** Machine code *)
-
-type tcode
-
-(** Values *)
-
-type vprod
-type vfun
-type vfix
-type vcofix
-type vblock
-type vswitch
-type arguments
-
-type atom =
- | Aid of Vars.id_key
- | Aind of inductive
- | Atype of Univ.Universe.t
-
-(** Zippers *)
-
-type zipper =
- | Zapp of arguments
- | Zfix of vfix * arguments (** might be empty *)
- | Zswitch of vswitch
- | Zproj of Constant.t (* name of the projection *)
-
-type stack = zipper list
-
-type to_up
-
-type whd =
- | Vsort of Sorts.t
- | Vprod of vprod
- | Vfun of vfun
- | Vfix of vfix * arguments option
- | Vcofix of vcofix * to_up * arguments option
- | Vconstr_const of int
- | Vconstr_block of vblock
- | Vatom_stk of atom * stack
- | Vuniv_level of Univ.Level.t
-
-(** For debugging purposes only *)
-
-val pr_atom : atom -> Pp.t
-val pr_whd : whd -> Pp.t
-val pr_stack : stack -> Pp.t
-
-(** Constructors *)
-
-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
-
-external val_of_annot_switch : annot_switch -> values = "%identity"
-
-(** Destructors *)
-
-val whd_val : values -> whd
-val uni_lvl_val : values -> Univ.Level.t
-
-(** Arguments *)
-
-val nargs : arguments -> int
-val arg : arguments -> int -> values
-
-(** Product *)
-
-val dom : vprod -> values
-val codom : vprod -> vfun
-
-(** Function *)
-
-val body_of_vfun : int -> vfun -> values
-val decompose_vfun2 : int -> vfun -> vfun -> int * values * values
-
-(** Fix *)
-
-val current_fix : vfix -> int
-val check_fix : vfix -> vfix -> bool
-val rec_args : vfix -> int array
val reduce_fix : int -> vfix -> vfun array * values array
(** bodies , types *)
-(** CoFix *)
-
-val current_cofix : vcofix -> int
-val check_cofix : vcofix -> vcofix -> bool
val reduce_cofix : int -> vcofix -> values array * values array
(** bodies , types *)
-(** Block *)
+val type_of_switch : vswitch -> values
-val btag : vblock -> int
-val bsize : vblock -> int
-val bfield : vblock -> int -> values
+val branch_of_switch : int -> vswitch -> (int * values) array
-(** Switch *)
+val reduce_fun : int -> vfun -> values
-val check_switch : vswitch -> vswitch -> bool
-val case_info : vswitch -> case_info
-val type_of_switch : vswitch -> values
-val branch_of_switch : int -> vswitch -> (int * values) array
+(** [decompose_vfun2 k f1 f2] takes two functions [f1] and [f2] at current
+ DeBruijn level [k], with [n] lambdas in common, returns [n] and the reduced
+ bodies under those lambdas. *)
+val decompose_vfun2 : int -> vfun -> vfun -> int * values * values
(** Apply a value *)
diff --git a/kernel/vmvalues.ml b/kernel/vmvalues.ml
new file mode 100644
index 0000000000..1102cdec18
--- /dev/null
+++ b/kernel/vmvalues.ml
@@ -0,0 +1,525 @@
+(************************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2017 *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(************************************************************************)
+open Names
+open Sorts
+open Cbytecodes
+
+(*******************************************)
+(* Initalization of the abstract machine ***)
+(* Necessary for [relaccu_tbl] *)
+(*******************************************)
+
+external init_vm : unit -> unit = "init_coq_vm"
+
+let _ = init_vm ()
+
+(******************************************************)
+(* Abstract data types and utility functions **********)
+(******************************************************)
+
+(* Values of the abstract machine *)
+type values
+let val_of_obj v = ((Obj.obj v):values)
+let crazy_val = (val_of_obj (Obj.repr 0))
+
+(* Abstract data *)
+type vprod
+type vfun
+type vfix
+type vcofix
+type vblock
+type arguments
+
+let fun_val v = (Obj.magic v : values)
+let fix_val v = (Obj.magic v : values)
+let cofix_upd_val v = (Obj.magic v : values)
+
+type vm_env
+let fun_env v = (Obj.magic v : vm_env)
+let fix_env v = (Obj.magic v : vm_env)
+let cofix_env v = (Obj.magic v : vm_env)
+let cofix_upd_env v = (Obj.magic v : vm_env)
+type vstack = values array
+
+let fun_of_val v = (Obj.magic v : vfun)
+
+(*******************************************)
+(* Machine code *** ************************)
+(*******************************************)
+
+type tcode
+
+external mkAccuCode : int -> tcode = "coq_makeaccu"
+external offset_tcode : tcode -> int -> tcode = "coq_offset_tcode"
+
+let tcode_of_obj v = ((Obj.obj v):tcode)
+let fun_code v = tcode_of_obj (Obj.field (Obj.repr v) 0)
+let fix_code v = fun_code v
+let cofix_upd_code v = fun_code v
+
+
+type vswitch = {
+ sw_type_code : tcode;
+ sw_code : tcode;
+ sw_annot : annot_switch;
+ sw_stk : vstack;
+ sw_env : vm_env
+ }
+
+(* Representation of values *)
+(* + Products : *)
+(* - vprod = 0_[ dom | codom] *)
+(* dom : values, codom : vfun *)
+(* *)
+(* + Functions have two representations : *)
+(* - unapplied fun : vf = Ct_[ C | fv1 | ... | fvn] *)
+(* C:tcode, fvi : values *)
+(* Remark : a function and its environment is the same value. *)
+(* - partially applied fun : Ct_[Restart:C| vf | arg1 | ... argn] *)
+(* *)
+(* + Fixpoints : *)
+(* - Ct_[C1|Infix_t|C2|...|Infix_t|Cn|fv1|...|fvn] *)
+(* One single block to represent all of the fixpoints, each fixpoint *)
+(* is the pointer to the field holding the pointer to its code, and *)
+(* the infix tag is used to know where the block starts. *)
+(* - Partial application follows the scheme of partially applied *)
+(* functions. Note: only fixpoints not having been applied to its *)
+(* recursive argument are coded this way. When the rec. arg. is *)
+(* applied, either it's a constructor and the fix reduces, or it's *)
+(* and the fix is coded as an accumulator. *)
+(* *)
+(* + Cofixpoints : see cbytegen.ml *)
+(* *)
+(* + vblock's encode (non constant) constructors as in Ocaml, but *)
+(* starting from 0 up. tag 0 ( = accu_tag) is reserved for *)
+(* accumulators. *)
+(* *)
+(* + vm_env is the type of the machine environments (i.e. a function or *)
+(* a fixpoint) *)
+(* *)
+(* + Accumulators : At_[accumulate| accu | arg1 | ... | argn ] *)
+(* - representation of [accu] : tag_[....] *)
+(* -- tag <= 3 : encoding atom type (sorts, free vars, etc.) *)
+(* -- 10_[accu|proj name] : a projection blocked by an accu *)
+(* -- 11_[accu|fix_app] : a fixpoint blocked by an accu *)
+(* -- 12_[accu|vswitch] : a match blocked by an accu *)
+(* -- 13_[fcofix] : a cofix function *)
+(* -- 14_[fcofix|val] : a cofix function, val represent the value *)
+(* of the function applied to arg1 ... argn *)
+(* The [arguments] type, which is abstracted as an array, represents : *)
+(* tag[ _ | _ |v1|... | vn] *)
+(* Generally the first field is a code pointer. *)
+
+(* Do not edit this type without editing C code, especially "coq_values.h" *)
+
+type atom =
+ | Aid of Vars.id_key
+ | Aind of inductive
+ | Atype of Univ.Universe.t
+
+(* Zippers *)
+
+type zipper =
+ | Zapp of arguments
+ | Zfix of vfix*arguments (* Possibly empty *)
+ | Zswitch of vswitch
+ | Zproj of Constant.t (* name of the projection *)
+
+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
+ | Vcofix of vcofix * to_update * arguments option
+ | Vconstr_const of int
+ | Vconstr_block of vblock
+ | Vatom_stk of atom * stack
+ | Vuniv_level of Univ.Level.t
+
+(* Functions over arguments *)
+let nargs : arguments -> int = fun args -> (Obj.size (Obj.repr args)) - 2
+let arg args i =
+ if 0 <= i && i < (nargs args) then
+ val_of_obj (Obj.field (Obj.repr args) (i+2))
+ else invalid_arg
+ ("Vm.arg size = "^(string_of_int (nargs args))^
+ " acces "^(string_of_int i))
+
+(*************************************************)
+(* Destructors ***********************************)
+(*************************************************)
+
+let uni_lvl_val (v : values) : Univ.Level.t =
+ let whd = Obj.magic v in
+ match whd with
+ | Vuniv_level lvl -> lvl
+ | _ ->
+ let pr =
+ let open Pp in
+ match whd with
+ | Vsort _ -> str "Vsort"
+ | Vprod _ -> str "Vprod"
+ | Vfun _ -> str "Vfun"
+ | Vfix _ -> str "Vfix"
+ | Vcofix _ -> str "Vcofix"
+ | Vconstr_const i -> str "Vconstr_const"
+ | Vconstr_block b -> str "Vconstr_block"
+ | Vatom_stk (a,stk) -> str "Vatom_stk"
+ | _ -> assert false
+ in
+ CErrors.anomaly
+ Pp.( strbrk "Parsing virtual machine value expected universe level, got "
+ ++ pr ++ str ".")
+
+let rec whd_accu a stk =
+ let stk =
+ if Int.equal (Obj.size a) 2 then stk
+ else Zapp (Obj.obj a) :: stk in
+ let at = Obj.field a 1 in
+ match Obj.tag at with
+ | i when Int.equal i type_atom_tag ->
+ begin match stk with
+ | [Zapp args] ->
+ let u = ref (Obj.obj (Obj.field at 0)) in
+ for i = 0 to nargs args - 1 do
+ u := Univ.Universe.sup !u (Univ.Universe.make (uni_lvl_val (arg args i)))
+ done;
+ Vsort (Type !u)
+ | _ -> assert false
+ end
+ | i when i <= max_atom_tag ->
+ Vatom_stk(Obj.magic at, stk)
+ | i when Int.equal i proj_tag ->
+ let zproj = Zproj (Obj.obj (Obj.field at 0)) in
+ whd_accu (Obj.field at 1) (zproj :: stk)
+ | i when Int.equal i fix_app_tag ->
+ let fa = Obj.field at 1 in
+ let zfix =
+ Zfix (Obj.obj (Obj.field fa 1), Obj.obj fa) in
+ whd_accu (Obj.field at 0) (zfix :: stk)
+ | i when Int.equal i switch_tag ->
+ let zswitch = Zswitch (Obj.obj (Obj.field at 1)) in
+ whd_accu (Obj.field at 0) (zswitch :: stk)
+ | i when Int.equal i cofix_tag ->
+ let vcfx = Obj.obj (Obj.field at 0) in
+ let to_up = Obj.obj a in
+ begin match stk with
+ | [] -> Vcofix(vcfx, to_up, None)
+ | [Zapp args] -> Vcofix(vcfx, to_up, Some args)
+ | _ -> assert false
+ end
+ | i when Int.equal i cofix_evaluated_tag ->
+ let vcofix = Obj.obj (Obj.field at 0) in
+ let res = Obj.obj a in
+ begin match stk with
+ | [] -> Vcofix(vcofix, res, None)
+ | [Zapp args] -> Vcofix(vcofix, res, Some args)
+ | _ -> assert false
+ end
+ | tg ->
+ CErrors.anomaly
+ Pp.(strbrk "Failed to parse VM value. Tag = " ++ int tg ++ str ".")
+
+external kind_of_closure : Obj.t -> int = "coq_kind_of_closure"
+external is_accumulate : tcode -> bool = "coq_is_accumulate_code"
+external int_tcode : tcode -> int -> int = "coq_int_tcode"
+external accumulate : unit -> tcode = "accumulate_code"
+let accumulate = accumulate ()
+
+let whd_val : values -> whd =
+ fun v ->
+ let o = Obj.repr v in
+ if Obj.is_int o then Vconstr_const (Obj.obj o)
+ 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))
+ else
+ if tag = Obj.closure_tag || tag = Obj.infix_tag then
+ (match kind_of_closure o with
+ | 0 -> Vfun(Obj.obj o)
+ | 1 -> Vfix(Obj.obj o, None)
+ | 2 -> Vfix(Obj.obj (Obj.field o 1), Some (Obj.obj o))
+ | 3 -> Vatom_stk(Aid(RelKey(int_tcode (fun_code o) 1)), [])
+ | _ -> CErrors.anomaly ~label:"Vm.whd " (Pp.str "kind_of_closure does not work."))
+ else
+ Vconstr_block(Obj.obj o)
+
+(**********************************************)
+(* Constructors *******************************)
+(**********************************************)
+
+let obj_of_atom : atom -> Obj.t =
+ fun a ->
+ let res = Obj.new_block accu_tag 2 in
+ Obj.set_field res 0 (Obj.repr accumulate);
+ Obj.set_field res 1 (Obj.repr a);
+ res
+
+(* 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_ind ind -> obj_of_atom (Aind ind)
+ | Const_proj p -> Obj.repr p
+ | Const_b0 tag -> Obj.repr tag
+ | Const_bn(tag, args) ->
+ let len = Array.length args in
+ let res = Obj.new_block tag len in
+ for i = 0 to len - 1 do
+ Obj.set_field res i (obj_of_str_const args.(i))
+ 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)
+
+let val_of_str_const str = val_of_obj (obj_of_str_const str)
+
+let val_of_atom a = val_of_obj (obj_of_atom a)
+
+let atom_of_proj kn v =
+ let r = Obj.new_block proj_tag 2 in
+ Obj.set_field r 0 (Obj.repr kn);
+ Obj.set_field r 1 (Obj.repr v);
+ ((Obj.obj r) : atom)
+
+let val_of_proj kn v =
+ val_of_atom (atom_of_proj kn v)
+
+module IdKeyHash =
+struct
+ type t = Constant.t tableKey
+ let equal = Names.eq_table_key Constant.equal
+ 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)
+end
+
+module KeyTable = Hashtbl.Make(IdKeyHash)
+
+let idkey_tbl = KeyTable.create 31
+
+let val_of_idkey key =
+ try KeyTable.find idkey_tbl key
+ with Not_found ->
+ let v = val_of_atom (Aid key) in
+ KeyTable.add idkey_tbl key v;
+ v
+
+let val_of_rel k = val_of_idkey (RelKey k)
+
+let val_of_named id = val_of_idkey (VarKey id)
+
+let val_of_constant c = val_of_idkey (ConstKey c)
+
+external val_of_annot_switch : annot_switch -> values = "%identity"
+
+(*************************************************)
+(** Operations manipulating data types ***********)
+(*************************************************)
+
+(* Functions over products *)
+
+let dom : vprod -> values = fun p -> val_of_obj (Obj.field (Obj.repr p) 0)
+let codom : vprod -> vfun = fun p -> (Obj.obj (Obj.field (Obj.repr p) 1))
+
+(* Functions over vfun *)
+
+external closure_arity : vfun -> int = "coq_closure_arity"
+
+(* Functions over fixpoint *)
+
+external offset : Obj.t -> int = "coq_offset"
+external offset_closure : Obj.t -> int -> Obj.t = "coq_offset_closure"
+external offset_closure_fix : vfix -> int -> vm_env = "coq_offset_closure"
+
+let first o = (offset_closure o (offset o))
+let first_fix (v:vfix) = (Obj.magic (first (Obj.repr v)) : vfix)
+
+let last o = (Obj.field o (Obj.size o - 1))
+let fix_types (v:vfix) = (Obj.magic (last (Obj.repr v)) : tcode array)
+let cofix_types (v:vcofix) = (Obj.magic (last (Obj.repr v)) : tcode array)
+
+let current_fix vf = - (offset (Obj.repr vf) / 2)
+
+let unsafe_fb_code fb i = tcode_of_obj (Obj.field (Obj.repr fb) (2 * i))
+
+let unsafe_rec_arg fb i = int_tcode (unsafe_fb_code fb i) 1
+
+let rec_args vf =
+ let fb = first (Obj.repr vf) in
+ let size = Obj.size (last fb) in
+ Array.init size (unsafe_rec_arg fb)
+
+exception FALSE
+
+let check_fix f1 f2 =
+ let i1, i2 = current_fix f1, current_fix f2 in
+ (* Checking starting point *)
+ if i1 = i2 then
+ let fb1,fb2 = first (Obj.repr f1), first (Obj.repr f2) in
+ let n = Obj.size (last fb1) in
+ (* Checking number of definitions *)
+ if n = Obj.size (last fb2) then
+ (* Checking recursive arguments *)
+ try
+ for i = 0 to n - 1 do
+ if unsafe_rec_arg fb1 i <> unsafe_rec_arg fb2 i
+ then raise FALSE
+ done;
+ true
+ with FALSE -> false
+ else false
+ else false
+
+external atom_rel : unit -> atom array = "get_coq_atom_tbl"
+external realloc_atom_rel : int -> unit = "realloc_coq_atom_tbl"
+
+let relaccu_tbl =
+ let atom_rel = atom_rel() in
+ let len = Array.length atom_rel in
+ for i = 0 to len - 1 do atom_rel.(i) <- Aid (RelKey i) done;
+ ref (Array.init len mkAccuCode)
+
+let relaccu_code i =
+ let len = Array.length !relaccu_tbl in
+ if i < len then !relaccu_tbl.(i)
+ else
+ begin
+ realloc_atom_rel i;
+ let atom_rel = atom_rel () in
+ let nl = Array.length atom_rel in
+ for j = len to nl - 1 do atom_rel.(j) <- Aid(RelKey j) done;
+ relaccu_tbl :=
+ Array.init nl
+ (fun j -> if j < len then !relaccu_tbl.(j) else mkAccuCode j);
+ !relaccu_tbl.(i)
+ end
+
+let mk_fix_body k ndef fb =
+ let e = Obj.dup (Obj.repr fb) in
+ for i = 0 to ndef - 1 do
+ Obj.set_field e (2 * i) (Obj.repr (relaccu_code (k + i)))
+ done;
+ let fix_body i =
+ let jump_grabrec c = offset_tcode c 2 in
+ let c = jump_grabrec (unsafe_fb_code fb i) in
+ let res = Obj.new_block Obj.closure_tag 2 in
+ Obj.set_field res 0 (Obj.repr c);
+ Obj.set_field res 1 (offset_closure e (2*i));
+ ((Obj.obj res) : vfun) in
+ Array.init ndef fix_body
+
+(* Functions over vcofix *)
+
+let get_fcofix vcf i =
+ match whd_val (Obj.obj (Obj.field (Obj.repr vcf) (i+1))) with
+ | Vcofix(vcfi, _, _) -> vcfi
+ | _ -> assert false
+
+let current_cofix vcf =
+ let ndef = Obj.size (last (Obj.repr vcf)) in
+ let rec find_cofix pos =
+ if pos < ndef then
+ if get_fcofix vcf pos == vcf then pos
+ else find_cofix (pos+1)
+ else raise Not_found in
+ try find_cofix 0
+ with Not_found -> assert false
+
+let check_cofix vcf1 vcf2 =
+ (current_cofix vcf1 = current_cofix vcf2) &&
+ (Obj.size (last (Obj.repr vcf1)) = Obj.size (last (Obj.repr vcf2)))
+
+let mk_cofix_body apply_varray k ndef vcf =
+ let e = Obj.dup (Obj.repr vcf) in
+ for i = 0 to ndef - 1 do
+ Obj.set_field e (i+1) (Obj.repr (val_of_rel (k+i)))
+ done;
+
+ let cofix_body i =
+ let vcfi = get_fcofix vcf i in
+ let c = Obj.field (Obj.repr vcfi) 0 in
+ Obj.set_field e 0 c;
+ let atom = Obj.new_block cofix_tag 1 in
+ let self = Obj.new_block accu_tag 2 in
+ Obj.set_field self 0 (Obj.repr accumulate);
+ Obj.set_field self 1 (Obj.repr atom);
+ apply_varray (Obj.obj e) [|Obj.obj self|] in
+ Array.init ndef cofix_body
+
+(* Functions over vblock *)
+
+let btag : vblock -> int = fun b -> Obj.tag (Obj.repr b)
+let bsize : vblock -> int = fun b -> Obj.size (Obj.repr b)
+let bfield b i =
+ if 0 <= i && i < (bsize b) then val_of_obj (Obj.field (Obj.repr b) i)
+ else invalid_arg "Vm.bfield"
+
+
+(* Functions over vswitch *)
+
+let check_switch sw1 sw2 = sw1.sw_annot.rtbl = sw2.sw_annot.rtbl
+
+let branch_arg k (tag,arity) =
+ if Int.equal arity 0 then ((Obj.magic tag):values)
+ else
+ let b, ofs =
+ if tag < last_variant_tag then Obj.new_block tag arity, 0
+ else
+ let b = Obj.new_block last_variant_tag (arity+1) in
+ Obj.set_field b 0 (Obj.repr (tag-last_variant_tag));
+ b,1 in
+ for i = ofs to ofs + arity - 1 do
+ Obj.set_field b i (Obj.repr (val_of_rel (k+i)))
+ done;
+ val_of_obj b
+
+(* Printing *)
+
+let rec pr_atom a =
+ Pp.(match a with
+ | Aid c -> str "Aid(" ++ (match c with
+ | ConstKey c -> Constant.print c
+ | RelKey i -> str "#" ++ int i
+ | _ -> str "...") ++ str ")"
+ | Aind (mi,i) -> str "Aind(" ++ MutInd.print mi ++ str "#" ++ int i ++ str ")"
+ | Atype _ -> str "Atype(")
+and pr_whd w =
+ Pp.(match w with
+ | Vsort _ -> str "Vsort"
+ | Vprod _ -> str "Vprod"
+ | Vfun _ -> str "Vfun"
+ | Vfix _ -> str "Vfix"
+ | Vcofix _ -> str "Vcofix"
+ | Vconstr_const i -> str "Vconstr_const(" ++ int i ++ str ")"
+ | Vconstr_block b -> str "Vconstr_block"
+ | Vatom_stk (a,stk) -> str "Vatom_stk(" ++ pr_atom a ++ str ", " ++ pr_stack stk ++ str ")"
+ | Vuniv_level _ -> assert false)
+and pr_stack stk =
+ Pp.(match stk with
+ | [] -> str "[]"
+ | s :: stk -> pr_zipper s ++ str " :: " ++ pr_stack stk)
+and pr_zipper z =
+ Pp.(match z with
+ | Zapp args -> str "Zapp(len = " ++ int (nargs args) ++ str ")"
+ | Zfix (f,args) -> str "Zfix(..., len=" ++ int (nargs args) ++ str ")"
+ | Zswitch s -> str "Zswitch(...)"
+ | Zproj c -> str "Zproj(" ++ Constant.print c ++ str ")")
diff --git a/kernel/vmvalues.mli b/kernel/vmvalues.mli
new file mode 100644
index 0000000000..350f71372f
--- /dev/null
+++ b/kernel/vmvalues.mli
@@ -0,0 +1,144 @@
+(************************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2017 *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(************************************************************************)
+
+open Names
+open Cbytecodes
+
+(** Values *)
+
+type values
+type vm_env
+type vprod
+type vfun
+type vfix
+type vcofix
+type vblock
+type arguments
+type vstack = values array
+type to_update
+
+val fun_val : vfun -> values
+val fix_val : vfix -> values
+val cofix_upd_val : to_update -> values
+
+val fun_env : vfun -> vm_env
+val fix_env : vfix -> vm_env
+val cofix_env : vcofix -> vm_env
+val cofix_upd_env : to_update -> vm_env
+
+(** Cast a value known to be a function, unsafe in general *)
+val fun_of_val : values -> vfun
+
+val crazy_val : values
+
+(** Machine code *)
+
+type tcode
+
+type vswitch = {
+ sw_type_code : tcode;
+ sw_code : tcode;
+ sw_annot : annot_switch;
+ sw_stk : vstack;
+ sw_env : vm_env
+ }
+
+external mkAccuCode : int -> tcode = "coq_makeaccu"
+
+val fun_code : vfun -> tcode
+val fix_code : vfix -> tcode
+val cofix_upd_code : to_update -> tcode
+
+type atom =
+ | Aid of Vars.id_key
+ | Aind of inductive
+ | Atype of Univ.Universe.t
+
+(** Zippers *)
+
+type zipper =
+ | Zapp of arguments
+ | Zfix of vfix * arguments (** might be empty *)
+ | Zswitch of vswitch
+ | Zproj of Constant.t (* name of the projection *)
+
+type stack = zipper list
+
+type whd =
+ | Vsort of Sorts.t
+ | Vprod of vprod
+ | Vfun of vfun
+ | Vfix of vfix * arguments option
+ | Vcofix of vcofix * to_update * arguments option
+ | Vconstr_const of int
+ | Vconstr_block of vblock
+ | Vatom_stk of atom * stack
+ | Vuniv_level of Univ.Level.t
+
+(** For debugging purposes only *)
+
+val pr_atom : atom -> Pp.t
+val pr_whd : whd -> Pp.t
+val pr_stack : stack -> Pp.t
+
+(** Constructors *)
+
+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_proj : Constant.t -> values -> values
+val val_of_atom : atom -> values
+
+external val_of_annot_switch : annot_switch -> values = "%identity"
+
+(** Destructors *)
+
+val whd_val : values -> whd
+val uni_lvl_val : values -> Univ.Level.t
+
+(** Arguments *)
+
+val nargs : arguments -> int
+val arg : arguments -> int -> values
+
+(** Product *)
+
+val dom : vprod -> values
+val codom : vprod -> vfun
+
+(** Fun *)
+external closure_arity : vfun -> int = "coq_closure_arity"
+
+(** Fix *)
+
+val current_fix : vfix -> int
+val check_fix : vfix -> vfix -> bool
+val rec_args : vfix -> int array
+val first_fix : vfix -> vfix
+val fix_types : vfix -> tcode array
+val cofix_types : vcofix -> tcode array
+external offset_closure_fix : vfix -> int -> vm_env = "coq_offset_closure"
+val mk_fix_body : int -> int -> vfix -> vfun array
+
+(** CoFix *)
+
+val current_cofix : vcofix -> int
+val check_cofix : vcofix -> vcofix -> bool
+val mk_cofix_body : (vfun -> vstack -> values) -> int -> int -> vcofix -> values array
+
+(** Block *)
+
+val btag : vblock -> int
+val bsize : vblock -> int
+val bfield : vblock -> int -> values
+
+(** Switch *)
+
+val check_switch : vswitch -> vswitch -> bool
+val branch_arg : int -> Cbytecodes.tag * int -> values
diff --git a/lib/flags.ml b/lib/flags.ml
index ee4c0734af..01361dad55 100644
--- a/lib/flags.ml
+++ b/lib/flags.ml
@@ -6,18 +6,28 @@
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
-let with_modified_ref r nf f x =
+(* If [restore] is false, whenever [f] modifies the ref, we will
+ preserve the modification. *)
+let with_modified_ref ?(restore=true) r nf f x =
let old_ref = !r in r := nf !r;
- try let res = f x in r := old_ref; res
+ try
+ let pre = !r in
+ let res = f x in
+ (* If r was modified don't restore its old value *)
+ if restore || pre == !r then r := old_ref;
+ res
with reraise ->
let reraise = Backtrace.add_backtrace reraise in
r := old_ref;
Exninfo.iraise reraise
-let with_option o f x = with_modified_ref o (fun _ -> true) f x
-let without_option o f x = with_modified_ref o (fun _ -> false) f x
+let with_option o f x = with_modified_ref ~restore:false o (fun _ -> true) f x
+let without_option o f x = with_modified_ref ~restore:false o (fun _ -> false) f x
let with_extra_values o l f x = with_modified_ref o (fun ol -> ol@l) f x
+(* hide the [restore] option as internal *)
+let with_modified_ref r nf f x = with_modified_ref r nf f x
+
let with_options ol f x =
let vl = List.map (!) ol in
let () = List.iter (fun r -> r := true) ol in
diff --git a/library/globnames.ml b/library/globnames.ml
index 9d7ab2db8d..a6e75fdb6a 100644
--- a/library/globnames.ml
+++ b/library/globnames.ml
@@ -30,7 +30,7 @@ let eq_gr gr1 gr2 =
| IndRef kn1, IndRef kn2 -> eq_ind kn1 kn2
| ConstructRef kn1, ConstructRef kn2 -> eq_constructor kn1 kn2
| VarRef v1, VarRef v2 -> Id.equal v1 v2
- | _ -> false
+ | (ConstRef _ | IndRef _ | ConstructRef _ | VarRef _), _ -> false
let destVarRef = function VarRef ind -> ind | _ -> failwith "destVarRef"
let destConstRef = function ConstRef ind -> ind | _ -> failwith "destConstRef"
diff --git a/parsing/g_proofs.ml4 b/parsing/g_proofs.ml4
index d88f6fa0dc..1c3ba78376 100644
--- a/parsing/g_proofs.ml4
+++ b/parsing/g_proofs.ml4
@@ -28,7 +28,8 @@ GEXTEND Gram
| ":"; l = LIST1 [id = IDENT -> id ] -> l ] ]
;
command:
- [ [ IDENT "Goal"; c = lconstr -> VernacGoal c
+ [ [ IDENT "Goal"; c = lconstr ->
+ VernacDefinition (Decl_kinds.(NoDischarge, Definition), ((Loc.tag ~loc:!@loc Names.Anonymous), None), ProveBody ([], c))
| IDENT "Proof" -> VernacProof (None,None)
| IDENT "Proof" ; IDENT "Mode" ; mn = string -> VernacProofMode mn
| IDENT "Proof"; c = lconstr -> VernacExactProof c
diff --git a/parsing/g_vernac.ml4 b/parsing/g_vernac.ml4
index d498bda341..3244b0ff2b 100644
--- a/parsing/g_vernac.ml4
+++ b/parsing/g_vernac.ml4
@@ -133,6 +133,12 @@ let test_plural_form_types loc kwd = function
warn_plural_command ~loc:!@loc kwd
| _ -> ()
+let lname_of_lident : lident -> lname =
+ Loc.map (fun s -> Name s)
+
+let name_of_ident_decl : ident_decl -> name_decl =
+ on_fst lname_of_lident
+
(* Gallina declarations *)
GEXTEND Gram
GLOBAL: gallina gallina_ext thm_token def_body of_type_with_opt_coercion
@@ -143,17 +149,17 @@ GEXTEND Gram
[ [ thm = thm_token; id = ident_decl; bl = binders; ":"; c = lconstr;
l = LIST0
[ "with"; id = ident_decl; bl = binders; ":"; c = lconstr ->
- (Some id,(bl,c)) ] ->
- VernacStartTheoremProof (thm, (Some id,(bl,c))::l)
+ (id,(bl,c)) ] ->
+ VernacStartTheoremProof (thm, (id,(bl,c))::l)
| stre = assumption_token; nl = inline; bl = assum_list ->
VernacAssumption (stre, nl, bl)
| (kwd,stre) = assumptions_token; nl = inline; bl = assum_list ->
test_plural_form loc kwd bl;
VernacAssumption (stre, nl, bl)
| d = def_token; id = ident_decl; b = def_body ->
- VernacDefinition (d, id, b)
+ VernacDefinition (d, name_of_ident_decl id, b)
| IDENT "Let"; id = identref; b = def_body ->
- VernacDefinition ((DoDischarge, Let), (id, None), b)
+ VernacDefinition ((DoDischarge, Let), (lname_of_lident id, None), b)
(* Gallina inductive declarations *)
| cum = cumulativity_token; priv = private_token; f = finite_token;
indl = LIST1 inductive_definition SEP "with" ->
@@ -623,12 +629,12 @@ GEXTEND Gram
VernacCanonical (ByNotation ntn)
| IDENT "Canonical"; IDENT "Structure"; qid = global; d = def_body ->
let s = coerce_reference_to_id qid in
- VernacDefinition ((NoDischarge,CanonicalStructure),((Loc.tag s),None),d)
+ VernacDefinition ((NoDischarge,CanonicalStructure),((Loc.tag (Name s)),None),d)
(* Coercions *)
| IDENT "Coercion"; qid = global; d = def_body ->
let s = coerce_reference_to_id qid in
- VernacDefinition ((NoDischarge,Coercion),((Loc.tag s),None),d)
+ VernacDefinition ((NoDischarge,Coercion),((Loc.tag (Name s)),None),d)
| IDENT "Identity"; IDENT "Coercion"; f = identref; ":";
s = class_rawexpr; ">->"; t = class_rawexpr ->
VernacIdentityCoercion (f, s, t)
diff --git a/plugins/funind/functional_principles_proofs.ml b/plugins/funind/functional_principles_proofs.ml
index 62ca706264..d04887a489 100644
--- a/plugins/funind/functional_principles_proofs.ml
+++ b/plugins/funind/functional_principles_proofs.ml
@@ -324,7 +324,7 @@ let change_eq env sigma hyp_id (context:rel_context) x t end_of_type =
context
in
let new_type_of_hyp =
- Reductionops.nf_betaiota sigma new_type_of_hyp in
+ Reductionops.nf_betaiota env sigma new_type_of_hyp in
let new_ctxt,new_end_of_type =
decompose_prod_n_assum sigma ctxt_size new_type_of_hyp
in
@@ -698,6 +698,7 @@ let build_proof
: tactic =
let rec build_proof_aux do_finalize dyn_infos : tactic =
fun g ->
+ let env = pf_env g in
let sigma = project g in
(* observe (str "proving on " ++ Printer.pr_lconstr_env (pf_env g) term);*)
match EConstr.kind sigma dyn_infos.info with
@@ -794,7 +795,7 @@ let build_proof
do_finalize dyn_infos g
| Lambda _ ->
let new_term =
- Reductionops.nf_beta sigma dyn_infos.info in
+ Reductionops.nf_beta env sigma dyn_infos.info in
build_proof do_finalize {dyn_infos with info = new_term}
g
| LetIn _ ->
@@ -1153,7 +1154,7 @@ let prove_princ_for_struct (evd:Evd.evar_map ref) interactive_proof fun_num fnam
let bodies_with_all_params =
Array.map
(fun body ->
- Reductionops.nf_betaiota (project g)
+ Reductionops.nf_betaiota (pf_env g) (project g)
(applist(substl (List.rev (Array.to_list all_funs_with_full_params)) body,
List.rev_map var_of_decl princ_params))
)
@@ -1191,12 +1192,12 @@ let prove_princ_for_struct (evd:Evd.evar_map ref) interactive_proof fun_num fnam
let body_with_param,num =
let body = get_body fnames.(i) in
let body_with_full_params =
- Reductionops.nf_betaiota (project g) (
+ Reductionops.nf_betaiota (pf_env g) (project g) (
applist(body,List.rev_map var_of_decl full_params))
in
match EConstr.kind (project g) body_with_full_params with
| Fix((_,num),(_,_,bs)) ->
- Reductionops.nf_betaiota (project g)
+ Reductionops.nf_betaiota (pf_env g) (project g)
(
(applist
(substl
@@ -1279,7 +1280,7 @@ let prove_princ_for_struct (evd:Evd.evar_map ref) interactive_proof fun_num fnam
nb_rec_hyps = -100;
rec_hyps = [];
info =
- Reductionops.nf_betaiota (project g)
+ Reductionops.nf_betaiota (pf_env g) (project g)
(applist(fix_body,List.rev_map mkVar args_id));
eq_hyps = []
}
@@ -1339,7 +1340,7 @@ let prove_princ_for_struct (evd:Evd.evar_map ref) interactive_proof fun_num fnam
nb_rec_hyps = -100;
rec_hyps = [];
info =
- Reductionops.nf_betaiota Evd.empty
+ Reductionops.nf_betaiota (pf_env g) Evd.empty
(applist(fbody_with_full_params,
(List.rev_map var_of_decl princ_params)@
(List.rev_map mkVar args_id)
diff --git a/plugins/funind/functional_principles_types.mli b/plugins/funind/functional_principles_types.mli
index a3315f22cf..ad396a2cbb 100644
--- a/plugins/funind/functional_principles_types.mli
+++ b/plugins/funind/functional_principles_types.mli
@@ -29,10 +29,6 @@ val generate_functional_principle :
(EConstr.constr array -> int -> Tacmach.tactic) ->
unit
-val compute_new_princ_type_from_rel : constr array -> Sorts.t array ->
- types -> types
-
-
exception No_graph_found
val make_scheme : Evd.evar_map ref ->
diff --git a/plugins/funind/glob_term_to_relation.ml b/plugins/funind/glob_term_to_relation.ml
index 0b929b8ca9..f7639d22d6 100644
--- a/plugins/funind/glob_term_to_relation.ml
+++ b/plugins/funind/glob_term_to_relation.ml
@@ -591,6 +591,7 @@ let rec build_entry_lc env funnames avoid rt : glob_constr build_entry_return =
*)
build_entry_lc env funnames avoid (mkGApp(b,args))
| GRec _ -> user_err Pp.(str "Not handled GRec")
+ | GProj _ -> user_err Pp.(str "Funind does not support primitive projections")
| GProd _ -> user_err Pp.(str "Cannot apply a type")
end (* end of the application treatement *)
@@ -697,6 +698,7 @@ let rec build_entry_lc env funnames avoid rt : glob_constr build_entry_return =
| GRec _ -> user_err Pp.(str "Not handled GRec")
| GCast(b,_) ->
build_entry_lc env funnames avoid b
+ | GProj(_,_) -> user_err Pp.(str "Funind does not support primitive projections")
and build_entry_lc_from_case env funname make_discr
(el:tomatch_tuples)
(brl:Glob_term.cases_clauses) avoid :
@@ -1245,7 +1247,7 @@ let rec compute_cst_params relnames params gt = DAst.with_val (function
discrimination ones *)
| GSort _ -> params
| GHole _ -> params
- | GIf _ | GRec _ | GCast _ ->
+ | GIf _ | GRec _ | GCast _ | GProj _ ->
raise (UserError(Some "compute_cst_params", str "Not handled case"))
) gt
and compute_cst_params_from_app acc (params,rtl) =
diff --git a/plugins/funind/glob_termops.ml b/plugins/funind/glob_termops.ml
index 0666ab4f1f..b4ca1073ca 100644
--- a/plugins/funind/glob_termops.ml
+++ b/plugins/funind/glob_termops.ml
@@ -17,69 +17,12 @@ let mkGLambda(n,t,b) = DAst.make @@ GLambda(n,Explicit,t,b)
let mkGProd(n,t,b) = DAst.make @@ GProd(n,Explicit,t,b)
let mkGLetIn(n,b,t,c) = DAst.make @@ GLetIn(n,b,t,c)
let mkGCases(rto,l,brl) = DAst.make @@ GCases(Term.RegularStyle,rto,l,brl)
-let mkGSort s = DAst.make @@ GSort(s)
let mkGHole () = DAst.make @@ GHole(Evar_kinds.BinderType Anonymous,Misctypes.IntroAnonymous,None)
-let mkGCast(b,t) = DAst.make @@ GCast(b,CastConv t)
(*
Some basic functions to decompose glob_constrs
These are analogous to the ones constrs
*)
-let glob_decompose_prod =
- let rec glob_decompose_prod args c = match DAst.get c with
- | GProd(n,k,t,b) ->
- glob_decompose_prod ((n,t)::args) b
- | _ -> args,c
- in
- glob_decompose_prod []
-
-let glob_decompose_prod_or_letin =
- let rec glob_decompose_prod args rt = match DAst.get rt with
- | GProd(n,k,t,b) ->
- glob_decompose_prod ((n,None,Some t)::args) b
- | GLetIn(n,b,t,c) ->
- glob_decompose_prod ((n,Some b,t)::args) c
- | _ -> args,rt
- in
- glob_decompose_prod []
-
-let glob_compose_prod =
- List.fold_left (fun b (n,t) -> mkGProd(n,t,b))
-
-let glob_compose_prod_or_letin =
- List.fold_left (
- fun concl decl ->
- match decl with
- | (n,None,Some t) -> mkGProd(n,t,concl)
- | (n,Some bdy,t) -> mkGLetIn(n,bdy,t,concl)
- | _ -> assert false)
-
-let glob_decompose_prod_n n =
- let rec glob_decompose_prod i args c =
- if i<=0 then args,c
- else
- match DAst.get c with
- | GProd(n,_,t,b) ->
- glob_decompose_prod (i-1) ((n,t)::args) b
- | _ -> args,c
- in
- glob_decompose_prod n []
-
-
-let glob_decompose_prod_or_letin_n n =
- let rec glob_decompose_prod i args c =
- if i<=0 then args,c
- else
- match DAst.get c with
- | GProd(n,_,t,b) ->
- glob_decompose_prod (i-1) ((n,None,Some t)::args) b
- | GLetIn(n,b,t,c) ->
- glob_decompose_prod (i-1) ((n,Some b,t)::args) c
- | _ -> args,c
- in
- glob_decompose_prod n []
-
-
let glob_decompose_app =
let rec decompose_rapp acc rt =
(* msgnl (str "glob_decompose_app on : "++ Printer.pr_glob_constr rt); *)
@@ -101,18 +44,6 @@ let glob_make_eq ?(typ= mkGHole ()) t1 t2 =
let glob_make_neq t1 t2 =
mkGApp(mkGRef (Lazy.force Coqlib.coq_not_ref),[glob_make_eq t1 t2])
-(* [glob_make_or P1 P2] build the glob_constr corresponding to [P1 \/ P2] *)
-let glob_make_or t1 t2 = mkGApp (mkGRef(Lazy.force Coqlib.coq_or_ref),[t1;t2])
-
-(* [glob_make_or_list [P1;...;Pn]] build the glob_constr corresponding
- to [P1 \/ ( .... \/ Pn)]
-*)
-let rec glob_make_or_list = function
- | [] -> invalid_arg "mk_or"
- | [e] -> e
- | e::l -> glob_make_or e (glob_make_or_list l)
-
-
let remove_name_from_mapping mapping na =
match na with
| Anonymous -> mapping
@@ -178,6 +109,7 @@ let change_vars =
| GCast(b,c) ->
GCast(change_vars mapping b,
Miscops.map_cast_type (change_vars mapping) c)
+ | GProj(p,c) -> GProj(p, change_vars mapping c)
) rt
and change_vars_br mapping ((loc,(idl,patl,res)) as br) =
let new_mapping = List.fold_right Id.Map.remove idl mapping in
@@ -362,6 +294,7 @@ let rec alpha_rt excluded rt =
GApp(alpha_rt excluded f,
List.map (alpha_rt excluded) args
)
+ | GProj(p,c) -> GProj(p, alpha_rt excluded c)
in
new_rt
@@ -413,6 +346,7 @@ let is_free_in id =
| GHole _ -> false
| GCast (b,(CastConv t|CastVM t|CastNative t)) -> is_free_in b || is_free_in t
| GCast (b,CastCoerce) -> is_free_in b
+ | GProj (_,c) -> is_free_in c
) x
and is_free_in_br (_,(ids,_,rt)) =
(not (Id.List.mem id ids)) && is_free_in rt
@@ -506,6 +440,8 @@ let replace_var_by_term x_id term =
| GCast(b,c) ->
GCast(replace_var_by_pattern b,
Miscops.map_cast_type replace_var_by_pattern c)
+ | GProj(p,c) ->
+ GProj(p,replace_var_by_pattern c)
) x
and replace_var_by_pattern_br ((loc,(idl,patl,res)) as br) =
if List.exists (fun id -> Id.compare id x_id == 0) idl
@@ -575,97 +511,6 @@ let ids_of_pat =
in
ids_of_pat Id.Set.empty
-let id_of_name = function
- | Anonymous -> Id.of_string "x"
- | Name x -> x
-
-(* TODO: finish Rec caes *)
-let ids_of_glob_constr c =
- let rec ids_of_glob_constr acc c =
- let idof = id_of_name in
- match DAst.get c with
- | GVar id -> id::acc
- | GApp (g,args) ->
- ids_of_glob_constr [] g @ List.flatten (List.map (ids_of_glob_constr []) args) @ acc
- | GLambda (na,k,ty,c) -> idof na :: ids_of_glob_constr [] ty @ ids_of_glob_constr [] c @ acc
- | GProd (na,k,ty,c) -> idof na :: ids_of_glob_constr [] ty @ ids_of_glob_constr [] c @ acc
- | GLetIn (na,b,t,c) -> idof na :: ids_of_glob_constr [] b @ Option.cata (ids_of_glob_constr []) [] t @ ids_of_glob_constr [] c @ acc
- | GCast (c,(CastConv t|CastVM t|CastNative t)) -> ids_of_glob_constr [] c @ ids_of_glob_constr [] t @ acc
- | GCast (c,CastCoerce) -> ids_of_glob_constr [] c @ acc
- | GIf (c,(na,po),b1,b2) -> ids_of_glob_constr [] c @ ids_of_glob_constr [] b1 @ ids_of_glob_constr [] b2 @ acc
- | GLetTuple (nal,(na,po),b,c) ->
- List.map idof nal @ ids_of_glob_constr [] b @ ids_of_glob_constr [] c @ acc
- | GCases (sty,rtntypopt,tml,brchl) ->
- List.flatten (List.map (fun (_,(idl,patl,c)) -> idl @ ids_of_glob_constr [] c) brchl)
- | GRec _ -> failwith "Fix inside a constructor branch"
- | (GSort _ | GHole _ | GRef _ | GEvar _ | GPatVar _) -> []
- in
- (* build the set *)
- List.fold_left (fun acc x -> Id.Set.add x acc) Id.Set.empty (ids_of_glob_constr [] c)
-
-
-
-
-
-let zeta_normalize =
- let rec zeta_normalize_term x = DAst.map (function
- | GRef _
- | GVar _
- | GEvar _
- | GPatVar _ as rt -> rt
- | GApp(rt',rtl) ->
- GApp(zeta_normalize_term rt',
- List.map zeta_normalize_term rtl
- )
- | GLambda(name,k,t,b) ->
- GLambda(name,
- k,
- zeta_normalize_term t,
- zeta_normalize_term b
- )
- | GProd(name,k,t,b) ->
- GProd(name,
- k,
- zeta_normalize_term t,
- zeta_normalize_term b
- )
- | GLetIn(Name id,def,typ,b) ->
- DAst.get (zeta_normalize_term (replace_var_by_term id def b))
- | GLetIn(Anonymous,def,typ,b) ->
- DAst.get (zeta_normalize_term b)
- | GLetTuple(nal,(na,rto),def,b) ->
- GLetTuple(nal,
- (na,Option.map zeta_normalize_term rto),
- zeta_normalize_term def,
- zeta_normalize_term b
- )
- | GCases(sty,infos,el,brl) ->
- GCases(sty,
- infos,
- List.map (fun (e,x) -> (zeta_normalize_term e,x)) el,
- List.map zeta_normalize_br brl
- )
- | GIf(b,(na,e_option),lhs,rhs) ->
- GIf(zeta_normalize_term b,
- (na,Option.map zeta_normalize_term e_option),
- zeta_normalize_term lhs,
- zeta_normalize_term rhs
- )
- | GRec _ -> raise (UserError(None,str "Not handled GRec"))
- | GSort _
- | GHole _ as rt -> rt
- | GCast(b,c) ->
- GCast(zeta_normalize_term b,
- Miscops.map_cast_type zeta_normalize_term c)
- ) x
- and zeta_normalize_br (loc,(idl,patl,res)) =
- (loc,(idl,patl,zeta_normalize_term res))
- in
- zeta_normalize_term
-
-
-
-
let expand_as =
let rec add_as map rt =
@@ -700,6 +545,7 @@ let expand_as =
| GCases(sty,po,el,brl) ->
GCases(sty, Option.map (expand_as map) po, List.map (fun (rt,t) -> expand_as map rt,t) el,
List.map (expand_as_br map) brl)
+ | GProj(p,c) -> GProj(p, expand_as map c)
)
and expand_as_br map (loc,(idl,cpl,rt)) =
(loc,(idl,cpl, expand_as (List.fold_left add_as map cpl) rt))
diff --git a/plugins/funind/glob_termops.mli b/plugins/funind/glob_termops.mli
index 99a258de98..7088ae596b 100644
--- a/plugins/funind/glob_termops.mli
+++ b/plugins/funind/glob_termops.mli
@@ -1,6 +1,5 @@
open Names
open Glob_term
-open Misctypes
(* [get_pattern_id pat] returns a list of all the variable appearing in [pat] *)
val get_pattern_id : cases_pattern -> Id.t list
@@ -21,22 +20,11 @@ val mkGLambda : Name.t * glob_constr * glob_constr -> glob_constr
val mkGProd : Name.t * glob_constr * glob_constr -> glob_constr
val mkGLetIn : Name.t * glob_constr * glob_constr option * glob_constr -> glob_constr
val mkGCases : glob_constr option * tomatch_tuples * cases_clauses -> glob_constr
-val mkGSort : glob_sort -> glob_constr
val mkGHole : unit -> glob_constr (* we only build Evd.BinderType Anonymous holes *)
-val mkGCast : glob_constr* glob_constr -> glob_constr
(*
Some basic functions to decompose glob_constrs
These are analogous to the ones constrs
*)
-val glob_decompose_prod : glob_constr -> (Name.t*glob_constr) list * glob_constr
-val glob_decompose_prod_or_letin :
- glob_constr -> (Name.t*glob_constr option*glob_constr option) list * glob_constr
-val glob_decompose_prod_n : int -> glob_constr -> (Name.t*glob_constr) list * glob_constr
-val glob_decompose_prod_or_letin_n : int -> glob_constr ->
- (Name.t*glob_constr option*glob_constr option) list * glob_constr
-val glob_compose_prod : glob_constr -> (Name.t*glob_constr) list -> glob_constr
-val glob_compose_prod_or_letin: glob_constr ->
- (Name.t*glob_constr option*glob_constr option) list -> glob_constr
val glob_decompose_app : glob_constr -> glob_constr*(glob_constr list)
@@ -44,14 +32,6 @@ val glob_decompose_app : glob_constr -> glob_constr*(glob_constr list)
val glob_make_eq : ?typ:glob_constr -> glob_constr -> glob_constr -> glob_constr
(* [glob_make_neq t1 t2] build the glob_constr corresponding to [t1 <> t2] *)
val glob_make_neq : glob_constr -> glob_constr -> glob_constr
-(* [glob_make_or P1 P2] build the glob_constr corresponding to [P1 \/ P2] *)
-val glob_make_or : glob_constr -> glob_constr -> glob_constr
-
-(* [glob_make_or_list [P1;...;Pn]] build the glob_constr corresponding
- to [P1 \/ ( .... \/ Pn)]
-*)
-val glob_make_or_list : glob_constr list -> glob_constr
-
(* alpha_conversion functions *)
@@ -109,18 +89,8 @@ val eq_cases_pattern : cases_pattern -> cases_pattern -> bool
*)
val ids_of_pat : cases_pattern -> Id.Set.t
-(* TODO: finish this function (Fix not treated) *)
-val ids_of_glob_constr: glob_constr -> Id.Set.t
-
-(*
- removing let_in construction in a glob_constr
-*)
-val zeta_normalize : Glob_term.glob_constr -> Glob_term.glob_constr
-
-
val expand_as : glob_constr -> glob_constr
-
(* [resolve_and_replace_implicits ?expected_type env sigma rt] solves implicits of [rt] w.r.t. [env] and [sigma] and then replace them by their solution
*)
val resolve_and_replace_implicits :
diff --git a/plugins/funind/indfun.ml b/plugins/funind/indfun.ml
index 071599d9c5..58154d3106 100644
--- a/plugins/funind/indfun.ml
+++ b/plugins/funind/indfun.ml
@@ -215,6 +215,7 @@ let is_rec names =
| GCases(_,_,el,brl) ->
List.exists (fun (e,_) -> lookup names e) el ||
List.exists (lookup_br names) brl
+ | GProj(_,c) -> lookup names c
and lookup_br names (_,(idl,_,rt)) =
let new_names = List.fold_right Id.Set.remove idl names in
lookup new_names rt
@@ -282,7 +283,6 @@ let derive_inversion fix_names =
in
Invfun.derive_correctness
Functional_principles_types.make_scheme
- functional_induction
fix_names_as_constant
lind;
with e when CErrors.noncritical e ->
@@ -780,6 +780,7 @@ let rec add_args id new_args = CAst.map (function
| CNotation _ -> anomaly ~label:"add_args " (Pp.str "CNotation.")
| CGeneralization _ -> anomaly ~label:"add_args " (Pp.str "CGeneralization.")
| CDelimiters _ -> anomaly ~label:"add_args " (Pp.str "CDelimiters.")
+ | CProj _ -> user_err Pp.(str "Funind does not support primitive projections")
)
exception Stop of Constrexpr.constr_expr
diff --git a/plugins/funind/indfun_common.ml b/plugins/funind/indfun_common.ml
index 5a9248d478..d6fd2f2a0f 100644
--- a/plugins/funind/indfun_common.ml
+++ b/plugins/funind/indfun_common.ml
@@ -190,7 +190,6 @@ let with_full_print f a =
Impargs.make_implicit_args false;
Impargs.make_strict_implicit_args false;
Impargs.make_contextual_implicit_args false;
- Impargs.make_contextual_implicit_args false;
Dumpglob.pause ();
try
let res = f a in
diff --git a/plugins/funind/invfun.ml b/plugins/funind/invfun.ml
index 694c800514..4acf82d000 100644
--- a/plugins/funind/invfun.ml
+++ b/plugins/funind/invfun.ml
@@ -56,12 +56,6 @@ let do_observe_tac s tac g =
CErrors.iprint e ++ str " on goal" ++ fnl() ++ goal ));
iraise reraise;;
-
-let observe_tac_strm s tac g =
- if do_observe ()
- then do_observe_tac s tac g
- else tac g
-
let observe_tac s tac g =
if do_observe ()
then do_observe_tac (str s) tac g
@@ -87,10 +81,6 @@ let make_eq () =
try
EConstr.of_constr (Universes.constr_of_global (Coqlib.build_coq_eq ()))
with _ -> assert false
-let make_eq_refl () =
- try
- EConstr.of_constr (Universes.constr_of_global (Coqlib.build_coq_eq_refl ()))
- with _ -> assert false
(* [generate_type g_to_f f graph i] build the completeness (resp. correctness) lemma type if [g_to_f = true]
@@ -194,10 +184,9 @@ let rec generate_fresh_id x avoid i =
id::(generate_fresh_id x (id::avoid) (pred i))
-(* [prove_fun_correct functional_induction funs_constr graphs_constr schemes lemmas_types_infos i ]
+(* [prove_fun_correct funs_constr graphs_constr schemes lemmas_types_infos i ]
is the tactic used to prove correctness lemma.
- [functional_induction] is the tactic defined in [indfun] (dependency problem)
[funs_constr], [graphs_constr] [schemes] [lemmas_types_infos] are the mutually recursive functions
(resp. graphs of the functions and principles and correctness lemma types) to prove correct.
@@ -218,7 +207,7 @@ let rec generate_fresh_id x avoid i =
\end{enumerate}
*)
-let prove_fun_correct evd functional_induction funs_constr graphs_constr schemes lemmas_types_infos i : Tacmach.tactic =
+let prove_fun_correct evd funs_constr graphs_constr schemes lemmas_types_infos i : Tacmach.tactic =
fun g ->
(* first of all we recreate the lemmas types to be used as predicates of the induction principle
that is~:
@@ -752,14 +741,13 @@ let prove_fun_complete funcs graphs schemes lemmas_types_infos i : Tacmach.tacti
g
-(* [derive_correctness make_scheme functional_induction funs graphs] create correctness and completeness
+(* [derive_correctness make_scheme funs graphs] create correctness and completeness
lemmas for each function in [funs] w.r.t. [graphs]
[make_scheme] is Functional_principle_types.make_scheme (dependency pb) and
- [functional_induction] is Indfun.functional_induction (same pb)
*)
-let derive_correctness make_scheme functional_induction (funs: pconstant list) (graphs:inductive list) =
+let derive_correctness make_scheme (funs: pconstant list) (graphs:inductive list) =
assert (funs <> []);
assert (graphs <> []);
let funs = Array.of_list funs and graphs = Array.of_list graphs in
@@ -809,7 +797,7 @@ let derive_correctness make_scheme functional_induction (funs: pconstant list) (
)
in
let proving_tac =
- prove_fun_correct !evd functional_induction funs_constr graphs_constr schemes lemmas_types_infos
+ prove_fun_correct !evd funs_constr graphs_constr schemes lemmas_types_infos
in
Array.iteri
(fun i f_as_constant ->
diff --git a/plugins/funind/invfun.mli b/plugins/funind/invfun.mli
new file mode 100644
index 0000000000..e07138596c
--- /dev/null
+++ b/plugins/funind/invfun.mli
@@ -0,0 +1,17 @@
+(************************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2017 *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(************************************************************************)
+
+val invfun :
+ Misctypes.quantified_hypothesis ->
+ Globnames.global_reference option ->
+ Evar.t Evd.sigma -> Evar.t list Evd.sigma
+val derive_correctness :
+ (Evd.evar_map ref ->
+ (Constr.pconstant * Sorts.family) list ->
+ 'a Entries.definition_entry list) ->
+ Constr.pconstant list -> Names.inductive list -> unit
diff --git a/plugins/funind/merge.ml b/plugins/funind/merge.ml
deleted file mode 100644
index 8f5d3f22f4..0000000000
--- a/plugins/funind/merge.ml
+++ /dev/null
@@ -1,1013 +0,0 @@
-(************************************************************************)
-(* v * The Coq Proof Assistant / The Coq Development Team *)
-(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2017 *)
-(* \VV/ **************************************************************)
-(* // * This file is distributed under the terms of the *)
-(* * GNU Lesser General Public License Version 2.1 *)
-(************************************************************************)
-
-(* Merging of induction principles. *)
-
-open Globnames
-open Tactics
-open Indfun_common
-open CErrors
-open Util
-open Constrexpr
-open Vernacexpr
-open Pp
-open Names
-open Term
-open Constr
-open Vars
-open Glob_term
-open Glob_termops
-open Decl_kinds
-open Declarations
-open Context.Rel.Declaration
-
-module RelDecl = Context.Rel.Declaration
-
-(** {1 Utilities} *)
-
-(** {2 Useful operations on constr and glob_constr} *)
-
-let pop c = Vars.lift (-1) c
-let rec popn i c = if i<=0 then c else pop (popn (i-1) c)
-
-(** Substitutions in constr *)
-let compare_constr_nosub t1 t2 =
- if Constr.compare_head (fun _ _ -> false) t1 t2
- then true
- else false
-
-let rec compare_constr' t1 t2 =
- if compare_constr_nosub t1 t2
- then true
- else (Constr.compare_head (compare_constr') t1 t2)
-
-let rec substitterm prof t by_t in_u =
- if (compare_constr' (lift prof t) in_u)
- then (lift prof by_t)
- else Constr.map_with_binders succ
- (fun i -> substitterm i t by_t) prof in_u
-
-let lift_ldecl n ldecl = List.map (fun (x,y) -> x,lift n y) ldecl
-
-let understand = Pretyping.understand (Global.env()) Evd.empty
-
-(** Operations on names and identifiers *)
-let id_of_name = function
- Anonymous -> Id.of_string "H"
- | Name id -> id;;
-let name_of_string = Id.of_string %> Name.mk_name
-let string_of_name = id_of_name %> Id.to_string
-
-(** [isVarf f x] returns [true] if term [x] is of the form [(Var f)]. *)
-let isVarf f x =
- match DAst.get x with
- | GVar x -> Id.equal x f
- | _ -> false
-
-(** [ident_global_exist id] returns true if identifier [id] is linked
- in global environment. *)
-let ident_global_exist id =
- try
- let ans = CAst.make @@ CRef (Libnames.Ident (Loc.tag id), None) in
- let _ = ignore (Constrintern.intern_constr (Global.env()) ans) in
- true
- with e when CErrors.noncritical e -> false
-
-(** [next_ident_fresh id] returns a fresh identifier (ie not linked in
- global env) with base [id]. *)
-let next_ident_fresh (id:Id.t) =
- let res = ref id in
- while ident_global_exist !res do res := Nameops.increment_subscript !res done;
- !res
-
-
-(** {2 Debugging} *)
-(* comment this line to see debug msgs *)
-let msg x = () ;; let pr_lconstr c = str ""
-(* uncomment this to see debugging *)
-let prconstr c =
- let sigma, env = Pfedit.get_current_context () in
- msg (str" " ++ Printer.pr_lconstr_env env sigma c)
-
-let prconstrnl c =
- let sigma, env = Pfedit.get_current_context () in
- msg (str" " ++ Printer.pr_lconstr_env env sigma c ++ str"\n")
-
-let prlistconstr lc = List.iter prconstr lc
-let prstr s = msg(str s)
-let prNamedConstr s c =
- let sigma, env = Pfedit.get_current_context () in
- begin
- msg(str "");
- msg(str(s^" {§ ") ++ Printer.pr_lconstr_env env sigma c ++ str " §} ");
- msg(str "");
- end
-let prNamedRConstr s c =
- let sigma, env = Pfedit.get_current_context () in
- begin
- msg(str "");
- msg(str(s^" {§ ") ++ Printer.pr_glob_constr_env env c ++ str " §} ");
- msg(str "");
- end
-let prNamedLConstr_aux lc = List.iter (prNamedConstr "\n") lc
-let prNamedLConstr s lc =
- begin
- prstr "[§§§ ";
- prstr s;
- prNamedLConstr_aux lc;
- prstr " §§§]\n";
- end
-let prNamedLDecl s lc =
- begin
- prstr s; prstr "\n";
- List.iter (fun (nm,_,tp) -> prNamedConstr (string_of_name nm) tp) lc;
- prstr "\n";
- end
-let prNamedRLDecl s lc =
- begin
- prstr s; prstr "\n"; prstr "{§§ ";
- List.iter
- (fun x ->
- match x with
- | (nm,None,Some tp) -> prNamedRConstr (string_of_name nm) tp
- | (nm,Some bdy,None) -> prNamedRConstr ("(letin) "^string_of_name nm) bdy
- | _ -> assert false
- ) lc;
- prstr " §§}\n";
- prstr "\n";
- end
-
-(** {2 Misc} *)
-
-exception Found of int
-
-(* Array scanning *)
-
-let array_prfx (arr: 'a array) (pred: int -> 'a -> bool): int =
-match Array.findi pred arr with
-| None -> Array.length arr (* all elt are positive *)
-| Some i -> i
-
-(* Like List.chop but except that [i] is the size of the suffix of [l]. *)
-let list_chop_end i l =
- let size_prefix = List.length l -i in
- if size_prefix < 0 then failwith "list_chop_end"
- else List.chop size_prefix l
-
-let list_fold_lefti (f: int -> 'a -> 'b -> 'a) (acc:'a) (arr:'b list): 'a =
- let i = ref 0 in
- List.fold_left
- (fun acc x ->
- let res = f !i acc x in i := !i + 1; res)
- acc arr
-
-let list_filteri (f: int -> 'a -> bool) (l:'a list):'a list =
- let i = ref 0 in
- List.filter (fun x -> let res = f !i x in i := !i + 1; res) l
-
-
-(** Iteration module *)
-module For =
-struct
- let rec map i j (f: int -> 'a) = if i>j then [] else f i :: (map (i+1) j f)
- let rec foldup i j (f: 'a -> int -> 'a) acc =
- if i>j then acc else let newacc = f acc i in foldup (i+1) j f newacc
- let rec folddown i j (f: 'a -> int -> 'a) acc =
- if i>j then acc else let newacc = f acc j in folddown i (j-1) f newacc
- let fold i j = if i<j then foldup i j else folddown i j
-end
-
-
-(** {1 Parameters shifting and linking information} *)
-
-(** This type is used to deal with debruijn linked indices. When a
- variable is linked to a previous one, we will ignore it and refer
- to previous one. *)
-type linked_var =
- | Linked of int
- | Unlinked
- | Funres
-
-(** When merging two graphs, parameters may become regular arguments,
- and thus be shifted. This type describes the result of computing
- the changes. *)
-type 'a shifted_params =
- {
- nprm1:'a;
- nprm2:'a;
- prm2_unlinked:'a list; (* ranks of unlinked params in nprms2 *)
- nuprm1:'a;
- nuprm2:'a;
- nargs1:'a;
- nargs2:'a;
- }
-
-
-let prlinked x =
- match x with
- | Linked i -> Printf.sprintf "Linked %d" i
- | Unlinked -> Printf.sprintf "Unlinked"
- | Funres -> Printf.sprintf "Funres"
-
-let linkmonad f lnkvar =
- match lnkvar with
- | Linked i -> Linked (f i)
- | Unlinked -> Unlinked
- | Funres -> Funres
-
-let linklift lnkvar i = linkmonad (fun x -> x+i) lnkvar
-
-(* This map is used to deal with debruijn linked indices. *)
-module Link = Map.Make (Int)
-
-let pr_links l =
- Printf.printf "links:\n";
- Link.iter (fun k e -> Printf.printf "%d : %s\n" k (prlinked e)) l;
- Printf.printf "_____________\n"
-
-type 'a merged_arg =
- | Prm_stable of 'a
- | Prm_linked of 'a
- | Prm_arg of 'a
- | Arg_stable of 'a
- | Arg_linked of 'a
- | Arg_funres
-
-(** Information about graph merging of two inductives.
- All rel_decl list are IN REVERSE ORDER (ie well suited for compose) *)
-
-type merge_infos =
- {
- ident:Id.t; (** new inductive name *)
- mib1: mutual_inductive_body;
- oib1: one_inductive_body;
- mib2: mutual_inductive_body;
- oib2: one_inductive_body;
-
- (** Array of links of the first inductive (should be all stable) *)
- lnk1: int merged_arg array;
-
- (** Array of links of the second inductive (point to the first ind param/args) *)
- lnk2: int merged_arg array;
-
- (** rec params which remain rec param (ie not linked) *)
- recprms1: Context.Rel.Declaration.t list;
- recprms2: Context.Rel.Declaration.t list;
- nrecprms1: int;
- nrecprms2: int;
-
- (** rec parms which became non parm (either linked to something
- or because after a rec parm that became non parm) *)
- otherprms1: Context.Rel.Declaration.t list;
- otherprms2: Context.Rel.Declaration.t list;
- notherprms1:int;
- notherprms2:int;
-
- (** args which remain args in merge *)
- args1:Context.Rel.Declaration.t list;
- args2:Context.Rel.Declaration.t list;
- nargs1:int;
- nargs2:int;
-
- (** functional result args *)
- funresprms1: Context.Rel.Declaration.t list;
- funresprms2: Context.Rel.Declaration.t list;
- nfunresprms1:int;
- nfunresprms2:int;
- }
-
-
-let pr_merginfo x =
- let i,s=
- match x with
- | Prm_linked i -> Some i,"Prm_linked"
- | Arg_linked i -> Some i,"Arg_linked"
- | Prm_stable i -> Some i,"Prm_stable"
- | Prm_arg i -> Some i,"Prm_arg"
- | Arg_stable i -> Some i,"Arg_stable"
- | Arg_funres -> None , "Arg_funres" in
- match i with
- | Some i -> Printf.sprintf "%s(%d)" s i
- | None -> Printf.sprintf "%s" s
-
-let isPrm_stable x = match x with Prm_stable _ -> true | _ -> false
-
-(* ?? prm_linked?? *)
-let isArg_stable x = match x with Arg_stable _ | Prm_arg _ -> true | _ -> false
-
-let is_stable x =
- match x with Arg_stable _ | Prm_stable _ | Prm_arg _ -> true | _ -> false
-
-let isArg_funres x = match x with Arg_funres -> true | _ -> false
-
-let filter_shift_stable (lnk:int merged_arg array) (l:'a list): 'a list =
- let prms = list_filteri (fun i _ -> isPrm_stable lnk.(i)) l in
- let args = list_filteri (fun i _ -> isArg_stable lnk.(i)) l in
- let fres = list_filteri (fun i _ -> isArg_funres lnk.(i)) l in
- prms@args@fres
-
-(** Reverse the link map, keeping only linked vars, elements are list
- of int as several vars may be linked to the same var. *)
-let revlinked lnk =
- For.fold 0 (Array.length lnk - 1)
- (fun acc k ->
- match lnk.(k) with
- | Unlinked | Funres -> acc
- | Linked i ->
- let old = try Link.find i acc with Not_found -> [] in
- Link.add i (k::old) acc)
- Link.empty
-
-let array_switch arr i j =
- let aux = arr.(j) in arr.(j) <- arr.(i); arr.(i) <- aux
-
-let filter_shift_stable_right (lnk:int merged_arg array) (l:'a list): 'a list =
- let larr = Array.of_list l in
- let _ =
- Array.iteri
- (fun j x ->
- match x with
- | Prm_linked i -> array_switch larr i j
- | Arg_linked i -> array_switch larr i j
- | Prm_stable i -> ()
- | Prm_arg i -> ()
- | Arg_stable i -> ()
- | Arg_funres -> ()
- ) lnk in
- filter_shift_stable lnk (Array.to_list larr)
-
-
-let error msg = user_err Pp.(str msg)
-
-(** {1 Utilities for merging} *)
-
-let ind1name = Id.of_string "__ind1"
-let ind2name = Id.of_string "__ind2"
-
-(** Performs verifications on two graphs before merging: they must not
- be co-inductive, and for the moment they must not be mutual
- either. *)
-let verify_inds mib1 mib2 =
- if mib1.mind_finite == CoFinite then error "First argument is coinductive";
- if mib2.mind_finite == CoFinite then error "Second argument is coinductive";
- if not (Int.equal mib1.mind_ntypes 1) then error "First argument is mutual";
- if not (Int.equal mib2.mind_ntypes 1) then error "Second argument is mutual";
- ()
-
-(*
-(** [build_raw_params prms_decl avoid] returns a list of variables
- attributed to the list of decl [prms_decl], avoiding names in
- [avoid]. *)
-let build_raw_params prms_decl avoid =
- let dummy_constr = compose_prod (List.map (fun (x,_,z) -> x,z) prms_decl) (mkRel 1) in
- let _ = prNamedConstr "DUMMY" dummy_constr in
- let dummy_glob_constr = Detyping.detype false avoid [] dummy_constr in
- let _ = prNamedRConstr "RAWDUMMY" dummy_glob_constr in
- let res,_ = glob_decompose_prod dummy_glob_constr in
- let comblist = List.combine prms_decl res in
- comblist, res , (avoid @ (Id.Set.elements (ids_of_glob_constr dummy_glob_constr)))
-*)
-
-let ids_of_rawlist avoid rawl =
- List.fold_left Id.Set.union avoid (List.map ids_of_glob_constr rawl)
-
-
-
-(** {1 Merging function graphs} *)
-
-(** [shift_linked_params mib1 mib2 lnk] Computes which parameters (rec
- uniform and ordinary ones) of mutual inductives [mib1] and [mib2]
- remain uniform when linked by [lnk]. All parameters are
- considered, ie we take parameters of the first inductive body of
- [mib1] and [mib2].
-
- Explanation: The two inductives have parameters, some of the first
- are recursively uniform, some of the last are functional result of
- the functional graph.
-
- (I x1 x2 ... xk ... xk' ... xn)
- (J y1 y2 ... xl ... yl' ... ym)
-
- Problem is, if some rec unif params are linked to non rec unif
- ones, they become non rec (and the following too). And functinal
- argument have to be shifted at the end *)
-let shift_linked_params mib1 mib2 (lnk1:linked_var array) (lnk2:linked_var array) id =
- let _ = prstr "\nYOUHOU shift\n" in
- let linked_targets = revlinked lnk2 in
- let is_param_of_mib1 x = x < mib1.mind_nparams_rec in
- let is_param_of_mib2 x = x < mib2.mind_nparams_rec in
- let is_targetted_by_non_recparam_lnk1 i =
- try
- let targets = Link.find i linked_targets in
- List.exists (fun x -> not (is_param_of_mib2 x)) targets
- with Not_found -> false in
- let mlnk1 =
- Array.mapi
- (fun i lkv ->
- let isprm = is_param_of_mib1 i in
- let prmlost = is_targetted_by_non_recparam_lnk1 i in
- match isprm , prmlost, lnk1.(i) with
- | true , true , _ -> Prm_arg i (* recparam becoming ordinary *)
- | true , false , _-> Prm_stable i (* recparam remains recparam*)
- | false , false , Funres -> Arg_funres
- | _ , _ , Funres -> assert false (* fun res cannot be a rec param or lost *)
- | false , _ , _ -> Arg_stable i) (* Args of lnk1 are not linked *)
- lnk1 in
- let mlnk2 =
- Array.mapi
- (fun i lkv ->
- (* Is this correct if some param of ind2 is lost? *)
- let isprm = is_param_of_mib2 i in
- match isprm , lnk2.(i) with
- | true , Linked j when not (is_param_of_mib1 j) ->
- Prm_arg j (* recparam becoming ordinary *)
- | true , Linked j -> Prm_linked j (*recparam linked to recparam*)
- | true , Unlinked -> Prm_stable i (* recparam remains recparam*)
- | false , Linked j -> Arg_linked j (* Args of lnk2 lost *)
- | false , Unlinked -> Arg_stable i (* Args of lnk2 remains *)
- | false , Funres -> Arg_funres
- | true , Funres -> assert false (* fun res cannot be a rec param *)
- )
- lnk2 in
- let oib1 = mib1.mind_packets.(0) in
- let oib2 = mib2.mind_packets.(0) in
- (* count params remaining params *)
- let n_params1 = array_prfx mlnk1 (fun i x -> not (isPrm_stable x)) in
- let n_params2 = array_prfx mlnk2 (fun i x -> not (isPrm_stable x)) in
- let bldprms arity_ctxt mlnk =
- list_fold_lefti
- (fun i (acc1,acc2,acc3,acc4) x ->
- prstr (pr_merginfo mlnk.(i));prstr "\n";
- match mlnk.(i) with
- | Prm_stable _ -> x::acc1 , acc2 , acc3, acc4
- | Prm_arg _ -> acc1 , x::acc2 , acc3, acc4
- | Arg_stable _ -> acc1 , acc2 , x::acc3, acc4
- | Arg_funres -> acc1 , acc2 , acc3, x::acc4
- | _ -> acc1 , acc2 , acc3, acc4)
- ([],[],[],[]) arity_ctxt in
-(* let arity_ctxt2 =
- build_raw_params oib2.mind_arity_ctxt
- (Id.Set.elements (ids_of_glob_constr oib1.mind_arity_ctxt)) in*)
- let recprms1,otherprms1,args1,funresprms1 = bldprms (List.rev oib1.mind_arity_ctxt) mlnk1 in
- let _ = prstr "\n\n\n" in
- let recprms2,otherprms2,args2,funresprms2 = bldprms (List.rev oib2.mind_arity_ctxt) mlnk2 in
- let _ = prstr "\notherprms1:\n" in
- let _ =
- List.iter (fun decl -> prstr (string_of_name (RelDecl.get_name decl) ^ " : ");
- prconstr (RelDecl.get_type decl); prstr "\n")
- otherprms1 in
- let _ = prstr "\notherprms2:\n" in
- let _ =
- List.iter (fun decl -> prstr (string_of_name (RelDecl.get_name decl) ^ " : "); prconstr (RelDecl.get_type decl); prstr "\n")
- otherprms2 in
- {
- ident=id;
- mib1=mib1;
- oib1 = oib1;
- mib2=mib2;
- oib2 = oib2;
- lnk1 = mlnk1;
- lnk2 = mlnk2;
- nrecprms1 = n_params1;
- recprms1 = recprms1;
- otherprms1 = otherprms1;
- args1 = args1;
- funresprms1 = funresprms1;
- notherprms1 = Array.length mlnk1 - n_params1;
- nfunresprms1 = List.length funresprms1;
- nargs1 = List.length args1;
- nrecprms2 = n_params2;
- recprms2 = recprms2;
- otherprms2 = otherprms2;
- args2 = args2;
- funresprms2 = funresprms2;
- notherprms2 = Array.length mlnk2 - n_params2;
- nargs2 = List.length args2;
- nfunresprms2 = List.length funresprms2;
- }
-
-
-
-
-(** {1 Merging functions} *)
-
-exception NoMerge
-
-let rec merge_app c1 c2 id1 id2 shift filter_shift_stable =
- let lnk = Array.append shift.lnk1 shift.lnk2 in
- match DAst.get c1, DAst.get c2 with
- | GApp(f1, arr1), GApp(f2,arr2) when isVarf id1 f1 && isVarf id2 f2 ->
- let _ = prstr "\nICI1!\n" in
- let args = filter_shift_stable lnk (arr1 @ arr2) in
- DAst.make @@ GApp ((DAst.make @@ GVar shift.ident) , args)
- | GApp(f1, arr1), GApp(f2,arr2) -> raise NoMerge
- | GLetIn(nme,bdy,typ,trm) , _ ->
- let _ = prstr "\nICI2!\n" in
- let newtrm = merge_app trm c2 id1 id2 shift filter_shift_stable in
- DAst.make @@ GLetIn(nme,bdy,typ,newtrm)
- | _, GLetIn(nme,bdy,typ,trm) ->
- let _ = prstr "\nICI3!\n" in
- let newtrm = merge_app c1 trm id1 id2 shift filter_shift_stable in
- DAst.make @@ GLetIn(nme,bdy,typ,newtrm)
- | _ -> let _ = prstr "\nICI4!\n" in
- raise NoMerge
-
-let rec merge_app_unsafe c1 c2 shift filter_shift_stable =
- let lnk = Array.append shift.lnk1 shift.lnk2 in
- match DAst.get c1, DAst.get c2 with
- | GApp(f1, arr1), GApp(f2,arr2) ->
- let args = filter_shift_stable lnk (arr1 @ arr2) in
- DAst.make @@ GApp (DAst.make @@ GVar shift.ident, args)
- (* FIXME: what if the function appears in the body of the let? *)
- | GLetIn(nme,bdy,typ,trm) , _ ->
- let _ = prstr "\nICI2 '!\n" in
- let newtrm = merge_app_unsafe trm c2 shift filter_shift_stable in
- DAst.make @@ GLetIn(nme,bdy,typ,newtrm)
- | _, GLetIn(nme,bdy,typ,trm) ->
- let _ = prstr "\nICI3 '!\n" in
- let newtrm = merge_app_unsafe c1 trm shift filter_shift_stable in
- DAst.make @@ GLetIn(nme,bdy,typ,newtrm)
- | _ -> let _ = prstr "\nICI4 '!\n" in raise NoMerge
-
-
-
-(* Heuristic when merging two lists of hypothesis: merge every rec
- calls of branch 1 with all rec calls of branch 2. *)
-(* TODO: reecrire cette heuristique (jusqu'a merge_types) *)
-let rec merge_rec_hyps shift accrec
- (ltyp:(Name.t * glob_constr option * glob_constr option) list)
- filter_shift_stable : (Name.t * glob_constr option * glob_constr option) list =
- let is_app c = match DAst.get c with GApp _ -> true | _ -> false in
- let mergeonehyp t reldecl =
- match reldecl with
- | (nme,x,Some ind) when is_app ind
- -> nme,x, Some (merge_app_unsafe ind t shift filter_shift_stable)
- | (nme,Some _,None) -> error "letins with recursive calls not treated yet"
- | (nme,None,Some _) -> assert false
- | (nme,None,None) | (nme,Some _,Some _) -> assert false in
- let is_app c = match DAst.get c with GApp (f, _) -> isVarf ind2name f | _ -> false in
- match ltyp with
- | [] -> []
- | (nme,None,Some t) :: lt when is_app t ->
- let rechyps = List.map (mergeonehyp t) accrec in
- rechyps @ merge_rec_hyps shift accrec lt filter_shift_stable
- | e::lt -> e :: merge_rec_hyps shift accrec lt filter_shift_stable
-
-
-let build_suppl_reccall (accrec:(Name.t * glob_constr) list) concl2 shift =
- List.map (fun (nm,tp) -> (nm,merge_app_unsafe tp concl2 shift)) accrec
-
-
-let find_app (nme:Id.t) ltyp =
- let is_app c = match DAst.get c with GApp (f, _) -> isVarf nme f | _ -> false in
- try
- ignore
- (List.map
- (fun x ->
- match x with
- | _,None,Some c when is_app c -> raise (Found 0)
- | _ -> ())
- ltyp);
- false
- with Found _ -> true
-
-let prnt_prod_or_letin nm letbdy typ =
- match letbdy , typ with
- | Some lbdy , None -> prNamedRConstr ("(letin) " ^ string_of_name nm) lbdy
- | None , Some tp -> prNamedRConstr (string_of_name nm) tp
- | _ , _ -> assert false
-
-
-let rec merge_types shift accrec1
- (ltyp1:(Name.t * glob_constr option * glob_constr option) list)
- (concl1:glob_constr) (ltyp2:(Name.t * glob_constr option * glob_constr option) list) concl2
- : (Name.t * glob_constr option * glob_constr option) list * glob_constr =
- let _ = prstr "MERGE_TYPES\n" in
- let _ = prstr "ltyp 1 : " in
- let _ = List.iter (fun (nm,lbdy,tp) -> prnt_prod_or_letin nm lbdy tp) ltyp1 in
- let _ = prstr "\nltyp 2 : " in
- let _ = List.iter (fun (nm,lbdy,tp) -> prnt_prod_or_letin nm lbdy tp) ltyp2 in
- let _ = prstr "\n" in
- let res =
- match ltyp1 with
- | [] ->
- let isrec1 = not (List.is_empty accrec1) in
- let isrec2 = find_app ind2name ltyp2 in
- let rechyps =
- if isrec1 && isrec2
- then (* merge_rec_hyps shift accrec1 ltyp2 filter_shift_stable *)
- merge_rec_hyps shift [name_of_string "concl1",None,Some concl1] ltyp2
- filter_shift_stable_right
- @ merge_rec_hyps shift accrec1 [name_of_string "concl2",None, Some concl2]
- filter_shift_stable
- else if isrec1
- (* if rec calls in accrec1 and not in ltyp2, add one to ltyp2 *)
- then
- merge_rec_hyps shift accrec1
- (ltyp2@[name_of_string "concl2",None,Some concl2]) filter_shift_stable
- else if isrec2
- then merge_rec_hyps shift [name_of_string "concl1",None,Some concl1] ltyp2
- filter_shift_stable_right
- else ltyp2 in
- let _ = prstr"\nrechyps : " in
- let _ = List.iter(fun (nm,lbdy,tp)-> prnt_prod_or_letin nm lbdy tp) rechyps in
- let _ = prstr "MERGE CONCL : " in
- let _ = prNamedRConstr "concl1" concl1 in
- let _ = prstr " with " in
- let _ = prNamedRConstr "concl2" concl2 in
- let _ = prstr "\n" in
- let concl =
- merge_app concl1 concl2 ind1name ind2name shift filter_shift_stable in
- let _ = prstr "FIN " in
- let _ = prNamedRConstr "concl" concl in
- let _ = prstr "\n" in
-
- rechyps , concl
- | (nme,None, Some t1)as e ::lt1 ->
- (match DAst.get t1 with
- | GApp(f,carr) when isVarf ind1name f ->
- merge_types shift (e::accrec1) lt1 concl1 ltyp2 concl2
- | _ ->
- let recres, recconcl2 =
- merge_types shift accrec1 lt1 concl1 ltyp2 concl2 in
- ((nme,None,Some t1) :: recres) , recconcl2)
- | (nme,Some bd, None) ::lt1 ->
- (* FIXME: what if ind1name appears in bd? *)
- let recres, recconcl2 =
- merge_types shift accrec1 lt1 concl1 ltyp2 concl2 in
- ((nme,Some bd,None) :: recres) , recconcl2
- | (_,None,None)::_ | (_,Some _,Some _)::_ -> assert false
- in
- res
-
-
-(** [build_link_map_aux allargs1 allargs2 shift] returns the mapping of
- linked args [allargs2] to target args of [allargs1] as specified
- in [shift]. [allargs1] and [allargs2] are in reverse order. Also
- returns the list of unlinked vars of [allargs2]. *)
-let build_link_map_aux (allargs1:Id.t array) (allargs2:Id.t array)
- (lnk:int merged_arg array) =
- Array.fold_left_i
- (fun i acc e ->
- if Int.equal i (Array.length lnk - 1) then acc (* functional arg, not in allargs *)
- else
- match e with
- | Prm_linked j | Arg_linked j -> Id.Map.add allargs2.(i) allargs1.(j) acc
- | _ -> acc)
- Id.Map.empty lnk
-
-let build_link_map allargs1 allargs2 lnk =
- let allargs1 =
- Array.of_list (List.rev_map (fun (x,_,_) -> id_of_name x) allargs1) in
- let allargs2 =
- Array.of_list (List.rev_map (fun (x,_,_) -> id_of_name x) allargs2) in
- build_link_map_aux allargs1 allargs2 lnk
-
-
-(** [merge_one_constructor lnk shift typcstr1 typcstr2] merges the two
- constructor rawtypes [typcstr1] and [typcstr2]. [typcstr1] and
- [typcstr2] contain all parameters (including rec. unif. ones) of
- their inductive.
-
- if [typcstr1] and [typcstr2] are of the form:
-
- forall recparams1, forall ordparams1, H1a -> H2a... (I1 x1 y1 ... z1)
- forall recparams2, forall ordparams2, H2b -> H2b... (I2 x2 y2 ... z2)
-
- we build:
-
- forall recparams1 (recparams2 without linked params),
- forall ordparams1 (ordparams2 without linked params),
- H1a' -> H2a' -> ... -> H2a' -> H2b'(shifted) -> ...
- -> (newI x1 ... z1 x2 y2 ...z2 without linked params)
-
- where Hix' have been adapted, ie:
- - linked vars have been changed,
- - rec calls to I1 and I2 have been replaced by rec calls to
- newI. More precisely calls to I1 and I2 have been merge by an
- experimental heuristic (in particular if n o rec calls for I1
- or I2 is found, we use the conclusion as a rec call). See
- [merge_types] above.
-
- Precond: vars sets of [typcstr1] and [typcstr2] must be disjoint.
-
- TODO: return nothing if equalities (after linking) are contradictory. *)
-let merge_one_constructor (shift:merge_infos) (typcstr1:glob_constr)
- (typcstr2:glob_constr) : glob_constr =
- (* FIXME: les noms des parametres corerspondent en principe au
- parametres du niveau mib, mais il faudrait s'en assurer *)
- (* shift.nfunresprmsx last args are functional result *)
- let nargs1 =
- shift.mib1.mind_nparams + shift.oib1.mind_nrealargs - shift.nfunresprms1 in
- let nargs2 =
- shift.mib2.mind_nparams + shift.oib2.mind_nrealargs - shift.nfunresprms2 in
- let allargs1,rest1 = glob_decompose_prod_or_letin_n nargs1 typcstr1 in
- let allargs2,rest2 = glob_decompose_prod_or_letin_n nargs2 typcstr2 in
- (* Build map of linked args of [typcstr2], and apply it to [typcstr2]. *)
- let linked_map = build_link_map allargs1 allargs2 shift.lnk2 in
- let rest2 = change_vars linked_map rest2 in
- let hyps1,concl1 = glob_decompose_prod_or_letin rest1 in
- let hyps2,concl2' = glob_decompose_prod_or_letin rest2 in
- let ltyp,concl2 =
- merge_types shift [] (List.rev hyps1) concl1 (List.rev hyps2) concl2' in
- let _ = prNamedRLDecl "ltyp result:" ltyp in
- let typ = glob_compose_prod_or_letin concl2 (List.rev ltyp) in
- let revargs1 =
- list_filteri (fun i _ -> isArg_stable shift.lnk1.(i)) (List.rev allargs1) in
- let _ = prNamedRLDecl "ltyp allargs1" allargs1 in
- let _ = prNamedRLDecl "ltyp revargs1" revargs1 in
- let revargs2 =
- list_filteri (fun i _ -> isArg_stable shift.lnk2.(i)) (List.rev allargs2) in
- let _ = prNamedRLDecl "ltyp allargs2" allargs2 in
- let _ = prNamedRLDecl "ltyp revargs2" revargs2 in
- let typwithprms =
- glob_compose_prod_or_letin typ (List.rev revargs2 @ List.rev revargs1) in
- typwithprms
-
-
-(** constructor numbering *)
-let fresh_cstror_suffix , cstror_suffix_init =
- let cstror_num = ref 0 in
- (fun () ->
- let res = string_of_int !cstror_num in
- cstror_num := !cstror_num + 1;
- res) ,
- (fun () -> cstror_num := 0)
-
-(** [merge_constructor_id id1 id2 shift] returns the identifier of the
- new constructor from the id of the two merged constructor and
- the merging info. *)
-let merge_constructor_id id1 id2 shift:Id.t =
- let id = Id.to_string shift.ident ^ "_" ^ fresh_cstror_suffix () in
- next_ident_fresh (Id.of_string id)
-
-
-
-(** [merge_constructors lnk shift avoid] merges the two list of
- constructor [(name*type)]. These are translated to glob_constr
- first, each of them having distinct var names. *)
-let merge_constructors (shift:merge_infos) (avoid:Id.Set.t)
- (typcstr1:(Id.t * glob_constr) list)
- (typcstr2:(Id.t * glob_constr) list) : (Id.t * glob_constr) list =
- List.flatten
- (List.map
- (fun (id1,rawtyp1) ->
- List.map
- (fun (id2,rawtyp2) ->
- let typ = merge_one_constructor shift rawtyp1 rawtyp2 in
- let newcstror_id = merge_constructor_id id1 id2 shift in
- let _ = prstr "\n**************\n" in
- newcstror_id , typ)
- typcstr2)
- typcstr1)
-
-(** [merge_inductive_body lnk shift avoid oib1 oib2] merges two
- inductive bodies [oib1] and [oib2], linking with [lnk], params
- info in [shift], avoiding identifiers in [avoid]. *)
-let merge_inductive_body (shift:merge_infos) avoid (oib1:one_inductive_body)
- (oib2:one_inductive_body) =
- (* building glob_constr type of constructors *)
- let mkrawcor nme avoid typ =
- (* first replace rel 1 by a varname *)
- let substindtyp = substitterm 0 (mkRel 1) (mkVar nme) typ in
- let substindtyp = EConstr.of_constr substindtyp in
- Detyping.detype Detyping.Now false avoid (Global.env()) Evd.empty substindtyp in
- let lcstr1: glob_constr list =
- Array.to_list (Array.map (mkrawcor ind1name avoid) oib1.mind_user_lc) in
- (* add to avoid all indentifiers of lcstr1 *)
- let avoid2 = Id.Set.union avoid (ids_of_rawlist avoid lcstr1) in
- let lcstr2 =
- Array.to_list (Array.map (mkrawcor ind2name avoid2) oib2.mind_user_lc) in
- let avoid3 = Id.Set.union avoid (ids_of_rawlist avoid lcstr2) in
-
- let params1 =
- try fst (glob_decompose_prod_n shift.nrecprms1 (List.hd lcstr1))
- with e when CErrors.noncritical e -> [] in
- let params2 =
- try fst (glob_decompose_prod_n shift.nrecprms2 (List.hd lcstr2))
- with e when CErrors.noncritical e -> [] in
-
- let lcstr1 = List.combine (Array.to_list oib1.mind_consnames) lcstr1 in
- let lcstr2 = List.combine (Array.to_list oib2.mind_consnames) lcstr2 in
-
- cstror_suffix_init();
- params1,params2,merge_constructors shift avoid3 lcstr1 lcstr2
-
-
-(** [merge_mutual_inductive_body lnk mib1 mib2 shift] merge mutual
- inductive bodies [mib1] and [mib2] linking vars with
- [lnk]. [shift] information on parameters of the new inductive.
- For the moment, inductives are supposed to be non mutual.
-*)
-let merge_mutual_inductive_body
- (mib1:mutual_inductive_body) (mib2:mutual_inductive_body) (shift:merge_infos) =
- (* Mutual not treated, we take first ind body of each. *)
- merge_inductive_body shift Id.Set.empty mib1.mind_packets.(0) mib2.mind_packets.(0)
-
-
-let glob_constr_to_constr_expr x = (* build a constr_expr from a glob_constr *)
- Flags.with_option Flags.raw_print (Constrextern.extern_glob_type Id.Set.empty) x
-
-let merge_rec_params_and_arity prms1 prms2 shift (concl:constr) =
- let params = prms2 @ prms1 in
- let resparams =
- List.fold_left
- (fun acc (nme,tp) ->
- let _ = prstr "param :" in
- let _ = prNamedRConstr (string_of_name nme) tp in
- let _ = prstr " ; " in
- let typ = glob_constr_to_constr_expr tp in
- CLocalAssum ([(Loc.tag nme)], Constrexpr_ops.default_binder_kind, typ) :: acc)
- [] params in
- let concl = Constrextern.extern_constr false (Global.env()) Evd.empty (EConstr.of_constr concl) in
- let arity,_ =
- List.fold_left
- (fun (acc,env) decl ->
- let nm = Context.Rel.Declaration.get_name decl in
- let c = RelDecl.get_type decl in
- let typ = Constrextern.extern_constr false env Evd.empty (EConstr.of_constr c) in
- let newenv = Environ.push_rel (LocalAssum (nm,c)) env in
- CAst.make @@ CProdN ([[(Loc.tag nm)],Constrexpr_ops.default_binder_kind,typ] , acc) , newenv)
- (concl,Global.env())
- (shift.funresprms2 @ shift.funresprms1
- @ shift.args2 @ shift.args1 @ shift.otherprms2 @ shift.otherprms1) in
- resparams,arity
-
-
-
-(** [glob_constr_list_to_inductive_expr ident rawlist] returns the
- induct_expr corresponding to the the list of constructor types
- [rawlist], named ident.
- FIXME: params et cstr_expr (arity) *)
-let glob_constr_list_to_inductive_expr prms1 prms2 mib1 mib2 shift
- (rawlist:(Id.t * glob_constr) list) =
- let lident = (Loc.tag shift.ident), None in
- let bindlist , cstr_expr = (* params , arities *)
- merge_rec_params_and_arity prms1 prms2 shift mkSet in
- let lcstor_expr : (bool * (lident * constr_expr)) list =
- List.map (* zeta_normalize t ? *)
- (fun (id,t) -> false, ((Loc.tag id),glob_constr_to_constr_expr t))
- rawlist in
- lident , bindlist , Some cstr_expr , lcstor_expr
-
-
-let mkProd_reldecl (rdecl:Context.Rel.Declaration.t) (t2:glob_constr) =
- match rdecl with
- | LocalAssum (nme,t) ->
- let t = EConstr.of_constr t in
- let traw = Detyping.detype Detyping.Now false Id.Set.empty (Global.env()) Evd.empty t in
- DAst.make @@ GProd (nme,Explicit,traw,t2)
- | LocalDef _ -> assert false
-
-
-(** [merge_inductive ind1 ind2 lnk] merges two graphs, linking
- variables specified in [lnk]. Graphs are not supposed to be mutual
- inductives for the moment. *)
-let merge_inductive (ind1: inductive) (ind2: inductive)
- (lnk1: linked_var array) (lnk2: linked_var array) id =
- let env = Global.env() in
- let mib1,_ = Inductive.lookup_mind_specif env ind1 in
- let mib2,_ = Inductive.lookup_mind_specif env ind2 in
- let _ = verify_inds mib1 mib2 in (* raises an exception if something wrong *)
- (* compute params that become ordinary args (because linked to ord. args) *)
- let shift_prm = shift_linked_params mib1 mib2 lnk1 lnk2 id in
- let prms1,prms2, rawlist = merge_mutual_inductive_body mib1 mib2 shift_prm in
- let _ = prstr "\nrawlist : " in
- let _ =
- List.iter (fun (nm,tp) -> prNamedRConstr (Id.to_string nm) tp;prstr "\n") rawlist in
- let _ = prstr "\nend rawlist\n" in
-(* FIX: retransformer en constr ici
- let shift_prm =
- { shift_prm with
- recprms1=prms1;
- recprms1=prms1;
- } in *)
- let indexpr = glob_constr_list_to_inductive_expr prms1 prms2 mib1 mib2 shift_prm rawlist in
- (* Declare inductive *)
- let indl,_,_ = ComInductive.extract_mutual_inductive_declaration_components [(indexpr,[])] in
- let mie,pl,impls = ComInductive.interp_mutual_inductive indl []
- false (* non-cumulative *) false (*FIXMEnon-poly *) false (* means not private *) Finite (* means: not coinductive *) in
- (* Declare the mutual inductive block with its associated schemes *)
- ignore (ComInductive.declare_mutual_inductive_with_eliminations mie pl impls)
-
-
-(* Find infos on identifier id. *)
-let find_Function_infos_safe (id:Id.t): Indfun_common.function_info =
- let kn_of_id x =
- let f_ref = Libnames.Ident (Loc.tag x) in
- locate_with_msg (str "Don't know what to do with " ++ Libnames.pr_reference f_ref)
- locate_constant f_ref in
- try find_Function_infos (kn_of_id id)
- with Not_found ->
- user_err ~hdr:"indfun" (Id.print id ++ str " has no functional scheme")
-
-(** [merge id1 id2 args1 args2 id] builds and declares a new inductive
- type called [id], representing the merged graphs of both graphs
- [ind1] and [ind2]. identifiers occurring in both arrays [args1] and
- [args2] are considered linked (i.e. are the same variable) in the
- new graph.
-
- Warning: For the moment, repetitions of an id in [args1] or
- [args2] are not supported. *)
-let merge (id1:Id.t) (id2:Id.t) (args1:Id.t array)
- (args2:Id.t array) id : unit =
- let finfo1 = find_Function_infos_safe id1 in
- let finfo2 = find_Function_infos_safe id2 in
- (* FIXME? args1 are supposed unlinked. mergescheme (G x x) ?? *)
- (* We add one arg (functional arg of the graph) *)
- let lnk1 = Array.make (Array.length args1 + 1) Unlinked in
- let lnk2' = (* args2 may be linked to args1 members. FIXME: same
- as above: vars may be linked inside args2?? *)
- Array.mapi
- (fun i c ->
- match Array.findi (fun i x -> Id.equal x c) args1 with
- | Some j -> Linked j
- | None -> Unlinked)
- args2 in
- (* We add one arg (functional arg of the graph) *)
- let lnk2 = Array.append lnk2' (Array.make 1 Unlinked) in
- (* setting functional results *)
- let _ = lnk1.(Array.length lnk1 - 1) <- Funres in
- let _ = lnk2.(Array.length lnk2 - 1) <- Funres in
- merge_inductive finfo1.graph_ind finfo2.graph_ind lnk1 lnk2 id
-
-
-let remove_last_arg c =
- let (x,y) = decompose_prod c in
- let xnolast = List.rev (List.tl (List.rev x)) in
- compose_prod xnolast y
-
-let rec remove_n_fst_list n l = if Int.equal n 0 then l else remove_n_fst_list (n-1) (List.tl l)
-let remove_n_last_list n l = List.rev (remove_n_fst_list n (List.rev l))
-
-let remove_last_n_arg n c =
- let (x,y) = decompose_prod c in
- let xnolast = remove_n_last_list n x in
- compose_prod xnolast y
-
-(* [funify_branches relinfo nfuns branch] returns the branch [branch]
- of the relinfo [relinfo] modified to fit in a functional principle.
- Things to do:
- - remove indargs from rel applications
- - replace *variables only* corresponding to function (recursive)
- results by the actual function application. *)
-let funify_branches relinfo nfuns branch =
- let mut_induct, induct =
- match relinfo.indref with
- | None -> assert false
- | Some (IndRef ((mutual_ind,i) as ind)) -> mutual_ind,ind
- | _ -> assert false in
- let is_dom c =
- match Constr.kind c with
- | Ind(((u,_),_)) | Construct(((u,_),_),_) -> MutInd.equal u mut_induct
- | _ -> false in
- let _dom_i c =
- assert (is_dom c);
- match Constr.kind c with
- | Ind((u,i)) | Construct((u,_),i) -> i
- | _ -> assert false in
- let _is_pred c shift =
- match Constr.kind c with
- | Rel i -> let reali = i-shift in (reali>=0 && reali<relinfo.nbranches)
- | _ -> false in
- (* FIXME: *)
- LocalDef (Anonymous,EConstr.mkProp,EConstr.mkProp)
-
-
-let relprinctype_to_funprinctype relprinctype nfuns =
- let relprinctype = EConstr.of_constr relprinctype in
- let relinfo = compute_elim_sig Evd.empty (** FIXME*) relprinctype in
- assert (not relinfo.farg_in_concl);
- assert (relinfo.indarg_in_concl);
- (* first remove indarg and indarg_in_concl *)
- let relinfo_noindarg = { relinfo with
- indarg_in_concl = false; indarg = None;
- concl = EConstr.of_constr (remove_last_arg (pop (EConstr.Unsafe.to_constr relinfo.concl))); } in
- (* the nfuns last induction arguments are functional ones: remove them *)
- let relinfo_argsok = { relinfo_noindarg with
- nargs = relinfo_noindarg.nargs - nfuns;
- (* args is in reverse order, so remove fst *)
- args = remove_n_fst_list nfuns relinfo_noindarg.args;
- concl = EConstr.of_constr (popn nfuns (EConstr.Unsafe.to_constr relinfo_noindarg.concl));
- } in
- let new_branches =
- List.map (funify_branches relinfo_argsok nfuns) relinfo_argsok.branches in
- let relinfo_branches = { relinfo_argsok with branches = new_branches } in
- relinfo_branches
-
-(* @article{ bundy93rippling,
- author = "Alan Bundy and Andrew Stevens and Frank van Harmelen and Andrew Ireland and Alan Smaill",
- title = "Rippling: A Heuristic for Guiding Inductive Proofs",
- journal = "Artificial Intelligence",
- volume = "62",
- number = "2",
- pages = "185-253",
- year = "1993",
- url = "citeseer.ist.psu.edu/bundy93rippling.html" }
-
- *)
diff --git a/plugins/funind/recdef.mli b/plugins/funind/recdef.mli
index 50b84731b5..b95d64ce9e 100644
--- a/plugins/funind/recdef.mli
+++ b/plugins/funind/recdef.mli
@@ -1,6 +1,5 @@
open Constr
-(* val evaluable_of_global_reference : Libnames.global_reference -> Names.evaluable_global_reference *)
val tclUSER_if_not_mes :
Tacmach.tactic ->
bool ->
diff --git a/plugins/funind/recdef_plugin.mlpack b/plugins/funind/recdef_plugin.mlpack
index 2b443f2a1b..755fa4f879 100644
--- a/plugins/funind/recdef_plugin.mlpack
+++ b/plugins/funind/recdef_plugin.mlpack
@@ -6,5 +6,4 @@ Functional_principles_proofs
Functional_principles_types
Invfun
Indfun
-Merge
G_indfun
diff --git a/plugins/ltac/rewrite.ml b/plugins/ltac/rewrite.ml
index 3cbb110010..acd7a30c43 100644
--- a/plugins/ltac/rewrite.ml
+++ b/plugins/ltac/rewrite.ml
@@ -210,9 +210,9 @@ end) = struct
let t = Reductionops.whd_all env (goalevars evars) ty in
match EConstr.kind (goalevars evars) t, l with
| Prod (na, ty, b), obj :: cstrs ->
- let b = Reductionops.nf_betaiota (goalevars evars) b in
+ let b = Reductionops.nf_betaiota env (goalevars evars) b in
if noccurn (goalevars evars) 1 b (* non-dependent product *) then
- let ty = Reductionops.nf_betaiota (goalevars evars) ty in
+ let ty = Reductionops.nf_betaiota env (goalevars evars) ty in
let (evars, b', arg, cstrs) = aux env evars (subst1 mkProp b) cstrs in
let evars, relty = mk_relty evars env ty obj in
let evars, newarg = app_poly env evars respectful [| ty ; b' ; relty ; arg |] in
@@ -221,7 +221,7 @@ end) = struct
let (evars, b, arg, cstrs) =
aux (push_rel (LocalAssum (na, ty)) env) evars b cstrs
in
- let ty = Reductionops.nf_betaiota (goalevars evars) ty in
+ let ty = Reductionops.nf_betaiota env (goalevars evars) ty in
let pred = mkLambda (na, ty, b) in
let liftarg = mkLambda (na, ty, arg) in
let evars, arg' = app_poly env evars forall_relation [| ty ; pred ; liftarg |] in
@@ -231,7 +231,7 @@ end) = struct
| _, [] ->
(match finalcstr with
| None | Some (_, None) ->
- let t = Reductionops.nf_betaiota (fst evars) ty in
+ let t = Reductionops.nf_betaiota env (fst evars) ty in
let evars, rel = mk_relty evars env t None in
evars, t, rel, [t, Some rel]
| Some (t, Some rel) -> evars, t, rel, [t, Some rel])
@@ -1557,9 +1557,8 @@ let newfail n s =
let cl_rewrite_clause_newtac ?abs ?origsigma ~progress strat clause =
let open Proofview.Notations in
(** For compatibility *)
- let beta_red _ sigma c = Reductionops.nf_betaiota sigma c in
- let beta = Tactics.reduct_in_concl (beta_red, DEFAULTcast) in
- let beta_hyp id = Tactics.reduct_in_hyp beta_red (id, InHyp) in
+ let beta = Tactics.reduct_in_concl (Reductionops.nf_betaiota, DEFAULTcast) in
+ let beta_hyp id = Tactics.reduct_in_hyp Reductionops.nf_betaiota (id, InHyp) in
let treat sigma res =
match res with
| None -> newfail 0 (str "Nothing to rewrite")
diff --git a/plugins/omega/coq_omega.ml b/plugins/omega/coq_omega.ml
index 8692842468..4271c80cd1 100644
--- a/plugins/omega/coq_omega.ml
+++ b/plugins/omega/coq_omega.ml
@@ -652,7 +652,7 @@ let decompile af =
(** Backward compat to emulate the old Refine: normalize the goal conclusion *)
let new_hole env sigma c =
- let c = Reductionops.nf_betaiota sigma c in
+ let c = Reductionops.nf_betaiota env sigma c in
Evarutil.new_evar env sigma c
let clever_rewrite_base_poly typ p result theorem =
diff --git a/plugins/ssr/ssrcommon.ml b/plugins/ssr/ssrcommon.ml
index 8493dbdbb5..7cdf051176 100644
--- a/plugins/ssr/ssrcommon.ml
+++ b/plugins/ssr/ssrcommon.ml
@@ -563,7 +563,7 @@ let pf_abs_evars_pirrel gl (sigma, c0) =
| _ -> Constr.fold put evlist c in
let evlist = put [] c0 in
if evlist = [] then 0, c0 else
- let pr_constr t = Printer.pr_econstr_env (pf_env gl) sigma (Reductionops.nf_beta (project gl) (EConstr.of_constr t)) in
+ let pr_constr t = Printer.pr_econstr_env (pf_env gl) sigma (Reductionops.nf_beta (pf_env gl) (project gl) (EConstr.of_constr t)) in
pp(lazy(str"evlist=" ++ pr_list (fun () -> str";")
(fun (k,_) -> Evar.print k) evlist));
let evplist =
@@ -894,7 +894,7 @@ let saturate ?(beta=false) ?(bi_types=false) env sigma c ?(ty=Retyping.get_type_
let sigma = create_evar_defs sigma in
let (sigma, x) =
Evarutil.new_evar env sigma
- (if bi_types then Reductionops.nf_betaiota sigma src else src) in
+ (if bi_types then Reductionops.nf_betaiota env sigma src else src) in
loop (EConstr.Vars.subst1 x tgt) ((m - n,x) :: args) sigma (n-1)
| CastType (t, _) -> loop t args sigma n
| LetInType (_, v, _, t) -> loop (EConstr.Vars.subst1 v t) args sigma n
diff --git a/plugins/ssr/ssrvernac.ml4 b/plugins/ssr/ssrvernac.ml4
index c0479dd24b..d74ad06b34 100644
--- a/plugins/ssr/ssrvernac.ml4
+++ b/plugins/ssr/ssrvernac.ml4
@@ -553,7 +553,7 @@ GEXTEND Gram
let s = coerce_reference_to_id qid in
Vernacexpr.VernacDefinition
((Decl_kinds.NoDischarge,Decl_kinds.CanonicalStructure),
- ((Loc.tag s),None), d)
+ ((Loc.tag (Name s)),None), d)
]];
END
diff --git a/pretyping/cases.ml b/pretyping/cases.ml
index 1207c967b5..311c1c09ec 100644
--- a/pretyping/cases.ml
+++ b/pretyping/cases.ml
@@ -1276,7 +1276,7 @@ let build_branch initial current realargs deps (realnames,curname) pb arsign eqn
(* This is a bit too strong I think, in the sense that what we would *)
(* really like is to have beta-iota reduction only at the positions where *)
(* parameters are substituted *)
- let typs = List.map (map_type (nf_betaiota !(pb.evdref))) typs in
+ let typs = List.map (map_type (nf_betaiota pb.env !(pb.evdref))) typs in
(* We build the matrix obtained by expanding the matching on *)
(* "C x1..xn as x" followed by a residual matching on eqn into *)
@@ -1426,7 +1426,7 @@ and match_current pb (initial,tomatch) =
find_predicate pb.caseloc pb.env pb.evdref
pred current indt (names,dep) tomatch in
let ci = make_case_info pb.env (fst mind) pb.casestyle in
- let pred = nf_betaiota !(pb.evdref) pred in
+ let pred = nf_betaiota pb.env !(pb.evdref) pred in
let case =
make_case_or_project pb.env !(pb.evdref) indf ci pred current brvals
in
@@ -1663,7 +1663,7 @@ let rec list_assoc_in_triple x = function
*)
let abstract_tycon ?loc env evdref subst tycon extenv t =
- let t = nf_betaiota !evdref t in (* it helps in some cases to remove K-redex*)
+ let t = nf_betaiota env !evdref t in (* it helps in some cases to remove K-redex*)
let src = match EConstr.kind !evdref t with
| Evar (evk,_) -> (Loc.tag ?loc @@ Evar_kinds.SubEvar evk)
| _ -> (Loc.tag ?loc @@ Evar_kinds.CasesType true) in
diff --git a/pretyping/cbv.ml b/pretyping/cbv.ml
index 192eca63bb..e42576d95b 100644
--- a/pretyping/cbv.ml
+++ b/pretyping/cbv.ml
@@ -171,7 +171,7 @@ let fixp_reducible flgs ((reci,i),_) stk =
let cofixp_reducible flgs _ stk =
if red_set flgs fCOFIX then
match stk with
- | (CASE _ | APP(_,CASE _)) -> true
+ | (CASE _ | PROJ _ | APP(_,CASE _) | APP(_,PROJ _)) -> true
| _ -> false
else
false
diff --git a/pretyping/detyping.ml b/pretyping/detyping.ml
index 23993243f4..754e881398 100644
--- a/pretyping/detyping.ml
+++ b/pretyping/detyping.ml
@@ -581,12 +581,7 @@ and detype_r d flags avoid env sigma t =
| Const (sp,u) -> GRef (ConstRef sp, detype_instance sigma u)
| Proj (p,c) ->
let noparams () =
- let pb = Environ.lookup_projection p (snd env) in
- let pars = pb.Declarations.proj_npars in
- let hole = DAst.make @@ GHole(Evar_kinds.InternalHole,Misctypes.IntroAnonymous,None) in
- let args = List.make pars hole in
- GApp (DAst.make @@ GRef (ConstRef (Projection.constant p), None),
- (args @ [detype d flags avoid env sigma c]))
+ GProj (p, detype d flags avoid env sigma c)
in
if fst flags || !Flags.in_debugger || !Flags.in_toplevel then
try noparams ()
@@ -1002,6 +997,13 @@ let rec subst_glob_constr subst = DAst.map (function
let r1' = subst_glob_constr subst r1 in
let k' = Miscops.smartmap_cast_type (subst_glob_constr subst) k in
if r1' == r1 && k' == k then raw else GCast (r1',k')
+
+ | GProj (p,c) as raw ->
+ let kn = Projection.constant p in
+ let b = Projection.unfolded p in
+ let kn' = subst_constant subst kn in
+ let c' = subst_glob_constr subst c in
+ if kn' == kn && c' == c then raw else GProj(Projection.make kn' b, c')
)
(* Utilities to transform kernel cases to simple pattern-matching problem *)
diff --git a/pretyping/evarconv.ml b/pretyping/evarconv.ml
index 41c4616f79..dc3acbc3e2 100644
--- a/pretyping/evarconv.ml
+++ b/pretyping/evarconv.ml
@@ -353,19 +353,7 @@ let exact_ise_stack2 env evd f sk1 sk2 =
let check_leq_inductives evd cumi u u' =
let u = EConstr.EInstance.kind evd u in
let u' = EConstr.EInstance.kind evd u' in
- let length_ind_instance =
- Univ.AUContext.size (Univ.ACumulativityInfo.univ_context cumi)
- in
- let ind_sbcst = Univ.ACumulativityInfo.subtyp_context cumi in
- if not ((length_ind_instance = Univ.Instance.length u) &&
- (length_ind_instance = Univ.Instance.length u')) then
- anomaly (Pp.str "Invalid inductive subtyping encountered!")
- else
- begin
- let comp_subst = (Univ.Instance.append u u') in
- let comp_cst = Univ.AUContext.instantiate comp_subst ind_sbcst in
- Evd.add_constraints evd comp_cst
- end
+ Evd.add_constraints evd (Reduction.get_cumulativity_constraints CUMUL cumi u u')
let rec evar_conv_x ts env evd pbty term1 term2 =
let term1 = whd_head_evar evd term1 in
diff --git a/pretyping/evardefine.ml b/pretyping/evardefine.ml
index b646a37f8a..fd83795f55 100644
--- a/pretyping/evardefine.ml
+++ b/pretyping/evardefine.ml
@@ -28,8 +28,8 @@ let env_nf_evar sigma env =
let env_nf_betaiotaevar sigma env =
process_rel_context
- (fun d e ->
- push_rel (RelDecl.map_constr (fun c -> Reductionops.nf_betaiota sigma c) d) e) env
+ (fun d env ->
+ push_rel (RelDecl.map_constr (fun c -> Reductionops.nf_betaiota env sigma c) d) env) env
(****************************************)
(* Operations on value/type constraints *)
diff --git a/pretyping/glob_ops.ml b/pretyping/glob_ops.ml
index 093f1f0b68..a21137a05c 100644
--- a/pretyping/glob_ops.ml
+++ b/pretyping/glob_ops.ml
@@ -133,8 +133,10 @@ let mk_glob_constr_eq f c1 c2 = match DAst.get c1, DAst.get c2 with
Miscops.intro_pattern_naming_eq nam1 nam2
| GCast (c1, t1), GCast (c2, t2) ->
f c1 c2 && cast_type_eq f t1 t2
+ | GProj (p1, t1), GProj (p2, t2) ->
+ Projection.equal p1 p2 && f t1 t2
| (GRef _ | GVar _ | GEvar _ | GPatVar _ | GApp _ | GLambda _ | GProd _ | GLetIn _ |
- GCases _ | GLetTuple _ | GIf _ | GRec _ | GSort _ | GHole _ | GCast _), _ -> false
+ GCases _ | GLetTuple _ | GIf _ | GRec _ | GSort _ | GHole _ | GCast _ | GProj _), _ -> false
let rec glob_constr_eq c = mk_glob_constr_eq glob_constr_eq c
@@ -180,6 +182,8 @@ let map_glob_constr_left_to_right f = DAst.map (function
let comp1 = f c in
let comp2 = Miscops.map_cast_type f k in
GCast (comp1,comp2)
+ | GProj (p,c) ->
+ GProj (p, f c)
| (GVar _ | GSort _ | GHole _ | GRef _ | GEvar _ | GPatVar _) as x -> x
)
@@ -212,6 +216,8 @@ let fold_glob_constr f acc = DAst.with_val (function
let acc = match k with
| CastConv t | CastVM t | CastNative t -> f acc t | CastCoerce -> acc in
f acc c
+ | GProj(_,c) ->
+ f acc c
| (GSort _ | GHole _ | GRef _ | GEvar _ | GPatVar _) -> acc
)
@@ -253,6 +259,8 @@ let fold_glob_constr_with_binders g f v acc = DAst.(with_val (function
let acc = match k with
| CastConv t | CastVM t | CastNative t -> f v acc t | CastCoerce -> acc in
f v acc c
+ | GProj(_,c) ->
+ f v acc c
| (GSort _ | GHole _ | GRef _ | GEvar _ | GPatVar _) -> acc))
let iter_glob_constr f = fold_glob_constr (fun () -> f) ()
diff --git a/pretyping/inductiveops.ml b/pretyping/inductiveops.ml
index 78e6bc6f14..275a079d5d 100644
--- a/pretyping/inductiveops.ml
+++ b/pretyping/inductiveops.ml
@@ -84,7 +84,7 @@ let mis_is_recursive_subset listind rarg =
List.exists
(fun ra ->
match dest_recarg ra with
- | Mrec (_,i) -> Int.List.mem i listind
+ | Mrec (_,i) -> Int.List.mem i listind
| _ -> false) rvec
in
Array.exists one_is_rec (dest_subterms rarg)
@@ -361,20 +361,20 @@ let make_case_or_project env sigma indf ci pred c branches =
if (* dependent *) not (Vars.noccurn sigma 1 t) &&
not (has_dependent_elim mib) then
user_err ~hdr:"make_case_or_project"
- Pp.(str"Dependent case analysis not allowed" ++
- str" on inductive type " ++ Names.MutInd.print (fst ind))
+ Pp.(str"Dependent case analysis not allowed" ++
+ str" on inductive type " ++ Names.MutInd.print (fst ind))
in
let branch = branches.(0) in
let ctx, br = decompose_lam_n_assum sigma (Array.length ps) branch in
let n, subst =
List.fold_right
(fun decl (i, subst) ->
- match decl with
- | LocalAssum (na, t) ->
- let t = mkProj (Projection.make ps.(i) true, c) in
- (i + 1, t :: subst)
- | LocalDef (na, b, t) -> (i, Vars.substl subst b :: subst))
- ctx (0, [])
+ match decl with
+ | LocalAssum (na, t) ->
+ let t = mkProj (Projection.make ps.(i) true, c) in
+ (i + 1, t :: subst)
+ | LocalDef (na, b, t) -> (i, Vars.substl subst b :: subst))
+ ctx (0, [])
in Vars.substl subst br
(* substitution in a signature *)
@@ -511,25 +511,25 @@ let is_predicate_explicitly_dep env sigma pred arsign =
let pv' = whd_all env sigma pval in
match EConstr.kind sigma pv', arsign with
| Lambda (na,t,b), (LocalAssum _)::arsign ->
- srec (push_rel_assum (na, t) env) b arsign
+ srec (push_rel_assum (na, t) env) b arsign
| Lambda (na,_,t), _ ->
(* The following code has an impact on the introduction names
- given by the tactics "case" and "inversion": when the
- elimination is not dependent, "case" uses Anonymous for
- inductive types in Prop and names created by mkProd_name for
- inductive types in Set/Type while "inversion" uses anonymous
- for inductive types both in Prop and Set/Type !!
-
- Previously, whether names were created or not relied on
- whether the predicate created in Indrec.make_case_com had a
- dependent arity or not. To avoid different predicates
- printed the same in v8, all predicates built in indrec.ml
- got a dependent arity (Aug 2004). The new way to decide
- whether names have to be created or not is to use an
- Anonymous or Named variable to enforce the expected
- dependency status (of course, Anonymous implies non
- dependent, but not conversely).
+ given by the tactics "case" and "inversion": when the
+ elimination is not dependent, "case" uses Anonymous for
+ inductive types in Prop and names created by mkProd_name for
+ inductive types in Set/Type while "inversion" uses anonymous
+ for inductive types both in Prop and Set/Type !!
+
+ Previously, whether names were created or not relied on
+ whether the predicate created in Indrec.make_case_com had a
+ dependent arity or not. To avoid different predicates
+ printed the same in v8, all predicates built in indrec.ml
+ got a dependent arity (Aug 2004). The new way to decide
+ whether names have to be created or not is to use an
+ Anonymous or Named variable to enforce the expected
+ dependency status (of course, Anonymous implies non
+ dependent, but not conversely).
From Coq > 8.2, using or not the the effective dependency of
the predicate is parametrable! *)
@@ -600,15 +600,15 @@ let rec instantiate_universes env evdref scl is = function
let ctx,_ = Reduction.dest_arity env ty in
let u = Univ.Universe.make l in
let s =
- (* Does the sort of parameter [u] appear in (or equal)
+ (* Does the sort of parameter [u] appear in (or equal)
the sort of inductive [is] ? *)
if univ_level_mem l is then
scl (* constrained sort: replace by scl *)
else
(* unconstrained sort: replace by fresh universe *)
let evm, s = Evd.new_sort_variable Evd.univ_flexible !evdref in
- let evm = Evd.set_leq_sort env evm s (Sorts.sort_of_univ u) in
- evdref := evm; s
+ let evm = Evd.set_leq_sort env evm s (Sorts.sort_of_univ u) in
+ evdref := evm; s
in
(LocalAssum (na,mkArity(ctx,s))) :: instantiate_universes env evdref scl is (sign, exp)
| sign, [] -> sign (* Uniform parameters are exhausted *)
@@ -656,93 +656,3 @@ let control_only_guard env c =
iter_constr_with_full_binders push_rel iter env c
in
iter env c
-
-(* inference of subtyping condition for inductive types *)
-
-let infer_inductive_subtyping_arity_constructor
- (env, evd, csts) (subst : constr -> constr) (arcn : types) is_arity (params : Context.Rel.t) =
- let numchecked = ref 0 in
- let numparams = Context.Rel.nhyps params in
- let update_contexts (env, evd, csts) csts' =
- (Environ.add_constraints csts' env, Evd.add_constraints evd csts', Univ.Constraint.union csts csts')
- in
- let basic_check (env, evd, csts) tp =
- let result =
- if !numchecked >= numparams then
- let csts' =
- Reduction.infer_conv_leq ~evars:(Evd.existential_opt_value evd) env (Evd.universes evd) tp (subst tp)
- in update_contexts (env, evd, csts) csts'
- else
- (env, evd, csts)
- in
- numchecked := !numchecked + 1; result
- in
- let infer_typ typ ctxs =
- match typ with
- | LocalAssum (_, typ') ->
- begin
- try
- let (env, evd, csts) = basic_check ctxs typ' in (Environ.push_rel typ env, evd, csts)
- with Reduction.NotConvertible ->
- anomaly ~label:"inference of record/inductive subtyping relation failed"
- (Pp.str "Can't infer subtyping for record/inductive type")
- end
- | _ -> anomaly (Pp.str "")
- in
- let arcn' = Term.it_mkProd_or_LetIn arcn params in
- let typs, codom = Reduction.dest_prod env arcn' in
- let last_contexts = Context.Rel.fold_outside infer_typ typs ~init:(env, evd, csts) in
- if not is_arity then basic_check last_contexts codom else last_contexts
-
-let infer_inductive_subtyping env evd mind_ent =
- let { Entries.mind_entry_params = params;
- Entries.mind_entry_inds = entries;
- Entries.mind_entry_universes = ground_univs;
- } = mind_ent
- in
- let uinfind =
- match ground_univs with
- | Entries.Monomorphic_ind_entry _
- | Entries.Polymorphic_ind_entry _ -> ground_univs
- | Entries.Cumulative_ind_entry cumi ->
- begin
- let uctx = Univ.CumulativityInfo.univ_context cumi in
- let sbsubst = Univ.CumulativityInfo.subtyping_susbst cumi in
- let dosubst = subst_univs_level_constr sbsubst in
- let instance_other =
- Univ.subst_univs_level_instance sbsubst (Univ.UContext.instance uctx)
- in
- let constraints_other =
- Univ.subst_univs_level_constraints
- sbsubst (Univ.UContext.constraints uctx)
- in
- let uctx_other = Univ.UContext.make (instance_other, constraints_other) in
- let env = Environ.push_context uctx env in
- let env = Environ.push_context uctx_other env in
- let evd =
- Evd.merge_universe_context
- evd (UState.of_context_set (Univ.ContextSet.of_context uctx_other))
- in
- let (_, _, subtyp_constraints) =
- List.fold_left
- (fun ctxs indentry ->
- let _, params = Typeops.infer_local_decls env params in
- let ctxs' = infer_inductive_subtyping_arity_constructor
- ctxs dosubst indentry.Entries.mind_entry_arity true params
- in
- List.fold_left
- (fun ctxs cons ->
- infer_inductive_subtyping_arity_constructor
- ctxs dosubst cons false params
- )
- ctxs' indentry.Entries.mind_entry_lc
- ) (env, evd, Univ.Constraint.empty) entries
- in
- Entries.Cumulative_ind_entry
- (Univ.CumulativityInfo.make
- (Univ.CumulativityInfo.univ_context cumi,
- Univ.UContext.make
- (Univ.UContext.instance (Univ.CumulativityInfo.subtyp_context cumi),
- subtyp_constraints)))
- end
- in {mind_ent with Entries.mind_entry_universes = uinfind;}
diff --git a/pretyping/inductiveops.mli b/pretyping/inductiveops.mli
index 58b1ce6c3f..55149552aa 100644
--- a/pretyping/inductiveops.mli
+++ b/pretyping/inductiveops.mli
@@ -199,12 +199,3 @@ val type_of_inductive_knowing_conclusion :
(********************)
val control_only_guard : env -> types -> unit
-
-(* inference of subtyping condition for inductive types *)
-(* for debugging purposes only to be removed *)
-val infer_inductive_subtyping_arity_constructor : Environ.env * Evd.evar_map * Univ.Constraint.t ->
-(constr -> constr) ->
-types -> bool -> Context.Rel.t -> Environ.env * Evd.evar_map * Univ.Constraint.t
-
-val infer_inductive_subtyping : Environ.env -> Evd.evar_map -> Entries.mutual_inductive_entry ->
- Entries.mutual_inductive_entry
diff --git a/pretyping/inferCumulativity.ml b/pretyping/inferCumulativity.ml
new file mode 100644
index 0000000000..a0a8276c5c
--- /dev/null
+++ b/pretyping/inferCumulativity.ml
@@ -0,0 +1,224 @@
+(************************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2017 *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(************************************************************************)
+
+open Reduction
+open Declarations
+open Constr
+open Univ
+open Util
+
+(** Throughout this module we modify a map [variances] from local
+ universes to [Variance.t]. It starts as a trivial mapping to
+ [Irrelevant] and every time we encounter a local universe we
+ restrict it accordingly. *)
+
+let infer_level_eq u variances =
+ if LMap.mem u variances
+ then LMap.set u Variance.Invariant variances
+ else variances
+
+let infer_level_leq u variances =
+ match LMap.find u variances with
+ | exception Not_found -> variances
+ | varu -> LMap.set u (Variance.sup varu Variance.Covariant) variances
+
+let infer_generic_instance_eq variances u =
+ Array.fold_left (fun variances u -> infer_level_eq u variances)
+ variances (Instance.to_array u)
+
+let variance_pb cv_pb var =
+ let open Variance in
+ match cv_pb, var with
+ | _, Irrelevant -> Irrelevant
+ | _, Invariant -> Invariant
+ | CONV, Covariant -> Invariant
+ | CUMUL, Covariant -> Covariant
+
+let infer_cumulative_ind_instance cv_pb cumi variances u =
+ Array.fold_left2 (fun variances varu u ->
+ match LMap.find u variances with
+ | exception Not_found -> variances
+ | varu' ->
+ LMap.set u (Variance.sup varu' (variance_pb cv_pb varu)) variances)
+ variances (ACumulativityInfo.variance cumi) (Instance.to_array u)
+
+let infer_inductive_instance cv_pb env variances ind nargs u =
+ let mind = Environ.lookup_mind (fst ind) env in
+ match mind.mind_universes with
+ | Monomorphic_ind _ -> assert (Instance.is_empty u); variances
+ | Polymorphic_ind _ -> infer_generic_instance_eq variances u
+ | Cumulative_ind cumi ->
+ if not (Int.equal (inductive_cumulativity_arguments (mind,snd ind)) nargs)
+ then infer_generic_instance_eq variances u
+ else infer_cumulative_ind_instance cv_pb cumi variances u
+
+let infer_constructor_instance_eq env variances ((mi,ind),ctor) nargs u =
+ let mind = Environ.lookup_mind mi env in
+ match mind.mind_universes with
+ | Monomorphic_ind _ -> assert (Instance.is_empty u); variances
+ | Polymorphic_ind _ -> infer_generic_instance_eq variances u
+ | Cumulative_ind cumi ->
+ if not (Int.equal (constructor_cumulativity_arguments (mind,ind,ctor)) nargs)
+ then infer_generic_instance_eq variances u
+ else infer_cumulative_ind_instance CONV cumi variances u
+
+let infer_sort cv_pb variances s =
+ match cv_pb with
+ | CONV ->
+ LSet.fold infer_level_eq (Universe.levels (Sorts.univ_of_sort s)) variances
+ | CUMUL ->
+ LSet.fold infer_level_leq (Universe.levels (Sorts.univ_of_sort s)) variances
+
+let infer_table_key infos variances c =
+ let open Names in
+ match c with
+ | ConstKey (_, u) ->
+ infer_generic_instance_eq variances u
+ | VarKey _ | RelKey _ -> variances
+
+let rec infer_fterm cv_pb infos variances hd stk =
+ Control.check_for_interrupt ();
+ let open CClosure in
+ let hd,stk = whd_stack infos hd stk in
+ match fterm_of hd with
+ | FAtom a ->
+ begin match kind a with
+ | Sort s -> infer_sort cv_pb variances s
+ | Meta _ -> infer_stack infos variances stk
+ | _ -> assert false
+ end
+ | FEvar ((_,args),e) ->
+ let variances = infer_stack infos variances stk in
+ infer_vect infos variances (Array.map (mk_clos e) args)
+ | FRel _ -> variances
+ | FFlex fl ->
+ let variances = infer_table_key infos variances fl in
+ infer_stack infos variances stk
+ | FProj (_,c) ->
+ let variances = infer_fterm CONV infos variances c [] in
+ infer_stack infos variances stk
+ | FLambda _ ->
+ let (_,ty,bd) = destFLambda mk_clos hd in
+ let variances = infer_fterm CONV infos variances ty [] in
+ infer_fterm CONV infos variances bd []
+ | FProd (_,dom,codom) ->
+ let variances = infer_fterm CONV infos variances dom [] in
+ infer_fterm cv_pb infos variances codom []
+ | FInd (ind, u) ->
+ let variances =
+ if Instance.is_empty u then variances
+ else
+ let nargs = stack_args_size stk in
+ infer_inductive_instance cv_pb (info_env infos) variances ind nargs u
+ in
+ infer_stack infos variances stk
+ | FConstruct (ctor,u) ->
+ let variances =
+ if Instance.is_empty u then variances
+ else
+ let nargs = stack_args_size stk in
+ infer_constructor_instance_eq (info_env infos) variances ctor nargs u
+ in
+ infer_stack infos variances stk
+ | FFix ((_,(_,tys,cl)),e) | FCoFix ((_,(_,tys,cl)),e) ->
+ let n = Array.length cl in
+ let variances = infer_vect infos variances (Array.map (mk_clos e) tys) in
+ let le = Esubst.subs_liftn n e in
+ let variances = infer_vect infos variances (Array.map (mk_clos le) cl) in
+ infer_stack infos variances stk
+
+ (* Removed by whnf *)
+ | FLOCKED | FCaseT _ | FCast _ | FLetIn _ | FApp _ | FLIFT _ | FCLOS _ -> assert false
+
+and infer_stack infos variances (stk:CClosure.stack) =
+ match stk with
+ | [] -> variances
+ | z :: stk ->
+ let open CClosure in
+ let variances = match z with
+ | Zapp v -> infer_vect infos variances v
+ | Zproj _ -> variances
+ | Zfix (fx,a) ->
+ let variances = infer_fterm CONV infos variances fx [] in
+ infer_stack infos variances a
+ | ZcaseT (ci,p,br,e) ->
+ let variances = infer_fterm CONV infos variances (mk_clos e p) [] in
+ infer_vect infos variances (Array.map (mk_clos e) br)
+ | Zshift _ -> variances
+ | Zupdate _ -> variances
+ in
+ infer_stack infos variances stk
+
+and infer_vect infos variances v =
+ Array.fold_left (fun variances c -> infer_fterm CONV infos variances c []) variances v
+
+let infer_term cv_pb env variances c =
+ let open CClosure in
+ let reds = RedFlags.red_add_transparent betaiotazeta Names.full_transparent_state in
+ let infos = create_clos_infos reds env in
+ infer_fterm cv_pb infos variances (CClosure.inject c) []
+
+let infer_arity_constructor env variances arcn is_arity params =
+ let numchecked = ref 0 in
+ let numparams = Context.Rel.nhyps params in
+ let basic_check env variances tp =
+ let variances =
+ if !numchecked >= numparams then
+ infer_term CUMUL env variances tp
+ else
+ variances
+ in
+ numchecked := !numchecked + 1; variances
+ in
+ let infer_typ typ (env,variances) =
+ match typ with
+ | Context.Rel.Declaration.LocalAssum (_, typ') ->
+ (Environ.push_rel typ env, basic_check env variances typ')
+ | Context.Rel.Declaration.LocalDef _ -> assert false
+ in
+ let arcn' = Term.it_mkProd_or_LetIn arcn params in
+ let typs, codom = Reduction.dest_prod env arcn' in
+ let env, variances = Context.Rel.fold_outside infer_typ typs ~init:(env, variances) in
+ (* If we have Inductive foo@{i j} : ... -> Type@{i} := C : ... -> foo Type@{j}
+ i is irrelevant, j is invariant. *)
+ if not is_arity then basic_check env variances codom else variances
+
+let infer_inductive env mie =
+ let open Entries in
+ let { mind_entry_params = params;
+ mind_entry_inds = entries; } = mie
+ in
+ let univs =
+ match mie.mind_entry_universes with
+ | Monomorphic_ind_entry _
+ | Polymorphic_ind_entry _ as univs -> univs
+ | Cumulative_ind_entry cumi ->
+ let uctx = CumulativityInfo.univ_context cumi in
+ let uarray = Instance.to_array @@ UContext.instance uctx in
+ let env = Environ.push_context uctx env in
+ let variances =
+ Array.fold_left (fun variances u -> LMap.add u Variance.Irrelevant variances)
+ LMap.empty uarray
+ in
+ let variances = List.fold_left (fun variances entry ->
+ let _, params = Typeops.infer_local_decls env params in
+ let variances = infer_arity_constructor
+ env variances entry.mind_entry_arity true params
+ in
+ List.fold_left
+ (fun variances cons ->
+ infer_arity_constructor
+ env variances cons false params)
+ variances entry.mind_entry_lc)
+ variances
+ entries
+ in
+ let variances = Array.map (fun u -> LMap.find u variances) uarray in
+ Cumulative_ind_entry (CumulativityInfo.make (uctx, variances))
+ in
+ { mie with mind_entry_universes = univs }
diff --git a/pretyping/inferCumulativity.mli b/pretyping/inferCumulativity.mli
new file mode 100644
index 0000000000..a5037ea475
--- /dev/null
+++ b/pretyping/inferCumulativity.mli
@@ -0,0 +1,10 @@
+(************************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2017 *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(************************************************************************)
+
+val infer_inductive : Environ.env -> Entries.mutual_inductive_entry ->
+ Entries.mutual_inductive_entry
diff --git a/pretyping/nativenorm.ml b/pretyping/nativenorm.ml
index 79e0afa72b..b41e15f5a6 100644
--- a/pretyping/nativenorm.ml
+++ b/pretyping/nativenorm.ml
@@ -224,7 +224,7 @@ and nf_accu env sigma accu =
if Int.equal (accu_nargs accu) 0 then nf_atom env sigma atom
else
let a,typ = nf_atom_type env sigma atom in
- let _, args = nf_args env sigma accu typ in
+ let _, args = nf_args env sigma (args_of_accu accu) typ in
mkApp(a,Array.of_list args)
and nf_accu_type env sigma accu =
@@ -232,10 +232,10 @@ and nf_accu_type env sigma accu =
if Int.equal (accu_nargs accu) 0 then nf_atom_type env sigma atom
else
let a,typ = nf_atom_type env sigma atom in
- let t, args = nf_args env sigma accu typ in
+ let t, args = nf_args env sigma (args_of_accu accu) typ in
mkApp(a,Array.of_list args), t
-and nf_args env sigma accu t =
+and nf_args env sigma args t =
let aux arg (t,l) =
let _,dom,codom =
try decompose_prod env t with
@@ -246,7 +246,7 @@ and nf_args env sigma accu t =
let c = nf_val env sigma arg dom in
(subst1 c codom, c::l)
in
- let t,l = List.fold_right aux (args_of_accu accu) (t,[]) in
+ let t,l = Array.fold_right aux args (t,[]) in
t, List.rev l
and nf_bargs env sigma b t =
@@ -277,7 +277,6 @@ and nf_atom env sigma atom =
let codom = nf_type env sigma (codom vn) in
mkProd(n,dom,codom)
| Ameta (mv,_) -> mkMeta mv
- | Aevar (ev,_) -> mkEvar ev
| Aproj(p,c) ->
let c = nf_accu env sigma c in
mkProj(Projection.make p true,c)
@@ -347,9 +346,9 @@ and nf_atom_type env sigma atom =
let env = push_rel (LocalAssum (n,dom)) env in
let codom,s2 = nf_type_sort env sigma (codom vn) in
mkProd(n,dom,codom), Typeops.type_of_product env n s1 s2
- | Aevar(ev,ty) ->
- let ty = nf_type env sigma ty in
- mkEvar ev, ty
+ | Aevar(evk,ty,args) ->
+ let ty = nf_type env sigma ty in
+ nf_evar env sigma evk ty args
| Ameta(mv,ty) ->
let ty = nf_type env sigma ty in
mkMeta mv, ty
@@ -386,6 +385,19 @@ and nf_predicate env sigma ind mip params v pT =
true, mkLambda(name,dom,body)
| _, _ -> false, nf_type env sigma v
+and nf_evar env sigma evk ty args =
+ 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
+ if List.is_empty hyps then begin
+ assert (Int.equal (Array.length args) 0);
+ mkEvar (evk, [||]), ty
+ end
+ else
+ let fold accu d = Term.mkNamedProd_or_LetIn d accu in
+ let t = List.fold_left fold ty hyps in
+ let ty, args = nf_args env sigma args t in
+ mkEvar (evk, Array.of_list args), ty
+
let evars_of_evar_map sigma =
{ Nativelambda.evars_val = Evd.existential_opt_value sigma;
Nativelambda.evars_typ = Evd.existential_type sigma;
diff --git a/pretyping/patternops.ml b/pretyping/patternops.ml
index 41e09004c6..1bec4a6f15 100644
--- a/pretyping/patternops.ml
+++ b/pretyping/patternops.ml
@@ -137,8 +137,7 @@ let rec head_pattern_bound t =
| PCase (_,p,c,br) -> head_pattern_bound c
| PRef r -> r
| PVar id -> VarRef id
- | PProj (p,c) -> ConstRef (Projection.constant p)
- | PEvar _ | PRel _ | PMeta _ | PSoApp _ | PSort _ | PFix _
+ | PEvar _ | PRel _ | PMeta _ | PSoApp _ | PSort _ | PFix _ | PProj _
-> raise BoundPattern
(* Perhaps they were arguments, but we don't beta-reduce *)
| PLambda _ -> raise BoundPattern
@@ -446,6 +445,9 @@ let rec pat_of_raw metas vars = DAst.with_loc_val (fun ?loc -> function
one non-trivial branch. These facts are used in [Constrextern]. *)
PCase (info, pred, pat_of_raw metas vars c, brs)
+ | GProj(p,c) ->
+ PProj(p, pat_of_raw metas vars c)
+
| GPatVar _ | GIf _ | GLetTuple _ | GCases _ | GEvar _ | GRec _ ->
err ?loc (Pp.str "Non supported pattern."))
diff --git a/pretyping/pretyping.ml b/pretyping/pretyping.ml
index b930c5db83..8809558ff7 100644
--- a/pretyping/pretyping.ml
+++ b/pretyping/pretyping.ml
@@ -70,7 +70,7 @@ let get_extra env sigma =
let ids = List.map get_id (named_context env) in
let avoid = List.fold_right Id.Set.add ids Id.Set.empty in
Context.Rel.fold_outside (fun d acc -> push_rel_decl_to_named_context sigma d acc)
- (rel_context env) ~init:(empty_csubst, [], avoid, named_context env)
+ (rel_context env) ~init:(empty_csubst, avoid, named_context env)
let make_env env sigma = { env = env; extra = lazy (get_extra env sigma) }
let rel_context env = rel_context env.env
@@ -90,12 +90,11 @@ let push_rel_context sigma ctx env = {
let lookup_named id env = lookup_named id env.env
let e_new_evar env evdref ?src ?naming typ =
- let subst2 subst vsubst c = csubst_subst subst (replace_vars vsubst c) in
let open Context.Named.Declaration in
let inst_vars = List.map (get_id %> mkVar) (named_context env.env) in
let inst_rels = List.rev (rel_list 0 (nb_rel env.env)) in
- let (subst, vsubst, _, nc) = Lazy.force env.extra in
- let typ' = subst2 subst vsubst typ in
+ let (subst, _, nc) = Lazy.force env.extra in
+ let typ' = csubst_subst subst typ in
let instance = inst_rels @ inst_vars in
let sign = val_of_named_context nc in
let sigma = !evdref in
@@ -738,6 +737,11 @@ let rec pretype k0 resolve_tc (tycon : type_constraint) (env : ExtraEnv.t) evdre
let j = pretype_sort ?loc evdref s in
inh_conv_coerce_to_tycon ?loc env evdref j tycon
+ | GProj (p, c) ->
+ (* TODO: once GProj is used as an input syntax, use bidirectional typing here *)
+ let cj = pretype empty_tycon env evdref lvar c in
+ judge_of_projection env.ExtraEnv.env !evdref p cj
+
| GApp (f,args) ->
let fj = pretype empty_tycon env evdref lvar f in
let floc = loc_of_glob_constr f in
diff --git a/pretyping/pretyping.mllib b/pretyping/pretyping.mllib
index 1da5b4567f..ae4ad0be7d 100644
--- a/pretyping/pretyping.mllib
+++ b/pretyping/pretyping.mllib
@@ -4,6 +4,7 @@ Locusops
Pretype_errors
Reductionops
Inductiveops
+InferCumulativity
Vnorm
Arguments_renaming
Nativenorm
diff --git a/pretyping/recordops.ml b/pretyping/recordops.ml
index 9ff9a75b3e..ab1f3cd320 100644
--- a/pretyping/recordops.ml
+++ b/pretyping/recordops.ml
@@ -298,29 +298,40 @@ let add_canonical_structure x = Lib.add_anonymous_leaf (inCanonStruc x)
(*s High-level declaration of a canonical structure *)
-let error_not_structure ref =
+let error_not_structure ref description =
user_err ~hdr:"object_declare"
- (Id.print (basename_of_global ref) ++ str" is not a structure object.")
+ (str"Could not declare a canonical structure " ++
+ (Id.print (basename_of_global ref) ++ str"." ++ spc() ++
+ str(description)))
let check_and_decompose_canonical_structure ref =
- let sp = match ref with ConstRef sp -> sp | _ -> error_not_structure ref in
+ let sp =
+ match ref with
+ ConstRef sp -> sp
+ | _ -> error_not_structure ref "Expected an instance of a record or structure."
+ in
let env = Global.env () in
let u = Univ.make_abstract_instance (Environ.constant_context env sp) in
let vc = match Environ.constant_opt_value_in env (sp, u) with
| Some vc -> vc
- | None -> error_not_structure ref in
+ | None -> error_not_structure ref "Could not find its value in the global environment." in
let body = snd (splay_lam (Global.env()) Evd.empty (EConstr.of_constr vc)) (** FIXME *) in
let body = EConstr.Unsafe.to_constr body in
let f,args = match kind body with
| App (f,args) -> f,args
- | _ -> error_not_structure ref in
+ | _ ->
+ error_not_structure ref "Expected a record or structure constructor applied to arguments." in
let indsp = match kind f with
| Construct ((indsp,1),u) -> indsp
- | _ -> error_not_structure ref in
- let s = try lookup_structure indsp with Not_found -> error_not_structure ref in
+ | _ -> error_not_structure ref "Expected an instance of a record or structure." in
+ let s =
+ try lookup_structure indsp
+ with Not_found ->
+ error_not_structure ref
+ ("Could not find the record or structure " ^ (MutInd.to_string (fst indsp))) in
let ntrue_projs = List.count snd s.s_PROJKIND in
if s.s_EXPECTEDPARAM + ntrue_projs > Array.length args then
- error_not_structure ref;
+ error_not_structure ref "Got too few arguments to the record or structure constructor.";
(sp,indsp)
let declare_canonical_structure ref =
diff --git a/pretyping/reductionops.ml b/pretyping/reductionops.ml
index 78de0437d0..418ea271cd 100644
--- a/pretyping/reductionops.ml
+++ b/pretyping/reductionops.ml
@@ -1241,9 +1241,9 @@ let clos_whd_flags flgs env sigma t =
(CClosure.inject (EConstr.Unsafe.to_constr t)))
with e when is_anomaly e -> user_err Pp.(str "Tried to normalize ill-typed term")
-let nf_beta = clos_norm_flags CClosure.beta (Global.env ())
-let nf_betaiota = clos_norm_flags CClosure.betaiota (Global.env ())
-let nf_betaiotazeta = clos_norm_flags CClosure.betaiotazeta (Global.env ())
+let nf_beta = clos_norm_flags CClosure.beta
+let nf_betaiota = clos_norm_flags CClosure.betaiota
+let nf_betaiotazeta = clos_norm_flags CClosure.betaiotazeta
let nf_all env sigma =
clos_norm_flags CClosure.all env sigma
@@ -1324,79 +1324,17 @@ let sigma_compare_instances ~flex i0 i1 sigma =
| Univ.UniverseInconsistency _ ->
raise Reduction.NotConvertible
-let sigma_check_inductive_instances cv_pb uinfind u u' sigma =
- let len_instance =
- Univ.AUContext.size (Univ.ACumulativityInfo.univ_context uinfind)
- in
- let ind_sbctx = Univ.ACumulativityInfo.subtyp_context uinfind in
- if not ((len_instance = Univ.Instance.length u) &&
- (len_instance = Univ.Instance.length u')) then
- anomaly (Pp.str "Invalid inductive subtyping encountered!")
- else
- let comp_cst =
- let comp_subst = (Univ.Instance.append u u') in
- Univ.AUContext.instantiate comp_subst ind_sbctx
- in
- let comp_cst =
- match cv_pb with
- Reduction.CONV ->
- let comp_subst = (Univ.Instance.append u' u) in
- let comp_cst' = Univ.AUContext.instantiate comp_subst ind_sbctx in
- Univ.Constraint.union comp_cst comp_cst'
- | Reduction.CUMUL -> comp_cst
- in
- try Evd.add_constraints sigma comp_cst
- with Evd.UniversesDiffer
- | Univ.UniverseInconsistency _ ->
- raise Reduction.NotConvertible
-
-let sigma_conv_inductives
- cv_pb (mind, ind) u1 sv1 u2 sv2 sigma =
- try sigma_compare_instances ~flex:false u1 u2 sigma with
- Reduction.NotConvertible ->
- match mind.Declarations.mind_universes with
- | Declarations.Monomorphic_ind _ ->
- raise Reduction.NotConvertible
- | Declarations.Polymorphic_ind _ ->
- raise Reduction.NotConvertible
- | Declarations.Cumulative_ind cumi ->
- let num_param_arity =
- mind.Declarations.mind_nparams +
- mind.Declarations.mind_packets.(ind).Declarations.mind_nrealargs
- in
- if not (num_param_arity = sv1 && num_param_arity = sv2) then
- raise Reduction.NotConvertible
- else
- sigma_check_inductive_instances cv_pb cumi u1 u2 sigma
-
-let sigma_conv_constructors
- (mind, ind, cns) u1 sv1 u2 sv2 sigma =
- try sigma_compare_instances ~flex:false u1 u2 sigma with
- Reduction.NotConvertible ->
- match mind.Declarations.mind_universes with
- | Declarations.Monomorphic_ind _ ->
- raise Reduction.NotConvertible
- | Declarations.Polymorphic_ind _ ->
- raise Reduction.NotConvertible
- | Declarations.Cumulative_ind cumi ->
- let num_cnstr_args =
- let nparamsctxt =
- mind.Declarations.mind_nparams +
- mind.Declarations.mind_packets.(ind).Declarations.mind_nrealargs
- in
- nparamsctxt +
- mind.Declarations.mind_packets.(ind).Declarations.mind_consnrealargs.(cns - 1)
- in
- if not (num_cnstr_args = sv1 && num_cnstr_args = sv2) then
- raise Reduction.NotConvertible
- else
- sigma_check_inductive_instances Reduction.CONV cumi u1 u2 sigma
+let sigma_check_inductive_instances csts sigma =
+ try Evd.add_constraints sigma csts
+ with Evd.UniversesDiffer
+ | Univ.UniverseInconsistency _ ->
+ raise Reduction.NotConvertible
let sigma_univ_state =
- { Reduction.compare = sigma_compare_sorts;
- Reduction.compare_instances = sigma_compare_instances;
- Reduction.conv_inductives = sigma_conv_inductives;
- Reduction.conv_constructors = sigma_conv_constructors}
+ let open Reduction in
+ { compare_sorts = sigma_compare_sorts;
+ compare_instances = sigma_compare_instances;
+ compare_cumul_instances = sigma_check_inductive_instances; }
let infer_conv_gen conv_fun ?(catch_incon=true) ?(pb=Reduction.CUMUL)
?(ts=full_transparent_state) env sigma x y =
diff --git a/pretyping/reductionops.mli b/pretyping/reductionops.mli
index a277864c92..0565baf45f 100644
--- a/pretyping/reductionops.mli
+++ b/pretyping/reductionops.mli
@@ -168,9 +168,9 @@ val clos_norm_flags : CClosure.RedFlags.reds -> reduction_function
val clos_whd_flags : CClosure.RedFlags.reds -> reduction_function
(** Same as [(strong whd_beta[delta][iota])], but much faster on big terms *)
-val nf_beta : local_reduction_function
-val nf_betaiota : local_reduction_function
-val nf_betaiotazeta : local_reduction_function
+val nf_beta : reduction_function
+val nf_betaiota : reduction_function
+val nf_betaiotazeta : reduction_function
val nf_all : reduction_function
val nf_evar : evar_map -> constr -> constr
diff --git a/pretyping/tacred.ml b/pretyping/tacred.ml
index 5a522e06a5..9b9408698d 100644
--- a/pretyping/tacred.ml
+++ b/pretyping/tacred.ml
@@ -60,9 +60,7 @@ let value_of_evaluable_ref env evref u =
match evref with
| EvalConstRef con ->
let u = Unsafe.to_instance u in
- EConstr.of_constr (try constant_value_in env (con,u)
- with NotEvaluableConst IsProj ->
- raise (Invalid_argument "value_of_evaluable_ref"))
+ EConstr.of_constr (constant_value_in env (con, u))
| EvalVarRef id -> env |> lookup_named id |> NamedDecl.get_value |> Option.get
let evaluable_of_global_reference env = function
@@ -476,7 +474,7 @@ let contract_fix_use_function env sigma f
let nbodies = Array.length recindices in
let make_Fi j = (mkFix((recindices,j),typedbodies), f j) in
let lbodies = List.init nbodies make_Fi in
- substl_checking_arity env (List.rev lbodies) sigma (nf_beta sigma bodies.(bodynum))
+ substl_checking_arity env (List.rev lbodies) sigma (nf_beta env sigma bodies.(bodynum))
let reduce_fix_use_function env sigma f whfun fix stack =
match fix_recarg fix (Stack.append_app_list stack Stack.empty) with
@@ -500,7 +498,7 @@ let contract_cofix_use_function env sigma f
let make_Fi j = (mkCoFix(j,typedbodies), f j) in
let subbodies = List.init nbodies make_Fi in
substl_checking_arity env (List.rev subbodies)
- sigma (nf_beta sigma bodies.(bodynum))
+ sigma (nf_beta env sigma bodies.(bodynum))
let reduce_mind_case_use_function func env sigma mia =
match EConstr.kind sigma mia.mconstr with
@@ -697,7 +695,7 @@ let rec red_elim_const env sigma ref u largs =
let whfun = whd_construct_stack env sigma in
(match reduce_fix_use_function env sigma f whfun (destFix sigma d) lrest with
| NotReducible -> raise Redelimination
- | Reduced (c,rest) -> (nf_beta sigma c, rest), nocase)
+ | Reduced (c,rest) -> (nf_beta env sigma c, rest), nocase)
| EliminationMutualFix (min,refgoal,refinfos) when nargs >= min ->
let rec descend (ref,u) args =
let c = reference_value env sigma ref u in
@@ -712,7 +710,7 @@ let rec red_elim_const env sigma ref u largs =
let whfun = whd_construct_stack env sigma in
(match reduce_fix_use_function env sigma f whfun (destFix sigma d) lrest with
| NotReducible -> raise Redelimination
- | Reduced (c,rest) -> (nf_beta sigma c, rest), nocase)
+ | Reduced (c,rest) -> (nf_beta env sigma c, rest), nocase)
| NotAnElimination when unfold_nonelim ->
let c = reference_value env sigma ref u in
(whd_betaiotazeta sigma (applist (c, largs)), []), nocase
@@ -1103,7 +1101,7 @@ let unfoldoccs env sigma (occs,name) c =
| [] -> ()
| _ -> error_invalid_occurrence rest
in
- nf_betaiotazeta sigma uc
+ nf_betaiotazeta env sigma uc
in
match occs with
| NoOccurrences -> c
@@ -1284,7 +1282,7 @@ let reduce_to_ref_gen allow_product env sigma ref t =
else raise Not_found
with Not_found ->
try
- let t' = nf_betaiota sigma (one_step_reduce env sigma t) in
+ let t' = nf_betaiota env sigma (one_step_reduce env sigma t) in
elimrec env t' l
with NotStepReducible -> error_cannot_recognize ref
in
diff --git a/pretyping/typing.mli b/pretyping/typing.mli
index 9f084ae8df..153a48a710 100644
--- a/pretyping/typing.mli
+++ b/pretyping/typing.mli
@@ -53,3 +53,4 @@ val judge_of_abstraction : Environ.env -> Name.t ->
unsafe_type_judgment -> unsafe_judgment -> unsafe_judgment
val judge_of_product : Environ.env -> Name.t ->
unsafe_type_judgment -> unsafe_type_judgment -> unsafe_judgment
+val judge_of_projection : env -> evar_map -> projection -> unsafe_judgment -> unsafe_judgment
diff --git a/pretyping/unification.ml b/pretyping/unification.ml
index 8df8f84742..e1720ec955 100644
--- a/pretyping/unification.ml
+++ b/pretyping/unification.ml
@@ -194,7 +194,7 @@ let pose_all_metas_as_evars env evd t =
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
- then nf_betaiota evd ty (* How it was in Coq <= 8.4 (but done in logic.ml at this time) *)
+ 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
let ev = Evarutil.e_new_evar env evdref ~src ty in
@@ -1277,7 +1277,7 @@ let w_coerce env evd mv c =
let unify_to_type env sigma flags c status u =
let sigma, c = refresh_universes (Some false) env sigma c in
let t = get_type_of env sigma (nf_meta sigma c) in
- let t = nf_betaiota sigma (nf_meta sigma t) in
+ let t = nf_betaiota env sigma (nf_meta sigma t) in
unify_0 env sigma CUMUL flags t u
let unify_type env sigma flags mv status c =
diff --git a/pretyping/vnorm.ml b/pretyping/vnorm.ml
index e395bdbc63..b21fbf0eb2 100644
--- a/pretyping/vnorm.ml
+++ b/pretyping/vnorm.ml
@@ -15,6 +15,7 @@ open Vars
open Environ
open Inductive
open Reduction
+open Vmvalues
open Vm
open Context.Rel.Declaration
@@ -134,7 +135,7 @@ let build_case_type dep p realargs c =
(* La fonction de normalisation *)
-let rec nf_val env sigma v t = nf_whd env sigma (whd_val v) t
+let rec nf_val env sigma v t = nf_whd env sigma (Vmvalues.whd_val v) t
and nf_vtype env sigma v = nf_val env sigma v crazy_type
@@ -144,7 +145,7 @@ and nf_whd env sigma whd typ =
| Vprod p ->
let dom = nf_vtype env sigma (dom p) in
let name = Name (Id.of_string "x") in
- let vc = body_of_vfun (nb_rel env) (codom p) in
+ let vc = reduce_fun (nb_rel env) (codom p) in
let codom = nf_vtype (push_rel (LocalAssum (name,dom)) env) sigma vc in
mkProd(name,dom,codom)
| Vfun f -> nf_fun env sigma f typ
@@ -191,7 +192,7 @@ and nf_univ_args ~nb_univs mk env sigma stk =
else match stk with
| Zapp args :: _ ->
let inst =
- Array.init nb_univs (fun i -> Vm.uni_lvl_val (arg args i))
+ Array.init nb_univs (fun i -> uni_lvl_val (arg args i))
in
Univ.Instance.of_array inst
| _ -> assert false
@@ -254,7 +255,7 @@ and nf_stk ?from:(from=0) env sigma c t stk =
in
let branchs = Array.mapi mkbranch bsw in
let tcase = build_case_type dep p realargs c in
- let ci = case_info sw in
+ let ci = sw.sw_annot.Cbytecodes.ci in
nf_stk env sigma (mkCase(ci, p, c, branchs)) tcase stk
| Zproj p :: stk ->
assert (from = 0) ;
@@ -266,14 +267,14 @@ and nf_predicate env sigma ind mip params v pT =
match whd_val v, kind pT with
| Vfun f, Prod _ ->
let k = nb_rel env in
- let vb = body_of_vfun k f in
+ let vb = reduce_fun k f in
let name,dom,codom = decompose_prod env pT in
let dep,body =
nf_predicate (push_rel (LocalAssum (name,dom)) env) sigma ind mip params vb codom in
dep, mkLambda(name,dom,body)
| Vfun f, _ ->
let k = nb_rel env in
- let vb = body_of_vfun k f in
+ let vb = reduce_fun k f in
let name = Name (Id.of_string "c") in
let n = mip.mind_nrealargs in
let rargs = Array.init n (fun i -> mkRel (n-i)) in
@@ -307,7 +308,7 @@ and nf_bargs env sigma b ofs t =
and nf_fun env sigma f typ =
let k = nb_rel env in
- let vb = body_of_vfun k f in
+ let vb = reduce_fun k f in
let name,dom,codom =
try decompose_prod env typ
with DestKO ->
diff --git a/printing/ppconstr.ml b/printing/ppconstr.ml
index 51735bc9e1..1146b42a01 100644
--- a/printing/ppconstr.ml
+++ b/printing/ppconstr.ml
@@ -732,6 +732,9 @@ let tag_var = tag Tag.variable
return (pr_prim_token p, prec_of_prim_token p)
| CDelimiters (sc,a) ->
return (pr_delimiters sc (pr mt (ldelim,E) a), ldelim)
+ | CProj (p,c) ->
+ let p = pr_proj (pr mt) pr_app c (CAst.make (CRef (p,None))) [] in
+ return (p, lproj)
in
let loc = constr_loc a in
pr_with_comments ?loc
diff --git a/printing/ppvernac.ml b/printing/ppvernac.ml
index 96e39e89a6..950246c531 100644
--- a/printing/ppvernac.ml
+++ b/printing/ppvernac.ml
@@ -31,12 +31,6 @@ open Decl_kinds
let pr_lconstr = pr_lconstr_expr
let pr_spc_lconstr = pr_sep_com spc pr_lconstr_expr
- let pr_lident (loc,id) =
- match loc with
- | None -> pr_id id
- | Some loc -> let (b,_) = Loc.unloc loc in
- pr_located pr_id @@ Loc.tag ~loc:(Loc.make_loc (b,b + String.length (Id.to_string id))) id
-
let pr_uconstraint (l, d, r) =
pr_glob_level l ++ spc () ++ Univ.pr_constraint_type d ++ spc () ++
pr_glob_level r
@@ -77,9 +71,8 @@ open Decl_kinds
| Some loc -> let (b,_) = Loc.unloc loc in
pr_located pr_fqid @@ Loc.tag ~loc:(Loc.make_loc (b,b + String.length (string_of_fqid fqid))) fqid
- let pr_lname = function
- | (loc,Name id) -> pr_lident (loc,id)
- | lna -> pr_located Name.print lna
+ let pr_lname_decl (n, u) =
+ pr_lname n ++ pr_universe_decl u
let pr_smart_global = Pputils.pr_or_by_notation pr_reference
@@ -398,8 +391,6 @@ open Decl_kinds
++ prlist (pr_decl_notation pr_constr) ntn
let pr_statement head (idpl,(bl,c)) =
- assert (not (Option.is_empty idpl));
- let idpl = Option.get idpl in
hov 2
(head ++ spc() ++ pr_ident_decl idpl ++ spc() ++
(match bl with [] -> mt() | _ -> pr_binders bl ++ spc()) ++
@@ -572,8 +563,6 @@ open Decl_kinds
return (keyword "Unfocus")
| VernacUnfocused ->
return (keyword "Unfocused")
- | VernacGoal c ->
- return (keyword "Goal" ++ pr_lconstrarg c)
| VernacAbort id ->
return (keyword "Abort" ++ pr_opt pr_lident id)
| VernacUndo i ->
@@ -684,7 +673,10 @@ open Decl_kinds
(* Gallina *)
| VernacDefinition ((discharge,kind),id,b) -> (* A verifier... *)
let pr_def_token dk =
- keyword (Kindops.string_of_definition_object_kind dk)
+ keyword (
+ if Name.is_anonymous (snd (fst id))
+ then "Goal"
+ else Kindops.string_of_definition_object_kind dk)
in
let pr_reduce = function
| None -> mt()
@@ -701,12 +693,13 @@ open Decl_kinds
in
(pr_binders_arg bl,ty,Some (pr_reduce red ++ pr_lconstr body))
| ProveBody (bl,t) ->
- (pr_binders_arg bl, str" :" ++ pr_spc_lconstr t, None) in
+ let typ u = if snd (fst id) = Anonymous then (assert (bl = []); u) else (str" :" ++ u) in
+ (pr_binders_arg bl, typ (pr_spc_lconstr t), None) in
let (binds,typ,c) = pr_def_body b in
return (
hov 2 (
pr_def_token kind ++ spc()
- ++ pr_ident_decl id ++ binds ++ typ
+ ++ pr_lname_decl id ++ binds ++ typ
++ (match c with
| None -> mt()
| Some cc -> str" :=" ++ spc() ++ cc))
diff --git a/printing/prettyp.ml b/printing/prettyp.ml
index 2b7886d115..114a071eee 100644
--- a/printing/prettyp.ml
+++ b/printing/prettyp.ml
@@ -78,6 +78,15 @@ let print_ref reduce ref udecl =
in EConstr.it_mkProd_or_LetIn ccl ctx
else typ in
let univs = Global.universes_of_global ref in
+ let variance = match ref with
+ | VarRef _ | ConstRef _ -> None
+ | IndRef (ind,_) | ConstructRef ((ind,_),_) ->
+ let mind = Environ.lookup_mind ind (Global.env ()) in
+ begin match mind.Declarations.mind_universes with
+ | Declarations.Monomorphic_ind _ | Declarations.Polymorphic_ind _ -> None
+ | Declarations.Cumulative_ind cumi -> Some (Univ.ACumulativityInfo.variance cumi)
+ end
+ in
let inst = Univ.AUContext.instance univs in
let univs = Univ.UContext.make (inst, Univ.AUContext.instantiate inst univs) in
let env = Global.env () in
@@ -89,7 +98,7 @@ let print_ref reduce ref udecl =
else mt ()
in
hov 0 (pr_global ref ++ inst ++ str " :" ++ spc () ++ pr_letype_env env sigma typ ++
- Printer.pr_universe_ctx sigma univs)
+ Printer.pr_universe_ctx sigma ?variance univs)
(********************************)
(** Printing implicit arguments *)
diff --git a/printing/printer.ml b/printing/printer.ml
index a63004cebe..d720bc2f8c 100644
--- a/printing/printer.ml
+++ b/printing/printer.ml
@@ -263,10 +263,10 @@ let pr_universe_ctx_set sigma c =
else
mt()
-let pr_universe_ctx sigma c =
+let pr_universe_ctx sigma ?variance c =
if !Detyping.print_universes && not (Univ.UContext.is_empty c) then
fnl()++pr_in_comment (fun c -> v 0
- (Univ.pr_universe_context (Termops.pr_evd_level sigma) c)) c
+ (Univ.pr_universe_context (Termops.pr_evd_level sigma) ?variance c)) c
else
mt()
diff --git a/printing/printer.mli b/printing/printer.mli
index 804014745c..a3427920af 100644
--- a/printing/printer.mli
+++ b/printing/printer.mli
@@ -120,7 +120,8 @@ val pr_sort : evar_map -> Sorts.t -> Pp.t
val pr_polymorphic : bool -> Pp.t
val pr_cumulative : bool -> bool -> Pp.t
val pr_universe_instance : evar_map -> Univ.UContext.t -> Pp.t
-val pr_universe_ctx : evar_map -> Univ.UContext.t -> Pp.t
+val pr_universe_ctx : evar_map -> ?variance:Univ.Variance.t array ->
+ Univ.UContext.t -> Pp.t
val pr_universe_ctx_set : evar_map -> Univ.ContextSet.t -> Pp.t
val pr_constant_universes : evar_map -> Entries.constant_universes_entry -> Pp.t
val pr_cumulativity_info : evar_map -> Univ.CumulativityInfo.t -> Pp.t
diff --git a/printing/printmod.ml b/printing/printmod.ml
index fb9d45a793..35487e09c1 100644
--- a/printing/printmod.ml
+++ b/printing/printmod.ml
@@ -113,13 +113,12 @@ let print_one_inductive env sigma mib ((_,i) as ind) =
let instantiate_cumulativity_info cumi =
let open Univ in
let univs = ACumulativityInfo.univ_context cumi in
- let subtyp = ACumulativityInfo.subtyp_context cumi in
let expose ctx =
let inst = AUContext.instance ctx in
let cst = AUContext.instantiate inst ctx in
UContext.make (inst, cst)
in
- CumulativityInfo.make (expose univs, expose subtyp)
+ CumulativityInfo.make (expose univs, ACumulativityInfo.variance cumi)
let print_mutual_inductive env mind mib udecl =
let inds = List.init (Array.length mib.mind_packets) (fun x -> (mind, x))
diff --git a/proofs/clenv.ml b/proofs/clenv.ml
index 16798a1d57..9e06d913b7 100644
--- a/proofs/clenv.ml
+++ b/proofs/clenv.ml
@@ -498,7 +498,7 @@ let clenv_unify_binding_type clenv c t u =
let clenv_assign_binding clenv k c =
let k_typ = clenv_hnf_constr clenv (clenv_meta_type clenv k) in
- let c_typ = nf_betaiota clenv.evd (clenv_get_type_of clenv c) in
+ let c_typ = nf_betaiota clenv.env clenv.evd (clenv_get_type_of clenv c) in
let status,clenv',c = clenv_unify_binding_type clenv c c_typ k_typ in
let c = EConstr.Unsafe.to_constr c in
{ clenv' with evd = meta_assign k (c,(Conv,status)) clenv'.evd }
diff --git a/proofs/logic.ml b/proofs/logic.ml
index 1d86a09092..5ff5fa38ad 100644
--- a/proofs/logic.ml
+++ b/proofs/logic.ml
@@ -334,7 +334,7 @@ let rec mk_refgoals sigma goal goalacc conclty trm =
else
match kind trm with
| Meta _ ->
- let conclty = nf_betaiota sigma (EConstr.of_constr conclty) in
+ let conclty = nf_betaiota env sigma (EConstr.of_constr conclty) in
if !check && occur_meta sigma conclty then
raise (RefinerError (env, sigma, MetaInType conclty));
let (gl,ev,sigma) = mk_goal hyps conclty in
@@ -416,7 +416,7 @@ and mk_hdgoals sigma goal goalacc trm =
match kind trm with
| Cast (c,_, ty) when isMeta c ->
check_typability env sigma ty;
- let (gl,ev,sigma) = mk_goal hyps (nf_betaiota sigma (EConstr.of_constr ty)) in
+ let (gl,ev,sigma) = mk_goal hyps (nf_betaiota env sigma (EConstr.of_constr ty)) in
let ev = EConstr.Unsafe.to_constr ev in
gl::goalacc,ty,sigma,ev
diff --git a/proofs/proof_global.ml b/proofs/proof_global.ml
index d04bdb6521..fc94a10132 100644
--- a/proofs/proof_global.ml
+++ b/proofs/proof_global.ml
@@ -485,7 +485,10 @@ let update_global_env () =
(* XXX: Bullet hook, should be really moved elsewhere *)
let _ =
let hook n =
- let prf = give_me_the_proof () in
- (Proof_bullet.suggest prf) in
+ try
+ let prf = give_me_the_proof () in
+ (Proof_bullet.suggest prf)
+ with NoCurrentProof -> mt ()
+ in
Proofview.set_nosuchgoals_hook hook
diff --git a/proofs/tacmach.ml b/proofs/tacmach.ml
index d415412510..bdcb4868bf 100644
--- a/proofs/tacmach.ml
+++ b/proofs/tacmach.ml
@@ -87,7 +87,7 @@ let pf_e_reduce = pf_apply
let pf_whd_all = pf_reduce whd_all
let pf_hnf_constr = pf_reduce hnf_constr
let pf_nf = pf_reduce simpl
-let pf_nf_betaiota = pf_reduce (fun _ -> nf_betaiota)
+let pf_nf_betaiota = pf_reduce nf_betaiota
let pf_compute = pf_reduce compute
let pf_unfoldn ubinds = pf_reduce (unfoldn ubinds)
let pf_unsafe_type_of = pf_reduce unsafe_type_of
diff --git a/stm/stm.ml b/stm/stm.ml
index 5f4fe6565d..b5848c662c 100644
--- a/stm/stm.ml
+++ b/stm/stm.ml
@@ -26,31 +26,50 @@ open Vernacexpr
module AsyncOpts = struct
- let async_proofs_n_workers = ref 1
- let async_proofs_n_tacworkers = ref 2
-
type cache = Force
- let async_proofs_cache : cache option ref = ref None
-
type async_proofs = APoff | APonLazy | APon
- let async_proofs_mode = ref APoff
+ type tac_error_filter = [ `None | `Only of string list | `All ]
- let async_proofs_private_flags = ref None
- let async_proofs_full = ref false
- let async_proofs_never_reopen_branch = ref false
+ type stm_opt = {
+ async_proofs_n_workers : int;
+ async_proofs_n_tacworkers : int;
- type tac_error_filter = [ `None | `Only of string list | `All ]
- let async_proofs_tac_error_resilience = ref (`Only [ "curly" ])
- let async_proofs_cmd_error_resilience = ref true
+ async_proofs_cache : cache option;
+ async_proofs_mode : async_proofs;
+
+ async_proofs_private_flags : string option;
+ async_proofs_full : bool;
+ async_proofs_never_reopen_branch : bool;
- let async_proofs_delegation_threshold = ref 0.03
+ async_proofs_tac_error_resilience : tac_error_filter;
+ async_proofs_cmd_error_resilience : bool;
+ async_proofs_delegation_threshold : float;
+ }
+ let default_opts = {
+ async_proofs_n_workers = 1;
+ async_proofs_n_tacworkers = 2;
+
+ async_proofs_cache = None;
+
+ async_proofs_mode = APoff;
+
+ async_proofs_private_flags = None;
+ async_proofs_full = false;
+ async_proofs_never_reopen_branch = false;
+
+ async_proofs_tac_error_resilience = `Only [ "curly" ];
+ async_proofs_cmd_error_resilience = true;
+ async_proofs_delegation_threshold = 0.03;
+ }
+
+ let cur_opt = ref default_opts
end
open AsyncOpts
-let async_proofs_is_master () =
- !async_proofs_mode = APon &&
+let async_proofs_is_master opt =
+ opt.async_proofs_mode = APon &&
!Flags.async_proofs_worker_id = "master"
(* Protect against state changes *)
@@ -547,8 +566,8 @@ end = struct (* {{{ *)
let reachable id = reachable !vcs id
let mk_branch_name { expr = x } = Branch.make
(match Vernacprop.under_control x with
- | VernacDefinition (_,((_,i),_),_) -> Id.to_string i
- | VernacStartTheoremProof (_,[Some ((_,i),_),_]) -> Id.to_string i
+ | VernacDefinition (_,((_, Name i),_),_) -> Id.to_string i
+ | VernacStartTheoremProof (_,[((_,i),_),_]) -> Id.to_string i
| _ -> "branch")
let edit_branch = Branch.make "edit"
let branch ?root ?pos name kind = vcs := branch !vcs ?root ?pos name kind
@@ -558,7 +577,7 @@ end = struct (* {{{ *)
| None -> raise Vcs_aux.Expired
let set_state id s =
(get_info id).state <- s;
- if async_proofs_is_master () then Hooks.(call state_ready id)
+ if async_proofs_is_master !cur_opt then Hooks.(call state_ready id)
let get_state id = (get_info id).state
let reached id =
let info = get_info id in
@@ -1150,7 +1169,7 @@ end = struct (* {{{ *)
" the \"-async-proofs-cache force\" option to Coq."))
let undo_vernac_classifier v =
- if VCS.is_interactive () = `No && !async_proofs_cache <> Some Force
+ if VCS.is_interactive () = `No && !cur_opt.async_proofs_cache <> Some Force
then undo_costly_in_batch_mode v;
try
match Vernacprop.under_control v with
@@ -1286,7 +1305,7 @@ let prev_node { id } =
let cur_node id = mk_doc_node id (VCS.visit id)
let is_block_name_enabled name =
- match !async_proofs_tac_error_resilience with
+ match !cur_opt.async_proofs_tac_error_resilience with
| `None -> false
| `All -> true
| `Only l -> List.mem name l
@@ -1294,7 +1313,7 @@ let is_block_name_enabled name =
let detect_proof_block id name =
let name = match name with None -> "indent" | Some x -> x in
if is_block_name_enabled name &&
- (async_proofs_is_master () || Flags.async_proofs_is_worker ())
+ (async_proofs_is_master !cur_opt || Flags.async_proofs_is_worker ())
then (
match cur_node id with
| None -> ()
@@ -1396,7 +1415,7 @@ end = struct (* {{{ *)
let task_match age t =
match age, t with
| Fresh, BuildProof { t_states } ->
- not !async_proofs_full ||
+ not !cur_opt.async_proofs_full ||
List.exists (fun x -> CList.mem_f Stateid.equal x !perspective) t_states
| Old my_states, States l ->
List.for_all (fun x -> CList.mem_f Stateid.equal x my_states) l
@@ -1433,7 +1452,7 @@ end = struct (* {{{ *)
feedback (InProgress ~-1);
t_assign (`Val pl);
record_pb_time ?loc:t_loc t_name time;
- if !async_proofs_full || t_drop
+ if !cur_opt.async_proofs_full || t_drop
then `Stay(t_states,[States t_states])
else `End
| Fresh, BuildProof { t_assign; t_loc; t_name; t_states },
@@ -1607,8 +1626,8 @@ end = struct (* {{{ *)
let queue = ref None
let init () =
- if async_proofs_is_master () then
- queue := Some (TaskQueue.create !async_proofs_n_workers)
+ if async_proofs_is_master !cur_opt then
+ queue := Some (TaskQueue.create !cur_opt.async_proofs_n_workers)
else
queue := Some (TaskQueue.create 0)
@@ -2074,7 +2093,7 @@ end = struct (* {{{ *)
QueryTask.({ t_where = prev; t_for = id; t_what = q }) ~cancel_switch
let init () = queue := Some (TaskQueue.create
- (if !async_proofs_full then 1 else 0))
+ (if !cur_opt.async_proofs_full then 1 else 0))
end (* }}} *)
@@ -2090,14 +2109,14 @@ let async_policy () =
let open Flags in
if is_universe_polymorphism () then false
else if VCS.is_interactive () = `Yes then
- (async_proofs_is_master () || !async_proofs_mode = APonLazy)
+ (async_proofs_is_master !cur_opt || !cur_opt.async_proofs_mode = APonLazy)
else
- (VCS.is_vio_doc () || !async_proofs_mode <> APoff)
+ (VCS.is_vio_doc () || !cur_opt.async_proofs_mode <> APoff)
let delegate name =
- get_hint_bp_time name >= !async_proofs_delegation_threshold
+ get_hint_bp_time name >= !cur_opt.async_proofs_delegation_threshold
|| VCS.is_vio_doc ()
- || !async_proofs_full
+ || !cur_opt.async_proofs_full
let warn_deprecated_nested_proofs =
CWarnings.create ~name:"deprecated-nested-proofs" ~category:"deprecated"
@@ -2212,7 +2231,7 @@ let collect_proof keep cur hd brkind id =
let rc = collect (Some cur) [] id in
if is_empty rc then make_sync `AlreadyEvaluated rc
else if (keep == VtKeep || keep == VtKeepAsAxiom) &&
- (not(State.is_cached_and_valid id) || !async_proofs_full)
+ (not(State.is_cached_and_valid id) || !cur_opt.async_proofs_full)
then check_policy rc
else make_sync `AlreadyEvaluated rc
@@ -2294,9 +2313,9 @@ let known_state ?(redefine_qed=false) ~cache id =
(* Absorb tactic errors from f () *)
let resilient_tactic id blockname f =
- if !async_proofs_tac_error_resilience = `None ||
- (async_proofs_is_master () &&
- !async_proofs_mode = APoff)
+ if !cur_opt.async_proofs_tac_error_resilience = `None ||
+ (async_proofs_is_master !cur_opt &&
+ !cur_opt.async_proofs_mode = APoff)
then f ()
else
try f ()
@@ -2305,9 +2324,9 @@ let known_state ?(redefine_qed=false) ~cache id =
error_absorbing_tactic id blockname ie in
(* Absorb errors from f x *)
let resilient_command f x =
- if not !async_proofs_cmd_error_resilience ||
- (async_proofs_is_master () &&
- !async_proofs_mode = APoff)
+ if not !cur_opt.async_proofs_cmd_error_resilience ||
+ (async_proofs_is_master !cur_opt &&
+ !cur_opt.async_proofs_mode = APoff)
then f x
else
try f x
@@ -2353,10 +2372,10 @@ let known_state ?(redefine_qed=false) ~cache id =
resilient_tactic id cblock (fun () ->
reach ~cache:`Shallow view.next;
Partac.vernac_interp ~solve ~abstract ~cancel_switch
- !async_proofs_n_tacworkers view.next id x)
+ !cur_opt.async_proofs_n_tacworkers view.next id x)
), cache, true
| `Cmd { cast = x; cqueue = `QueryQueue cancel_switch }
- when async_proofs_is_master () -> (fun () ->
+ when async_proofs_is_master !cur_opt -> (fun () ->
reach view.next;
Query.vernac_interp ~cancel_switch view.next id x
), cache, false
@@ -2370,7 +2389,7 @@ let known_state ?(redefine_qed=false) ~cache id =
if eff then update_global_env ()
), (if eff then `Yes else cache), true
| `Cmd { cast = x; ceff = eff } -> (fun () ->
- (match !async_proofs_mode with
+ (match !cur_opt.async_proofs_mode with
| APon | APonLazy ->
resilient_command reach view.next
| APoff -> reach view.next);
@@ -2500,7 +2519,7 @@ let known_state ?(redefine_qed=false) ~cache id =
), cache, true
in
let cache_step =
- if !async_proofs_cache = Some Force then `Yes
+ if !cur_opt.async_proofs_cache = Some Force then `Yes
else cache_step in
State.define ?safe_id
~cache:cache_step ~redefine:redefine_qed ~feedback_processed step id;
@@ -2513,15 +2532,28 @@ end (* }}} *)
(********************************* STM API ************************************)
(******************************************************************************)
+(* Main initalization routine *)
type stm_init_options = {
+ (* The STM will set some internal flags differently depending on the
+ specified [doc_type]. This distinction should dissappear at some
+ some point. *)
doc_type : stm_doc_type;
+
+ (* Initial load path in scope for the document. Usually extracted
+ from -R options / _CoqProject *)
+ iload_path : Mltop.coq_path list;
+
+ (* Require [require_libs] before the initial state is
+ ready. Parameters follow [Library], that is to say,
+ [lib,prefix,import_export] means require library [lib] from
+ optional [prefix] and [import_export] if [Some false/Some true]
+ is used. *)
require_libs : (string * string option * bool option) list;
-(*
- fb_handler : Feedback.feedback -> unit;
- iload_path : (string list * string * bool) list;
- implicit_std : bool;
-*)
+
+ (* STM options that apply to the current document. *)
+ stm_options : AsyncOpts.stm_opt;
}
+(* fb_handler : Feedback.feedback -> unit; *)
(*
let doc_type_module_name (std : stm_doc_type) =
@@ -2531,10 +2563,11 @@ let doc_type_module_name (std : stm_doc_type) =
*)
let init_core () =
- if !async_proofs_mode = APon then Control.enable_thread_delay := true;
+ if !cur_opt.async_proofs_mode = APon then Control.enable_thread_delay := true;
State.register_root_state ()
-let new_doc { doc_type ; require_libs } =
+let new_doc { doc_type ; iload_path; require_libs; stm_options } =
+
let load_objs libs =
let rq_file (dir, from, exp) =
let mp = Libnames.(Qualid (Loc.tag @@ qualid_of_string dir)) in
@@ -2543,11 +2576,19 @@ let new_doc { doc_type ; require_libs } =
List.(iter rq_file (rev libs))
in
+ (* Set the options from the new documents *)
+ AsyncOpts.cur_opt := stm_options;
+
(* We must reset the whole state before creating a document! *)
State.restore_root_state ();
let doc = VCS.init doc_type Stateid.initial in
+ (* Set load path; important, this has to happen before we declare
+ the library below as [Declaremods/Library] will infer the module
+ name by looking at the load path! *)
+ List.iter Mltop.add_coq_path iload_path;
+
begin match doc_type with
| Interactive ln ->
Safe_typing.allow_delayed_constants := true;
@@ -2564,16 +2605,18 @@ let new_doc { doc_type ; require_libs } =
VCS.set_ldir ldir;
set_compilation_hints ln
end;
+
+ (* Import initial libraries. *)
load_objs require_libs;
- (* We record the state here! *)
+ (* We record the state at this point! *)
State.define ~cache:`Yes ~redefine:true (fun () -> ()) Stateid.initial;
Backtrack.record ();
Slaves.init ();
- if async_proofs_is_master () then begin
+ if async_proofs_is_master !cur_opt then begin
stm_prerr_endline (fun () -> "Initializing workers");
Query.init ();
- let opts = match !async_proofs_private_flags with
+ let opts = match !cur_opt.async_proofs_private_flags with
| None -> []
| Some s -> Str.split_delim (Str.regexp ",") s in
begin try
@@ -2772,7 +2815,7 @@ let process_transaction ?(newtip=Stateid.fresh ()) ?(part_of_script=true)
| VtQuery (true, route), w ->
let id = VCS.new_node ~id:newtip () in
let queue =
- if !async_proofs_full then `QueryQueue (ref false)
+ if !cur_opt.async_proofs_full then `QueryQueue (ref false)
else if VCS.is_vio_doc () &&
VCS.((get_branch head).kind = `Master) &&
may_pierce_opaque (Vernacprop.under_control x.expr)
@@ -3104,7 +3147,7 @@ let edit_at ~doc id =
VCS.delete_boxes_of id;
VCS.gc ();
VCS.print ();
- if not !async_proofs_full then
+ if not !cur_opt.async_proofs_full then
Reach.known_state ~cache:(VCS.is_interactive ()) id;
VCS.checkout_shallowest_proof_branch ();
`NewTip in
@@ -3120,7 +3163,7 @@ let edit_at ~doc id =
| _, Some _, None -> assert false
| false, Some { qed = qed_id ; lemma = start }, Some(mode,bn) ->
let tip = VCS.cur_tip () in
- if has_failed qed_id && is_pure qed_id && not !async_proofs_never_reopen_branch
+ if has_failed qed_id && is_pure qed_id && not !cur_opt.async_proofs_never_reopen_branch
then reopen_branch start id mode qed_id tip bn
else backto id (Some bn)
| true, Some { qed = qed_id }, Some(mode,bn) ->
diff --git a/stm/stm.mli b/stm/stm.mli
index 587b756422..8a4de34b4a 100644
--- a/stm/stm.mli
+++ b/stm/stm.mli
@@ -10,6 +10,33 @@ open Names
(** state-transaction-machine interface *)
+(* Flags *)
+module AsyncOpts : sig
+
+ type cache = Force
+ type async_proofs = APoff | APonLazy | APon
+ type tac_error_filter = [ `None | `Only of string list | `All ]
+
+ type stm_opt = {
+ async_proofs_n_workers : int;
+ async_proofs_n_tacworkers : int;
+
+ async_proofs_cache : cache option;
+ async_proofs_mode : async_proofs;
+
+ async_proofs_private_flags : string option;
+ async_proofs_full : bool;
+ async_proofs_never_reopen_branch : bool;
+
+ async_proofs_tac_error_resilience : tac_error_filter;
+ async_proofs_cmd_error_resilience : bool;
+ async_proofs_delegation_threshold : float;
+ }
+
+ val default_opts : stm_opt
+
+end
+
(** The STM doc type determines some properties such as what
uncompleted proofs are allowed and recording of aux files. *)
type stm_doc_type =
@@ -19,14 +46,26 @@ type stm_doc_type =
(* Main initalization routine *)
type stm_init_options = {
+ (* The STM will set some internal flags differently depending on the
+ specified [doc_type]. This distinction should dissappear at some
+ some point. *)
doc_type : stm_doc_type;
+
+ (* Initial load path in scope for the document. Usually extracted
+ from -R options / _CoqProject *)
+ iload_path : Mltop.coq_path list;
+
+ (* Require [require_libs] before the initial state is
+ ready. Parameters follow [Library], that is to say,
+ [lib,prefix,import_export] means require library [lib] from
+ optional [prefix] and [import_export] if [Some false/Some true]
+ is used. *)
require_libs : (string * string option * bool option) list;
-(*
- fb_handler : Feedback.feedback -> unit;
- iload_path : (string list * string * bool) list;
- implicit_std : bool;
-*)
+
+ (* STM options that apply to the current document. *)
+ stm_options : AsyncOpts.stm_opt;
}
+(* fb_handler : Feedback.feedback -> unit; *)
(** The type of a STM document *)
type doc
@@ -228,27 +267,3 @@ val get_all_proof_names : doc:doc -> Id.t list
(** Enable STM debugging *)
val stm_debug : bool ref
-
-(* Flags *)
-module AsyncOpts : sig
-
- (* Defaults for worker creation *)
- val async_proofs_n_workers : int ref
- val async_proofs_n_tacworkers : int ref
-
- type async_proofs = APoff | APonLazy | APon
- val async_proofs_mode : async_proofs ref
-
- type cache = Force
- val async_proofs_cache : cache option ref
-
- val async_proofs_private_flags : string option ref
- val async_proofs_full : bool ref
- val async_proofs_never_reopen_branch : bool ref
-
- type tac_error_filter = [ `None | `Only of string list | `All ]
- val async_proofs_tac_error_resilience : tac_error_filter ref
- val async_proofs_cmd_error_resilience : bool ref
- val async_proofs_delegation_threshold : float ref
-
-end
diff --git a/stm/vernac_classifier.ml b/stm/vernac_classifier.ml
index 99b56d4846..cbbb54e45b 100644
--- a/stm/vernac_classifier.ml
+++ b/stm/vernac_classifier.ml
@@ -48,6 +48,11 @@ let declare_vernac_classifier
=
classifiers := !classifiers @ [s,f]
+let idents_of_name : Names.Name.t -> Names.Id.t list =
+ function
+ | Names.Anonymous -> []
+ | Names.Name n -> [n]
+
let classify_vernac e =
let static_classifier ~poly e = match e with
(* Univ poly compatibility: we run it now, so that we can just
@@ -83,18 +88,14 @@ let classify_vernac e =
| VernacSetOption (["Default";"Proof";"Using"],_) -> VtSideff [], VtNow
(* StartProof *)
| VernacDefinition ((Decl_kinds.DoDischarge,_),((_,i),_),ProveBody _) ->
- VtStartProof(default_proof_mode (),Doesn'tGuaranteeOpacity,[i]), VtLater
+ VtStartProof(default_proof_mode (),Doesn'tGuaranteeOpacity, idents_of_name i), VtLater
| VernacDefinition (_,((_,i),_),ProveBody _) ->
let guarantee = if poly then Doesn'tGuaranteeOpacity else GuaranteesOpacity in
- VtStartProof(default_proof_mode (),guarantee,[i]), VtLater
+ VtStartProof(default_proof_mode (),guarantee, idents_of_name i), VtLater
| VernacStartTheoremProof (_,l) ->
- let ids =
- CList.map_filter (function (Some ((_,i),pl), _) -> Some i | _ -> None) l in
+ let ids = List.map (fun (((_, i), _), _) -> i) l in
let guarantee = if poly then Doesn'tGuaranteeOpacity else GuaranteesOpacity in
VtStartProof (default_proof_mode (),guarantee,ids), VtLater
- | VernacGoal _ ->
- let guarantee = if poly then Doesn'tGuaranteeOpacity else GuaranteesOpacity in
- VtStartProof (default_proof_mode (),guarantee,[]), VtLater
| VernacFixpoint (discharge,l) ->
let guarantee =
if discharge = Decl_kinds.DoDischarge || poly then Doesn'tGuaranteeOpacity
@@ -121,7 +122,7 @@ let classify_vernac e =
| VernacAssumption (_,_,l) ->
let ids = List.flatten (List.map (fun (_,(l,_)) -> List.map (fun (id, _) -> snd id) l) l) in
VtSideff ids, VtLater
- | VernacDefinition (_,((_,id),_),DefineBody _) -> VtSideff [id], VtLater
+ | VernacDefinition (_,((_,id),_),DefineBody _) -> VtSideff (idents_of_name id), VtLater
| VernacInductive (_, _,_,l) ->
let ids = List.map (fun (((_,((_,id),_)),_,_,_,cl),_) -> id :: match cl with
| Constructors l -> List.map (fun (_,((_,id),_)) -> id) l
diff --git a/tactics/class_tactics.ml b/tactics/class_tactics.ml
index 9e4d132d4e..cfadfc5353 100644
--- a/tactics/class_tactics.ml
+++ b/tactics/class_tactics.ml
@@ -1569,7 +1569,7 @@ let _ =
Hook.set Typeclasses.solve_all_instances_hook solve_inst
let resolve_one_typeclass env ?(sigma=Evd.empty) gl unique =
- let nc, gl, subst, _, _ = Evarutil.push_rel_context_to_named_context env sigma gl in
+ let nc, gl, subst, _ = Evarutil.push_rel_context_to_named_context env sigma gl in
let (gl,t,sigma) =
Goal.V82.mk_goal sigma nc gl Store.empty in
let (ev, _) = destEvar sigma t in
diff --git a/tactics/equality.ml b/tactics/equality.ml
index 22073d39b6..450d684364 100644
--- a/tactics/equality.ml
+++ b/tactics/equality.ml
@@ -1583,7 +1583,7 @@ let subst_tuple_term env sigma dep_pair1 dep_pair2 b =
let body = mkApp (lambda_create env sigma (typ,pred_body),[|dep_pair1|]) in
let expected_goal = beta_applist sigma (abst_B,List.map fst e2_list) in
(* Simulate now the normalisation treatment made by Logic.mk_refgoals *)
- let expected_goal = nf_betaiota sigma expected_goal in
+ let expected_goal = nf_betaiota env sigma expected_goal in
(* Retype to get universes right *)
let sigma, expected_goal_ty = Typing.type_of env sigma expected_goal in
let sigma, _ = Typing.type_of env sigma body in
diff --git a/tactics/tactics.ml b/tactics/tactics.ml
index 4ee0a8a7b2..9fded04dbe 100644
--- a/tactics/tactics.ml
+++ b/tactics/tactics.ml
@@ -471,7 +471,7 @@ let internal_cut_gen ?(check=true) dir replace id t =
(if check && mem_named_context_val id sign then
user_err (str "Variable " ++ Id.print id ++ str " is already declared.");
push_named_context_val (LocalAssum (id,t)) sign,t,concl,sigma) in
- let nf_t = nf_betaiota sigma t in
+ let nf_t = nf_betaiota env sigma t in
Proofview.tclTHEN
(Proofview.Unsafe.tclEVARS sigma)
(Refine.refine ~typecheck:false begin fun sigma ->
@@ -1728,7 +1728,7 @@ let general_apply with_delta with_destruct with_evars clear_flag (loc,(c,lbind :
let env = Proofview.Goal.env gl in
let sigma = Tacmach.New.project gl in
- let thm_ty0 = nf_betaiota sigma (Retyping.get_type_of env sigma c) in
+ let thm_ty0 = nf_betaiota env sigma (Retyping.get_type_of env sigma c) in
let try_apply thm_ty nprod =
try
let n = nb_prod_modulo_zeta sigma thm_ty - nprod in
@@ -1864,7 +1864,7 @@ let explain_unable_to_apply_lemma ?loc env sigma thm innerclause =
str "."))
let apply_in_once_main flags innerclause env sigma (loc,d,lbind) =
- let thm = nf_betaiota sigma (Retyping.get_type_of env sigma d) in
+ let thm = nf_betaiota env sigma (Retyping.get_type_of env sigma d) in
let rec aux clause =
try progress_with_clause flags innerclause clause
with e when CErrors.noncritical e ->
@@ -2162,7 +2162,7 @@ let apply_type newcl args =
let env = Proofview.Goal.env gl in
let store = Proofview.Goal.extra gl in
Refine.refine ~typecheck:false begin fun sigma ->
- let newcl = nf_betaiota sigma newcl (* As in former Logic.refine *) in
+ let newcl = nf_betaiota env sigma newcl (* As in former Logic.refine *) in
let (sigma, ev) =
Evarutil.new_evar env sigma ~principal:true ~store newcl in
(sigma, applist (ev, args))
diff --git a/test-suite/bugs/closed/5286.v b/test-suite/bugs/closed/5286.v
new file mode 100644
index 0000000000..98d4e5c968
--- /dev/null
+++ b/test-suite/bugs/closed/5286.v
@@ -0,0 +1,9 @@
+Set Primitive Projections.
+
+CoInductive R := mkR { p : unit }.
+
+CoFixpoint foo := mkR tt.
+
+Check (eq_refl tt : p foo = tt).
+Check (eq_refl tt <: p foo = tt).
+Check (eq_refl tt <<: p foo = tt).
diff --git a/test-suite/bugs/closed/6534.v b/test-suite/bugs/closed/6534.v
new file mode 100644
index 0000000000..f5013994c5
--- /dev/null
+++ b/test-suite/bugs/closed/6534.v
@@ -0,0 +1,7 @@
+Goal forall x : nat, x = x.
+Proof.
+intros x.
+refine ((fun x x => _ tt) tt tt).
+let t := match goal with [ |- ?P ] => P end in
+let _ := type of t in
+idtac.
diff --git a/test-suite/coqchk/include.v b/test-suite/coqchk/include.v
new file mode 100644
index 0000000000..6232c1b80f
--- /dev/null
+++ b/test-suite/coqchk/include.v
@@ -0,0 +1,11 @@
+(* See https://github.com/coq/coq/issues/5747 *)
+Module Type S.
+End S.
+
+Module N.
+Inductive I := .
+End N.
+
+Module M : S.
+ Include N.
+End M.
diff --git a/test-suite/coqchk/primproj2.v b/test-suite/coqchk/primproj2.v
new file mode 100644
index 0000000000..f73c627ee4
--- /dev/null
+++ b/test-suite/coqchk/primproj2.v
@@ -0,0 +1,10 @@
+Set Primitive Projections.
+
+Record Pack (A : Type) := pack { unpack : A }.
+
+Definition p : Pack bool.
+Proof.
+refine (pack _ true).
+Qed.
+
+Definition boom : unpack bool p = let u := unpack _ in u p := eq_refl.
diff --git a/test-suite/output/ErrorInCanonicalStructures.out b/test-suite/output/ErrorInCanonicalStructures.out
new file mode 100644
index 0000000000..73da4f44f8
--- /dev/null
+++ b/test-suite/output/ErrorInCanonicalStructures.out
@@ -0,0 +1,5 @@
+File "stdin", line 3, characters 0-24:
+Error:
+Could not declare a canonical structure Foo.
+Expected an instance of a record or structure.
+
diff --git a/test-suite/output/ErrorInCanonicalStructures.v b/test-suite/output/ErrorInCanonicalStructures.v
new file mode 100644
index 0000000000..49597df6f7
--- /dev/null
+++ b/test-suite/output/ErrorInCanonicalStructures.v
@@ -0,0 +1,3 @@
+Record Foo := MkFoo { field1 : nat; field2 : nat -> nat }.
+
+Canonical Structure Foo.
diff --git a/test-suite/output/ErrorInCanonicalStructures2.out b/test-suite/output/ErrorInCanonicalStructures2.out
new file mode 100644
index 0000000000..63a2871b82
--- /dev/null
+++ b/test-suite/output/ErrorInCanonicalStructures2.out
@@ -0,0 +1,5 @@
+File "stdin", line 3, characters 0-24:
+Error:
+Could not declare a canonical structure bar.
+Expected an instance of a record or structure.
+
diff --git a/test-suite/output/ErrorInCanonicalStructures2.v b/test-suite/output/ErrorInCanonicalStructures2.v
new file mode 100644
index 0000000000..10ee177aaf
--- /dev/null
+++ b/test-suite/output/ErrorInCanonicalStructures2.v
@@ -0,0 +1,3 @@
+Definition bar := 99.
+
+Canonical Structure bar.
diff --git a/test-suite/output/UnivBinders.out b/test-suite/output/UnivBinders.out
index d6d410d1ae..668b4e5788 100644
--- a/test-suite/output/UnivBinders.out
+++ b/test-suite/output/UnivBinders.out
@@ -5,7 +5,7 @@ PWrap has primitive projections with eta conversion.
For PWrap: Argument scope is [type_scope]
For pwrap: Argument scopes are [type_scope _]
punwrap@{u} =
-fun (A : Type@{u}) (p : PWrap@{u} A) => punwrap _ p
+fun (A : Type@{u}) (p : PWrap@{u} A) => p.(punwrap)
: forall A : Type@{u}, PWrap@{u} A -> A
(* u |= *)
diff --git a/test-suite/success/cumulativity.v b/test-suite/success/cumulativity.v
index 0ee85712e2..1fb3abfe41 100644
--- a/test-suite/success/cumulativity.v
+++ b/test-suite/success/cumulativity.v
@@ -45,6 +45,15 @@ Section TpLift.
End TpLift.
+Record Tp' := { tp' : Tp }.
+
+Definition CTp := Tp.
+(* here we have to reduce a constant to infer the correct subtyping. *)
+Record Tp'' := { tp'' : CTp }.
+
+Definition LiftTp'@{i j|i < j} : Tp'@{i} -> Tp'@{j} := fun x => x.
+Definition LiftTp''@{i j|i < j} : Tp''@{i} -> Tp''@{j} := fun x => x.
+
Lemma LiftC_Lem (t : Tp) : LiftTp t = t.
Proof. reflexivity. Qed.
@@ -98,3 +107,20 @@ Section down.
intros H f g Hfg. exact (H f g Hfg).
Defined.
End down.
+
+Record Arrow@{i j} := { arrow : Type@{i} -> Type@{j} }.
+
+Fail Definition arrow_lift@{i i' j j' | i' < i, j < j'}
+ : Arrow@{i j} -> Arrow@{i' j'}
+ := fun x => x.
+
+Definition arrow_lift@{i i' j j' | i' = i, j < j'}
+ : Arrow@{i j} -> Arrow@{i' j'}
+ := fun x => x.
+
+Inductive Mut1 A :=
+| Base1 : Type -> Mut1 A
+| Node1 : (A -> Mut2 A) -> Mut1 A
+with Mut2 A :=
+ | Base2 : Type -> Mut2 A
+ | Node2 : Mut1 A -> Mut2 A.
diff --git a/theories/Lists/List.v b/theories/Lists/List.v
index fbf992dbf4..eae2c52de3 100644
--- a/theories/Lists/List.v
+++ b/theories/Lists/List.v
@@ -2110,13 +2110,13 @@ Section Exists_Forall.
{Exists l} + {~ Exists l}.
Proof.
intro Pdec. induction l as [|a l' Hrec].
- - right. now rewrite Exists_nil.
+ - right. abstract now rewrite Exists_nil.
- destruct Hrec as [Hl'|Hl'].
* left. now apply Exists_cons_tl.
* destruct (Pdec a) as [Ha|Ha].
+ left. now apply Exists_cons_hd.
- + right. now inversion_clear 1.
- Qed.
+ + right. abstract now inversion 1.
+ Defined.
Inductive Forall : list A -> Prop :=
| Forall_nil : Forall nil
@@ -2152,9 +2152,9 @@ Section Exists_Forall.
- destruct Hrec as [Hl'|Hl'].
+ destruct (Pdec a) as [Ha|Ha].
* left. now apply Forall_cons.
- * right. now inversion_clear 1.
- + right. now inversion_clear 1.
- Qed.
+ * right. abstract now inversion 1.
+ + right. abstract now inversion 1.
+ Defined.
End One_predicate.
@@ -2179,6 +2179,16 @@ Section Exists_Forall.
* now apply Exists_cons_hd.
Qed.
+ Lemma neg_Forall_Exists_neg (P:A->Prop) (l:list A) :
+ (forall x:A, {P x} + { ~ P x }) ->
+ ~ Forall P l ->
+ Exists (fun x => ~ P x) l.
+ Proof.
+ intro Dec.
+ apply Exists_Forall_neg; intros.
+ destruct (Dec x); auto.
+ Qed.
+
Lemma Forall_Exists_dec (P:A->Prop) :
(forall x:A, {P x} + { ~ P x }) ->
forall l:list A,
@@ -2186,9 +2196,8 @@ Section Exists_Forall.
Proof.
intros Pdec l.
destruct (Forall_dec P Pdec l); [left|right]; trivial.
- apply Exists_Forall_neg; trivial.
- intro x. destruct (Pdec x); [now left|now right].
- Qed.
+ now apply neg_Forall_Exists_neg.
+ Defined.
Lemma Forall_impl : forall (P Q : A -> Prop), (forall a, P a -> Q a) ->
forall l, Forall P l -> Forall Q l.
diff --git a/toplevel/coqinit.ml b/toplevel/coqinit.ml
index 176dfb3c93..10205964a2 100644
--- a/toplevel/coqinit.ml
+++ b/toplevel/coqinit.ml
@@ -59,13 +59,23 @@ let load_rcfile ~time doc sid =
doc, sid)
(* Recursively puts dir in the LoadPath if -nois was not passed *)
-let add_stdlib_path ~load_init ~unix_path ~coq_root ~with_ml =
- let add_ml = if with_ml then Mltop.AddRecML else Mltop.AddNoML in
- Mltop.add_rec_path add_ml ~unix_path ~coq_root ~implicit:load_init
+let build_stdlib_path ~load_init ~unix_path ~coq_path ~with_ml =
+ let open Mltop in
+ let add_ml = if with_ml then AddRecML else AddNoML in
+ { recursive = true;
+ path_spec = VoPath { unix_path; coq_path ; has_ml = add_ml; implicit = load_init }
+ }
-let add_userlib_path ~unix_path =
- Mltop.add_rec_path Mltop.AddRecML ~unix_path
- ~coq_root:Libnames.default_root_prefix ~implicit:false
+let build_userlib_path ~unix_path =
+ let open Mltop in
+ { recursive = true;
+ path_spec = VoPath {
+ unix_path;
+ coq_path = Libnames.default_root_prefix;
+ has_ml = Mltop.AddRecML;
+ implicit = false;
+ }
+ }
(* Options -I, -I-as, and -R of the command line *)
let includes = ref []
@@ -74,51 +84,69 @@ let push_include s alias implicit =
let ml_includes = ref []
let push_ml_include s = ml_includes := s :: !ml_includes
-(* Initializes the LoadPath *)
-let init_load_path ~load_init =
+let ml_path_if c p =
+ let open Mltop in
+ let f x = { recursive = false; path_spec = MlPath x } in
+ if c then List.map f p else []
+
+(* LoadPath for toploop toplevels *)
+let toplevel_init_load_path () =
+ let coqlib = Envars.coqlib () in
+ (* NOTE: These directories are searched from last to first *)
+ (* first, developer specific directory to open *)
+ ml_path_if Coq_config.local [coqlib/"dev"] @
+
+ (* main loops *)
+ ml_path_if (Coq_config.local || !Flags.boot) [coqlib/"stm"; coqlib/"ide"] @
+ ml_path_if (System.exists_dir (coqlib/"toploop")) [coqlib/"toploop"]
+
+(* LoadPath for Coq user libraries *)
+let libs_init_load_path ~load_init =
+
+ let open Mltop in
let coqlib = Envars.coqlib () in
let user_contrib = coqlib/"user-contrib" in
let xdg_dirs = Envars.xdg_dirs ~warn:(fun x -> Feedback.msg_warning (str x)) in
let coqpath = Envars.coqpath in
- let coq_root = Names.DirPath.make [Libnames.coq_root] in
- (* NOTE: These directories are searched from last to first *)
- (* first, developer specific directory to open *)
- if Coq_config.local then
- Mltop.add_ml_dir (coqlib/"dev");
- (* main loops *)
- if Coq_config.local || !Flags.boot then begin
- Mltop.add_ml_dir (coqlib/"stm");
- Mltop.add_ml_dir (coqlib/"ide")
- end;
- if System.exists_dir (coqlib/"toploop") then
- Mltop.add_ml_dir (coqlib/"toploop");
- (* then standard library *)
- add_stdlib_path ~load_init ~unix_path:(coqlib/"theories") ~coq_root ~with_ml:false;
- (* then plugins *)
- add_stdlib_path ~load_init ~unix_path:(coqlib/"plugins") ~coq_root ~with_ml:true;
- (* then user-contrib *)
- if Sys.file_exists user_contrib then
- add_userlib_path ~unix_path:user_contrib;
- (* then directories in XDG_DATA_DIRS and XDG_DATA_HOME *)
- List.iter (fun s -> add_userlib_path ~unix_path:s) xdg_dirs;
- (* then directories in COQPATH *)
- List.iter (fun s -> add_userlib_path ~unix_path:s) coqpath;
- (* then current directory (not recursively!) *)
- Mltop.add_ml_dir ".";
- Loadpath.add_load_path "." Libnames.default_root_prefix ~implicit:false;
- (* additional loadpath, given with options -Q and -R *)
- List.iter
- (fun (unix_path, coq_root, implicit) ->
- Mltop.add_rec_path Mltop.AddNoML ~unix_path ~coq_root ~implicit)
- (List.rev !includes);
- (* additional ml directories, given with option -I *)
- List.iter Mltop.add_ml_dir (List.rev !ml_includes)
+ let coq_path = Names.DirPath.make [Libnames.coq_root] in
+
+ (* then standard library and plugins *)
+ [build_stdlib_path ~load_init ~unix_path:(coqlib/"theories") ~coq_path ~with_ml:false;
+ build_stdlib_path ~load_init ~unix_path:(coqlib/"plugins") ~coq_path ~with_ml:true ] @
+
+ (* then user-contrib *)
+ (if Sys.file_exists user_contrib then
+ [build_userlib_path ~unix_path:user_contrib] else []
+ ) @
+
+ (* then directories in XDG_DATA_DIRS and XDG_DATA_HOME and COQPATH *)
+ List.map (fun s -> build_userlib_path ~unix_path:s) (xdg_dirs @ coqpath) @
+
+ (* then current directory (not recursively!) *)
+ [ { recursive = false;
+ path_spec = VoPath { unix_path = ".";
+ coq_path = Libnames.default_root_prefix;
+ implicit = false;
+ has_ml = AddTopML }
+ } ] @
+
+ (* additional loadpaths, given with options -Q and -R *)
+ List.map
+ (fun (unix_path, coq_path, implicit) ->
+ { recursive = true;
+ path_spec = VoPath { unix_path; coq_path; has_ml = Mltop.AddNoML; implicit } })
+ (List.rev !includes) @
+
+ (* additional ml directories, given with option -I *)
+ List.map (fun s -> {recursive = false; path_spec = MlPath s}) (List.rev !ml_includes)
(* Initialises the Ocaml toplevel before launching it, so that it can
find the "include" file in the *source* directory *)
let init_ocaml_path () =
+ let open Mltop in
+ let lp s = { recursive = false; path_spec = MlPath s } in
let add_subdir dl =
- Mltop.add_ml_dir (List.fold_left (/) Envars.coqroot [dl])
+ Mltop.add_coq_path (lp (List.fold_left (/) Envars.coqroot [dl]))
in
- Mltop.add_ml_dir (Envars.coqlib ());
+ Mltop.add_coq_path (lp (Envars.coqlib ()));
List.iter add_subdir Coq_config.all_src_dirs
diff --git a/toplevel/coqinit.mli b/toplevel/coqinit.mli
index c3fd727541..0d2da84bb0 100644
--- a/toplevel/coqinit.mli
+++ b/toplevel/coqinit.mli
@@ -20,6 +20,9 @@ val push_include : string -> Names.DirPath.t -> bool -> unit
val push_ml_include : string -> unit
-val init_load_path : load_init:bool -> unit
-
val init_ocaml_path : unit -> unit
+
+(* LoadPath for toploop toplevels *)
+val toplevel_init_load_path : unit -> Mltop.coq_path list
+(* LoadPath for Coq user libraries *)
+val libs_init_load_path : load_init:bool -> Mltop.coq_path list
diff --git a/toplevel/coqtop.ml b/toplevel/coqtop.ml
index a3a4e20af8..400f7048d2 100644
--- a/toplevel/coqtop.ml
+++ b/toplevel/coqtop.ml
@@ -291,6 +291,8 @@ let ensure_exists f =
if not (Sys.file_exists f) then
compile_error (hov 0 (str "Can't find file" ++ spc () ++ str f))
+let top_stm_options = ref Stm.AsyncOpts.default_opts
+
(* Compile a vernac file *)
let compile ~time ~verbosely ~f_in ~f_out =
let check_pending_proofs () =
@@ -302,6 +304,9 @@ let compile ~time ~verbosely ~f_in ~f_out =
|> prlist_with_sep pr_comma Names.Id.print)
++ str ".")
in
+ let iload_path = Coqinit.libs_init_load_path ~load_init:!load_init in
+ let require_libs = require_libs () in
+ let stm_options = !top_stm_options in
match !compilation_mode with
| BuildVo ->
Flags.record_aux_file := true;
@@ -314,7 +319,9 @@ let compile ~time ~verbosely ~f_in ~f_out =
let doc, sid = Stm.(new_doc
{ doc_type = VoDoc long_f_dot_vo;
- require_libs = require_libs ()
+ iload_path;
+ require_libs;
+ stm_options;
}) in
let doc, sid = load_init_vernaculars ~time doc sid in
@@ -349,7 +356,9 @@ let compile ~time ~verbosely ~f_in ~f_out =
let doc, sid = Stm.(new_doc
{ doc_type = VioDoc long_f_dot_vio;
- require_libs = require_libs ()
+ iload_path;
+ require_libs;
+ stm_options;
}) in
let doc, sid = load_init_vernaculars ~time doc sid in
@@ -420,12 +429,15 @@ let set_vio_checking_j opt j =
prerr_endline "setting the J variable like in 'make vio2vo J=3'";
exit 1
-let schedule_vio_checking () =
- if !vio_files <> [] && !vio_checking then
- Vio_checking.schedule_vio_checking !vio_files_j !vio_files
+let schedule_vio () =
+ (* We must add update the loadpath here as the scheduling process
+ happens outside of the STM *)
+ let iload_path = Coqinit.libs_init_load_path ~load_init:!load_init in
+ List.iter Mltop.add_coq_path iload_path;
-let schedule_vio_compilation () =
- if !vio_files <> [] && not !vio_checking then
+ if !vio_checking then
+ Vio_checking.schedule_vio_checking !vio_files_j !vio_files
+ else
Vio_checking.schedule_vio_compilation !vio_files_j !vio_files
(******************************************************************************)
@@ -489,11 +501,12 @@ exception NoCoqLib
let usage batch =
begin
- try
- Envars.set_coqlib ~fail:(fun x -> raise NoCoqLib);
- Coqinit.init_load_path ~load_init:!load_init;
- with NoCoqLib -> usage_no_coqlib ()
+ try Envars.set_coqlib ~fail:(fun x -> raise NoCoqLib)
+ with NoCoqLib -> usage_no_coqlib ()
end;
+ let lp = Coqinit.toplevel_init_load_path () in
+ (* Necessary for finding the toplevels below *)
+ List.iter Mltop.add_coq_path lp;
if batch then Usage.print_usage_coqc ()
else begin
Mltop.load_ml_objects_raw_rex
@@ -650,23 +663,47 @@ let parse_args arglist =
(* Options with one arg *)
|"-coqlib" -> Flags.coqlib_spec:=true; Flags.coqlib:=(next ())
|"-async-proofs" ->
- Stm.AsyncOpts.async_proofs_mode := get_async_proofs_mode opt (next())
+ top_stm_options :=
+ { !top_stm_options with
+ Stm.AsyncOpts.async_proofs_mode = get_async_proofs_mode opt (next())
+ }
|"-async-proofs-j" ->
- Stm.AsyncOpts.async_proofs_n_workers := (get_int opt (next ()))
+ top_stm_options :=
+ { !top_stm_options with
+ Stm.AsyncOpts.async_proofs_n_workers = (get_int opt (next ()))
+ }
|"-async-proofs-cache" ->
- Stm.AsyncOpts.async_proofs_cache := get_cache opt (next ())
+ top_stm_options :=
+ { !top_stm_options with
+ Stm.AsyncOpts.async_proofs_cache = get_cache opt (next ())
+ }
|"-async-proofs-tac-j" ->
- Stm.AsyncOpts.async_proofs_n_tacworkers := (get_int opt (next ()))
+ top_stm_options :=
+ { !top_stm_options with
+ Stm.AsyncOpts.async_proofs_n_tacworkers = (get_int opt (next ()))
+ }
|"-async-proofs-worker-priority" ->
WorkerLoop.async_proofs_worker_priority := get_priority opt (next ())
|"-async-proofs-private-flags" ->
- Stm.AsyncOpts.async_proofs_private_flags := Some (next ());
+ top_stm_options :=
+ { !top_stm_options with
+ Stm.AsyncOpts.async_proofs_private_flags = Some (next ());
+ }
|"-async-proofs-tactic-error-resilience" ->
- Stm.AsyncOpts.async_proofs_tac_error_resilience := get_error_resilience opt (next ())
+ top_stm_options :=
+ { !top_stm_options with
+ Stm.AsyncOpts.async_proofs_tac_error_resilience = get_error_resilience opt (next ());
+ }
|"-async-proofs-command-error-resilience" ->
- Stm.AsyncOpts.async_proofs_cmd_error_resilience := get_bool opt (next ())
+ top_stm_options :=
+ { !top_stm_options with
+ Stm.AsyncOpts.async_proofs_cmd_error_resilience = get_bool opt (next ())
+ }
|"-async-proofs-delegation-threshold" ->
- Stm.AsyncOpts.async_proofs_delegation_threshold:= get_float opt (next ())
+ top_stm_options :=
+ { !top_stm_options with
+ Stm.AsyncOpts.async_proofs_delegation_threshold = get_float opt (next ())
+ }
|"-worker-id" -> set_worker_id opt (next ())
|"-compat" ->
let v = G_vernac.parse_compat_version ~allow_old:false (next ()) in
@@ -706,9 +743,15 @@ let parse_args arglist =
|"-async-queries-always-delegate"
|"-async-proofs-always-delegate"
|"-async-proofs-full" ->
- Stm.AsyncOpts.async_proofs_full := true;
+ top_stm_options :=
+ { !top_stm_options with
+ Stm.AsyncOpts.async_proofs_full = true;
+ }
|"-async-proofs-never-reopen-branch" ->
- Stm.AsyncOpts.async_proofs_never_reopen_branch := true;
+ top_stm_options :=
+ { !top_stm_options with
+ Stm.AsyncOpts.async_proofs_never_reopen_branch = true;
+ }
|"-batch" -> set_batch_mode ()
|"-test-mode" -> Flags.test_mode := true
|"-beautify" -> Flags.beautify := true
@@ -776,7 +819,8 @@ let init_toplevel arglist =
if !print_config then (Envars.print_config stdout Coq_config.all_src_dirs; exit (exitcode ()));
if !print_tags then (print_style_tags (); exit (exitcode ()));
if !filter_opts then (print_string (String.concat "\n" extras); exit 0);
- Coqinit.init_load_path ~load_init:!load_init;
+ let top_lp = Coqinit.toplevel_init_load_path () in
+ List.iter Mltop.add_coq_path top_lp;
Option.iter Mltop.load_ml_object_raw !toploop;
let extras = !toploop_init extras in
if not (CList.is_empty extras) then begin
@@ -805,13 +849,22 @@ let init_toplevel arglist =
We split the codepath here depending whether coqtop is called
in interactive mode or not. *)
- if (not !batch_mode || CList.is_empty !compile_list)
+ (* The condition for starting the interactive mode is a bit
+ convoluted, we should really refactor batch/compilation_mode
+ more. *)
+ if (not !batch_mode
+ || CList.(is_empty !compile_list && is_empty !vio_files && is_empty !vio_tasks))
(* Interactive *)
then begin
+ let iload_path = Coqinit.libs_init_load_path ~load_init:!load_init in
+ let require_libs = require_libs () in
+ let stm_options = !top_stm_options in
try
let doc, sid = Stm.(new_doc
{ doc_type = Interactive !toplevel_name;
- require_libs = require_libs ()
+ iload_path;
+ require_libs;
+ stm_options;
}) in
Some (load_init_vernaculars ~time:!measure_time doc sid)
with any -> flush_all(); fatal_error any
@@ -819,8 +872,9 @@ let init_toplevel arglist =
end else begin
try
compile_files ~time:!measure_time;
- schedule_vio_checking ();
- schedule_vio_compilation ();
+ (* Vio compile pass *)
+ if !vio_files <> [] then schedule_vio ();
+ (* Vio task pass *)
check_vio_tasks ();
(* Allow the user to output an arbitrary state *)
outputstate ();
diff --git a/vernac/comInductive.ml b/vernac/comInductive.ml
index 1c8677e9cd..41474fc638 100644
--- a/vernac/comInductive.ml
+++ b/vernac/comInductive.ml
@@ -340,7 +340,7 @@ let interp_mutual_inductive (paramsl,indl) notations cum poly prv finite =
match uctx with
| Polymorphic_const_entry uctx ->
if cum then
- Cumulative_ind_entry (Universes.univ_inf_ind_from_universe_context uctx)
+ Cumulative_ind_entry (Univ.CumulativityInfo.from_universe_context uctx)
else Polymorphic_ind_entry uctx
| Monomorphic_const_entry uctx ->
Monomorphic_ind_entry uctx
@@ -356,7 +356,7 @@ let interp_mutual_inductive (paramsl,indl) notations cum poly prv finite =
}
in
(if poly && cum then
- Inductiveops.infer_inductive_subtyping env_ar sigma mind_ent
+ InferCumulativity.infer_inductive env_ar mind_ent
else mind_ent), Evd.universe_binders sigma, impls
(* Very syntactical equality *)
diff --git a/vernac/explainErr.ml b/vernac/explainErr.ml
index d328ad0cf8..fc34957968 100644
--- a/vernac/explainErr.ml
+++ b/vernac/explainErr.ml
@@ -32,6 +32,7 @@ let explain_exn_default = function
| Sys_error msg -> hov 0 (str "System error: " ++ guill msg)
| Out_of_memory -> hov 0 (str "Out of memory.")
| Stack_overflow -> hov 0 (str "Stack overflow.")
+ | Dynlink.Error e -> hov 0 (str "Dynlink error: " ++ str Dynlink.(error_message e))
| Timeout -> hov 0 (str "Timeout!")
| Sys.Break -> hov 0 (fnl () ++ str "User interrupt.")
(* Exceptions with pre-evaluated error messages *)
diff --git a/vernac/himsg.ml b/vernac/himsg.ml
index e8c5aeedd1..f00c1e6046 100644
--- a/vernac/himsg.ml
+++ b/vernac/himsg.ml
@@ -83,12 +83,12 @@ let rec contract3' env sigma a b c = function
(** Ad-hoc reductions *)
-let j_nf_betaiotaevar sigma j =
+let j_nf_betaiotaevar env sigma j =
{ uj_val = j.uj_val;
- uj_type = Reductionops.nf_betaiota sigma j.uj_type }
+ uj_type = Reductionops.nf_betaiota env sigma j.uj_type }
-let jv_nf_betaiotaevar sigma jl =
- Array.map (fun j -> j_nf_betaiotaevar sigma j) jl
+let jv_nf_betaiotaevar env sigma jl =
+ Array.map (fun j -> j_nf_betaiotaevar env sigma j) jl
(** Printers *)
@@ -258,7 +258,7 @@ let explain_number_branches env sigma cj expn =
str "expects " ++ int expn ++ str " branches."
let explain_ill_formed_branch env sigma c ci actty expty =
- let simp t = Reductionops.nf_betaiota sigma t in
+ let simp t = Reductionops.nf_betaiota env sigma t in
let env = make_all_name_different env sigma in
let pc = pr_leconstr_env env sigma c in
let pa, pe = pr_explicit env sigma (simp actty) (simp expty) in
@@ -295,8 +295,8 @@ let explain_unification_error env sigma p1 p2 = function
| NotSameArgSize | NotSameHead | NoCanonicalStructure ->
(* Error speaks from itself *) []
| ConversionFailed (env,t1,t2) ->
- let t1 = Reductionops.nf_betaiota sigma t1 in
- let t2 = Reductionops.nf_betaiota sigma t2 in
+ let t1 = Reductionops.nf_betaiota env sigma t1 in
+ let t2 = Reductionops.nf_betaiota env sigma t2 in
if EConstr.eq_constr sigma t1 p1 && EConstr.eq_constr sigma t2 p2 then [] else
let env = make_all_name_different env sigma in
if not (EConstr.eq_constr sigma t1 p1) || not (EConstr.eq_constr sigma t2 p2) then
@@ -336,8 +336,8 @@ let explain_unification_error env sigma p1 p2 = function
let explain_actual_type env sigma j t reason =
let env = make_all_name_different env sigma in
- let j = j_nf_betaiotaevar sigma j in
- let t = Reductionops.nf_betaiota sigma t in
+ let j = j_nf_betaiotaevar env sigma j in
+ let t = Reductionops.nf_betaiota env sigma t in
(** Actually print *)
let pe = pr_ne_context_of (str "In environment") env sigma in
let pc = pr_leconstr_env env sigma (Environ.j_val j) in
@@ -351,8 +351,8 @@ let explain_actual_type env sigma j t reason =
ppreason ++ str ".")
let explain_cant_apply_bad_type env sigma (n,exptyp,actualtyp) rator randl =
- let randl = jv_nf_betaiotaevar sigma randl in
- let actualtyp = Reductionops.nf_betaiota sigma actualtyp in
+ let randl = jv_nf_betaiotaevar env sigma randl in
+ let actualtyp = Reductionops.nf_betaiota env sigma actualtyp in
let env = make_all_name_different env sigma in
let actualtyp, exptyp = pr_explicit env sigma actualtyp exptyp in
let nargs = Array.length randl in
diff --git a/vernac/lemmas.ml b/vernac/lemmas.ml
index 6ef310837c..57436784b8 100644
--- a/vernac/lemmas.ml
+++ b/vernac/lemmas.ml
@@ -210,17 +210,16 @@ let save ?export_seff id const uctx do_guard (locality,poly,kind) hook =
let default_thm_id = Id.of_string "Unnamed_thm"
-let compute_proof_name locality = function
- | Some ((loc,id),pl) ->
- (* We check existence here: it's a bit late at Qed time *)
- if Nametab.exists_cci (Lib.make_path id) || is_section_variable id ||
- locality == Global && Nametab.exists_cci (Lib.make_path_except_section id)
- then
- user_err ?loc (Id.print id ++ str " already exists.");
- id
- | None ->
- let avoid = Id.Set.of_list (Proof_global.get_all_proof_names ()) in
- next_global_ident_away default_thm_id avoid
+let fresh_name_for_anonymous_theorem () =
+ let avoid = Id.Set.of_list (Proof_global.get_all_proof_names ()) in
+ next_global_ident_away default_thm_id avoid
+
+let check_name_freshness locality (loc,id) : unit =
+ (* We check existence here: it's a bit late at Qed time *)
+ if Nametab.exists_cci (Lib.make_path id) || is_section_variable id ||
+ locality == Global && Nametab.exists_cci (Lib.make_path_except_section id)
+ then
+ user_err ?loc (Id.print id ++ str " already exists.")
let save_remaining_recthms (locality,p,kind) norm univs body opaq i (id,(t_i,(_,imps))) =
let t_i = norm t_i in
@@ -435,20 +434,17 @@ let start_proof_with_initialization kind sigma decl recguard thms snl hook =
let start_proof_com ?inference_hook kind thms hook =
let env0 = Global.env () in
let decl = fst (List.hd thms) in
- let evd, decl =
- match decl with
- | None -> Evd.from_env env0, Univdecls.default_univ_decl
- | Some decl ->
- Univdecls.interp_univ_decl_opt env0 (snd decl) in
- let evd, thms = List.fold_left_map (fun evd (sopt,(bl,t)) ->
+ let evd, decl = Univdecls.interp_univ_decl_opt env0 (snd decl) in
+ let evd, thms = List.fold_left_map (fun evd ((id, _), (bl, t)) ->
let evd, (impls, ((env, ctx), imps)) = interp_context_evars env0 evd bl in
let evd, (t', imps') = interp_type_evars_impls ~impls env evd t in
let flags = all_and_fail_flags in
let flags = { flags with use_hook = inference_hook } in
let evd = solve_remaining_evars flags env evd Evd.empty in
let ids = List.map RelDecl.get_name ctx in
+ check_name_freshness (pi1 kind) id;
(* XXX: The nf_evar is critical !! *)
- evd, (compute_proof_name (pi1 kind) sopt,
+ evd, (snd id,
(Evarutil.nf_evar evd (EConstr.it_mkProd_or_LetIn t' ctx),
(ids, imps @ lift_implicits (Context.Rel.nhyps ctx) imps'))))
evd thms in
diff --git a/vernac/lemmas.mli b/vernac/lemmas.mli
index ca92e856bc..126dcd8b07 100644
--- a/vernac/lemmas.mli
+++ b/vernac/lemmas.mli
@@ -52,6 +52,8 @@ val standard_proof_terminator :
Proof_global.lemma_possible_guards -> unit declaration_hook ->
Proof_global.proof_terminator
+val fresh_name_for_anonymous_theorem : unit -> Id.t
+
(** {6 ... } *)
(** A hook the next three functions pass to cook_proof *)
diff --git a/vernac/mltop.ml b/vernac/mltop.ml
index 00554e3bae..053b9d0705 100644
--- a/vernac/mltop.ml
+++ b/vernac/mltop.ml
@@ -184,10 +184,28 @@ let warn_cannot_open_path =
type add_ml = AddNoML | AddTopML | AddRecML
-let add_rec_path add_ml ~unix_path ~coq_root ~implicit =
+type vo_path_spec = {
+ unix_path : string;
+ coq_path : Names.DirPath.t;
+ implicit : bool;
+ has_ml : add_ml;
+}
+
+type coq_path_spec =
+ | VoPath of vo_path_spec
+ | MlPath of string
+
+type coq_path = {
+ path_spec: coq_path_spec;
+ recursive: bool;
+}
+
+let add_vo_path ~recursive lp =
+ let unix_path = lp.unix_path in
+ let implicit = lp.implicit in
if exists_dir unix_path then
- let dirs = all_subdirs ~unix_path in
- let prefix = Names.DirPath.repr coq_root in
+ let dirs = if recursive then all_subdirs ~unix_path else [] in
+ let prefix = Names.DirPath.repr lp.coq_path in
let convert_dirs (lp, cp) =
try
let path = List.rev_map convert_string cp @ prefix in
@@ -195,17 +213,23 @@ let add_rec_path add_ml ~unix_path ~coq_root ~implicit =
with Exit -> None
in
let dirs = List.map_filter convert_dirs dirs in
- let () = match add_ml with
+ let () = match lp.has_ml with
| AddNoML -> ()
| AddTopML -> add_ml_dir unix_path
| AddRecML -> List.iter (fun (lp,_) -> add_ml_dir lp) dirs in
let add (path, dir) =
Loadpath.add_load_path path ~implicit dir in
let () = List.iter add dirs in
- Loadpath.add_load_path unix_path ~implicit coq_root
+ Loadpath.add_load_path unix_path ~implicit lp.coq_path
else
warn_cannot_open_path unix_path
+let add_coq_path { recursive; path_spec } = match path_spec with
+ | VoPath lp ->
+ add_vo_path ~recursive lp
+ | MlPath dir ->
+ if recursive then add_rec_ml_dir dir else add_ml_dir dir
+
(* convertit un nom quelconque en nom de fichier ou de module *)
let mod_of_name name =
if Filename.check_suffix name ".cmo" then
diff --git a/vernac/mltop.mli b/vernac/mltop.mli
index 324a66d382..e44a7c2438 100644
--- a/vernac/mltop.mli
+++ b/vernac/mltop.mli
@@ -42,14 +42,26 @@ val dir_ml_load : string -> unit
(** Dynamic interpretation of .ml *)
val dir_ml_use : string -> unit
-(** Adds a path to the ML paths *)
-val add_ml_dir : string -> unit
-val add_rec_ml_dir : string -> unit
-
+(** Adds a path to the Coq and ML paths *)
type add_ml = AddNoML | AddTopML | AddRecML
-(** Adds a path to the Coq and ML paths *)
-val add_rec_path : add_ml -> unix_path:string -> coq_root:Names.DirPath.t -> implicit:bool -> unit
+type vo_path_spec = {
+ unix_path : string; (* Filesystem path contaning vo/ml files *)
+ coq_path : Names.DirPath.t; (* Coq prefix for the path *)
+ implicit : bool; (* [implicit = true] avoids having to qualify with [coq_path] *)
+ has_ml : add_ml; (* If [has_ml] is true, the directory will also be search for plugins *)
+}
+
+type coq_path_spec =
+ | VoPath of vo_path_spec
+ | MlPath of string
+
+type coq_path = {
+ path_spec: coq_path_spec;
+ recursive: bool;
+}
+
+val add_coq_path : coq_path -> unit
(** List of modules linked to the toplevel *)
val add_known_module : string -> unit
diff --git a/vernac/record.ml b/vernac/record.ml
index 1e464eb8bf..d9af5378f4 100644
--- a/vernac/record.ml
+++ b/vernac/record.ml
@@ -423,16 +423,7 @@ let declare_structure finite ubinders univs id idbuild paramimpls params arity t
mind_entry_universes = univs;
}
in
- let mie =
- match ctx with
- | Polymorphic_const_entry ctx ->
- let env = Global.env () in
- let env' = Environ.push_context ctx env in
- let evd = Evd.from_env env' in
- Inductiveops.infer_inductive_subtyping env' evd mie
- | Monomorphic_const_entry _ ->
- mie
- in
+ let mie = InferCumulativity.infer_inductive (Global.env ()) mie in
let kn = ComInductive.declare_mutual_inductive_with_eliminations mie ubinders [(paramimpls,[])] in
let rsp = (kn,0) in (* This is ind path of idstruc *)
let cstr = (rsp,1) in
@@ -501,7 +492,7 @@ let declare_class finite def cum ubinders univs id idbuild paramimpls params ari
match univs with
| Polymorphic_const_entry univs ->
if cum then
- Cumulative_ind_entry (Universes.univ_inf_ind_from_universe_context univs)
+ Cumulative_ind_entry (Univ.CumulativityInfo.from_universe_context univs)
else
Polymorphic_ind_entry univs
| Monomorphic_const_entry univs ->
@@ -632,7 +623,7 @@ let definition_structure (kind,cum,poly,finite,(is_coe,((loc,idstruc),pl)),ps,cf
match univs with
| Polymorphic_const_entry univs ->
if cum then
- Cumulative_ind_entry (Universes.univ_inf_ind_from_universe_context univs)
+ Cumulative_ind_entry (Univ.CumulativityInfo.from_universe_context univs)
else
Polymorphic_ind_entry univs
| Monomorphic_const_entry univs ->
diff --git a/vernac/vernacentries.ml b/vernac/vernacentries.ml
index 3358951f4c..be09696d1b 100644
--- a/vernac/vernacentries.ml
+++ b/vernac/vernacentries.ml
@@ -471,33 +471,40 @@ let vernac_definition_hook p = function
| SubClass -> Class.add_subclass_hook p
| _ -> no_hook
-let vernac_definition ~atts discharge kind ((loc,id as lid),pl) def =
+let vernac_definition ~atts discharge kind ((loc, id), pl) def =
let local = enforce_locality_exp atts.locality discharge in
let hook = vernac_definition_hook atts.polymorphic kind in
- let () = match local with
- | Discharge -> Dumpglob.dump_definition lid true "var"
- | Local | Global -> Dumpglob.dump_definition lid false "def"
+ let () =
+ match id with
+ | Anonymous -> ()
+ | Name n -> let lid = (loc, n) in
+ match local with
+ | Discharge -> Dumpglob.dump_definition lid true "var"
+ | Local | Global -> Dumpglob.dump_definition lid false "def"
in
let program_mode = Flags.is_program_mode () in
+ let name =
+ match id with
+ | Anonymous -> fresh_name_for_anonymous_theorem ()
+ | Name n -> n
+ in
(match def with
| ProveBody (bl,t) -> (* local binders, typ *)
- start_proof_and_print (local, atts.polymorphic, DefinitionBody kind)
- [Some (lid,pl), (bl,t)] hook
+ start_proof_and_print (local, atts.polymorphic, DefinitionBody kind)
+ [((loc, name), pl), (bl, t)] hook
| DefineBody (bl,red_option,c,typ_opt) ->
let red_option = match red_option with
| None -> None
| Some r ->
let sigma, env = Pfedit.get_current_context () in
Some (snd (Hook.get f_interp_redexp env sigma r)) in
- ComDefinition.do_definition ~program_mode id (local, atts.polymorphic, kind) pl bl red_option c typ_opt hook)
+ ComDefinition.do_definition ~program_mode name
+ (local, atts.polymorphic, kind) pl bl red_option c typ_opt hook)
let vernac_start_proof ~atts kind l =
let local = enforce_locality_exp atts.locality NoDischarge in
if Dumpglob.dump () then
- List.iter (fun (id, _) ->
- match id with
- | Some (lid,_) -> Dumpglob.dump_definition lid false "prf"
- | None -> ()) l;
+ List.iter (fun ((id, _), _) -> Dumpglob.dump_definition id false "prf") l;
start_proof_and_print (local, atts.polymorphic, Proof kind) l no_hook
let vernac_end_proof ?proof = function
@@ -905,9 +912,11 @@ let expand filename =
Envars.expand_path_macros ~warn:(fun x -> Feedback.msg_warning (str x)) filename
let vernac_add_loadpath implicit pdir ldiropt =
+ let open Mltop in
let pdir = expand pdir in
let alias = Option.default Libnames.default_root_prefix ldiropt in
- Mltop.add_rec_path Mltop.AddTopML ~unix_path:pdir ~coq_root:alias ~implicit
+ add_coq_path { recursive = true;
+ path_spec = VoPath { unix_path = pdir; coq_path = alias; has_ml = AddTopML; implicit } }
let vernac_remove_loadpath path =
Loadpath.remove_load_path (expand path)
@@ -915,7 +924,8 @@ let vernac_remove_loadpath path =
(* Coq syntax for ML or system commands *)
let vernac_add_ml_path isrec path =
- (if isrec then Mltop.add_rec_ml_dir else Mltop.add_ml_dir) (expand path)
+ let open Mltop in
+ add_coq_path { recursive = isrec; path_spec = MlPath (expand path) }
let vernac_declare_ml_module ~atts l =
let local = make_locality atts.locality in
@@ -1584,7 +1594,7 @@ let vernac_check_may_eval ~atts redexp glopt rc =
| None ->
let evars_of_term c = Evarutil.undefined_evars_of_term sigma' c in
let l = Evar.Set.union (evars_of_term j.Environ.uj_val) (evars_of_term j.Environ.uj_type) in
- let j = { j with Environ.uj_type = Reductionops.nf_betaiota sigma' j.Environ.uj_type } in
+ let j = { j with Environ.uj_type = Reductionops.nf_betaiota env sigma' j.Environ.uj_type } in
Feedback.msg_notice (print_judgment env sigma' j ++
pr_ne_evar_set (fnl () ++ str "where" ++ fnl ()) (mt ()) sigma' l ++
Printer.pr_universe_ctx_set sigma uctx)
@@ -2065,7 +2075,6 @@ let interp ?proof ~atts ~st c =
| VernacComments l -> Flags.if_verbose Feedback.msg_info (str "Comments ok\n")
(* Proof management *)
- | VernacGoal t -> vernac_start_proof ~atts Theorem [None,([],t)]
| VernacFocus n -> vernac_focus n
| VernacUnfocus -> vernac_unfocus ()
| VernacUnfocused -> vernac_unfocused ()