aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--.gitignore3
-rw-r--r--.merlin2
-rw-r--r--CHANGES28
-rw-r--r--COMPATIBILITY31
-rw-r--r--INSTALL5
-rw-r--r--INSTALL.ide2
-rw-r--r--Makefile6
-rw-r--r--Makefile.build84
-rw-r--r--Makefile.common12
-rw-r--r--_tags1
-rw-r--r--checker/check.mllib2
-rw-r--r--checker/checker.ml8
-rw-r--r--checker/safe_typing.ml6
-rw-r--r--checker/votour.ml11
-rw-r--r--config/coq_config.mli7
-rw-r--r--configure.ml219
-rw-r--r--dev/base_include1
-rw-r--r--dev/db1
-rw-r--r--dev/doc/changes.txt50
-rw-r--r--dev/ocamldebug-coq.run3
-rwxr-xr-xdev/ocamldoc/fix-ocamldoc-utf86
-rw-r--r--dev/ocamldoc/header.tex14
-rw-r--r--dev/printers.mllib6
-rw-r--r--dev/top_printers.ml29
-rw-r--r--doc/common/macros.tex1
-rw-r--r--doc/refman/Program.tex2
-rw-r--r--doc/refman/RefMan-ltac.tex14
-rw-r--r--doc/refman/RefMan-oth.tex8
-rw-r--r--doc/refman/RefMan-tac.tex129
-rw-r--r--doc/stdlib/index-list.html.template1
-rw-r--r--engine/engine.mllib7
-rw-r--r--engine/evd.ml (renamed from pretyping/evd.ml)692
-rw-r--r--engine/evd.mli (renamed from pretyping/evd.mli)42
-rw-r--r--engine/logic_monad.ml (renamed from proofs/logic_monad.ml)221
-rw-r--r--engine/logic_monad.mli (renamed from proofs/logic_monad.mli)65
-rw-r--r--engine/namegen.ml (renamed from pretyping/namegen.ml)0
-rw-r--r--engine/namegen.mli (renamed from pretyping/namegen.mli)13
-rw-r--r--engine/proofview_monad.ml (renamed from proofs/proofview_monad.ml)5
-rw-r--r--engine/proofview_monad.mli (renamed from proofs/proofview_monad.mli)0
-rw-r--r--engine/sigma.ml105
-rw-r--r--engine/sigma.mli122
-rw-r--r--engine/termops.ml (renamed from pretyping/termops.ml)84
-rw-r--r--engine/termops.mli (renamed from pretyping/termops.mli)104
-rw-r--r--engine/uState.ml466
-rw-r--r--engine/uState.mli117
-rw-r--r--grammar/argextend.ml4144
-rw-r--r--grammar/grammar.mllib2
-rw-r--r--grammar/q_coqast.ml424
-rw-r--r--grammar/q_util.ml470
-rw-r--r--grammar/q_util.mli8
-rw-r--r--grammar/tacextend.ml4140
-rw-r--r--grammar/vernacextend.ml421
-rw-r--r--ide/FAQ2
-rw-r--r--ide/coq.ml21
-rw-r--r--ide/coqOps.ml37
-rw-r--r--ide/coqide.ml257
-rw-r--r--ide/document.ml8
-rw-r--r--ide/fileOps.ml8
-rw-r--r--ide/ide.mllib2
-rw-r--r--ide/ide_slave.ml27
-rw-r--r--ide/ideutils.ml55
-rw-r--r--ide/ideutils.mli9
-rw-r--r--ide/interface.mli9
-rw-r--r--ide/nanoPG.ml2
-rw-r--r--ide/preferences.ml1195
-rw-r--r--ide/preferences.mli169
-rw-r--r--ide/project_file.ml481
-rw-r--r--ide/sentence.ml4
-rw-r--r--ide/session.ml22
-rw-r--r--ide/session.mli1
-rw-r--r--ide/tags.ml54
-rw-r--r--ide/tags.mli19
-rw-r--r--ide/wg_Command.ml25
-rw-r--r--ide/wg_Command.mli2
-rw-r--r--ide/wg_Completion.ml2
-rw-r--r--ide/wg_Find.ml2
-rw-r--r--ide/wg_MessageView.ml39
-rw-r--r--ide/wg_MessageView.mli11
-rw-r--r--ide/wg_ProofView.ml39
-rw-r--r--ide/wg_ScriptView.ml29
-rw-r--r--ide/wg_Segment.ml3
-rw-r--r--ide/xmlprotocol.ml414
-rw-r--r--ide/xmlprotocol.mli4
-rw-r--r--interp/constrarg.ml40
-rw-r--r--interp/constrarg.mli10
-rw-r--r--interp/constrexpr_ops.ml7
-rw-r--r--interp/constrextern.ml54
-rw-r--r--interp/constrextern.mli3
-rw-r--r--interp/constrintern.ml29
-rw-r--r--interp/constrintern.mli5
-rw-r--r--interp/coqlib.ml2
-rw-r--r--interp/genintern.ml14
-rw-r--r--interp/topconstr.ml10
-rw-r--r--intf/constrexpr.mli21
-rw-r--r--intf/extend.mli46
-rw-r--r--intf/glob_term.mli8
-rw-r--r--intf/misctypes.mli10
-rw-r--r--intf/tacexpr.mli27
-rw-r--r--intf/vernacexpr.mli21
-rw-r--r--kernel/cemitcodes.ml16
-rw-r--r--kernel/cemitcodes.mli4
-rw-r--r--kernel/closure.ml21
-rw-r--r--kernel/closure.mli2
-rw-r--r--kernel/constr.ml42
-rw-r--r--kernel/constr.mli46
-rw-r--r--kernel/context.ml342
-rw-r--r--kernel/context.mli237
-rw-r--r--kernel/cooking.ml6
-rw-r--r--kernel/csymtable.ml21
-rw-r--r--kernel/declarations.mli7
-rw-r--r--kernel/declareops.ml85
-rw-r--r--kernel/declareops.mli1
-rw-r--r--kernel/environ.ml44
-rw-r--r--kernel/environ.mli47
-rw-r--r--kernel/fast_typeops.ml2
-rw-r--r--kernel/indtypes.ml130
-rw-r--r--kernel/indtypes.mli4
-rw-r--r--kernel/inductive.ml45
-rw-r--r--kernel/inductive.mli9
-rw-r--r--kernel/kernel.mllib1
-rw-r--r--kernel/mod_typing.ml2
-rw-r--r--kernel/names.ml41
-rw-r--r--kernel/names.mli51
-rw-r--r--kernel/nativecode.ml9
-rw-r--r--kernel/nativeconv.mli2
-rw-r--r--kernel/nativelambda.ml2
-rw-r--r--kernel/nativelib.ml11
-rw-r--r--kernel/nativevalues.ml27
-rw-r--r--kernel/opaqueproof.ml2
-rw-r--r--kernel/opaqueproof.mli2
-rw-r--r--kernel/pre_env.ml21
-rw-r--r--kernel/pre_env.mli16
-rw-r--r--kernel/reduction.ml157
-rw-r--r--kernel/reduction.mli59
-rw-r--r--kernel/safe_typing.ml9
-rw-r--r--kernel/subtyping.ml2
-rw-r--r--kernel/term.ml112
-rw-r--r--kernel/term.mli68
-rw-r--r--kernel/term_typing.ml5
-rw-r--r--kernel/typeops.ml7
-rw-r--r--kernel/typeops.mli5
-rw-r--r--kernel/uGraph.ml906
-rw-r--r--kernel/uGraph.mli63
-rw-r--r--kernel/univ.ml838
-rw-r--r--kernel/univ.mli54
-rw-r--r--kernel/vars.ml45
-rw-r--r--kernel/vars.mli92
-rw-r--r--kernel/vconv.mli2
-rw-r--r--lib/cList.ml23
-rw-r--r--lib/cList.mli5
-rw-r--r--lib/cMap.ml42
-rw-r--r--lib/cMap.mli15
-rw-r--r--lib/cSig.mli4
-rw-r--r--lib/clib.mllib1
-rw-r--r--lib/dyn.ml96
-rw-r--r--lib/dyn.mli45
-rw-r--r--lib/envars.ml27
-rw-r--r--lib/envars.mli13
-rw-r--r--lib/feedback.ml6
-rw-r--r--lib/feedback.mli2
-rw-r--r--lib/flags.ml19
-rw-r--r--lib/flags.mli6
-rw-r--r--lib/future.ml7
-rw-r--r--lib/future.mli3
-rw-r--r--lib/genarg.ml337
-rw-r--r--lib/genarg.mli135
-rw-r--r--lib/hMap.ml13
-rw-r--r--lib/hashcons.ml31
-rw-r--r--lib/hashset.ml2
-rw-r--r--lib/heap.ml2
-rw-r--r--lib/lib.mllib1
-rw-r--r--lib/option.ml4
-rw-r--r--lib/option.mli16
-rw-r--r--lib/pp.ml33
-rw-r--r--lib/pp.mli4
-rw-r--r--lib/richpp.ml34
-rw-r--r--lib/richpp.mli26
-rw-r--r--lib/serialize.ml4
-rw-r--r--lib/serialize.mli2
-rw-r--r--lib/system.ml108
-rw-r--r--lib/system.mli38
-rw-r--r--lib/unicode.ml7
-rw-r--r--lib/unicode.mli22
-rw-r--r--lib/util.ml1
-rw-r--r--lib/util.mli2
-rw-r--r--library/declare.ml8
-rw-r--r--library/declaremods.ml2
-rw-r--r--library/decls.ml3
-rw-r--r--library/global.mli6
-rw-r--r--library/globnames.ml8
-rw-r--r--library/globnames.mli8
-rw-r--r--library/keys.ml28
-rw-r--r--library/lib.mli8
-rw-r--r--library/libnames.ml4
-rw-r--r--library/libobject.ml21
-rw-r--r--library/libobject.mli5
-rw-r--r--library/library.ml46
-rw-r--r--library/library.mli3
-rw-r--r--library/loadpath.ml25
-rw-r--r--library/loadpath.mli2
-rw-r--r--library/nameops.ml4
-rw-r--r--library/nametab.ml2
-rw-r--r--library/summary.ml26
-rw-r--r--library/summary.mli4
-rw-r--r--library/universes.ml83
-rw-r--r--library/universes.mli13
-rw-r--r--myocamlbuild.ml2
-rw-r--r--parsing/compat.ml472
-rw-r--r--parsing/egramcoq.ml57
-rw-r--r--parsing/egramcoq.mli4
-rw-r--r--parsing/egramml.ml72
-rw-r--r--parsing/egramml.mli18
-rw-r--r--parsing/entry.ml59
-rw-r--r--parsing/entry.mli44
-rw-r--r--parsing/g_constr.ml420
-rw-r--r--parsing/g_ltac.ml417
-rw-r--r--parsing/g_prim.ml45
-rw-r--r--parsing/g_tactic.ml456
-rw-r--r--parsing/g_vernac.ml419
-rw-r--r--parsing/lexer.ml462
-rw-r--r--parsing/parsing.mllib1
-rw-r--r--parsing/pcoq.ml (renamed from parsing/pcoq.ml4)472
-rw-r--r--parsing/pcoq.mli93
-rw-r--r--parsing/tok.ml7
-rw-r--r--parsing/tok.mli1
-rw-r--r--plugins/btauto/refl_btauto.ml9
-rw-r--r--plugins/cc/cctac.ml40
-rw-r--r--plugins/decl_mode/decl_proof_instr.ml9
-rw-r--r--plugins/derive/derive.ml1
-rw-r--r--plugins/extraction/extraction.ml1
-rw-r--r--plugins/extraction/table.ml2
-rw-r--r--plugins/firstorder/formula.mli3
-rw-r--r--plugins/firstorder/g_ground.ml49
-rw-r--r--plugins/fourier/fourierR.ml14
-rw-r--r--plugins/funind/functional_principles_proofs.ml16
-rw-r--r--plugins/funind/functional_principles_types.ml13
-rw-r--r--plugins/funind/g_indfun.ml44
-rw-r--r--plugins/funind/glob_term_to_relation.ml2
-rw-r--r--plugins/funind/indfun.ml13
-rw-r--r--plugins/funind/invfun.ml15
-rw-r--r--plugins/funind/merge.ml19
-rw-r--r--plugins/funind/recdef.ml25
-rw-r--r--plugins/micromega/Psatz.v8
-rw-r--r--plugins/micromega/certificate.ml1566
-rw-r--r--plugins/micromega/coq_micromega.ml399
-rw-r--r--plugins/micromega/g_micromega.ml440
-rw-r--r--plugins/micromega/mfourier.ml24
-rw-r--r--plugins/micromega/mutils.ml9
-rw-r--r--plugins/omega/coq_omega.ml29
-rw-r--r--plugins/quote/quote.ml11
-rw-r--r--plugins/setoid_ring/g_newring.ml490
-rw-r--r--plugins/setoid_ring/newring.ml (renamed from plugins/setoid_ring/newring.ml4)232
-rw-r--r--plugins/setoid_ring/newring.mli78
-rw-r--r--plugins/setoid_ring/newring_ast.mli63
-rw-r--r--plugins/setoid_ring/newring_plugin.mllib1
-rw-r--r--pretyping/cases.ml35
-rw-r--r--pretyping/cases.mli9
-rw-r--r--pretyping/constr_matching.ml5
-rw-r--r--pretyping/detyping.ml13
-rw-r--r--pretyping/detyping.mli3
-rw-r--r--pretyping/evarconv.ml7
-rw-r--r--pretyping/evarsolve.ml18
-rw-r--r--pretyping/evarutil.ml70
-rw-r--r--pretyping/evarutil.mli12
-rw-r--r--pretyping/find_subterm.mli5
-rw-r--r--pretyping/indrec.ml62
-rw-r--r--pretyping/indrec.mli8
-rw-r--r--pretyping/inductiveops.ml74
-rw-r--r--pretyping/inductiveops.mli20
-rw-r--r--pretyping/nativenorm.mli1
-rw-r--r--pretyping/patternops.mli1
-rw-r--r--pretyping/pretyping.ml41
-rw-r--r--pretyping/pretyping.mli7
-rw-r--r--pretyping/pretyping.mllib3
-rw-r--r--pretyping/recordops.ml2
-rw-r--r--pretyping/reductionops.ml56
-rw-r--r--pretyping/reductionops.mli18
-rw-r--r--pretyping/retyping.mli3
-rw-r--r--pretyping/tacred.ml6
-rw-r--r--pretyping/typeclasses.ml13
-rw-r--r--pretyping/typeclasses.mli7
-rw-r--r--pretyping/typeclasses_errors.ml3
-rw-r--r--pretyping/typeclasses_errors.mli5
-rw-r--r--pretyping/typing.ml5
-rw-r--r--pretyping/unification.ml58
-rw-r--r--pretyping/unification.mli12
-rw-r--r--pretyping/vnorm.ml12
-rw-r--r--pretyping/vnorm.mli1
-rw-r--r--printing/genprint.ml6
-rw-r--r--printing/miscprint.ml4
-rw-r--r--printing/ppconstr.ml30
-rw-r--r--printing/pptactic.ml378
-rw-r--r--printing/pptactic.mli8
-rw-r--r--printing/pptacticsig.mli56
-rw-r--r--printing/ppvernac.ml37
-rw-r--r--printing/prettyp.ml2
-rw-r--r--printing/printer.ml16
-rw-r--r--printing/printer.mli13
-rw-r--r--printing/printmod.ml6
-rw-r--r--proofs/clenv.ml58
-rw-r--r--proofs/clenv.mli1
-rw-r--r--proofs/clenvtac.ml12
-rw-r--r--proofs/goal.mli2
-rw-r--r--proofs/logic.ml6
-rw-r--r--proofs/logic.mli2
-rw-r--r--proofs/pfedit.ml5
-rw-r--r--proofs/proof_global.ml46
-rw-r--r--proofs/proof_global.mli9
-rw-r--r--proofs/proofs.mllib2
-rw-r--r--proofs/proofview.ml107
-rw-r--r--proofs/proofview.mli104
-rw-r--r--proofs/redexpr.ml2
-rw-r--r--proofs/refiner.ml4
-rw-r--r--proofs/refiner.mli3
-rw-r--r--proofs/tacmach.ml18
-rw-r--r--proofs/tacmach.mli53
-rw-r--r--proofs/tactic_debug.ml5
-rw-r--r--stm/asyncTaskQueue.ml6
-rw-r--r--stm/lemmas.ml24
-rw-r--r--stm/lemmas.mli9
-rw-r--r--stm/stm.ml13
-rw-r--r--stm/stm.mli5
-rw-r--r--stm/texmacspp.ml16
-rw-r--r--stm/vernac_classifier.ml20
-rw-r--r--tactics/auto.ml75
-rw-r--r--tactics/auto.mli25
-rw-r--r--tactics/autorewrite.ml27
-rw-r--r--tactics/class_tactics.ml128
-rw-r--r--tactics/contradiction.ml34
-rw-r--r--tactics/coretactics.ml438
-rw-r--r--tactics/eauto.ml4151
-rw-r--r--tactics/eauto.mli17
-rw-r--r--tactics/elim.ml46
-rw-r--r--tactics/elimschemes.ml9
-rw-r--r--tactics/eqdecide.ml21
-rw-r--r--tactics/eqschemes.ml79
-rw-r--r--tactics/equality.ml180
-rw-r--r--tactics/evar_tactics.ml15
-rw-r--r--tactics/extratactics.ml4169
-rw-r--r--tactics/extratactics.mli2
-rw-r--r--tactics/ftactic.ml30
-rw-r--r--tactics/ftactic.mli21
-rw-r--r--tactics/g_auto.ml476
-rw-r--r--tactics/geninterp.ml15
-rw-r--r--tactics/geninterp.mli7
-rw-r--r--tactics/hightactics.mllib1
-rw-r--r--tactics/hints.ml28
-rw-r--r--tactics/hints.mli5
-rw-r--r--tactics/hipattern.mli6
-rw-r--r--tactics/inv.ml49
-rw-r--r--tactics/leminv.ml14
-rw-r--r--tactics/rewrite.ml50
-rw-r--r--tactics/rewrite.mli2
-rw-r--r--tactics/taccoerce.ml40
-rw-r--r--tactics/taccoerce.mli9
-rw-r--r--tactics/tacenv.ml13
-rw-r--r--tactics/tacenv.mli13
-rw-r--r--tactics/tacintern.ml114
-rw-r--r--tactics/tacintern.mli1
-rw-r--r--tactics/tacinterp.ml940
-rw-r--r--tactics/tacinterp.mli21
-rw-r--r--tactics/tacsubst.ml102
-rw-r--r--tactics/tactic_matching.mli2
-rw-r--r--tactics/tacticals.ml216
-rw-r--r--tactics/tacticals.mli58
-rw-r--r--tactics/tactics.ml1221
-rw-r--r--tactics/tactics.mli57
-rw-r--r--tactics/tauto.ml4190
-rw-r--r--test-suite/Makefile2
-rw-r--r--test-suite/bugs/closed/3849.v (renamed from test-suite/bugs/opened/3849.v)2
-rw-r--r--test-suite/bugs/closed/3911.v26
-rw-r--r--test-suite/bugs/closed/3929.v12
-rw-r--r--test-suite/bugs/closed/3957.v6
-rw-r--r--test-suite/bugs/closed/4214.v (renamed from test-suite/bugs/opened/4214.v)3
-rw-r--r--test-suite/bugs/closed/4479.v3
-rw-r--r--test-suite/bugs/opened/3889.v11
-rw-r--r--test-suite/bugs/opened/3890.v18
-rw-r--r--test-suite/bugs/opened/3916.v3
-rw-r--r--test-suite/bugs/opened/3919.v-disabled13
-rw-r--r--test-suite/bugs/opened/3922.v-disabled83
-rw-r--r--test-suite/bugs/opened/3926.v30
-rw-r--r--test-suite/bugs/opened/3928.v-disabled12
-rw-r--r--test-suite/bugs/opened/3938.v6
-rw-r--r--test-suite/bugs/opened/3946.v11
-rw-r--r--test-suite/bugs/opened/3948.v25
-rw-r--r--test-suite/failure/positivity.v46
-rw-r--r--test-suite/micromega/square.v3
-rw-r--r--test-suite/output/Cases.out4
-rw-r--r--test-suite/output/Cases.v4
-rw-r--r--test-suite/output/inference.out2
-rw-r--r--test-suite/stm/Nijmegen_QArithSternBrocot_Zaux.v20
-rw-r--r--test-suite/success/Injection.v6
-rw-r--r--test-suite/success/Typeclasses.v23
-rw-r--r--test-suite/success/decl_mode2.v249
-rw-r--r--test-suite/success/induct.v43
-rw-r--r--test-suite/success/intros.v44
-rw-r--r--test-suite/success/shrink_abstract.v13
-rw-r--r--test-suite/success/shrink_obligations.v28
-rw-r--r--test-suite/success/subst.v25
-rw-r--r--theories/Compat/Coq85.v7
-rw-r--r--theories/Init/Datatypes.v2
-rw-r--r--theories/Init/Notations.v1
-rw-r--r--theories/Lists/List.v76
-rw-r--r--theories/Lists/ListSet.v109
-rw-r--r--theories/Logic/ClassicalFacts.v78
-rw-r--r--theories/Logic/PropFacts.v50
-rw-r--r--theories/Program/Wf.v2
-rw-r--r--theories/Sorting/Permutation.v2
-rw-r--r--theories/Wellfounded/Lexicographic_Exponentiation.v6
-rw-r--r--tools/coq_makefile.ml27
-rw-r--r--tools/coqc.ml25
-rw-r--r--tools/coqdep.ml11
-rw-r--r--tools/coqdep_common.ml82
-rw-r--r--tools/coqdep_common.mli8
-rw-r--r--tools/coqdep_lexer.mll126
-rw-r--r--tools/coqmktop.ml13
-rw-r--r--tools/fake_ide.ml23
-rw-r--r--tools/ocamllibdep.mll201
-rw-r--r--toplevel/assumptions.ml2
-rw-r--r--toplevel/assumptions.mli3
-rw-r--r--toplevel/auto_ind_decl.ml52
-rw-r--r--toplevel/class.ml4
-rw-r--r--toplevel/classes.ml7
-rw-r--r--toplevel/classes.mli5
-rw-r--r--toplevel/command.ml15
-rw-r--r--toplevel/coqinit.ml2
-rw-r--r--toplevel/coqtop.ml35
-rw-r--r--toplevel/discharge.ml7
-rw-r--r--toplevel/discharge.mli3
-rw-r--r--toplevel/himsg.ml18
-rw-r--r--toplevel/metasyntax.ml43
-rw-r--r--toplevel/metasyntax.mli2
-rw-r--r--toplevel/mltop.ml2
-rw-r--r--toplevel/obligations.ml71
-rw-r--r--toplevel/record.ml13
-rw-r--r--toplevel/record.mli7
-rw-r--r--toplevel/search.ml27
-rw-r--r--toplevel/usage.ml7
-rw-r--r--toplevel/vernac.ml9
-rw-r--r--toplevel/vernacentries.ml97
440 files changed, 13263 insertions, 9789 deletions
diff --git a/.gitignore b/.gitignore
index 3adb9c67c..5c932ad02 100644
--- a/.gitignore
+++ b/.gitignore
@@ -98,6 +98,8 @@ doc/RecTutorial/RecTutorial.html
doc/RecTutorial/RecTutorial.pdf
doc/RecTutorial/RecTutorial.ps
dev/doc/naming-conventions.pdf
+dev/ocamldoc/*.html
+dev/ocamldoc/*.css
# .mll files
@@ -110,6 +112,7 @@ plugins/dp/dp_zenon.ml
tools/gallina_lexer.ml
tools/coqwc.ml
tools/coqdep_lexer.ml
+tools/ocamllibdep.ml
tools/coqdoc/cpretty.ml
lib/xml_lexer.ml
diff --git a/.merlin b/.merlin
index 02420c4d8..91dbc336b 100644
--- a/.merlin
+++ b/.merlin
@@ -12,6 +12,8 @@ S kernel/byterun
B kernel/byterun
S library
B library
+S engine
+B engine
S pretyping
B pretyping
S interp
diff --git a/CHANGES b/CHANGES
index 531d5049f..e80a3b454 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,24 @@
+Changes beyond V8.5
+===================
+
+Tactics
+
+- Flag "Bracketing Last Introduction Pattern" is now on by default.
+- New flag "Shrink Abstract" that minimalizes proofs generated by the abstract
+ tactical w.r.t. variables appearing in the body of the proof.
+- Serious bugs are fixed in tactic "double induction" (source of
+ incompatibilities as soon as the inductive types have dependencies in
+ the type of their constructors; "double induction" remains however
+ deprecated).
+- In introduction patterns of the form (pat1,...,patn), n should match
+ the exact number of hypotheses introduced (except for local definitions
+ for which pattern can be omitted, as in regular pattern-matching).
+
+Program
+
+- The "Shrink Obligations" flag now applies to all obligations, not only those
+ solved by the automatic tactic.
+
Changes from V8.5beta3 to V8.5
==============================
@@ -63,6 +84,13 @@ Tactics
"intros" automatically complete the introduction of its subcomponents, as the
the disjunctive-conjunctive introduction patterns in non-terminal position
already do.
+- New flag "Shrink Abstract" that minimalizes proofs generated by the abstract
+ tactical w.r.t. variables appearing in the body of the proof.
+
+Program
+
+- The "Shrink Obligations" flag now applies to all obligations, not only those
+solved by the automatic tactic.
- Importing Program no longer overrides the "exists" tactic (potential source
of incompatibilities).
- Hints costs are now correctly taken into account (potential source of
diff --git a/COMPATIBILITY b/COMPATIBILITY
index eaeb2cba2..ab29903b9 100644
--- a/COMPATIBILITY
+++ b/COMPATIBILITY
@@ -3,7 +3,36 @@ Potential sources of incompatibilities between Coq V8.4 and V8.5
(see also file CHANGES)
-Universe Polymorphism.
+- options for *coq* compilation (see below for ocaml).
+
+** [-I foo] is now deprecated and will not add directory foo to the
+ coq load path (only for ocaml, see below). Just replace [-I foo] by
+ [-Q foo ""] in your project file and re-generate makefile. Or
+ perform the same operation directly in your makefile if you edit it
+ by hand.
+
+** Option -R Foo bar is the same in v8.5 than in v8.4 concerning coq
+ load path.
+
+** Option [-I foo -as bar] is unchanged but discouraged unless you
+ compile ocaml code. Use -Q foo bar instead.
+
+ for more details: file CHANGES or section "Customization at launch
+ time" of the reference manual.
+
+- Command line options for ocaml Compilation of ocaml code (plugins)
+
+** [-I foo] is *not* deprecated to add foo to the ocaml load path.
+
+** [-I foo -as bar] adds foo to the ocaml load path *and* adds foo to
+ the coq load path with logical name bar (shortcut for -I foo -Q foo
+ bar).
+
+ for more details: file CHANGES or section "Customization at launch
+ time" of the reference manual.
+
+
+- Universe Polymorphism.
- Refinement, unification and tactics are now aware of universes,
resulting in more localized errors. Universe inconsistencies
diff --git a/INSTALL b/INSTALL
index 83c1b9f3f..955150c2c 100644
--- a/INSTALL
+++ b/INSTALL
@@ -32,6 +32,11 @@ WHAT DO YOU NEED ?
- Objective Caml version 3.12.1 or later
(available at http://caml.inria.fr/)
+ - Findlib (included in OCaml binary distribution under windows,
+ probably available in your distribution and for sure at
+ http://projects.camlcity.org/projects/findlib.html)
+
+
- Camlp5 (version >= 6.02) (Coq compiles with Camlp4 but might be less
well supported)
diff --git a/INSTALL.ide b/INSTALL.ide
index 6e41b2d05..b651e77db 100644
--- a/INSTALL.ide
+++ b/INSTALL.ide
@@ -39,7 +39,7 @@ COMPILATION REQUIREMENTS
install GTK+ 2.x, should you need to force it for one reason
or another.)
- The OCaml bindings for GTK+ 2.x, lablgtk2 with support for gtksourceview2.
- You need at least version 2.14.2.
+ You need at least version 2.16.
Your distribution may contain precompiled packages. For example, for
Debian, run
diff --git a/Makefile b/Makefile
index bb51e3dd5..c5415d9f6 100644
--- a/Makefile
+++ b/Makefile
@@ -69,7 +69,6 @@ USEGRAMMAR := '(\*.*camlp4deps.*grammar'
## Files in the source tree
-YACCFILES:=$(call find, '*.mly')
LEXFILES := $(call find, '*.mll')
export MLLIBFILES := $(call find, '*.mllib')
export ML4BASEFILES := $(call findx, '*.ml4', grep -L -e $(USEGRAMMAR))
@@ -86,10 +85,9 @@ EXISTINGMLI := $(call find, '*.mli')
## Files that will be generated
GENML4FILES:= $(ML4FILES:.ml4=.ml)
-GENMLIFILES:=$(YACCFILES:.mly=.mli)
GENPLUGINSMOD:=$(filter plugins/%,$(MLLIBFILES:%.mllib=%_mod.ml))
-export GENMLFILES:=$(LEXFILES:.mll=.ml) $(YACCFILES:.mly=.ml) \
- tools/tolink.ml kernel/copcodes.ml $(GENPLUGINSMOD)
+export GENMLFILES:=$(LEXFILES:.mll=.ml) $(GENPLUGINSMOD) \
+ tools/tolink.ml kernel/copcodes.ml
export GENHFILES:=kernel/byterun/coq_jumptbl.h
export GENVFILES:=theories/Numbers/Natural/BigN/NMake_gen.v
export GENFILES:=$(GENMLFILES) $(GENMLIFILES) $(GENHFILES) $(GENVFILES)
diff --git a/Makefile.build b/Makefile.build
index 48f448ce8..ffac80cb8 100644
--- a/Makefile.build
+++ b/Makefile.build
@@ -94,8 +94,8 @@ HIDE := $(if $(VERBOSE),,@)
LOCALINCLUDES=$(addprefix -I , $(SRCDIRS) )
MLINCLUDES=$(LOCALINCLUDES) -I $(MYCAMLP4LIB)
-OCAMLC := $(OCAMLC) $(CAMLFLAGS)
-OCAMLOPT := $(OCAMLOPT) $(CAMLFLAGS)
+OCAMLC := $(OCAMLFIND) ocamlc $(CAMLFLAGS)
+OCAMLOPT := $(OCAMLFIND) opt $(CAMLFLAGS)
BYTEFLAGS=-thread $(CAMLDEBUG) $(USERFLAGS)
OPTFLAGS=-thread $(CAMLDEBUGOPT) $(CAMLTIMEPROF) $(USERFLAGS)
@@ -180,7 +180,7 @@ endif
TOTARGET = > "$@" || (RV=$$?; rm -f "$@"; exit $${RV})
###########################################################################
-# Compilation option for .c files
+# Compilation option for .c files
###########################################################################
CINCLUDES= -I $(CAMLHLIB)
@@ -190,9 +190,9 @@ CINCLUDES= -I $(CAMLHLIB)
# NB: We used to do a ranlib after ocamlmklib, but it seems that
# ocamlmklib is already doing it
-$(LIBCOQRUN): kernel/byterun/coq_jumptbl.h $(BYTERUN)
+$(LIBCOQRUN): kernel/byterun/coq_jumptbl.h $(BYTERUN)
cd $(dir $(LIBCOQRUN)) && \
- $(OCAMLMKLIB) -oc $(COQRUN) $(foreach u,$(BYTERUN),$(notdir $(u)))
+ $(OCAMLFIND) ocamlmklib -oc $(COQRUN) $(foreach u,$(BYTERUN),$(notdir $(u)))
#coq_jumptbl.h is required only if you have GCC 2.0 or later
kernel/byterun/coq_jumptbl.h : kernel/byterun/coq_instruct.h
@@ -503,12 +503,13 @@ test-suite: world $(ALLSTDLIB).v
##################################################################
.PHONY: lib kernel byterun library proofs tactics interp parsing pretyping
-.PHONY: highparsing stm toplevel hightactics
+.PHONY: engine highparsing stm toplevel hightactics
lib: lib/clib.cma lib/lib.cma
kernel: kernel/kernel.cma
byterun: $(BYTERUN)
library: library/library.cma
+engine: engine/engine.cma
proofs: proofs/proofs.cma
tactics: tactics/tactics.cma
interp: interp/interp.cma
@@ -602,7 +603,7 @@ theories/Numbers/Natural/BigN/NMake_gen.v: theories/Numbers/Natural/BigN/NMake_g
printers: $(DEBUGPRINTERS)
-tools: $(TOOLS) $(DEBUGPRINTERS) $(COQDEPBOOT)
+tools: $(TOOLS) $(DEBUGPRINTERS) $(OCAMLLIBDEP)
# coqdep_boot : a basic version of coqdep, with almost no dependencies.
@@ -610,12 +611,9 @@ tools: $(TOOLS) $(DEBUGPRINTERS) $(COQDEPBOOT)
# to avoid using implicit rules and hence .ml.d files that would need
# coqdep_boot.
-COQDEPBOOTSRC:= \
- tools/coqdep_lexer.mli tools/coqdep_lexer.ml \
- tools/coqdep_common.mli tools/coqdep_common.ml \
- tools/coqdep_boot.ml
+OCAMLLIBDEPSRC:= tools/ocamllibdep.ml
-$(COQDEPBOOT): $(COQDEPBOOTSRC)
+$(OCAMLLIBDEP): $(OCAMLLIBDEPSRC)
$(SHOW)'OCAMLBEST -o $@'
$(HIDE)$(call bestocaml, -I tools, unix)
@@ -830,34 +828,40 @@ install-latex:
source-doc: mli-doc $(OCAMLDOCDIR)/coq.pdf
$(OCAMLDOCDIR)/coq.tex: $(DOCMLIS:.mli=.cmi)
- $(OCAMLDOC) -latex -rectypes -I $(MYCAMLP4LIB) $(MLINCLUDES)\
- $(DOCMLIS) -t "Coq mlis documentation" \
- -intro $(OCAMLDOCDIR)/docintro -o $@
+ $(SHOW)'OCAMLDOC -latex -o $@'
+ $(HIDE)$(OCAMLFIND) ocamldoc -latex -rectypes -I $(MYCAMLP4LIB) $(MLINCLUDES)\
+ $(DOCMLIS) -noheader -t "Coq mlis documentation" \
+ -intro $(OCAMLDOCDIR)/docintro -o $@.tmp
+ $(SHOW)'OCAMLDOC utf8 fix'
+ $(HIDE)$(OCAMLDOCDIR)/fix-ocamldoc-utf8 $@.tmp
+ $(HIDE)cat $(OCAMLDOCDIR)/header.tex $@.tmp > $@
+ rm $@.tmp
mli-doc: $(DOCMLIS:.mli=.cmi)
- $(OCAMLDOC) -html -rectypes -I +threads -I $(MYCAMLP4LIB) $(MLINCLUDES) \
+ $(SHOW)'OCAMLDOC -html'
+ $(HIDE)$(OCAMLFIND) ocamldoc -charset utf-8 -html -rectypes -I +threads -I $(MYCAMLP4LIB) $(MLINCLUDES) \
$(DOCMLIS) -d $(OCAMLDOCDIR)/html -colorize-code \
-t "Coq mlis documentation" -intro $(OCAMLDOCDIR)/docintro \
-css-style style.css
ml-dot: $(MLFILES)
- $(OCAMLDOC) -dot -dot-reduce -rectypes -I +threads -I $(CAMLLIB) -I $(MYCAMLP4LIB) $(MLINCLUDES) \
+ $(OCAMLFIND) ocamldoc -dot -dot-reduce -rectypes -I +threads -I $(CAMLLIB) -I $(MYCAMLP4LIB) $(MLINCLUDES) \
$(filter $(addsuffix /%.ml,$(CORESRCDIRS)),$(MLFILES)) -o $(OCAMLDOCDIR)/coq.dot
%_dep.png: %.dot
$(DOT) -Tpng $< -o $@
%_types.dot: %.mli
- $(OCAMLDOC) -rectypes $(MLINCLUDES) $(ODOCDOTOPTS) -dot-types -o $@ $<
+ $(OCAMLFIND) ocamldoc -rectypes $(MLINCLUDES) $(ODOCDOTOPTS) -dot-types -o $@ $<
-OCAMLDOC_MLLIBD = $(OCAMLDOC) -rectypes $(MLINCLUDES) $(ODOCDOTOPTS) -o $@ \
+OCAMLDOC_MLLIBD = $(OCAMLFIND) ocamldoc -rectypes $(MLINCLUDES) $(ODOCDOTOPTS) -o $@ \
$(foreach lib,$(|:.mllib.d=_MLLIB_DEPENDENCIES),$(addsuffix .ml,$($(lib))))
%.dot: | %.mllib.d
$(OCAMLDOC_MLLIBD)
ml-doc:
- $(OCAMLDOC) -html -rectypes -I +threads $(MLINCLUDES) $(COQIDEFLAGS) -d $(OCAMLDOCDIR) $(MLSTATICFILES)
+ $(OCAMLFIND) ocamldoc -charset utf-8 -html -rectypes -I +threads $(MLINCLUDES) $(COQIDEFLAGS) -d $(OCAMLDOCDIR) $(MLSTATICFILES)
parsing/parsing.dot : | parsing/parsing.mllib.d parsing/highparsing.mllib.d
$(OCAMLDOC_MLLIBD)
@@ -869,10 +873,12 @@ tactics/tactics.dot: | tactics/tactics.mllib.d tactics/hightactics.mllib.d
$(OCAMLDOC_MLLIBD)
%.dot: %.mli
- $(OCAMLDOC) -rectypes $(MLINCLUDES) $(ODOCDOTOPTS) -o $@ $<
+ $(OCAMLFIND) ocamldoc -rectypes $(MLINCLUDES) $(ODOCDOTOPTS) -o $@ $<
$(OCAMLDOCDIR)/%.pdf: $(OCAMLDOCDIR)/%.tex
- (cd $(OCAMLDOCDIR) ; pdflatex $*.tex && pdflatex $*.tex)
+ $(SHOW)'PDFLATEX $*.tex'
+ $(HIDE)(cd $(OCAMLDOCDIR) ; pdflatex -interaction=batchmode $*.tex && pdflatex -interaction=batchmode $*.tex)
+ $(HIDE)(cd doc/tools/; show_latex_messages -no-overfull ../../$(OCAMLDOCDIR)/$*.log)
###########################################################################
### Special rules
@@ -1018,10 +1024,6 @@ endif
$(SHOW)'OCAMLLEX $<'
$(HIDE)$(OCAMLLEX) -o $@ "$*.mll"
-%.ml %.mli: %.mly
- $(SHOW)'OCAMLYACC $<'
- $(HIDE)$(OCAMLYACC) $<
-
plugins/%_mod.ml: plugins/%.mllib
$(SHOW)'ECHO... > $@'
$(HIDE)sed -e "s/\([^ ]\{1,\}\)/let _=Mltop.add_known_module\"\1\" /g" $< > $@
@@ -1061,35 +1063,39 @@ endif
# Since OCaml 3.12.1, we could use again ocamldep directly, thanks to
# the option -ml-synonym
-OCAMLDEP_NG = $(OCAMLDEP) -slash -ml-synonym .ml4
+OCAMLDEP_NG = $(OCAMLFIND) ocamldep -slash -ml-synonym .ml4
-checker/%.ml.d: $(D_DEPEND_BEFORE_SRC) checker/%.ml $(D_DEPEND_AFTER_SRC) $(COQDEPBOOT) $(GENFILES)
+checker/%.ml.d: $(D_DEPEND_BEFORE_SRC) checker/%.ml $(D_DEPEND_AFTER_SRC) $(GENFILES)
$(SHOW)'OCAMLDEP $<'
$(HIDE)$(OCAMLDEP_NG) $(LOCALCHKLIBS) "$<" $(TOTARGET)
-checker/%.mli.d: $(D_DEPEND_BEFORE_SRC) checker/%.mli $(D_DEPEND_AFTER_SRC) $(COQDEPBOOT) $(GENFILES)
+checker/%.mli.d: $(D_DEPEND_BEFORE_SRC) checker/%.mli $(D_DEPEND_AFTER_SRC) $(GENFILES)
$(SHOW)'OCAMLDEP $<'
$(HIDE)$(OCAMLDEP_NG) $(LOCALCHKLIBS) "$<" $(TOTARGET)
-%.ml.d: $(D_DEPEND_BEFORE_SRC) %.ml $(D_DEPEND_AFTER_SRC) $(COQDEPBOOT) $(GENFILES)
+%.ml.d: $(D_DEPEND_BEFORE_SRC) %.ml $(D_DEPEND_AFTER_SRC) $(GENFILES)
$(SHOW)'OCAMLDEP $<'
$(HIDE)$(OCAMLDEP_NG) $(DEPFLAGS) "$<" $(TOTARGET)
-%.mli.d: $(D_DEPEND_BEFORE_SRC) %.mli $(D_DEPEND_AFTER_SRC) $(COQDEPBOOT) $(GENFILES)
+%.mli.d: $(D_DEPEND_BEFORE_SRC) %.mli $(D_DEPEND_AFTER_SRC) $(GENFILES)
$(SHOW)'OCAMLDEP $<'
$(HIDE)$(OCAMLDEP_NG) $(DEPFLAGS) "$<" $(TOTARGET)
-checker/%.mllib.d: $(D_DEPEND_BEFORE_SRC) checker/%.mllib $(D_DEPEND_AFTER_SRC) $(COQDEPBOOT) $(GENFILES)
- $(SHOW)'COQDEP $<'
- $(HIDE)$(COQDEPBOOT) -I checker -c "$<" $(TOTARGET)
+checker/%.mllib.d: $(D_DEPEND_BEFORE_SRC) checker/%.mllib $(D_DEPEND_AFTER_SRC) $(OCAMLLIBDEP) $(GENFILES)
+ $(SHOW)'OCAMLLIBDEP $<'
+ $(HIDE)$(OCAMLLIBDEP) $(LOCALCHKLIBS) "$<" $(TOTARGET)
+
+dev/%.mllib.d: $(D_DEPEND_BEFORE_SRC) dev/%.mllib $(D_DEPEND_AFTER_SRC) $(OCAMLLIBDEP) $(GENFILES)
+ $(SHOW)'OCAMLLIBDEP $<'
+ $(HIDE)$(OCAMLLIBDEP) $(DEPFLAGS) -I dev "$<" $(TOTARGET)
-%.mllib.d: $(D_DEPEND_BEFORE_SRC) %.mllib $(D_DEPEND_AFTER_SRC) $(COQDEPBOOT) $(GENFILES)
- $(SHOW)'COQDEP $<'
- $(HIDE)$(COQDEPBOOT) -I kernel -I tools/coqdoc -c "$<" $(TOTARGET)
+%.mllib.d: $(D_DEPEND_BEFORE_SRC) %.mllib $(D_DEPEND_AFTER_SRC) $(OCAMLLIBDEP) $(GENFILES)
+ $(SHOW)'OCAMLLIBDEP $<'
+ $(HIDE)$(OCAMLLIBDEP) $(DEPFLAGS) "$<" $(TOTARGET)
-%.v.d: $(D_DEPEND_BEFORE_SRC) %.v $(D_DEPEND_AFTER_SRC) $(COQDEPBOOT) $(GENVFILES)
+%.v.d: $(D_DEPEND_BEFORE_SRC) %.v $(D_DEPEND_AFTER_SRC) $(COQDEP) $(GENVFILES)
$(SHOW)'COQDEP $<'
- $(HIDE)$(COQDEPBOOT) $(DEPNATDYN) "$<" $(TOTARGET)
+ $(HIDE)$(COQDEP) -boot $(DEPNATDYN) "$<" $(TOTARGET)
%_stubs.c.d: $(D_DEPEND_BEFORE_SRC) %_stubs.c $(D_DEPEND_AFTER_SRC)
$(SHOW)'CCDEP $<'
diff --git a/Makefile.common b/Makefile.common
index 1a903539c..6cf332686 100644
--- a/Makefile.common
+++ b/Makefile.common
@@ -63,7 +63,7 @@ CSDPCERT:=plugins/micromega/csdpcert$(EXE)
CORESRCDIRS:=\
config lib kernel kernel/byterun library \
proofs tactics pretyping interp stm \
- toplevel parsing printing grammar intf
+ toplevel parsing printing grammar intf engine
PLUGINS:=\
omega romega micromega quote \
@@ -87,7 +87,7 @@ CHKSRCDIRS:= checker lib config kernel parsing
###########################################################################
COQDEP:=bin/coqdep$(EXE)
-COQDEPBOOT:=bin/coqdep_boot$(EXE)
+OCAMLLIBDEP:=bin/ocamllibdep$(EXE)
COQMAKEFILE:=bin/coq_makefile$(EXE)
GALLINA:=bin/gallina$(EXE)
COQTEX:=bin/coq-tex$(EXE)
@@ -99,7 +99,7 @@ COQWORKMGR:=bin/coqworkmgr$(EXE)
TOOLS:=$(COQDEP) $(COQMAKEFILE) $(GALLINA) $(COQTEX) $(COQWC) $(COQDOC) $(COQC)\
$(COQWORKMGR)
-PRIVATEBINARIES:=$(FAKEIDE) $(COQDEPBOOT)
+PRIVATEBINARIES:=$(FAKEIDE) $(OCAMLLIBDEP)
###########################################################################
# Documentation
@@ -166,7 +166,7 @@ BYTERUN:=$(addprefix kernel/byterun/, \
# the libraries directly
CORECMA:=lib/clib.cma lib/lib.cma kernel/kernel.cma library/library.cma \
- pretyping/pretyping.cma interp/interp.cma proofs/proofs.cma \
+ engine/engine.cma pretyping/pretyping.cma interp/interp.cma proofs/proofs.cma \
parsing/parsing.cma printing/printing.cma tactics/tactics.cma \
stm/stm.cma toplevel/toplevel.cma parsing/highparsing.cma tactics/hightactics.cma
@@ -260,7 +260,7 @@ CSDPCERTCMO:=$(addprefix plugins/micromega/, \
DEBUGPRINTERS:=dev/top_printers.cmo dev/vm_printers.cmo dev/printers.cma
-COQDEPCMO:=$(COQENVCMO) tools/coqdep_lexer.cmo tools/coqdep_common.cmo tools/coqdep.cmo
+COQDEPCMO:=$(COQENVCMO) lib/system.cmo tools/coqdep_lexer.cmo tools/coqdep_common.cmo tools/coqdep.cmo
COQDOCCMO:=lib/clib.cma $(addprefix tools/coqdoc/, \
cdglobals.cmo alpha.cmo index.cmo tokens.cmo output.cmo cpretty.cmo main.cmo )
@@ -377,7 +377,7 @@ MANPAGES:=man/coq-tex.1 man/coqdep.1 man/gallina.1 \
OCAMLDOCDIR=dev/ocamldoc
DOCMLIS=$(wildcard ./lib/*.mli ./intf/*.mli ./kernel/*.mli ./library/*.mli \
- ./pretyping/*.mli ./interp/*.mli printing/*.mli \
+ ./engine/*.mli ./pretyping/*.mli ./interp/*.mli printing/*.mli \
./parsing/*.mli ./proofs/*.mli \
./tactics/*.mli ./stm/*.mli ./toplevel/*.mli)
diff --git a/_tags b/_tags
index 5c978cabd..f805eeaa3 100644
--- a/_tags
+++ b/_tags
@@ -63,6 +63,7 @@
"library": include
"parsing": include
"plugins": include
+"engine": include
"pretyping": include
"printing": include
"proofs": include
diff --git a/checker/check.mllib b/checker/check.mllib
index 0d36e3a0f..3725989e8 100644
--- a/checker/check.mllib
+++ b/checker/check.mllib
@@ -8,6 +8,7 @@ Hashcons
CSet
CMap
Int
+Dyn
HMap
Option
Store
@@ -35,6 +36,7 @@ Errors
Ephemeron
Future
CUnix
+
System
Profile
RemoteCounter
diff --git a/checker/checker.ml b/checker/checker.ml
index 825fb4dc7..91a207a60 100644
--- a/checker/checker.ml
+++ b/checker/checker.ml
@@ -217,12 +217,6 @@ open Type_errors
let anomaly_string () = str "Anomaly: "
let report () = (str "." ++ spc () ++ str "Please report.")
-let print_loc loc =
- if loc = Loc.ghost then
- (str"<unknown>")
- else
- let loc = Loc.unloc loc in
- (int (fst loc) ++ str"-" ++ int (snd loc))
let guill s = str "\"" ++ str s ++ str "\""
let where s =
@@ -337,8 +331,6 @@ let parse_args argv =
| ("-I"|"-include") :: d :: rem -> set_default_include d; parse rem
| ("-I"|"-include") :: [] -> usage ()
- | "-R" :: d :: "-as" :: p :: rem -> set_rec_include d p;parse rem
- | "-R" :: d :: "-as" :: [] -> usage ()
| "-R" :: d :: p :: rem -> set_rec_include d p;parse rem
| "-R" :: ([] | [_]) -> usage ()
diff --git a/checker/safe_typing.ml b/checker/safe_typing.ml
index fa4297550..7f9ed92f9 100644
--- a/checker/safe_typing.ml
+++ b/checker/safe_typing.ml
@@ -13,6 +13,8 @@ open Cic
open Names
open Environ
+let pr_dirpath dp = str (DirPath.to_string dp)
+
(************************************************************************)
(*
* Global environment
@@ -52,9 +54,9 @@ let check_engagement env (expected_impredicative_set,expected_type_in_type) =
let report_clash f caller dir =
let msg =
- str "compiled library " ++ str(DirPath.to_string caller) ++
+ str "compiled library " ++ pr_dirpath caller ++
spc() ++ str "makes inconsistent assumptions over library" ++ spc() ++
- str(DirPath.to_string dir) ++ fnl() in
+ pr_dirpath dir ++ fnl() in
f msg
diff --git a/checker/votour.ml b/checker/votour.ml
index 78978bb26..79755da4a 100644
--- a/checker/votour.ml
+++ b/checker/votour.ml
@@ -22,6 +22,7 @@ sig
val input : in_channel -> obj
val repr : obj -> obj repr
val size : obj -> int
+ val oid : obj -> int option
end
module ReprObj : S =
@@ -45,6 +46,7 @@ struct
else INT (Obj.magic obj)
let size (_, p) = CObj.shared_size_of_pos p
+ let oid _ = None
end
module ReprMem : S =
@@ -97,6 +99,9 @@ struct
let _ = init_size seen obj in
obj
+ let oid = function
+ | Int _ | Atm _ | Fun _ -> None
+ | Ptr p -> Some p
end
module Visit (Repr : S) :
@@ -149,9 +154,13 @@ let rec get_details v o = match v, Repr.repr o with
|Annot (s,v), _ -> get_details v o
|_ -> ""
+let get_oid obj = match Repr.oid obj with
+| None -> ""
+| Some id -> Printf.sprintf " [0x%08x]" id
+
let node_info (v,o,p) =
get_name ~extra:true v ^ get_details v o ^
- " (size "^ string_of_int (Repr.size o)^"w)"
+ " (size "^ string_of_int (Repr.size o)^"w)" ^ get_oid o
(** Children of a block : type, object, position.
For lists, we collect all elements of the list at once *)
diff --git a/config/coq_config.mli b/config/coq_config.mli
index f25005931..a0e1019fa 100644
--- a/config/coq_config.mli
+++ b/config/coq_config.mli
@@ -14,12 +14,7 @@ val datadir : string option (* where extra data files are installed *)
val docdir : string (* where the doc is installed *)
val ocaml : string (* names of ocaml binaries *)
-val ocamlc : string
-val ocamlopt : string
-val ocamlmklib : string
-val ocamldoc : string
-val ocamldep : string
-val ocamlyacc : string
+val ocamlfind : string
val ocamllex : string
val camlbin : string (* base directory of OCaml binaries *)
diff --git a/configure.ml b/configure.ml
index 7ab197094..b8bb650b1 100644
--- a/configure.ml
+++ b/configure.ml
@@ -11,11 +11,11 @@
#load "str.cma"
open Printf
-let coq_version = "8.5"
-let coq_macos_version = "8.5.0" (** "[...] should be a string comprised of
+let coq_version = "trunk"
+let coq_macos_version = "8.4.90" (** "[...] should be a string comprised of
three non-negative, period-separed integers [...]" *)
-let vo_magic = 8500
-let state_magic = 58500
+let vo_magic = 8511
+let state_magic = 58511
let distributed_exec = ["coqtop";"coqc";"coqchk";"coqdoc";"coqmktop";"coqworkmgr";
"coqdoc";"coq_makefile";"coq-tex";"gallina";"coqwc";"csdpcert";"coqdep"]
@@ -236,7 +236,7 @@ module Prefs = struct
let docdir = ref (None : string option)
let emacslib = ref (None : string option)
let coqdocdir = ref (None : string option)
- let camldir = ref (None : string option)
+ let ocamlfindcmd = ref (None : string option)
let lablgtkdir = ref (None : string option)
let usecamlp5 = ref true
let camlp5dir = ref (None : string option)
@@ -290,8 +290,8 @@ let args_options = Arg.align [
"<dir> Obsolete: same as -emacslib";
"-coqdocdir", arg_string_option Prefs.coqdocdir,
"<dir> Where to install Coqdoc style files";
- "-camldir", arg_string_option Prefs.camldir,
- "<dir> Specifies the path to the OCaml binaries";
+ "-ocamlfind", arg_string_option Prefs.ocamlfindcmd,
+ "<dir> Specifies the ocamlfind command to use";
"-lablgtkdir", arg_string_option Prefs.lablgtkdir,
"<dir> Specifies the path to the Lablgtk library";
"-usecamlp5", Arg.Set Prefs.usecamlp5,
@@ -352,42 +352,18 @@ let _ = parse_args ()
(** Default OCaml binaries *)
type camlexec =
- { mutable byte : string;
- mutable opt : string;
+ { mutable find : string;
mutable top : string;
- mutable mklib : string;
- mutable dep : string;
- mutable doc : string;
- mutable lex : string;
- mutable yacc : string }
-
-(* TODO: autodetect .opt binaries ? *)
+ mutable lex : string; }
let camlexec =
- { byte = "ocamlc";
- opt = "ocamlopt";
+ { find = "ocamlfind";
top = "ocaml";
- mklib = "ocamlmklib";
- dep = "ocamldep";
- doc = "ocamldoc";
- lex = "ocamllex";
- yacc = "ocamlyacc" }
-
-let reset_caml_byte c o = c.byte <- o
-let reset_caml_opt c o = c.opt <- o
-let reset_caml_doc c o = c.doc <- o
+ lex = "ocamllex"; }
+
let reset_caml_lex c o = c.lex <- o
-let reset_caml_dep c o = c.dep <- o
-
-let rebase_camlexec dir c =
- c.byte <- Filename.concat dir c.byte;
- c.opt <- Filename.concat dir c.opt;
- c.top <- Filename.concat dir c.top;
- c.mklib <- Filename.concat dir c.mklib;
- c.dep <- Filename.concat dir c.dep;
- c.doc <- Filename.concat dir c.doc;
- c.lex <- Filename.concat dir c.lex;
- c.yacc <- Filename.concat dir c.yacc
+let reset_caml_top c o = c.top <- o
+let reset_caml_find c o = c.find <- o
let coq_debug_flag = if !Prefs.debug then "-g" else ""
let coq_profile_flag = if !Prefs.profile then "-p" else ""
@@ -471,32 +447,28 @@ let browser =
(** * OCaml programs *)
let camlbin, caml_version, camllib =
- let camlbin, camlc = match !Prefs.camldir with
- | Some dir ->
- rebase_camlexec dir camlexec;
- Filename.dirname camlexec.byte, camlexec.byte
- | None ->
- try let camlc = which camlexec.byte in
- let dir = Filename.dirname camlc in
- if not arch_win32 then rebase_camlexec dir camlexec; (* win32: TOCHECK *)
- dir, camlc
- with Not_found ->
- die (sprintf "Error: cannot find '%s' in your path!\n" camlexec.byte ^
- "Please adjust your path or use the -camldir option of ./configure")
+ let () = match !Prefs.ocamlfindcmd with
+ | Some cmd -> reset_caml_find camlexec cmd
+ | None ->
+ try reset_caml_find camlexec (which camlexec.find)
+ with Not_found ->
+ die (sprintf "Error: cannot find '%s' in your path!\n" camlexec.find ^
+ "Please adjust your path or use the -ocamlfind option of ./configure")
in
- let camlcopt = camlc ^ ".opt" in
- let camlc =
- if is_executable camlcopt then begin
- reset_caml_byte camlexec (camlexec.byte ^ ".opt");
- camlcopt
- end
- else if is_executable camlc then
- camlc
- else
- die ("Error: cannot find the executable '"^camlc^"'.") in
- let caml_version, _ = run camlc ["-version"] in
- let camllib, _ = run camlc ["-where"] in
- camlbin, caml_version, camllib
+ if not (is_executable camlexec.find)
+ then die ("Error: cannot find the executable '"^camlexec.find^"'.")
+ else
+ let caml_version, _ = run camlexec.find ["ocamlc";"-version"] in
+ let camllib, _ = run camlexec.find ["printconf";"stdlib"] in
+ let camlbin = (* TODO beurk beurk beurk *)
+ Filename.dirname (Filename.dirname camllib) / "bin/" in
+ let () =
+ if is_executable (camlbin / "ocamllex")
+ then reset_caml_lex camlexec (camlbin / "ocamllex") in
+ let () =
+ if is_executable (camlbin / "ocaml")
+ then reset_caml_top camlexec (camlbin / "ocaml") in
+ camlbin, caml_version, camllib
let camlp4compat = "-loc loc"
@@ -544,12 +516,8 @@ let camltag = match caml_version_list with
(* Convention: we use camldir as a prioritary location for camlpX, if given *)
let which_camlpX base =
- match !Prefs.camldir with
- | Some dir ->
- let file = Filename.concat dir base in
- if is_executable file then file else which base
- | None ->
- which base
+ let file = Filename.concat camlbin base in
+ if is_executable file then file else which base
(* TODO: camlp5dir should rather be the *binary* location, just as camldir *)
(* TODO: remove the late attempts at finding gramlib.cma *)
@@ -646,40 +614,23 @@ let msg_no_dynlink_cmxa () =
printf "and then run ./configure -natdynlink no\n"
let check_native () =
- if !Prefs.byteonly then raise Not_found;
- let camloptopt = camlexec.opt ^ ".opt" in
- if (is_executable camloptopt || program_in_path camloptopt) then
- reset_caml_opt camlexec camloptopt
- else if not (is_executable camlexec.opt || program_in_path camlexec.opt) then
- (msg_no_ocamlopt (); raise Not_found);
- if not (Sys.file_exists (fullcamlpXlibdir/camlpXmod^".cmxa")) then
- (msg_no_camlpX_cmxa (); raise Not_found);
- if not (Sys.file_exists (camllib/"dynlink.cmxa")) then
- (msg_no_dynlink_cmxa (); raise Not_found);
- let version, _ = run camlexec.opt ["-version"] in
- if version <> caml_version then
- printf
- "Warning: Native and bytecode compilers do not have the same version!\n";
- printf "You have native-code compilation. Good!\n"
+ let () = if !Prefs.byteonly then raise Not_found in
+ let version, _ = tryrun camlexec.find ["opt";"-version"] in
+ if version = "" then let () = msg_no_ocamlopt () in raise Not_found
+ else if not (Sys.file_exists (fullcamlpXlibdir/camlpXmod^".cmxa"))
+ then let () = msg_no_camlpX_cmxa () in raise Not_found
+ else if fst (tryrun camlexec.find ["query";"dynlink"]) = ""
+ then let () = msg_no_dynlink_cmxa () in raise Not_found
+ else
+ let () =
+ if version <> caml_version then
+ printf
+ "Warning: Native and bytecode compilers do not have the same version!\n"
+ in printf "You have native-code compilation. Good!\n"
let best_compiler =
try check_native (); "opt" with Not_found -> "byte"
-let _ =
- let camllexopt = camlexec.lex ^ ".opt" in
- if is_executable camllexopt || program_in_path camllexopt then
- reset_caml_lex camlexec camllexopt
-
-let _ =
- let camldepopt = camlexec.dep ^ ".opt" in
- if is_executable camldepopt || program_in_path camldepopt then
- reset_caml_dep camlexec camldepopt
-
-let _ =
- let camldocopt = camlexec.doc ^ ".opt" in
- if is_executable camldocopt || program_in_path camldocopt then
- reset_caml_doc camlexec camldocopt
-
(** * Native dynlink *)
let hasnatdynlink = !Prefs.natdynlink && best_compiler = "opt"
@@ -719,10 +670,18 @@ let operating_system, osdeplibs =
(** * lablgtk2 and CoqIDE *)
+type source = Manual | OCamlFind | Stdlib
+
+let get_source = function
+| Manual -> "manually provided"
+| OCamlFind -> "via ocamlfind"
+| Stdlib -> "in OCaml library"
+
(** Is some location a suitable LablGtk2 installation ? *)
-let check_lablgtkdir ?(fatal=false) msg dir =
+let check_lablgtkdir ?(fatal=false) src dir =
let yell msg = if fatal then die msg else (printf "%s\n" msg; false) in
+ let msg = get_source src in
if not (dir_exists dir) then
yell (sprintf "No such directory '%s' (%s)." dir msg)
else if not (Sys.file_exists (dir/"gSourceView2.cmi")) then
@@ -736,11 +695,11 @@ let check_lablgtkdir ?(fatal=false) msg dir =
let get_lablgtkdir () =
match !Prefs.lablgtkdir with
| Some dir ->
- let msg = "manually provided" in
+ let msg = Manual in
if check_lablgtkdir ~fatal:true msg dir then dir, msg
- else "", ""
+ else "", msg
| None ->
- let msg = "via ocamlfind" in
+ let msg = OCamlFind in
let d1,_ = tryrun "ocamlfind" ["query";"lablgtk2.sourceview2"] in
if d1 <> "" && check_lablgtkdir msg d1 then d1, msg
else
@@ -748,10 +707,34 @@ let get_lablgtkdir () =
let d2,_ = tryrun "ocamlfind" ["query";"lablgtk2"] in
if d2 <> "" && d2 <> d1 && check_lablgtkdir msg d2 then d2, msg
else
- let msg = "in OCaml library" in
+ let msg = Stdlib in
let d3 = camllib^"/lablgtk2" in
if check_lablgtkdir msg d3 then d3, msg
- else "", ""
+ else "", msg
+
+(** Detect and/or verify the Lablgtk2 version *)
+
+let check_lablgtk_version src dir = match src with
+| Manual | Stdlib ->
+ let test accu f =
+ if accu then
+ let test = sprintf "grep -q -w %s %S/glib.mli" f dir in
+ Sys.command test = 0
+ else false
+ in
+ let heuristics = [
+ "convert_with_fallback";
+ "wrap_poll_func"; (** Introduced in lablgtk 2.16 *)
+ ] in
+ let ans = List.fold_left test true heuristics in
+ if ans then printf "Warning: could not check the version of lablgtk2.\n";
+ (ans, "an unknown version")
+| OCamlFind ->
+ let v, _ = tryrun "ocamlfind" ["query"; "-format"; "%v"; "lablgtk2"] in
+ try
+ let vi = List.map s2i (numeric_prefix_list v) in
+ ([2; 16] <= vi, v)
+ with _ -> (false, v)
let pr_ide = function No -> "no" | Byte -> "only bytecode" | Opt -> "native"
@@ -775,9 +758,9 @@ let check_coqide () =
if !Prefs.coqide = Some No then set_ide No "CoqIde manually disabled";
let dir, via = get_lablgtkdir () in
if dir = "" then set_ide No "LablGtk2 not found";
- let found = sprintf "LablGtk2 found (%s)" via in
- let test = sprintf "grep -q -w convert_with_fallback %S/glib.mli" dir in
- if Sys.command test <> 0 then set_ide No (found^" but too old");
+ let (ok, version) = check_lablgtk_version via dir in
+ let found = sprintf "LablGtk2 found (%s, %s)" (get_source via) version in
+ if not ok then set_ide No (found^", but too old (required >= 2.16, found " ^ version ^ ")");
(* We're now sure to produce at least one kind of coqide *)
lablgtkdir := shorten_camllib dir;
if !Prefs.coqide = Some Byte then set_ide Byte (found^", bytecode requested");
@@ -830,14 +813,14 @@ let strip =
if hasnatdynlink then "true" else "strip"
else
if !Prefs.profile || !Prefs.debug then "true" else begin
- let _, all = run camlexec.byte ["-config"] in
+ let _, all = run camlexec.find ["ocamlc";"-config"] in
let strip = String.concat "" (List.map (fun l ->
match string_split ' ' l with
| "ranlib:" :: cc :: _ -> (* on windows, we greb the right strip *)
Str.replace_first (Str.regexp "ranlib") "strip" cc
| _ -> ""
) all) in
- if strip = "" then "stip" else strip
+ if strip = "" then "strip" else strip
end
(** * md5sum command *)
@@ -1047,12 +1030,7 @@ let write_configml f =
pr_o "datadir" datadir;
pr_s "docdir" docdir;
pr_s "ocaml" camlexec.top;
- pr_s "ocamlc" camlexec.byte;
- pr_s "ocamlopt" camlexec.opt;
- pr_s "ocamlmklib" camlexec.mklib;
- pr_s "ocamldep" camlexec.dep;
- pr_s "ocamldoc" camlexec.doc;
- pr_s "ocamlyacc" camlexec.yacc;
+ pr_s "ocamlfind" camlexec.find;
pr_s "ocamllex" camlexec.lex;
pr_s "camlbin" camlbin;
pr_s "camllib" camllib;
@@ -1136,13 +1114,8 @@ let write_makefile f =
pr "VERSION4MACOS=%s\n\n" coq_macos_version;
pr "# Objective-Caml compile command\n";
pr "OCAML=%S\n" camlexec.top;
- pr "OCAMLC=%S\n" camlexec.byte;
- pr "OCAMLMKLIB=%S\n" camlexec.mklib;
- pr "OCAMLOPT=%S\n" camlexec.opt;
- pr "OCAMLDEP=%S\n" camlexec.dep;
- pr "OCAMLDOC=%S\n" camlexec.doc;
+ pr "OCAMLFIND=%S\n" camlexec.find;
pr "OCAMLLEX=%S\n" camlexec.lex;
- pr "OCAMLYACC=%S\n\n" camlexec.yacc;
pr "# The best compiler: native (=opt) or bytecode (=byte)\n";
pr "BEST=%s\n\n" best_compiler;
pr "# Ocaml version number\n";
@@ -1152,8 +1125,6 @@ let write_makefile f =
pr "# Ocaml .h directory\n";
pr "CAMLHLIB=%S\n\n" camllib;
pr "# Caml link command and Caml make top command\n";
- pr "CAMLLINK=%S\n" camlexec.byte;
- pr "CAMLOPTLINK=%S\n\n" camlexec.opt;
pr "# Caml flags\n";
pr "CAMLFLAGS=-rectypes %s\n" coq_annotate_flag;
pr "# User compilation flag\n";
diff --git a/dev/base_include b/dev/base_include
index dac1f6093..767e023ea 100644
--- a/dev/base_include
+++ b/dev/base_include
@@ -8,6 +8,7 @@
#directory "toplevel";;
#directory "library";;
#directory "kernel";;
+#directory "engine";;
#directory "pretyping";;
#directory "lib";;
#directory "proofs";;
diff --git a/dev/db b/dev/db
index 36a171af1..86e35a3ec 100644
--- a/dev/db
+++ b/dev/db
@@ -11,6 +11,7 @@ install_printer Top_printers.ppexistentialset
install_printer Top_printers.ppintset
install_printer Top_printers.pplab
install_printer Top_printers.ppdir
+install_printer Top_printers.ppmbid
install_printer Top_printers.ppmp
install_printer Top_printers.ppkn
install_printer Top_printers.ppcon
diff --git a/dev/doc/changes.txt b/dev/doc/changes.txt
index 2f62be9af..c143afd37 100644
--- a/dev/doc/changes.txt
+++ b/dev/doc/changes.txt
@@ -1,4 +1,54 @@
=========================================
+= CHANGES BETWEEN COQ V8.5 AND CQQ V8.6 =
+=========================================
+
+- The interface of the Context module was changed.
+ Related types and functions were put in separate submodules.
+ The mapping from old identifiers to new identifiers is the following:
+
+ Context.named_declaration ---> Context.Named.Declaration.t
+ Context.named_list_declaration ---> Context.NamedList.Declaration.t
+ Context.rel_declaration ---> Context.Rel.Declaration.t
+ Context.map_named_declaration ---> Context.Named.Declaration.map
+ Context.map_named_list_declaration ---> Context.NamedList.Declaration.map
+ Context.map_rel_declaration ---> Context.Rel.Declaration.map
+ Context.fold_named_declaration ---> Context.Named.Declaration.fold
+ Context.fold_rel_declaration ---> Context.Rel.Declaration.fold
+ Context.exists_named_declaration ---> Context.Named.Declaration.exists
+ Context.exists_rel_declaration ---> Context.Rel.Declaration.exists
+ Context.for_all_named_declaration ---> Context.Named.Declaration.for_all
+ Context.for_all_rel_declaration ---> Context.Rel.Declaration.for_all
+ Context.eq_named_declaration ---> Context.Named.Declaration.equal
+ Context.eq_rel_declaration ---> Context.Rel.Declaration.equal
+ Context.named_context ---> Context.Named.t
+ Context.named_list_context ---> Context.NamedList.t
+ Context.rel_context ---> Context.Rel.t
+ Context.empty_named_context ---> Context.Named.empty
+ Context.add_named_decl ---> Context.Named.add
+ Context.vars_of_named_context ---> Context.Named.to_vars
+ Context.lookup_named ---> Context.Named.lookup
+ Context.named_context_length ---> Context.Named.length
+ Context.named_context_equal ---> Context.Named.equal
+ Context.fold_named_context ---> Context.Named.fold_outside
+ Context.fold_named_list_context ---> Context.NamedList.fold
+ Context.fold_named_context_reverse ---> Context.Named.fold_inside
+ Context.instance_from_named_context ---> Context.Named.to_instance
+ Context.extended_rel_list ---> Context.Rel.to_extended_list
+ Context.extended_rel_vect ---> Context.Rel.to_extended_vect
+ Context.fold_rel_context ---> Context.Rel.fold_outside
+ Context.fold_rel_context_reverse ---> Context.Rel.fold_inside
+ Context.map_rel_context ---> Context.Rel.map
+ Context.map_named_context ---> Context.Named.map
+ Context.iter_rel_context ---> Context.Rel.iter
+ Context.iter_named_context ---> Context.Named.iter
+ Context.empty_rel_context ---> Context.Rel.empty
+ Context.add_rel_decl ---> Context.Rel.add
+ Context.lookup_rel ---> Context.Rel.lookup
+ Context.rel_context_length ---> Context.Rel.length
+ Context.rel_context_nhyps ---> Context.Rel.nhyps
+ Context.rel_context_tags ---> Context.Rel.to_tags
+
+=========================================
= CHANGES BETWEEN COQ V8.4 AND CQQ V8.5 =
=========================================
diff --git a/dev/ocamldebug-coq.run b/dev/ocamldebug-coq.run
index d4ab22ced..b00d084ed 100644
--- a/dev/ocamldebug-coq.run
+++ b/dev/ocamldebug-coq.run
@@ -17,7 +17,8 @@ exec $OCAMLDEBUG \
-I $COQTOP \
-I $COQTOP/config -I $COQTOP/printing -I $COQTOP/grammar \
-I $COQTOP/lib -I $COQTOP/intf -I $COQTOP/kernel \
- -I $COQTOP/library -I $COQTOP/pretyping -I $COQTOP/parsing \
+ -I $COQTOP/library -I $COQTOP/engine \
+ -I $COQTOP/pretyping -I $COQTOP/parsing \
-I $COQTOP/interp -I $COQTOP/proofs -I $COQTOP/tactics -I $COQTOP/stm \
-I $COQTOP/toplevel -I $COQTOP/dev -I $COQTOP/config \
-I $COQTOP/plugins/cc -I $COQTOP/plugins/dp \
diff --git a/dev/ocamldoc/fix-ocamldoc-utf8 b/dev/ocamldoc/fix-ocamldoc-utf8
new file mode 100755
index 000000000..fe2e0c115
--- /dev/null
+++ b/dev/ocamldoc/fix-ocamldoc-utf8
@@ -0,0 +1,6 @@
+#!/bin/sh
+
+# This reverts automatic translation of latin1 accentuated letters by ocamldoc
+# Usage: fix-ocamldoc-utf8 file
+
+sed -i -e 's/\\`a/\d224/g' -e "s/\\\^a/\d226/g" -e "s/\\\'e/\d233/g" -e 's/\\`e/\d232/g' -e "s/\\\^e/\d234/g" -e 's/\\\"e/\d235/g' -e "s/\\\^o/\d244/g" -e 's/\\\"o/\d246/g' -e "s/\\\^i/\d238/g" -e 's/\\\"i/\d239/g' -e 's/\\`u/\d249/g' -e "s/\\\^u/\d251/g" -e "s/\\\c{c}/\d231/g" $1
diff --git a/dev/ocamldoc/header.tex b/dev/ocamldoc/header.tex
new file mode 100644
index 000000000..4091f8144
--- /dev/null
+++ b/dev/ocamldoc/header.tex
@@ -0,0 +1,14 @@
+\documentclass[11pt]{article}
+\usepackage[utf8x]{inputenc}
+\usepackage[T1]{fontenc}
+\usepackage{textcomp}
+\usepackage{tipa}
+\usepackage{textgreek}
+\usepackage{fullpage}
+\usepackage{url}
+\usepackage{ocamldoc}
+\title{Coq mlis documentation}
+\begin{document}
+\maketitle
+\tableofcontents
+\vspace{0.2cm}
diff --git a/dev/printers.mllib b/dev/printers.mllib
index ab7e9fc34..bb627f590 100644
--- a/dev/printers.mllib
+++ b/dev/printers.mllib
@@ -8,6 +8,7 @@ Hashcons
CSet
CMap
Int
+Dyn
HMap
Option
Store
@@ -36,7 +37,6 @@ Util
Ppstyle
Errors
Bigint
-Dyn
CUnix
System
Envars
@@ -55,6 +55,7 @@ Monad
Names
Univ
+UGraph
Esubst
Uint31
Sorts
@@ -116,7 +117,9 @@ Miscops
Universes
Termops
Namegen
+UState
Evd
+Sigma
Glob_ops
Redops
Reductionops
@@ -188,6 +191,7 @@ Pfedit
Tactic_debug
Decl_mode
Ppconstr
+Entry
Pcoq
Printer
Pptactic
diff --git a/dev/top_printers.ml b/dev/top_printers.ml
index 6e5b048cc..aef9b10b2 100644
--- a/dev/top_printers.ml
+++ b/dev/top_printers.ml
@@ -40,10 +40,10 @@ let ppid id = pp (pr_id id)
let pplab l = pp (pr_lab l)
let ppmbid mbid = pp (str (MBId.debug_to_string mbid))
let ppdir dir = pp (pr_dirpath dir)
-let ppmp mp = pp(str (string_of_mp mp))
+let ppmp mp = pp(str (ModPath.debug_to_string mp))
let ppcon con = pp(debug_pr_con con)
let ppproj con = pp(debug_pr_con (Projection.constant con))
-let ppkn kn = pp(pr_kn kn)
+let ppkn kn = pp(str (KerName.to_string kn))
let ppmind kn = pp(debug_pr_mind kn)
let ppind (kn,i) = pp(debug_pr_mind kn ++ str"," ++int i)
let ppsp sp = pp(pr_path sp)
@@ -221,7 +221,7 @@ let ppuniverseconstraints c = pp (Universes.Constraints.pr c)
let ppuniverse_context_future c =
let ctx = Future.force c in
ppuniverse_context ctx
-let ppuniverses u = pp (Univ.pr_universes Level.pr u)
+let ppuniverses u = pp (UGraph.pr_universes Level.pr u)
let ppnamedcontextval e =
pp (pr_named_context (Global.env ()) Evd.empty (named_context_of_val e))
@@ -467,12 +467,13 @@ let pp_generic_argument arg =
pp(str"<genarg:"++pr_argument_type(genarg_tag arg)++str">")
let prgenarginfo arg =
- let tpe = pr_argument_type (genarg_tag arg) in
- let pr_gtac _ x = Pptactic.pr_glob_tactic (Global.env()) x in
- try
- let data = Pptactic.pr_top_generic pr_constr pr_lconstr pr_gtac pr_constr_pattern arg in
- str "<genarg:" ++ tpe ++ str " := [ " ++ data ++ str " ] >"
- with _any ->
+ let Val.Dyn (tag, _) = arg in
+ let tpe = Val.repr tag in
+ (** FIXME *)
+(* try *)
+(* let data = Pptactic.pr_top_generic (Global.env ()) arg in *)
+(* str "<genarg:" ++ tpe ++ str " := [ " ++ data ++ str " ] >" *)
+(* with _any -> *)
str "<genarg:" ++ tpe ++ str ">"
let ppgenarginfo arg = pp (prgenarginfo arg)
@@ -509,7 +510,7 @@ let _ =
try
Vernacinterp.vinterp_add false ("PrintConstr", 0)
(function
- [c] when genarg_tag c = ConstrArgType && true ->
+ [c] when genarg_tag c = unquote (topwit wit_constr) && true ->
let c = out_gen (rawwit wit_constr) c in
(fun () -> in_current_context constr_display c)
| _ -> failwith "Vernac extension: cannot occur")
@@ -519,14 +520,13 @@ let _ =
extend_vernac_command_grammar ("PrintConstr", 0) None
[GramTerminal "PrintConstr";
GramNonTerminal
- (Loc.ghost,ConstrArgType,Aentry ("constr","constr"),
- Some (Names.Id.of_string "c"))]
+ (Loc.ghost,rawwit wit_constr,Aentry (Entry.unsafe_of_name ("constr","constr")))]
let _ =
try
Vernacinterp.vinterp_add false ("PrintPureConstr", 0)
(function
- [c] when genarg_tag c = ConstrArgType && true ->
+ [c] when genarg_tag c = unquote (topwit wit_constr) && true ->
let c = out_gen (rawwit wit_constr) c in
(fun () -> in_current_context print_pure_constr c)
| _ -> failwith "Vernac extension: cannot occur")
@@ -536,8 +536,7 @@ let _ =
extend_vernac_command_grammar ("PrintPureConstr", 0) None
[GramTerminal "PrintPureConstr";
GramNonTerminal
- (Loc.ghost,ConstrArgType,Aentry ("constr","constr"),
- Some (Names.Id.of_string "c"))]
+ (Loc.ghost,rawwit wit_constr,Aentry (Entry.unsafe_of_name ("constr","constr")))]
(* Setting printer of unbound global reference *)
open Names
diff --git a/doc/common/macros.tex b/doc/common/macros.tex
index 3b12f259b..077e2f0df 100644
--- a/doc/common/macros.tex
+++ b/doc/common/macros.tex
@@ -198,6 +198,7 @@
\newcommand{\pattern}{\nterm{pattern}} % pattern for pattern-matching
\newcommand{\orpattern}{\nterm{or\_pattern}}
\newcommand{\intropattern}{\nterm{intro\_pattern}}
+\newcommand{\intropatternlist}{\nterm{intro\_pattern\_list}}
\newcommand{\disjconjintropattern}{\nterm{disj\_conj\_intro\_pattern}}
\newcommand{\namingintropattern}{\nterm{naming\_intro\_pattern}}
\newcommand{\termpattern}{\nterm{term\_pattern}} % term with holes
diff --git a/doc/refman/Program.tex b/doc/refman/Program.tex
index 3a99bfdd4..11dd3a051 100644
--- a/doc/refman/Program.tex
+++ b/doc/refman/Program.tex
@@ -261,7 +261,7 @@ tactic is replaced by the default one if not specified.
as implicit arguments of the special constant
\texttt{Program.Tactics.obligation}.
\item {\tt Set Shrink Obligations}\optindex{Shrink Obligations}
- Control whether obligations defined by tactics should have their
+ Control whether obligations should have their
context minimized to the set of variables used in the proof of the
obligation, to avoid unnecessary dependencies.
\end{itemize}
diff --git a/doc/refman/RefMan-ltac.tex b/doc/refman/RefMan-ltac.tex
index 5880487f7..cc7e6b53b 100644
--- a/doc/refman/RefMan-ltac.tex
+++ b/doc/refman/RefMan-ltac.tex
@@ -1041,6 +1041,18 @@ This tactical is useful with tactics such as \texttt{omega} or
the user can avoid the explosion at time of the \texttt{Save} command
without having to cut manually the proof in smaller lemmas.
+It may be useful to generate lemmas minimal w.r.t. the assumptions they depend
+on. This can be obtained thanks to the option below.
+
+\begin{quote}
+\optindex{Shrink Abstract}
+{\tt Set Shrink Abstract}
+\end{quote}
+
+When set, all lemmas generated through \texttt{abstract {\tacexpr}} are
+quantified only over the variables that appear in the term constructed by
+\texttt{\tacexpr}.
+
\begin{Variants}
\item \texttt{abstract {\tacexpr} using {\ident}}.\\
Give explicitly the name of the auxiliary lemma.
@@ -1089,7 +1101,7 @@ using the syntax:
{\tt Ltac} {\qualid} {\ident}$_1$ ... {\ident}$_n$ {\tt ::=}
{\tacexpr}
\end{quote}
-A previous definition of \qualid must exist in the environment.
+A previous definition of {\qualid} must exist in the environment.
The new definition will always be used instead of the old one and
it goes accross module boundaries.
diff --git a/doc/refman/RefMan-oth.tex b/doc/refman/RefMan-oth.tex
index 0a243308d..aea2bae38 100644
--- a/doc/refman/RefMan-oth.tex
+++ b/doc/refman/RefMan-oth.tex
@@ -914,6 +914,14 @@ This command turns off the normal displaying.
\subsection[\tt Unset Silent.]{\tt Unset Silent.\optindex{Silent}}
This command turns the normal display on.
+\subsection[\tt Set Search Output Name Only.]{\tt Set Search Output Name Only.\optindex{Search Output Name Only}
+\label{Search-Output-Name-Only}
+\index{Search Output Name Only mode}}
+This command restricts the output of search commands to identifier names; turning it on causes invocations of {\tt Search}, {\tt SearchHead}, {\tt SearchPattern}, {\tt SearchRewrite} etc. to omit types from their output, printing only identifiers.
+
+\subsection[\tt Unset Search Output Name Only.]{\tt Unset Search Output Name Only.\optindex{Search Output Name Only}}
+This command turns type display in search results back on.
+
\subsection[\tt Set Printing Width {\integer}.]{\tt Set Printing Width {\integer}.\optindex{Printing Width}}
\label{SetPrintingWidth}
This command sets which left-aligned part of the width of the screen
diff --git a/doc/refman/RefMan-tac.tex b/doc/refman/RefMan-tac.tex
index 9a365b829..edf986392 100644
--- a/doc/refman/RefMan-tac.tex
+++ b/doc/refman/RefMan-tac.tex
@@ -802,7 +802,7 @@ the tactic {\tt intro} applies the tactic {\tt hnf} until the tactic
\end{Variants}
-\subsection{\tt intros {\intropattern} \mbox{\dots} \intropattern}
+\subsection{\tt intros {\intropatternlist}}
\label{intros-pattern}
\tacindex{intros \intropattern}
\index{Introduction patterns}
@@ -811,9 +811,11 @@ the tactic {\tt intro} applies the tactic {\tt hnf} until the tactic
\index{Disjunctive/conjunctive introduction patterns}
\index{Equality introduction patterns}
-
-This extension of the tactic {\tt intros} combines introduction of
-variables or hypotheses and case analysis. An {\em introduction pattern} is
+This extension of the tactic {\tt intros} allows to apply tactics on
+the fly on the variables or hypotheses which have been introduced. An
+{\em introduction pattern list} {\intropatternlist} is a list of
+introduction patterns possibly containing the filling introduction
+patterns {\tt *} and {\tt **}. An {\em introduction pattern} is
either:
\begin{itemize}
\item a {\em naming introduction pattern}, i.e. either one of:
@@ -827,7 +829,7 @@ either:
\item a {\em disjunctive/conjunctive introduction pattern}, i.e. either one of:
\begin{itemize}
\item a disjunction of lists of patterns:
- {\tt [$p_{11}$ \dots\ $p_{1m_1}$ | \dots\ | $p_{11}$ \dots\ $p_{nm_n}$]}
+ {\tt [$\intropatternlist_1$ | \dots\ | $\intropatternlist_n$]}
\item a conjunction of patterns: {\tt ($p_1$ , \dots\ , $p_n$)}
\item a list of patterns {\tt ($p_1$ \&\ \dots\ \&\ $p_n$)}
for sequence of right-associative binary constructs
@@ -844,10 +846,6 @@ either:
\item the wildcard: {\tt \_}
\end{itemize}
-Introduction patterns can be combined into lists. An {\em introduction
- pattern list} is a list of introduction patterns possibly containing
-the filling introduction patterns {\tt *} and {\tt **}.
-
Assuming a goal of type $Q \to P$ (non-dependent product), or
of type $\forall x:T,~P$ (dependent product), the behavior of
{\tt intros $p$} is defined inductively over the structure of the
@@ -860,21 +858,22 @@ introduction pattern~$p$:
\item introduction on \texttt{\ident} behaves as described in
Section~\ref{intro};
\item introduction over a disjunction of list of patterns {\tt
- [$p_{11}$ \dots\ $p_{1m_1}$ | \dots\ | $p_{11}$ \dots\ $p_{nm_n}$]}
- expects the product to be over an inductive type
- whose number of constructors is $n$ (or more generally over a type
- of conclusion an inductive type built from $n$ constructors,
- e.g. {\tt C -> A\textbackslash/B} with $n=2$ since {\tt
- A\textbackslash/B} has 2 constructors): it destructs the introduced
- hypothesis as {\tt destruct} (see Section~\ref{destruct}) would and
- applies on each generated subgoal the corresponding tactic;
- \texttt{intros}~$p_{i1}$ {\ldots} $p_{im_i}$; if the disjunctive
- pattern is part of a sequence of patterns, then {\Coq} completes the
- pattern so that all the arguments of the constructors of the
- inductive type are introduced (for instance, the list of patterns
- {\tt [$\;$|$\;$] H} applied on goal {\tt forall x:nat, x=0 -> 0=x}
- behaves the same as the list of patterns {\tt [$\,$|$\,$?$\,$] H},
- up to one exception explained in the Remark below);
+ [$\intropatternlist_{1}$ | \dots\ | $\intropatternlist_n$]} expects
+ the product to be over an inductive type whose number of
+ constructors is $n$ (or more generally over a type of conclusion an
+ inductive type built from $n$ constructors, e.g. {\tt C ->
+ A\textbackslash/B} with $n=2$ since {\tt A\textbackslash/B} has 2
+ constructors): it destructs the introduced hypothesis as {\tt
+ destruct} (see Section~\ref{destruct}) would and applies on each
+ generated subgoal the corresponding tactic;
+ \texttt{intros}~$\intropatternlist_i$. The introduction patterns in
+ $\intropatternlist_i$ are expected to consume no more than the
+ number of arguments of the $i^{\mbox{\scriptsize th}}$
+ constructor. If it consumes less, then {\Coq} completes the pattern
+ so that all the arguments of the constructors of the inductive type
+ are introduced (for instance, the list of patterns {\tt [$\;$|$\;$]
+ H} applied on goal {\tt forall x:nat, x=0 -> 0=x} behaves the same
+ as the list of patterns {\tt [$\,$|$\,$?$\,$] H});
\item introduction over a conjunction of patterns {\tt ($p_1$, \ldots,
$p_n$)} expects the goal to be a product over an inductive type $I$ with a
single constructor that itself has at least $n$ arguments: it
@@ -926,19 +925,6 @@ introduction pattern~$p$:
not any more a quantification or an implication.
\end{itemize}
-Then, if $p_1$ ... $p_n$ is a list of introduction patterns possibly
-containing {\tt *} or {\tt **}, {\tt intros $p_1$ ... $p_n$}
-\begin{itemize}
-\item introduction over {\tt *} introduces all forthcoming quantified
- variables appearing in a row;
-\item introduction over {\tt **} introduces all forthcoming quantified
- variables or hypotheses until the goal is not any more a
- quantification or an implication;
-\item introduction over an introduction pattern $p$ introduces the
- forthcoming quantified variables or premise of the goal and applies
- the introduction pattern $p$ to it.
-\end{itemize}
-
\Example
\begin{coq_example}
@@ -949,37 +935,39 @@ intros * [a | (_,c)] f.
Abort.
\end{coq_eval}
-\Rem {\tt intros $p_1~\ldots~p_n$} is not fully equivalent to
-\texttt{intros $p_1$;\ldots; intros $p_n$} for the following reasons:
-\label{bracketing-last}
-\begin{itemize}
-\item A wildcard pattern never succeeds when applied isolated on a
- dependent product, while it succeeds as part of a list of
- introduction patterns if the hypotheses that depends on it are
- erased too.
-\item A disjunctive or conjunctive pattern followed by an introduction
- pattern forces the introduction in the context of all arguments of
- the constructors before applying the next pattern while a terminal
- disjunctive or conjunctive pattern does not. Here is an example
-
-\begin{coq_example}
-Goal forall n:nat, n = 0 -> n = 0.
-intros [ | ] H.
-Show 2.
-Undo.
-intros [ | ]; intros H.
-Show 2.
-\end{coq_example}
+\Rem {\tt intros $p_1~\ldots~p_n$} is not equivalent to \texttt{intros
+ $p_1$;\ldots; intros $p_n$} for the following reason: If one of the
+$p_i$ is a wildcard pattern, he might succeed in the first case
+because the further hypotheses it depends in are eventually erased too
+while it might fail in the second case because of dependencies in
+hypotheses which are not yet introduced (and a fortiori not yet
+erased).
+
+\Rem In {\tt intros $\intropatternlist$}, if the last introduction
+pattern is a disjunctive or conjunctive pattern {\tt
+ [$\intropatternlist_1$ | \dots\ | $\intropatternlist_n$]}, the
+completion of $\intropatternlist_i$ so that all the arguments of the
+$i^{\mbox{\scriptsize th}}$ constructors of the corresponding
+inductive type are introduced can be controlled with the
+following option:
+\optindex{Bracketing Last Introduction Pattern}
-\end{itemize}
+\begin{quote}
+{\tt Set Bracketing Last Introduction Pattern}
+\end{quote}
-This later behavior can be avoided by setting the following option:
+Force completion, if needed, when the last introduction pattern is a
+disjunctive or conjunctive pattern (this is the default).
\begin{quote}
-\optindex{Bracketing Last Introduction Pattern}
-{\tt Set Bracketing Last Introduction Pattern}
+{\tt Unset Bracketing Last Introduction Pattern}
\end{quote}
+Deactivate completion when the last introduction pattern is a disjunctive
+or conjunctive pattern.
+
+
+
\subsection{\tt clear \ident}
\tacindex{clear}
\label{clear}
@@ -1267,18 +1255,9 @@ in the list of subgoals remaining to prove.
introduction pattern (in particular, if {\intropattern} is {\ident},
the tactic behaves like \texttt{assert ({\ident} :\ {\form})}).
- If {\intropattern} is a disjunctive/conjunctive
- introduction pattern, the tactic behaves like \texttt{assert
- {\form}} followed by a {\tt destruct} using this introduction pattern.
-
- If {\intropattern} is a rewriting intropattern pattern, the tactic
- behaves like \texttt{assert {\form}} followed by a call to {\tt
- subst} on the resulting hypothesis, if applicable, or to {\tt
- rewrite} otherwise.
-
- If {\intropattern} is an injection intropattern pattern, the tactic
- behaves like \texttt{assert {\form}} followed by {\tt injection}
- using this introduction pattern.
+ If {\intropattern} is an action introduction pattern, the tactic
+ behaves like \texttt{assert {\form}} followed by the action done by
+ this introduction pattern.
\item \texttt{assert {\form} as {\intropattern} by {\tac}}
@@ -2890,7 +2869,7 @@ Additionally, it prevents a local definition such as {\tt \ident :=
configurations containing hypotheses of the form {\tt {\ident} = $u$},
or {\tt $u'$ = \ident} with $u'$ not a variable.
-The option is off by default.
+The option is on by default.
\end{Variants}
diff --git a/doc/stdlib/index-list.html.template b/doc/stdlib/index-list.html.template
index d6b1af797..a12983ab8 100644
--- a/doc/stdlib/index-list.html.template
+++ b/doc/stdlib/index-list.html.template
@@ -59,6 +59,7 @@ through the <tt>Require Import</tt> command.</p>
theories/Logic/WeakFan.v
theories/Logic/WKL.v
theories/Logic/FinFun.v
+ theories/Logic/PropFacts.v
</dd>
<dt> <b>Structures</b>:
diff --git a/engine/engine.mllib b/engine/engine.mllib
new file mode 100644
index 000000000..7197a2583
--- /dev/null
+++ b/engine/engine.mllib
@@ -0,0 +1,7 @@
+Logic_monad
+Termops
+Namegen
+UState
+Evd
+Sigma
+Proofview_monad
diff --git a/pretyping/evd.ml b/engine/evd.ml
index 01083142b..b4375d4d6 100644
--- a/pretyping/evd.ml
+++ b/engine/evd.ml
@@ -259,234 +259,22 @@ let instantiate_evar_array info c args =
| [] -> c
| _ -> replace_vars inst c
-module StringOrd = struct type t = string let compare = String.compare end
-module UNameMap = struct
-
- include Map.Make(StringOrd)
-
- let union s t =
- if s == t then s
- else
- merge (fun k l r ->
- match l, r with
- | Some _, _ -> l
- | _, _ -> r) s t
-end
-
-(* 2nd part used to check consistency on the fly. *)
-type evar_universe_context =
- { uctx_names : Univ.Level.t UNameMap.t * string Univ.LMap.t;
- uctx_local : Univ.universe_context_set; (** The local context of variables *)
- uctx_univ_variables : Universes.universe_opt_subst;
- (** The local universes that are unification variables *)
- uctx_univ_algebraic : Univ.universe_set;
- (** The subset of unification variables that can be instantiated with
- algebraic universes as they appear in inferred types only. *)
- uctx_universes : Univ.universes; (** The current graph extended with the local constraints *)
- uctx_initial_universes : Univ.universes; (** The graph at the creation of the evar_map *)
- }
-
-let empty_evar_universe_context =
- { uctx_names = UNameMap.empty, Univ.LMap.empty;
- uctx_local = Univ.ContextSet.empty;
- uctx_univ_variables = Univ.LMap.empty;
- uctx_univ_algebraic = Univ.LSet.empty;
- uctx_universes = Univ.initial_universes;
- uctx_initial_universes = Univ.initial_universes }
-
-let evar_universe_context_from e =
- let u = universes e in
- {empty_evar_universe_context with
- uctx_universes = u; uctx_initial_universes = u}
-
-let is_empty_evar_universe_context ctx =
- Univ.ContextSet.is_empty ctx.uctx_local &&
- Univ.LMap.is_empty ctx.uctx_univ_variables
-
-let union_evar_universe_context ctx ctx' =
- if ctx == ctx' then ctx
- else if is_empty_evar_universe_context ctx' then ctx
- else
- let local = Univ.ContextSet.union ctx.uctx_local ctx'.uctx_local in
- let names = UNameMap.union (fst ctx.uctx_names) (fst ctx'.uctx_names) in
- let newus = Univ.LSet.diff (Univ.ContextSet.levels ctx'.uctx_local)
- (Univ.ContextSet.levels ctx.uctx_local) in
- let newus = Univ.LSet.diff newus (Univ.LMap.domain ctx.uctx_univ_variables) in
- let declarenew g =
- Univ.LSet.fold (fun u g -> Univ.add_universe u false g) newus g
- in
- let names_rev = Univ.LMap.union (snd ctx.uctx_names) (snd ctx'.uctx_names) in
- { uctx_names = (names, names_rev);
- uctx_local = local;
- uctx_univ_variables =
- Univ.LMap.subst_union ctx.uctx_univ_variables ctx'.uctx_univ_variables;
- uctx_univ_algebraic =
- Univ.LSet.union ctx.uctx_univ_algebraic ctx'.uctx_univ_algebraic;
- uctx_initial_universes = declarenew ctx.uctx_initial_universes;
- uctx_universes =
- if local == ctx.uctx_local then ctx.uctx_universes
- else
- let cstrsr = Univ.ContextSet.constraints ctx'.uctx_local in
- Univ.merge_constraints cstrsr (declarenew ctx.uctx_universes) }
-
-(* let union_evar_universe_context_key = Profile.declare_profile "union_evar_universe_context";; *)
-(* let union_evar_universe_context = *)
-(* Profile.profile2 union_evar_universe_context_key union_evar_universe_context;; *)
-
+type evar_universe_context = UState.t
type 'a in_evar_universe_context = 'a * evar_universe_context
-let evar_universe_context_set diff ctx =
- let initctx = ctx.uctx_local in
- let cstrs =
- Univ.LSet.fold
- (fun l cstrs ->
- try
- match Univ.LMap.find l ctx.uctx_univ_variables with
- | Some u -> Univ.Constraint.add (l, Univ.Eq, Option.get (Univ.Universe.level u)) cstrs
- | None -> cstrs
- with Not_found | Option.IsNone -> cstrs)
- (Univ.Instance.levels (Univ.UContext.instance diff)) Univ.Constraint.empty
- in
- Univ.ContextSet.add_constraints cstrs initctx
-
-let evar_universe_context_constraints ctx = snd ctx.uctx_local
-let evar_context_universe_context ctx = Univ.ContextSet.to_context ctx.uctx_local
-
-let evar_universe_context_of ctx = { empty_evar_universe_context with uctx_local = ctx }
-let evar_universe_context_subst ctx = ctx.uctx_univ_variables
-
-let add_uctx_names s l (names, names_rev) =
- (UNameMap.add s l names, Univ.LMap.add l s names_rev)
-
-let evar_universe_context_of_binders b =
- let ctx = empty_evar_universe_context in
- let names =
- List.fold_left (fun acc (id, l) -> add_uctx_names (Id.to_string id) l acc)
- ctx.uctx_names b
- in { ctx with uctx_names = names }
-
-let instantiate_variable l b v =
- v := Univ.LMap.add l (Some b) !v
-
-exception UniversesDiffer
-
-let process_universe_constraints univs vars alg cstrs =
- let vars = ref vars in
- let normalize = Universes.normalize_universe_opt_subst vars in
- let rec unify_universes fo l d r local =
- let l = normalize l and r = normalize r in
- if Univ.Universe.equal l r then local
- else
- let varinfo x =
- match Univ.Universe.level x with
- | None -> Inl x
- | Some l -> Inr (l, Univ.LMap.mem l !vars, Univ.LSet.mem l alg)
- in
- if d == Universes.ULe then
- if Univ.check_leq univs l r then
- (** Keep Prop/Set <= var around if var might be instantiated by prop or set
- later. *)
- if Univ.Universe.is_level l then
- match Univ.Universe.level r with
- | Some r ->
- Univ.Constraint.add (Option.get (Univ.Universe.level l),Univ.Le,r) local
- | _ -> local
- else local
- else
- match Univ.Universe.level r with
- | None -> error ("Algebraic universe on the right")
- | Some rl ->
- if Univ.Level.is_small rl then
- let levels = Univ.Universe.levels l in
- Univ.LSet.fold (fun l local ->
- if Univ.Level.is_small l || Univ.LMap.mem l !vars then
- unify_universes fo (Univ.Universe.make l) Universes.UEq r local
- else raise (Univ.UniverseInconsistency (Univ.Le, Univ.Universe.make l, r, None)))
- levels local
- else
- Univ.enforce_leq l r local
- else if d == Universes.ULub then
- match varinfo l, varinfo r with
- | (Inr (l, true, _), Inr (r, _, _))
- | (Inr (r, _, _), Inr (l, true, _)) ->
- instantiate_variable l (Univ.Universe.make r) vars;
- Univ.enforce_eq_level l r local
- | Inr (_, _, _), Inr (_, _, _) ->
- unify_universes true l Universes.UEq r local
- | _, _ -> assert false
- else (* d = Universes.UEq *)
- match varinfo l, varinfo r with
- | Inr (l', lloc, _), Inr (r', rloc, _) ->
- let () =
- if lloc then
- instantiate_variable l' r vars
- else if rloc then
- instantiate_variable r' l vars
- else if not (Univ.check_eq univs l r) then
- (* Two rigid/global levels, none of them being local,
- one of them being Prop/Set, disallow *)
- if Univ.Level.is_small l' || Univ.Level.is_small r' then
- raise (Univ.UniverseInconsistency (Univ.Eq, l, r, None))
- else
- if fo then
- raise UniversesDiffer
- in
- Univ.enforce_eq_level l' r' local
- | Inr (l, loc, alg), Inl r
- | Inl r, Inr (l, loc, alg) ->
- let inst = Univ.univ_level_rem l r r in
- if alg then (instantiate_variable l inst vars; local)
- else
- let lu = Univ.Universe.make l in
- if Univ.univ_level_mem l r then
- Univ.enforce_leq inst lu local
- else raise (Univ.UniverseInconsistency (Univ.Eq, lu, r, None))
- | _, _ (* One of the two is algebraic or global *) ->
- if Univ.check_eq univs l r then local
- else raise (Univ.UniverseInconsistency (Univ.Eq, l, r, None))
- in
- let local =
- Universes.Constraints.fold (fun (l,d,r) local -> unify_universes false l d r local)
- cstrs Univ.Constraint.empty
- in
- !vars, local
-
-let add_constraints_context ctx cstrs =
- let univs, local = ctx.uctx_local in
- let cstrs' = Univ.Constraint.fold (fun (l,d,r) acc ->
- let l = Univ.Universe.make l and r = Univ.Universe.make r in
- let cstr' =
- if d == Univ.Lt then (Univ.Universe.super l, Universes.ULe, r)
- else (l, (if d == Univ.Le then Universes.ULe else Universes.UEq), r)
- in Universes.Constraints.add cstr' acc)
- cstrs Universes.Constraints.empty
- in
- let vars, local' =
- process_universe_constraints ctx.uctx_universes
- ctx.uctx_univ_variables ctx.uctx_univ_algebraic
- cstrs'
- in
- { ctx with uctx_local = (univs, Univ.Constraint.union local local');
- uctx_univ_variables = vars;
- uctx_universes = Univ.merge_constraints local' ctx.uctx_universes }
-
-(* let addconstrkey = Profile.declare_profile "add_constraints_context";; *)
-(* let add_constraints_context = Profile.profile2 addconstrkey add_constraints_context;; *)
-
-let add_universe_constraints_context ctx cstrs =
- let univs, local = ctx.uctx_local in
- let vars, local' =
- process_universe_constraints ctx.uctx_universes
- ctx.uctx_univ_variables ctx.uctx_univ_algebraic
- cstrs
- in
- { ctx with uctx_local = (univs, Univ.Constraint.union local local');
- uctx_univ_variables = vars;
- uctx_universes = Univ.merge_constraints local' ctx.uctx_universes }
+let empty_evar_universe_context = UState.empty
+let is_empty_evar_universe_context = UState.is_empty
+let union_evar_universe_context = UState.union
+let evar_universe_context_set = UState.context_set
+let evar_universe_context_constraints = UState.constraints
+let evar_context_universe_context = UState.context
+let evar_universe_context_of = UState.of_context_set
+let evar_universe_context_subst = UState.subst
+let add_constraints_context = UState.add_constraints
+let add_universe_constraints_context = UState.add_universe_constraints
+let constrain_variables = UState.constrain_variables
+let evar_universe_context_of_binders = UState.of_binders
-(* let addunivconstrkey = Profile.declare_profile "add_universe_constraints_context";; *)
-(* let add_universe_constraints_context = *)
-(* Profile.profile2 addunivconstrkey add_universe_constraints_context;; *)
(*******************************************************************)
(* Metamaps *)
@@ -647,14 +435,30 @@ let reassign_name_defined evk evk' (evtoid,idtoev) =
(EvMap.add evk' id (EvMap.remove evk evtoid),
Idmap.add id evk' (Idmap.remove id idtoev))
-let add d e i = match i.evar_body with
+let add_with_name ?(naming = Misctypes.IntroAnonymous) d e i = match i.evar_body with
| Evar_empty ->
- let evar_names = add_name_undefined Misctypes.IntroAnonymous e i d.evar_names in
+ let evar_names = add_name_undefined naming e i d.evar_names in
{ d with undf_evars = EvMap.add e i d.undf_evars; evar_names }
| Evar_defined _ ->
let evar_names = remove_name_possibly_already_defined e d.evar_names in
{ d with defn_evars = EvMap.add e i d.defn_evars; evar_names }
+let add d e i = add_with_name d e i
+
+(** New evars *)
+
+let evar_counter_summary_name = "evar counter"
+
+(* Generator of existential names *)
+let new_untyped_evar =
+ let evar_ctr = Summary.ref 0 ~name:evar_counter_summary_name in
+ fun () -> incr evar_ctr; Evar.unsafe_of_int !evar_ctr
+
+let new_evar evd ?naming evi =
+ let evk = new_untyped_evar () in
+ let evd = add_with_name evd ?naming evk evi in
+ (evd, evk)
+
let remove d e =
let undf_evars = EvMap.remove e d.undf_evars in
let defn_evars = EvMap.remove e d.defn_evars in
@@ -770,10 +574,6 @@ let cmap f evd =
(* spiwack: deprecated *)
let create_evar_defs sigma = { sigma with
conv_pbs=[]; last_mods=Evar.Set.empty; metas=Metamap.empty }
-(* spiwack: tentatively deprecated *)
-let create_goal_evar_defs sigma = { sigma with
- (* conv_pbs=[]; last_mods=Evar.Set.empty; metas=Metamap.empty } *)
- metas=Metamap.empty }
let empty = {
defn_evars = EvMap.empty;
@@ -790,7 +590,7 @@ let empty = {
}
let from_env e =
- { empty with universes = evar_universe_context_from e }
+ { empty with universes = UState.make (Environ.universes e) }
let from_ctx ctx = { empty with universes = ctx }
@@ -851,27 +651,8 @@ let define evk body evd =
let evar_names = remove_name_defined evk evd.evar_names in
{ evd with defn_evars; undf_evars; last_mods; evar_names }
-let evar_declare hyps evk ty ?(src=(Loc.ghost,Evar_kinds.InternalHole))
- ?(filter=Filter.identity) ?candidates ?(store=Store.empty)
- ?(naming=Misctypes.IntroAnonymous) evd =
- let () = match Filter.repr filter with
- | None -> ()
- | Some filter ->
- assert (Int.equal (List.length filter) (List.length (named_context_of_val hyps)))
- in
- let evar_info = {
- evar_hyps = hyps;
- evar_concl = ty;
- evar_body = Evar_empty;
- evar_filter = filter;
- evar_source = src;
- evar_candidates = candidates;
- evar_extra = store; }
- in
- let evar_names = add_name_newly_undefined naming evk evar_info evd.evar_names in
- { evd with undf_evars = EvMap.add evk evar_info evd.undf_evars; evar_names }
-
-let restrict evk evk' filter ?candidates evd =
+let restrict evk filter ?candidates evd =
+ let evk' = new_untyped_evar () in
let evar_info = EvMap.find evk evd.undf_evars in
let evar_info' =
{ evar_info with evar_filter = filter;
@@ -883,7 +664,7 @@ let restrict evk evk' filter ?candidates evd =
let body = mkEvar(evk',id_inst) in
let (defn_evars, undf_evars) = define_aux evd.defn_evars evd.undf_evars evk body in
{ evd with undf_evars = EvMap.add evk' evar_info' undf_evars;
- defn_evars; evar_names }
+ defn_evars; evar_names }, evk'
let downcast evk ccl evd =
let evar_info = EvMap.find evk evd.undf_evars in
@@ -958,7 +739,7 @@ let evars_of_filtered_evar_info evi =
(**********************************************************)
(* Sort variables *)
-type rigid =
+type rigid = UState.rigid =
| UnivRigid
| UnivFlexible of bool (** Is substitution by an algebraic ok? *)
@@ -968,132 +749,32 @@ let univ_flexible_alg = UnivFlexible true
let evar_universe_context d = d.universes
-let universe_context_set d = d.universes.uctx_local
-
-let pr_uctx_level uctx =
- let map, map_rev = uctx.uctx_names in
- fun l ->
- try str(Univ.LMap.find l map_rev)
- with Not_found ->
- Universes.pr_with_global_universes l
-
-let universe_context ?names evd =
- match names with
- | None -> [], Univ.ContextSet.to_context evd.universes.uctx_local
- | Some pl ->
- let levels = Univ.ContextSet.levels evd.universes.uctx_local in
- let newinst, map, left =
- List.fold_right
- (fun (loc,id) (newinst, map, acc) ->
- let l =
- try UNameMap.find (Id.to_string id) (fst evd.universes.uctx_names)
- with Not_found ->
- user_err_loc (loc, "universe_context",
- str"Universe " ++ pr_id id ++ str" is not bound anymore.")
- in (l :: newinst, (id, l) :: map, Univ.LSet.remove l acc))
- pl ([], [], levels)
- in
- if not (Univ.LSet.is_empty left) then
- let n = Univ.LSet.cardinal left in
- errorlabstrm "universe_context"
- (str(CString.plural n "Universe") ++ spc () ++
- Univ.LSet.pr (pr_uctx_level evd.universes) left ++
- spc () ++ str (CString.conjugate_verb_to_be n) ++ str" unbound.")
- else
- let inst = Univ.Instance.of_array (Array.of_list newinst) in
- let ctx = Univ.UContext.make (inst,
- Univ.ContextSet.constraints evd.universes.uctx_local)
- in map, ctx
+let universe_context_set d = UState.context_set d.universes
+
+let pr_uctx_level = UState.pr_uctx_level
+let universe_context ?names evd = UState.universe_context ?names evd.universes
let restrict_universe_context evd vars =
- let uctx = evd.universes in
- let uctx' = Universes.restrict_universe_context uctx.uctx_local vars in
- { evd with universes = { uctx with uctx_local = uctx' } }
-
+ { evd with universes = UState.restrict evd.universes vars }
+
let universe_subst evd =
- evd.universes.uctx_univ_variables
-
-let merge_uctx sideff rigid uctx ctx' =
- let open Univ in
- let levels = ContextSet.levels ctx' in
- let uctx = if sideff then uctx else
- match rigid with
- | UnivRigid -> uctx
- | UnivFlexible b ->
- let fold u accu =
- if LMap.mem u accu then accu
- else LMap.add u None accu
- in
- let uvars' = LSet.fold fold levels uctx.uctx_univ_variables in
- if b then
- { uctx with uctx_univ_variables = uvars';
- uctx_univ_algebraic = LSet.union uctx.uctx_univ_algebraic levels }
- else { uctx with uctx_univ_variables = uvars' }
- in
- let uctx_local =
- if sideff then uctx.uctx_local
- else ContextSet.append ctx' uctx.uctx_local
- in
- let declare g =
- LSet.fold (fun u g ->
- try Univ.add_universe u false g
- with Univ.AlreadyDeclared when sideff -> g)
- levels g
- in
- let initial = declare uctx.uctx_initial_universes in
- let univs = declare uctx.uctx_universes in
- let uctx_universes = merge_constraints (ContextSet.constraints ctx') univs in
- { uctx with uctx_local; uctx_universes; uctx_initial_universes = initial }
+ UState.subst evd.universes
let merge_context_set ?(sideff=false) rigid evd ctx' =
- {evd with universes = merge_uctx sideff rigid evd.universes ctx'}
+ {evd with universes = UState.merge sideff rigid evd.universes ctx'}
-let merge_uctx_subst uctx s =
- { uctx with uctx_univ_variables = Univ.LMap.subst_union uctx.uctx_univ_variables s }
-
let merge_universe_subst evd subst =
- {evd with universes = merge_uctx_subst evd.universes subst }
+ {evd with universes = UState.merge_subst evd.universes subst }
let with_context_set rigid d (a, ctx) =
(merge_context_set rigid d ctx, a)
-let emit_universe_side_effects eff u =
- let uctxs = Safe_typing.universes_of_private eff in
- List.fold_left (merge_uctx true univ_rigid) u uctxs
-
-let uctx_new_univ_variable rigid name predicative
- ({ uctx_local = ctx; uctx_univ_variables = uvars; uctx_univ_algebraic = avars} as uctx) =
- let u = Universes.new_univ_level (Global.current_dirpath ()) in
- let ctx' = Univ.ContextSet.add_universe u ctx in
- let uctx', pred =
- match rigid with
- | UnivRigid -> uctx, true
- | UnivFlexible b ->
- let uvars' = Univ.LMap.add u None uvars in
- if b then {uctx with uctx_univ_variables = uvars';
- uctx_univ_algebraic = Univ.LSet.add u avars}, false
- else {uctx with uctx_univ_variables = uvars'}, false
- in
- let names =
- match name with
- | Some n -> add_uctx_names n u uctx.uctx_names
- | None -> uctx.uctx_names
- in
- let initial =
- Univ.add_universe u false uctx.uctx_initial_universes
- in
- let uctx' =
- {uctx' with uctx_names = names; uctx_local = ctx';
- uctx_universes = Univ.add_universe u false uctx.uctx_universes;
- uctx_initial_universes = initial}
- in uctx', u
-
let new_univ_level_variable ?name ?(predicative=true) rigid evd =
- let uctx', u = uctx_new_univ_variable rigid name predicative evd.universes in
+ let uctx', u = UState.new_univ_variable rigid name evd.universes in
({evd with universes = uctx'}, u)
let new_univ_variable ?name ?(predicative=true) rigid evd =
- let uctx', u = uctx_new_univ_variable rigid name predicative evd.universes in
+ let uctx', u = UState.new_univ_variable rigid name evd.universes in
({evd with universes = uctx'}, Univ.Universe.make u)
let new_sort_variable ?name ?(predicative=true) rigid d =
@@ -1101,43 +782,21 @@ let new_sort_variable ?name ?(predicative=true) rigid d =
(d', Type u)
let add_global_univ d u =
- let uctx = d.universes in
- let initial =
- Univ.add_universe u true uctx.uctx_initial_universes
- in
- let univs =
- Univ.add_universe u true uctx.uctx_universes
- in
- { d with universes = { uctx with uctx_local = Univ.ContextSet.add_universe u uctx.uctx_local;
- uctx_initial_universes = initial;
- uctx_universes = univs } }
-
+ { d with universes = UState.add_global_univ d.universes u }
+
let make_flexible_variable evd b u =
- let {uctx_univ_variables = uvars; uctx_univ_algebraic = avars} as ctx = evd.universes in
- let uvars' = Univ.LMap.add u None uvars in
- let avars' =
- if b then
- let uu = Univ.Universe.make u in
- let substu_not_alg u' v =
- Option.cata (fun vu -> Univ.Universe.equal uu vu && not (Univ.LSet.mem u' avars)) false v
- in
- if not (Univ.LMap.exists substu_not_alg uvars)
- then Univ.LSet.add u avars else avars
- else avars
- in
- {evd with universes = {ctx with uctx_univ_variables = uvars';
- uctx_univ_algebraic = avars'}}
-
-let make_evar_universe_context e l =
- let uctx = evar_universe_context_from e in
- match l with
- | None -> uctx
- | Some us ->
- List.fold_left
- (fun uctx (loc,id) ->
- fst (uctx_new_univ_variable univ_rigid (Some (Id.to_string id)) true uctx))
- uctx us
-
+ { evd with universes = UState.make_flexible_variable evd.universes b u }
+
+let make_evar_universe_context e l =
+ let uctx = UState.make (Environ.universes e) in
+ match l with
+ | None -> uctx
+ | Some us ->
+ List.fold_left
+ (fun uctx (loc,id) ->
+ fst (UState.new_univ_variable univ_rigid (Some (Id.to_string id)) uctx))
+ uctx us
+
(****************************************)
(* Operations on constants *)
(****************************************)
@@ -1159,20 +818,11 @@ let fresh_global ?(rigid=univ_flexible) ?names env evd gr =
let whd_sort_variable evd t = t
-let is_sort_variable evd s =
- match s with
- | Type u ->
- (match Univ.universe_level u with
- | Some l as x ->
- let uctx = evd.universes in
- if Univ.LSet.mem l (Univ.ContextSet.levels uctx.uctx_local) then x
- else None
- | None -> None)
- | _ -> None
+let is_sort_variable evd s = UState.is_sort_variable evd.universes s
let is_flexible_level evd l =
let uctx = evd.universes in
- Univ.LMap.mem l uctx.uctx_univ_variables
+ Univ.LMap.mem l (UState.subst uctx)
let is_eq_sort s1 s2 =
if Sorts.equal s1 s2 then None
@@ -1183,12 +833,12 @@ let is_eq_sort s1 s2 =
else Some (u1, u2)
let normalize_universe evd =
- let vars = ref evd.universes.uctx_univ_variables in
+ let vars = ref (UState.subst evd.universes) in
let normalize = Universes.normalize_universe_opt_subst vars in
normalize
let normalize_universe_instance evd l =
- let vars = ref evd.universes.uctx_univ_variables in
+ let vars = ref (UState.subst evd.universes) in
let normalize = Univ.level_subst_of (Universes.normalize_univ_variable_opt_subst vars) in
Univ.Instance.subst_fn normalize l
@@ -1212,12 +862,9 @@ let set_eq_sort env d s1 s2 =
d
let has_lub evd u1 u2 =
- (* let normalize = Universes.normalize_universe_opt_subst (ref univs.uctx_univ_variables) in *)
- (* (\* let dref, norm = memo_normalize_universe d in *\) *)
- (* let u1 = normalize u1 and u2 = normalize u2 in *)
- if Univ.Universe.equal u1 u2 then evd
- else add_universe_constraints evd
- (Universes.Constraints.singleton (u1,Universes.ULub,u2))
+ if Univ.Universe.equal u1 u2 then evd
+ else add_universe_constraints evd
+ (Universes.Constraints.singleton (u1,Universes.ULub,u2))
let set_eq_level d u1 u2 =
add_constraints d (Univ.enforce_eq_level u1 u2 Univ.Constraint.empty)
@@ -1235,107 +882,29 @@ let set_leq_sort env evd s1 s2 =
match is_eq_sort s1 s2 with
| None -> evd
| Some (u1, u2) ->
- (* if Univ.is_type0_univ u2 then *)
- (* if Univ.is_small_univ u1 then evd *)
- (* else raise (Univ.UniverseInconsistency (Univ.Le, u1, u2, [])) *)
- (* else if Univ.is_type0m_univ u2 then *)
- (* raise (Univ.UniverseInconsistency (Univ.Le, u1, u2, [])) *)
- (* else *)
- if not (type_in_type env) then
- add_universe_constraints evd (Universes.Constraints.singleton (u1,Universes.ULe,u2))
- else evd
+ if not (type_in_type env) then
+ add_universe_constraints evd (Universes.Constraints.singleton (u1,Universes.ULe,u2))
+ else evd
let check_eq evd s s' =
- Univ.check_eq evd.universes.uctx_universes s s'
+ UGraph.check_eq (UState.ugraph evd.universes) s s'
let check_leq evd s s' =
- Univ.check_leq evd.universes.uctx_universes s s'
-
-let subst_univs_context_with_def def usubst (ctx, cst) =
- (Univ.LSet.diff ctx def, Univ.subst_univs_constraints usubst cst)
+ UGraph.check_leq (UState.ugraph evd.universes) s s'
-let normalize_evar_universe_context_variables uctx =
- let normalized_variables, undef, def, subst =
- Universes.normalize_univ_variables uctx.uctx_univ_variables
- in
- let ctx_local = subst_univs_context_with_def def (Univ.make_subst subst) uctx.uctx_local in
- let ctx_local', univs = Universes.refresh_constraints uctx.uctx_initial_universes ctx_local in
- subst, { uctx with uctx_local = ctx_local';
- uctx_univ_variables = normalized_variables;
- uctx_universes = univs }
-
-(* let normvarsconstrkey = Profile.declare_profile "normalize_evar_universe_context_variables";; *)
-(* let normalize_evar_universe_context_variables = *)
-(* Profile.profile1 normvarsconstrkey normalize_evar_universe_context_variables;; *)
-
-let abstract_undefined_variables uctx =
- let vars' =
- Univ.LMap.fold (fun u v acc ->
- if v == None then Univ.LSet.remove u acc
- else acc)
- uctx.uctx_univ_variables uctx.uctx_univ_algebraic
- in { uctx with uctx_local = Univ.ContextSet.empty;
- uctx_univ_algebraic = vars' }
-
-let fix_undefined_variables ({ universes = uctx } as evm) =
- let algs', vars' =
- Univ.LMap.fold (fun u v (algs, vars as acc) ->
- if v == None then (Univ.LSet.remove u algs, Univ.LMap.remove u vars)
- else acc)
- uctx.uctx_univ_variables
- (uctx.uctx_univ_algebraic, uctx.uctx_univ_variables)
- in
- {evm with universes =
- { uctx with uctx_univ_variables = vars';
- uctx_univ_algebraic = algs' } }
+let normalize_evar_universe_context_variables = UState.normalize_variables
+let abstract_undefined_variables = UState.abstract_undefined_variables
-let refresh_undefined_univ_variables uctx =
- let subst, ctx' = Universes.fresh_universe_context_set_instance uctx.uctx_local in
- let alg = Univ.LSet.fold (fun u acc -> Univ.LSet.add (Univ.subst_univs_level_level subst u) acc)
- uctx.uctx_univ_algebraic Univ.LSet.empty
- in
- let vars =
- Univ.LMap.fold
- (fun u v acc ->
- Univ.LMap.add (Univ.subst_univs_level_level subst u)
- (Option.map (Univ.subst_univs_level_universe subst) v) acc)
- uctx.uctx_univ_variables Univ.LMap.empty
- in
- let declare g = Univ.LSet.fold (fun u g -> Univ.add_universe u false g)
- (Univ.ContextSet.levels ctx') g in
- let initial = declare uctx.uctx_initial_universes in
- let univs = declare Univ.initial_universes in
- let uctx' = {uctx_names = uctx.uctx_names;
- uctx_local = ctx';
- uctx_univ_variables = vars; uctx_univ_algebraic = alg;
- uctx_universes = univs;
- uctx_initial_universes = initial } in
- uctx', subst
+let fix_undefined_variables evd =
+ { evd with universes = UState.fix_undefined_variables evd.universes }
let refresh_undefined_universes evd =
- let uctx', subst = refresh_undefined_univ_variables evd.universes in
+ let uctx', subst = UState.refresh_undefined_univ_variables evd.universes in
let evd' = cmap (subst_univs_level_constr subst) {evd with universes = uctx'} in
evd', subst
-let normalize_evar_universe_context uctx =
- let rec fixpoint uctx =
- let ((vars',algs'), us') =
- Universes.normalize_context_set uctx.uctx_local uctx.uctx_univ_variables
- uctx.uctx_univ_algebraic
- in
- if Univ.ContextSet.equal us' uctx.uctx_local then uctx
- else
- let us', universes = Universes.refresh_constraints uctx.uctx_initial_universes us' in
- let uctx' =
- { uctx_names = uctx.uctx_names;
- uctx_local = us';
- uctx_univ_variables = vars';
- uctx_univ_algebraic = algs';
- uctx_universes = universes;
- uctx_initial_universes = uctx.uctx_initial_universes }
- in fixpoint uctx'
- in fixpoint uctx
+let normalize_evar_universe_context = UState.normalize
let nf_univ_variables evd =
let subst, uctx' = normalize_evar_universe_context_variables evd.universes in
@@ -1347,52 +916,42 @@ let nf_constraints evd =
let uctx' = normalize_evar_universe_context uctx' in
{evd with universes = uctx'}
-let nf_constraints =
- if Flags.profile then
- let nfconstrkey = Profile.declare_profile "nf_constraints" in
- Profile.profile1 nfconstrkey nf_constraints
- else nf_constraints
-
-let universe_of_name evd s =
- UNameMap.find s (fst evd.universes.uctx_names)
+let universe_of_name evd s = UState.universe_of_name evd.universes s
let add_universe_name evd s l =
- let names' = add_uctx_names s l evd.universes.uctx_names in
- {evd with universes = {evd.universes with uctx_names = names'}}
+ { evd with universes = UState.add_universe_name evd.universes s l }
-let universes evd = evd.universes.uctx_universes
+let universes evd = UState.ugraph evd.universes
let update_sigma_env evd env =
- let univs = Environ.universes env in
- let eunivs =
- { evd.universes with uctx_initial_universes = univs;
- uctx_universes = univs }
- in
- let eunivs = merge_uctx true univ_rigid eunivs eunivs.uctx_local in
- { evd with universes = eunivs }
+ { evd with universes = UState.update_sigma_env evd.universes env }
(* Conversion w.r.t. an evar map and its local universes. *)
let test_conversion_gen env evd pb t u =
match pb with
| Reduction.CONV ->
- Reduction.trans_conv_universes
- full_transparent_state ~evars:(existential_opt_value evd) env
- evd.universes.uctx_universes t u
- | Reduction.CUMUL -> Reduction.trans_conv_leq_universes
- full_transparent_state ~evars:(existential_opt_value evd) env
- evd.universes.uctx_universes t u
+ Reduction.conv env
+ ~evars:((existential_opt_value evd), (UState.ugraph evd.universes))
+ t u
+ | Reduction.CUMUL -> Reduction.conv_leq env
+ ~evars:((existential_opt_value evd), (UState.ugraph evd.universes))
+ t u
let test_conversion env d pb t u =
try test_conversion_gen env d pb t u; true
with _ -> false
+exception UniversesDiffer = UState.UniversesDiffer
+
let eq_constr_univs evd t u =
- let b, c = Universes.eq_constr_univs_infer evd.universes.uctx_universes t u in
- if b then
- try let evd' = add_universe_constraints evd c in evd', b
- with Univ.UniverseInconsistency _ | UniversesDiffer -> evd, false
- else evd, b
+ let fold cstr sigma =
+ try Some (add_universe_constraints sigma cstr)
+ with Univ.UniverseInconsistency _ | UniversesDiffer -> None
+ in
+ match Universes.eq_constr_univs_infer (UState.ugraph evd.universes) fold t u evd with
+ | None -> evd, false
+ | Some evd -> evd, true
let e_eq_constr_univs evdref t u =
let evd, b = eq_constr_univs !evdref t u in
@@ -1403,7 +962,7 @@ let e_eq_constr_univs evdref t u =
let emit_side_effects eff evd =
{ evd with effects = Safe_typing.concat_private eff evd.effects;
- universes = emit_universe_side_effects eff evd.universes }
+ universes = UState.emit_side_effects eff evd.universes }
let drop_side_effects evd =
{ evd with effects = Safe_typing.empty_private_constants; }
@@ -1520,39 +1079,6 @@ let meta_reassign mv (v, pb) evd =
let meta_name evd mv =
try fst (clb_name (Metamap.find mv evd.metas)) with Not_found -> Anonymous
-let explain_no_such_bound_variable evd id =
- let mvl =
- List.rev (Metamap.fold (fun n clb l ->
- let na = fst (clb_name clb) in
- if na != Anonymous then out_name na :: l else l)
- evd.metas []) in
- errorlabstrm "Evd.meta_with_name"
- (str"No such bound variable " ++ pr_id id ++
- (if mvl == [] then str " (no bound variables at all in the expression)."
- else
- (str" (possible name" ++
- str (if List.length mvl == 1 then " is: " else "s are: ") ++
- pr_enum pr_id mvl ++ str").")))
-
-let meta_with_name evd id =
- let na = Name id in
- let (mvl,mvnodef) =
- Metamap.fold
- (fun n clb (l1,l2 as l) ->
- let (na',def) = clb_name clb in
- if Name.equal na na' then if def then (n::l1,l2) else (n::l1,n::l2)
- else l)
- evd.metas ([],[]) in
- match mvnodef, mvl with
- | _,[] ->
- explain_no_such_bound_variable evd id
- | ([n],_|_,[n]) ->
- n
- | _ ->
- errorlabstrm "Evd.meta_with_name"
- (str "Binder name \"" ++ pr_id id ++
- strbrk "\" occurs more than once in clause.")
-
let clear_metas evd = {evd with metas = Metamap.empty}
let meta_merge ?(with_univs = true) evd1 evd2 =
@@ -1576,18 +1102,6 @@ let retract_coercible_metas evd =
let metas = Metamap.smartmapi map evd.metas in
!mc, set_metas evd metas
-let subst_defined_metas_evars (bl,el) c =
- let rec substrec c = match kind_of_term c with
- | Meta i ->
- let select (j,_,_) = Int.equal i j in
- substrec (pi2 (List.find select bl))
- | Evar (evk,args) ->
- let select (_,(evk',args'),_) = Evar.equal evk evk' && Array.equal Constr.equal args args' in
- (try substrec (pi3 (List.find select el))
- with Not_found -> map_constr substrec c)
- | _ -> map_constr substrec c
- in try Some (substrec c) with Not_found -> None
-
let evar_source_of_meta mv evd =
match meta_name evd mv with
| Anonymous -> (Loc.ghost,Evar_kinds.GoalEvar)
@@ -1716,7 +1230,7 @@ let pr_decl ((id,b,_),ok) =
| Some c -> str (if ok then "(" else "{") ++ pr_id id ++ str ":=" ++
print_constr c ++ str (if ok then ")" else "}")
-let rec pr_evar_source = function
+let pr_evar_source = function
| Evar_kinds.QuestionMark _ -> str "underscore"
| Evar_kinds.CasesType false -> str "pattern-matching return predicate"
| Evar_kinds.CasesType true ->
@@ -1818,11 +1332,11 @@ let pr_evar_universe_context ctx =
if is_empty_evar_universe_context ctx then mt ()
else
(str"UNIVERSES:"++brk(0,1)++
- h 0 (Univ.pr_universe_context_set prl ctx.uctx_local) ++ fnl () ++
+ h 0 (Univ.pr_universe_context_set prl (evar_universe_context_set ctx)) ++ fnl () ++
str"ALGEBRAIC UNIVERSES:"++brk(0,1)++
- h 0 (Univ.LSet.pr prl ctx.uctx_univ_algebraic) ++ fnl() ++
+ h 0 (Univ.LSet.pr prl (UState.algebraics ctx)) ++ fnl() ++
str"UNDEFINED UNIVERSES:"++brk(0,1)++
- h 0 (Universes.pr_universe_opt_subst ctx.uctx_univ_variables) ++ fnl())
+ h 0 (Universes.pr_universe_opt_subst (UState.subst ctx)) ++ fnl())
let print_env_short env =
let pr_body n = function
diff --git a/pretyping/evd.mli b/engine/evd.mli
index 0b4f18536..d43d4f5f9 100644
--- a/pretyping/evd.mli
+++ b/engine/evd.mli
@@ -10,7 +10,6 @@ open Util
open Loc
open Names
open Term
-open Context
open Environ
(** {5 Existential variables and unification states}
@@ -105,8 +104,8 @@ type evar_info = {
val make_evar : named_context_val -> types -> evar_info
val evar_concl : evar_info -> constr
-val evar_context : evar_info -> named_context
-val evar_filtered_context : evar_info -> named_context
+val evar_context : evar_info -> Context.Named.t
+val evar_filtered_context : evar_info -> Context.Named.t
val evar_hyps : evar_info -> named_context_val
val evar_filtered_hyps : evar_info -> named_context_val
val evar_body : evar_info -> evar_body
@@ -119,7 +118,7 @@ val map_evar_info : (constr -> constr) -> evar_info -> evar_info
(** {6 Unification state} **)
-type evar_universe_context
+type evar_universe_context = UState.t
(** The universe context associated to an evar map *)
type evar_map
@@ -143,6 +142,10 @@ val has_undefined : evar_map -> bool
(** [has_undefined sigma] is [true] if and only if
there are uninstantiated evars in [sigma]. *)
+val new_evar : evar_map ->
+ ?naming:Misctypes.intro_pattern_naming_expr -> evar_info -> evar_map * evar
+(** Creates a fresh evar mapping to the given information. *)
+
val add : evar_map -> evar -> evar_info -> evar_map
(** [add sigma ev info] adds [ev] with evar info [info] in sigma.
Precondition: ev must not preexist in [sigma]. *)
@@ -219,7 +222,7 @@ val existential_opt_value : evar_map -> existential -> constr option
(** Same as {!existential_value} but returns an option instead of raising an
exception. *)
-val evar_instance_array : (named_declaration -> 'a -> bool) -> evar_info ->
+val evar_instance_array : (Context.Named.Declaration.t -> 'a -> bool) -> evar_info ->
'a array -> (Id.t * 'a) list
val instantiate_evar_array : evar_info -> constr -> constr array -> constr
@@ -230,14 +233,8 @@ val evars_reset_evd : ?with_conv_pbs:bool -> ?with_univs:bool ->
(** {6 Misc} *)
-val evar_declare :
- named_context_val -> evar -> types -> ?src:Loc.t * Evar_kinds.t ->
- ?filter:Filter.t -> ?candidates:constr list -> ?store:Store.t ->
- ?naming:Misctypes.intro_pattern_naming_expr -> evar_map -> evar_map
-(** Convenience function. Just a wrapper around {!add}. *)
-
-val restrict : evar -> evar -> Filter.t -> ?candidates:constr list ->
- evar_map -> evar_map
+val restrict : evar -> Filter.t -> ?candidates:constr list ->
+ evar_map -> evar_map * evar
(** Restrict an undefined evar into a new evar by filtering context and
possibly limiting the instances to a set of candidates *)
@@ -425,7 +422,7 @@ val evar_list : constr -> existential list
val evars_of_term : constr -> Evar.Set.t
(** including evars in instances of evars *)
-val evars_of_named_context : named_context -> Evar.Set.t
+val evars_of_named_context : Context.Named.t -> Evar.Set.t
val evars_of_filtered_evar_info : evar_info -> Evar.Set.t
@@ -442,7 +439,6 @@ val meta_opt_fvalue : evar_map -> metavariable -> (constr freelisted * instance_
val meta_type : evar_map -> metavariable -> types
val meta_ftype : evar_map -> metavariable -> types freelisted
val meta_name : evar_map -> metavariable -> Name.t
-val meta_with_name : evar_map -> Id.t -> metavariable
val meta_declare :
metavariable -> types -> ?name:Name.t -> evar_map -> evar_map
val meta_assign : metavariable -> constr * instance_status -> evar_map -> evar_map
@@ -459,7 +455,6 @@ val map_metas_fvalue : (constr -> constr) -> evar_map -> evar_map
type metabinding = metavariable * constr * instance_status
val retract_coercible_metas : evar_map -> metabinding list * evar_map
-val subst_defined_metas_evars : metabinding list * ('a * existential * constr) list -> constr -> constr option
(** {5 FIXME: Nothing to do here} *)
@@ -468,7 +463,7 @@ val subst_defined_metas_evars : metabinding list * ('a * existential * constr) l
(** Rigid or flexible universe variables *)
-type rigid =
+type rigid = UState.rigid =
| UnivRigid
| UnivFlexible of bool (** Is substitution by an algebraic ok? *)
@@ -478,7 +473,7 @@ val univ_flexible_alg : rigid
type 'a in_evar_universe_context = 'a * evar_universe_context
-val evar_universe_context_set : Univ.universe_context -> evar_universe_context -> Univ.universe_context_set
+val evar_universe_context_set : evar_universe_context -> Univ.universe_context_set
val evar_universe_context_constraints : evar_universe_context -> Univ.constraints
val evar_context_universe_context : evar_universe_context -> Univ.universe_context
val evar_universe_context_of : Univ.universe_context_set -> evar_universe_context
@@ -486,6 +481,8 @@ val empty_evar_universe_context : evar_universe_context
val union_evar_universe_context : evar_universe_context -> evar_universe_context ->
evar_universe_context
val evar_universe_context_subst : evar_universe_context -> Universes.universe_opt_subst
+val constrain_variables : Univ.LSet.t -> evar_universe_context -> Univ.constraints
+
val evar_universe_context_of_binders :
Universes.universe_binders -> evar_universe_context
@@ -496,8 +493,6 @@ val restrict_universe_context : evar_map -> Univ.universe_set -> evar_map
val universe_of_name : evar_map -> string -> Univ.universe_level
val add_universe_name : evar_map -> string -> Univ.universe_level -> evar_map
-val universes : evar_map -> Univ.universes
-
val add_constraints_context : evar_universe_context ->
Univ.constraints -> evar_universe_context
@@ -519,7 +514,6 @@ val is_sort_variable : evar_map -> sorts -> Univ.universe_level option
not a local sort variable declared in [evm] *)
val is_flexible_level : evar_map -> Univ.Level.t -> bool
-val whd_sort_variable : evar_map -> constr -> constr
(* val normalize_universe_level : evar_map -> Univ.universe_level -> Univ.universe_level *)
val normalize_universe : evar_map -> Univ.universe -> Univ.universe
val normalize_universe_instance : evar_map -> Univ.universe_instance -> Univ.universe_instance
@@ -540,7 +534,7 @@ val universe_context_set : evar_map -> Univ.universe_context_set
val universe_context : ?names:(Id.t located) list -> evar_map ->
(Id.t * Univ.Level.t) list * Univ.universe_context
val universe_subst : evar_map -> Universes.universe_opt_subst
-val universes : evar_map -> Univ.universes
+val universes : evar_map -> UGraph.t
val merge_universe_context : evar_map -> evar_universe_context -> evar_map
@@ -618,4 +612,6 @@ val pr_evd_level : evar_map -> Univ.Level.t -> Pp.std_ppcmds
val create_evar_defs : evar_map -> evar_map
(** Create an [evar_map] with empty meta map: *)
-val create_goal_evar_defs : evar_map -> evar_map
+(** {5 Summary names} *)
+
+val evar_counter_summary_name : string
diff --git a/proofs/logic_monad.ml b/engine/logic_monad.ml
index 68efa71e8..4b78bc05d 100644
--- a/proofs/logic_monad.ml
+++ b/engine/logic_monad.ml
@@ -138,46 +138,13 @@ end
(** A view type for the logical monad, which is a form of list, hence
we can decompose it with as a list. *)
-type ('a, 'b) list_view =
- | Nil of Exninfo.iexn
- | Cons of 'a * 'b
+type ('a, 'b, 'e) list_view =
+ | Nil of 'e
+ | Cons of 'a * ('e -> 'b)
-module type Param = sig
-
- (** Read only *)
- type e
-
- (** Write only *)
- type w
-
- (** [w] must be a monoid *)
- val wunit : w
- val wprod : w -> w -> w
-
- (** Read-write *)
- type s
-
- (** Update-only. Essentially a writer on [u->u]. *)
- type u
-
- (** [u] must be pointed. *)
- val uunit : u
-
-end
-
-
-module Logical (P:Param) =
+module BackState =
struct
- (** All three of environment, writer and state are coded as a single
- state-passing-style monad.*)
- type state = {
- rstate : P.e;
- ustate : P.u;
- wstate : P.w;
- sstate : P.s;
- }
-
(** Double-continuation backtracking monads are reasonable folklore
for "search" implementations (including the Tac interactive
prover's tactics). Yet it's quite hard to wrap your head around
@@ -208,32 +175,25 @@ struct
In that vision, [bind] is simply [concat_map] (though the cps
version is significantly simpler), [plus] is concatenation, and
[split] is pattern-matching. *)
- type rich_exn = Exninfo.iexn
-
- type 'a iolist =
- { iolist : 'r. state -> (rich_exn -> 'r NonLogical.t) ->
- ('a -> state -> (rich_exn -> 'r NonLogical.t) -> 'r NonLogical.t) ->
- 'r NonLogical.t }
-
- include Monad.Make(struct
- type 'a t = 'a iolist
+ type ('a, 'i, 'o, 'e) t =
+ { iolist : 'r. 'i -> ('e -> 'r NonLogical.t) ->
+ ('a -> 'o -> ('e -> 'r NonLogical.t) -> 'r NonLogical.t) ->
+ 'r NonLogical.t }
- let return x =
- { iolist = fun s nil cons -> cons x s nil }
+ let return x =
+ { iolist = fun s nil cons -> cons x s nil }
- let (>>=) m f =
- { iolist = fun s nil cons ->
- m.iolist s nil (fun x s next -> (f x).iolist s next cons) }
+ let (>>=) m f =
+ { iolist = fun s nil cons ->
+ m.iolist s nil (fun x s next -> (f x).iolist s next cons) }
- let (>>) m f =
- { iolist = fun s nil cons ->
- m.iolist s nil (fun () s next -> f.iolist s next cons) }
+ let (>>) m f =
+ { iolist = fun s nil cons ->
+ m.iolist s nil (fun () s next -> f.iolist s next cons) }
- let map f m =
- { iolist = fun s nil cons -> m.iolist s nil (fun x s next -> cons (f x) s next) }
-
- end)
+ let map f m =
+ { iolist = fun s nil cons -> m.iolist s nil (fun x s next -> cons (f x) s next) }
let zero e =
{ iolist = fun _ nil cons -> nil e }
@@ -250,27 +210,21 @@ struct
(** State related *)
let get =
- { iolist = fun s nil cons -> cons s.sstate s nil }
+ { iolist = fun s nil cons -> cons s s nil }
- let set (sstate : P.s) =
- { iolist = fun s nil cons -> cons () { s with sstate } nil }
+ let set s =
+ { iolist = fun _ nil cons -> cons () s nil }
- let modify (f : P.s -> P.s) =
- { iolist = fun s nil cons -> cons () { s with sstate = f s.sstate } nil }
+ let modify f =
+ { iolist = fun s nil cons -> cons () (f s) nil }
- let current =
- { iolist = fun s nil cons -> cons s.rstate s nil }
+ (** Exception manipulation *)
- let local e m =
+ let interleave src dst m =
{ iolist = fun s nil cons ->
- m.iolist { s with rstate = e } nil
- (fun x s' next -> cons x {s' with rstate = s.rstate} next) }
-
- let put w =
- { iolist = fun s nil cons -> cons () { s with wstate = P.wprod s.wstate w } nil }
-
- let update (f : P.u -> P.u) =
- { iolist = fun s nil cons -> cons () { s with ustate = f s.ustate } nil }
+ m.iolist s (fun e1 -> nil (src e1))
+ (fun x s next -> cons x s (fun e2 -> next (dst e2)))
+ }
(** List observation *)
@@ -284,9 +238,9 @@ struct
(** For [reflect] and [split] see the "Backtracking, Interleaving,
and Terminating Monad Transformers" paper. *)
- type 'a reified = ('a, rich_exn -> 'a reified) list_view NonLogical.t
+ type ('a, 'e) reified = ('a, ('a, 'e) reified, 'e) list_view NonLogical.t
- let rec reflect (m : ('a * state) reified) : 'a iolist =
+ let rec reflect (m : ('a * 'o, 'e) reified) =
{ iolist = fun s0 nil cons ->
let next = function
| Nil e -> nil e
@@ -295,7 +249,7 @@ struct
NonLogical.(m >>= next)
}
- let split m : ('a, rich_exn -> 'a t) list_view t =
+ let split m : ((_, _, _) list_view, _, _, _) t =
let rnil e = NonLogical.return (Nil e) in
let rcons p s l = NonLogical.return (Cons ((p, s), l)) in
{ iolist = fun s nil cons ->
@@ -307,6 +261,117 @@ struct
cons (Cons (x, l)) s nil
end }
+ let run m s =
+ let rnil e = NonLogical.return (Nil e) in
+ let rcons x s l =
+ let p = (x, s) in
+ NonLogical.return (Cons (p, l))
+ in
+ m.iolist s rnil rcons
+
+ let repr x = x
+end
+
+module type Param = sig
+
+ (** Read only *)
+ type e
+
+ (** Write only *)
+ type w
+
+ (** [w] must be a monoid *)
+ val wunit : w
+ val wprod : w -> w -> w
+
+ (** Read-write *)
+ type s
+
+ (** Update-only. Essentially a writer on [u->u]. *)
+ type u
+
+ (** [u] must be pointed. *)
+ val uunit : u
+
+end
+
+
+module Logical (P:Param) =
+struct
+
+ module Unsafe =
+ struct
+ (** All three of environment, writer and state are coded as a single
+ state-passing-style monad.*)
+ type state = {
+ rstate : P.e;
+ ustate : P.u;
+ wstate : P.w;
+ sstate : P.s;
+ }
+
+ let make m = m
+ let repr m = m
+ end
+
+ open Unsafe
+
+ type state = Unsafe.state
+
+ type iexn = Exninfo.iexn
+
+ type 'a reified = ('a, iexn) BackState.reified
+
+ (** Inherited from Backstate *)
+
+ open BackState
+
+ include Monad.Make(struct
+ type 'a t = ('a, state, state, iexn) BackState.t
+ let return = BackState.return
+ let (>>=) = BackState.(>>=)
+ let (>>) = BackState.(>>)
+ let map = BackState.map
+ end)
+
+ let zero = BackState.zero
+ let plus = BackState.plus
+ let ignore = BackState.ignore
+ let lift = BackState.lift
+ let once = BackState.once
+ let break = BackState.break
+ let reflect = BackState.reflect
+ let split = BackState.split
+ let repr = BackState.repr
+
+ (** State related. We specialize them here to ensure soundness (for reader and
+ writer) and efficiency. *)
+
+ let get =
+ { iolist = fun s nil cons -> cons s.sstate s nil }
+
+ let set (sstate : P.s) =
+ { iolist = fun s nil cons -> cons () { s with sstate } nil }
+
+ let modify (f : P.s -> P.s) =
+ { iolist = fun s nil cons -> cons () { s with sstate = f s.sstate } nil }
+
+ let current =
+ { iolist = fun s nil cons -> cons s.rstate s nil }
+
+ let local e m =
+ { iolist = fun s nil cons ->
+ m.iolist { s with rstate = e } nil
+ (fun x s' next -> cons x {s' with rstate = s.rstate} next) }
+
+ let put w =
+ { iolist = fun s nil cons -> cons () { s with wstate = P.wprod s.wstate w } nil }
+
+ let update (f : P.u -> P.u) =
+ { iolist = fun s nil cons -> cons () { s with ustate = f s.ustate } nil }
+
+ (** Monadic run is specialized to handle reader / writer *)
+
let run m r s =
let s = { wstate = P.wunit; ustate = P.uunit; rstate = r; sstate = s } in
let rnil e = NonLogical.return (Nil e) in
@@ -316,6 +381,4 @@ struct
in
m.iolist s rnil rcons
- let repr x = x
-
end
diff --git a/proofs/logic_monad.mli b/engine/logic_monad.mli
index 96655d538..c5160443b 100644
--- a/proofs/logic_monad.mli
+++ b/engine/logic_monad.mli
@@ -102,9 +102,48 @@ end
(** A view type for the logical monad, which is a form of list, hence
we can decompose it with as a list. *)
-type ('a, 'b) list_view =
-| Nil of Exninfo.iexn
-| Cons of 'a * 'b
+type ('a, 'b, 'e) list_view =
+| Nil of 'e
+| Cons of 'a * ('e -> 'b)
+
+module BackState : sig
+
+ type (+'a, -'i, +'o, 'e) t
+ val return : 'a -> ('a, 's, 's, 'e) t
+ val (>>=) : ('a, 'i, 'm, 'e) t -> ('a -> ('b, 'm, 'o, 'e) t) -> ('b, 'i, 'o, 'e) t
+ val (>>) : (unit, 'i, 'm, 'e) t -> ('b, 'm, 'o, 'e) t -> ('b, 'i, 'o, 'e) t
+ val map : ('a -> 'b) -> ('a, 'i, 'o, 'e) t -> ('b, 'i, 'o, 'e) t
+
+ val ignore : ('a, 'i, 'o, 'e) t -> (unit, 'i, 'o, 'e) t
+
+ val set : 'o -> (unit, 'i, 'o, 'e) t
+ val get : ('s, 's, 's, 'e) t
+ val modify : ('i -> 'o) -> (unit, 'i, 'o, 'e) t
+
+ val interleave : ('e1 -> 'e2) -> ('e2 -> 'e1) -> ('a, 'i, 'o, 'e1) t ->
+ ('a, 'i, 'o, 'e2) t
+ (** [interleave src dst m] adapts the exceptional content of the monad
+ according to the functions [src] and [dst]. To ensure a meaningful result,
+ those functions must form a retraction, i.e. [dst (src e1) = e1] for all
+ [e1]. This is typically the case when the type ['e1] is [unit]. *)
+
+ val zero : 'e -> ('a, 'i, 'o, 'e) t
+ val plus : ('a, 'i, 'o, 'e) t -> ('e -> ('a, 'i, 'o, 'e) t) -> ('a, 'i, 'o, 'e) t
+
+ val split : ('a, 's, 's, 'e) t ->
+ (('a, ('a, 'i, 's, 'e) t, 'e) list_view, 's, 's, 'e) t
+
+ val once : ('a, 'i, 'o, 'e) t -> ('a, 'i, 'o, 'e) t
+ val break : ('e -> 'e option) -> ('a, 'i, 'o, 'e) t -> ('a, 'i, 'o, 'e) t
+ val lift : 'a NonLogical.t -> ('a, 's, 's, 'e) t
+
+ type ('a, 'e) reified
+
+ val repr : ('a, 'e) reified -> ('a, ('a, 'e) reified, 'e) list_view NonLogical.t
+
+ val run : ('a, 'i, 'o, 'e) t -> 'i -> ('a * 'o, 'e) reified
+
+end
(** The monad is parametrised in the types of state, environment and
writer. *)
@@ -147,16 +186,30 @@ module Logical (P:Param) : sig
val zero : Exninfo.iexn -> 'a t
val plus : 'a t -> (Exninfo.iexn -> 'a t) -> 'a t
- val split : 'a t -> (('a,(Exninfo.iexn->'a t)) list_view) t
+ val split : 'a t -> ('a, 'a t, Exninfo.iexn) list_view t
val once : 'a t -> 'a t
val break : (Exninfo.iexn -> Exninfo.iexn option) -> 'a t -> 'a t
val lift : 'a NonLogical.t -> 'a t
- type 'a reified
+ type 'a reified = ('a, Exninfo.iexn) BackState.reified
- val repr : 'a reified -> ('a, Exninfo.iexn -> 'a reified) list_view NonLogical.t
+ val repr : 'a reified -> ('a, 'a reified, Exninfo.iexn) list_view NonLogical.t
val run : 'a t -> P.e -> P.s -> ('a * P.s * P.w * P.u) reified
+ module Unsafe :
+ sig
+ type state = {
+ rstate : P.e;
+ ustate : P.u;
+ wstate : P.w;
+ sstate : P.s;
+ }
+
+ val make : ('a, state, state, Exninfo.iexn) BackState.t -> 'a t
+ val repr : 'a t -> ('a, state, state, Exninfo.iexn) BackState.t
+
+ end
+
end
diff --git a/pretyping/namegen.ml b/engine/namegen.ml
index fc3f0cc75..fc3f0cc75 100644
--- a/pretyping/namegen.ml
+++ b/engine/namegen.ml
diff --git a/pretyping/namegen.mli b/engine/namegen.mli
index 6751bd3cf..a2923fee9 100644
--- a/pretyping/namegen.mli
+++ b/engine/namegen.mli
@@ -8,7 +8,6 @@
open Names
open Term
-open Context
open Environ
(*********************************************************************
@@ -39,13 +38,13 @@ val lambda_name : env -> Name.t * types * constr -> constr
val prod_create : env -> types * types -> constr
val lambda_create : env -> types * constr -> constr
-val name_assumption : env -> rel_declaration -> rel_declaration
-val name_context : env -> rel_context -> rel_context
+val name_assumption : env -> Context.Rel.Declaration.t -> Context.Rel.Declaration.t
+val name_context : env -> Context.Rel.t -> Context.Rel.t
-val mkProd_or_LetIn_name : env -> types -> rel_declaration -> types
-val mkLambda_or_LetIn_name : env -> constr -> rel_declaration -> constr
-val it_mkProd_or_LetIn_name : env -> types -> rel_context -> types
-val it_mkLambda_or_LetIn_name : env -> constr -> rel_context -> constr
+val mkProd_or_LetIn_name : env -> types -> Context.Rel.Declaration.t -> types
+val mkLambda_or_LetIn_name : env -> constr -> Context.Rel.Declaration.t -> constr
+val it_mkProd_or_LetIn_name : env -> types -> Context.Rel.t -> types
+val it_mkLambda_or_LetIn_name : env -> constr -> Context.Rel.t -> constr
(*********************************************************************
Fresh names *)
diff --git a/proofs/proofview_monad.ml b/engine/proofview_monad.ml
index e9bc7761e..2b9db60b4 100644
--- a/proofs/proofview_monad.ml
+++ b/engine/proofview_monad.ml
@@ -108,11 +108,6 @@ module Info = struct
and compress f =
CList.map_filter compress_tree f
- let rec is_empty = let open Trace in function
- | Seq(Dispatch,brs) -> List.for_all is_empty brs
- | Seq(DBranch,br) -> List.for_all is_empty br
- | _ -> false
-
(** [with_sep] is [true] when [Tactic m] must be printed with a
trailing semi-colon. *)
let rec pr_tree with_sep = let open Trace in function
diff --git a/proofs/proofview_monad.mli b/engine/proofview_monad.mli
index 7a6ea10fe..7a6ea10fe 100644
--- a/proofs/proofview_monad.mli
+++ b/engine/proofview_monad.mli
diff --git a/engine/sigma.ml b/engine/sigma.ml
new file mode 100644
index 000000000..e886b0d1e
--- /dev/null
+++ b/engine/sigma.ml
@@ -0,0 +1,105 @@
+(************************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2015 *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(************************************************************************)
+
+type 'a t = Evd.evar_map
+
+type ('a, 'b) le = unit
+
+let refl = ()
+let cons _ _ = ()
+let (+>) = fun _ _ -> ()
+
+type ('a, 'r) sigma = Sigma : 'a * 's t * ('r, 's) le -> ('a, 'r) sigma
+
+type 'a evar = Evar.t
+
+let lift_evar evk () = evk
+
+let to_evar_map evd = evd
+let to_evar evk = evk
+
+let here x s = Sigma (x, s, ())
+
+(** API *)
+
+type 'r fresh = Fresh : 's evar * 's t * ('r, 's) le -> 'r fresh
+
+let new_evar sigma ?naming info =
+ let (sigma, evk) = Evd.new_evar sigma ?naming info in
+ Fresh (evk, sigma, ())
+
+let define evk c sigma =
+ Sigma ((), Evd.define evk c sigma, ())
+
+let fresh_sort_in_family ?rigid env sigma s =
+ let (sigma, s) = Evd.fresh_sort_in_family ?rigid env sigma s in
+ Sigma (s, sigma, ())
+
+let fresh_constant_instance env sigma cst =
+ let (sigma, cst) = Evd.fresh_constant_instance env sigma cst in
+ Sigma (cst, sigma, ())
+
+let fresh_inductive_instance env sigma ind =
+ let (sigma, ind) = Evd.fresh_inductive_instance env sigma ind in
+ Sigma (ind, sigma, ())
+
+let fresh_constructor_instance env sigma pc =
+ let (sigma, c) = Evd.fresh_constructor_instance env sigma pc in
+ Sigma (c, sigma, ())
+
+let fresh_global ?rigid ?names env sigma r =
+ let (sigma, c) = Evd.fresh_global ?rigid ?names env sigma r in
+ Sigma (c, sigma, ())
+
+(** Run *)
+
+type 'a run = { run : 'r. 'r t -> ('a, 'r) sigma }
+
+let run sigma f : 'a * Evd.evar_map =
+ let Sigma (x, sigma, ()) = f.run sigma in
+ (x, sigma)
+
+(** Monotonic references *)
+
+type evdref = Evd.evar_map ref
+
+let apply evdref f =
+ let Sigma (x, sigma, ()) = f.run !evdref in
+ evdref := sigma;
+ x
+
+let purify f =
+ let f (sigma : Evd.evar_map) =
+ let evdref = ref sigma in
+ let ans = f evdref in
+ Sigma (ans, !evdref, ())
+ in
+ { run = f }
+
+(** Unsafe primitives *)
+
+module Unsafe =
+struct
+
+let le = ()
+let of_evar_map sigma = sigma
+let of_evar evk = evk
+let of_ref ref = ref
+let of_pair (x, sigma) = Sigma (x, sigma, ())
+
+end
+
+module Notations =
+struct
+ type ('a, 'r) sigma_ = ('a, 'r) sigma =
+ Sigma : 'a * 's t * ('r, 's) le -> ('a, 'r) sigma_
+
+ let (+>) = fun _ _ -> ()
+
+ type 'a run_ = 'a run = { run : 'r. 'r t -> ('a, 'r) sigma }
+end
diff --git a/engine/sigma.mli b/engine/sigma.mli
new file mode 100644
index 000000000..cb948dba5
--- /dev/null
+++ b/engine/sigma.mli
@@ -0,0 +1,122 @@
+(************************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2015 *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(************************************************************************)
+
+open Names
+open Constr
+
+(** Monotonous state enforced by typing.
+
+ This module allows to constrain uses of evarmaps in a monotonous fashion,
+ and in particular statically suppress evar leaks and the like.
+*)
+
+(** {5 Stages} *)
+
+type ('a, 'b) le
+(** Relationship stating that stage ['a] is anterior to stage ['b] *)
+
+val refl : ('a, 'a) le
+(** Reflexivity of anteriority *)
+
+val cons : ('a, 'b) le -> ('b, 'c) le -> ('a, 'c) le
+(** Transitivity of anteriority *)
+
+val (+>) : ('a, 'b) le -> ('b, 'c) le -> ('a, 'c) le
+(** Alias for {!cons} *)
+
+(** {5 Monotonous evarmaps} *)
+
+type 'r t
+(** Stage-indexed evarmaps. *)
+
+type ('a, 'r) sigma = Sigma : 'a * 's t * ('r, 's) le -> ('a, 'r) sigma
+(** Return values at a later stage *)
+
+type 'r evar
+(** Stage-indexed evars *)
+
+(** {5 Constructors} *)
+
+val here : 'a -> 'r t -> ('a, 'r) sigma
+(** [here x s] is a shorthand for [Sigma (x, s, refl)] *)
+
+(** {5 Postponing} *)
+
+val lift_evar : 'r evar -> ('r, 's) le -> 's evar
+(** Any evar existing at stage ['r] is also valid at any later stage. *)
+
+(** {5 Downcasting} *)
+
+val to_evar_map : 'r t -> Evd.evar_map
+val to_evar : 'r evar -> Evar.t
+
+(** {5 Monotonous API} *)
+
+type 'r fresh = Fresh : 's evar * 's t * ('r, 's) le -> 'r fresh
+
+val new_evar : 'r t -> ?naming:Misctypes.intro_pattern_naming_expr ->
+ Evd.evar_info -> 'r fresh
+
+val define : 'r evar -> Constr.t -> 'r t -> (unit, 'r) sigma
+
+(** Polymorphic universes *)
+
+val fresh_sort_in_family : ?rigid:Evd.rigid -> Environ.env ->
+ 'r t -> Term.sorts_family -> (Term.sorts, 'r) sigma
+val fresh_constant_instance :
+ Environ.env -> 'r t -> constant -> (pconstant, 'r) sigma
+val fresh_inductive_instance :
+ Environ.env -> 'r t -> inductive -> (pinductive, 'r) sigma
+val fresh_constructor_instance : Environ.env -> 'r t -> constructor ->
+ (pconstructor, 'r) sigma
+
+val fresh_global : ?rigid:Evd.rigid -> ?names:Univ.Instance.t -> Environ.env ->
+ 'r t -> Globnames.global_reference -> (constr, 'r) sigma
+
+(** FILLME *)
+
+(** {5 Run} *)
+
+type 'a run = { run : 'r. 'r t -> ('a, 'r) sigma }
+
+val run : Evd.evar_map -> 'a run -> 'a * Evd.evar_map
+
+(** {5 Imperative monotonic functions} *)
+
+type evdref
+(** Monotonic references over evarmaps *)
+
+val apply : evdref -> 'a run -> 'a
+(** Apply a monotonic function on a reference. *)
+
+val purify : (evdref -> 'a) -> 'a run
+(** Converse of {!apply}. *)
+
+(** {5 Unsafe primitives} *)
+
+module Unsafe :
+sig
+ val le : ('a, 'b) le
+ val of_evar_map : Evd.evar_map -> 'r t
+ val of_evar : Evd.evar -> 'r evar
+ val of_ref : Evd.evar_map ref -> evdref
+ val of_pair : ('a * Evd.evar_map) -> ('a, 'r) sigma
+end
+
+(** {5 Notations} *)
+
+module Notations :
+sig
+ type ('a, 'r) sigma_ = ('a, 'r) sigma =
+ Sigma : 'a * 's t * ('r, 's) le -> ('a, 'r) sigma_
+
+ type 'a run_ = 'a run = { run : 'r. 'r t -> ('a, 'r) sigma }
+
+ val (+>) : ('a, 'b) le -> ('b, 'c) le -> ('a, 'c) le
+ (** Alias for {!cons} *)
+end
diff --git a/pretyping/termops.ml b/engine/termops.ml
index 9d469cb71..b7d89ba7b 100644
--- a/pretyping/termops.ml
+++ b/engine/termops.ml
@@ -13,7 +13,6 @@ open Names
open Nameops
open Term
open Vars
-open Context
open Environ
(* Sorts and sort family *)
@@ -158,19 +157,6 @@ let rel_list n m =
in
reln [] 1
-(* Same as [rel_list] but takes a context as argument and skips let-ins *)
-let extended_rel_list n hyps =
- let rec reln l p = function
- | (_,None,_) :: hyps -> reln (mkRel (n+p) :: l) (p+1) hyps
- | (_,Some _,_) :: hyps -> reln l (p+1) hyps
- | [] -> l
- in
- reln [] 1 hyps
-
-let extended_rel_vect n hyps = Array.of_list (extended_rel_list n hyps)
-
-
-
let push_rel_assum (x,t) env = push_rel (x,None,t) env
let push_rels_assum assums =
@@ -713,9 +699,9 @@ let replace_term = replace_term_gen eq_constr
let vars_of_env env =
let s =
- Context.fold_named_context (fun (id,_,_) s -> Id.Set.add id s)
+ Context.Named.fold_outside (fun (id,_,_) s -> Id.Set.add id s)
(named_context env) ~init:Id.Set.empty in
- Context.fold_rel_context
+ Context.Rel.fold_outside
(fun (na,_,_) s -> match na with Name id -> Id.Set.add id s | _ -> s)
(rel_context env) ~init:s
@@ -741,12 +727,12 @@ let lookup_rel_of_name id names =
let empty_names_context = []
let ids_of_rel_context sign =
- Context.fold_rel_context
+ Context.Rel.fold_outside
(fun (na,_,_) l -> match na with Name id -> id::l | Anonymous -> l)
sign ~init:[]
let ids_of_named_context sign =
- Context.fold_named_context (fun (id,_,_) idl -> id::idl) sign ~init:[]
+ Context.Named.fold_outside (fun (id,_,_) idl -> id::idl) sign ~init:[]
let ids_of_context env =
(ids_of_rel_context (rel_context env))
@@ -801,7 +787,7 @@ let split_app c = match kind_of_term c with
c::(Array.to_list prev), last
| _ -> assert false
-type subst = (rel_context*constr) Evar.Map.t
+type subst = (Context.Rel.t * constr) Evar.Map.t
exception CannotFilter
@@ -838,7 +824,7 @@ let filtering env cv_pb c1 c2 =
in
aux env cv_pb c1 c2; !evm
-let decompose_prod_letin : constr -> int * rel_context * constr =
+let decompose_prod_letin : constr -> int * Context.Rel.t * constr =
let rec prodec_rec i l c = match kind_of_term c with
| Prod (n,t,c) -> prodec_rec (succ i) ((n,None,t)::l) c
| LetIn (n,d,t,c) -> prodec_rec (succ i) ((n,Some d,t)::l) c
@@ -846,7 +832,35 @@ let decompose_prod_letin : constr -> int * rel_context * constr =
| _ -> i,l,c in
prodec_rec 0 []
-let align_prod_letin c a : rel_context * constr =
+(* (nb_lam [na1:T1]...[nan:Tan]c) where c is not an abstraction
+ * gives n (casts are ignored) *)
+let nb_lam =
+ let rec nbrec n c = match kind_of_term c with
+ | Lambda (_,_,c) -> nbrec (n+1) c
+ | Cast (c,_,_) -> nbrec n c
+ | _ -> n
+ in
+ nbrec 0
+
+(* similar to nb_lam, but gives the number of products instead *)
+let nb_prod =
+ let rec nbrec n c = match kind_of_term c with
+ | Prod (_,_,c) -> nbrec (n+1) c
+ | Cast (c,_,_) -> nbrec n c
+ | _ -> n
+ in
+ nbrec 0
+
+let nb_prod_modulo_zeta x =
+ let rec count n c =
+ match kind_of_term c with
+ Prod(_,_,t) -> count (n+1) t
+ | LetIn(_,a,_,t) -> count n (subst1 a t)
+ | Cast(c,_,_) -> count n c
+ | _ -> n
+ in count 0 x
+
+let align_prod_letin c a : Context.Rel.t * constr =
let (lc,_,_) = decompose_prod_letin c in
let (la,l,a) = decompose_prod_letin a in
if not (la >= lc) then invalid_arg "align_prod_letin";
@@ -884,10 +898,10 @@ let process_rel_context f env =
let sign = named_context_val env in
let rels = rel_context env in
let env0 = reset_with_named_context sign env in
- Context.fold_rel_context f rels ~init:env0
+ Context.Rel.fold_outside f rels ~init:env0
let assums_of_rel_context sign =
- Context.fold_rel_context
+ Context.Rel.fold_outside
(fun (na,c,t) l ->
match c with
Some _ -> l
@@ -897,7 +911,7 @@ let assums_of_rel_context sign =
let map_rel_context_in_env f env sign =
let rec aux env acc = function
| d::sign ->
- aux (push_rel d env) (map_rel_declaration (f env) d :: acc) sign
+ aux (push_rel d env) (Context.Rel.Declaration.map (f env) d :: acc) sign
| [] ->
acc
in
@@ -905,10 +919,10 @@ let map_rel_context_in_env f env sign =
let map_rel_context_with_binders f sign =
let rec aux k = function
- | d::sign -> map_rel_declaration (f k) d :: aux (k-1) sign
+ | d::sign -> Context.Rel.Declaration.map (f k) d :: aux (k-1) sign
| [] -> []
in
- aux (rel_context_length sign) sign
+ aux (Context.Rel.length sign) sign
let substl_rel_context l =
map_rel_context_with_binders (fun k -> substnl l (k-1))
@@ -925,16 +939,6 @@ let smash_rel_context sign =
aux (List.rev (substl_rel_context [b] (List.rev acc))) l
in List.rev (aux [] sign)
-let adjust_subst_to_rel_context sign l =
- let rec aux subst sign l =
- match sign, l with
- | (_,None,_)::sign', a::args' -> aux (a::subst) sign' args'
- | (_,Some c,_)::sign', args' ->
- aux (substl subst c :: subst) sign' args'
- | [], [] -> List.rev subst
- | _ -> anomaly (Pp.str "Instance and signature do not match")
- in aux [] (List.rev sign) l
-
let fold_named_context_both_sides f l ~init = List.fold_right_and_left f l init
let rec mem_named_context id = function
@@ -950,7 +954,7 @@ let compact_named_context_reverse sign =
if Option.equal Constr.equal c1 c2 && Constr.equal t1 t2
then (i1::l2,c2,t2)::q
else ([i1],c1,t1)::l
- in Context.fold_named_context_reverse compact ~init:[] sign
+ in Context.Named.fold_inside compact ~init:[] sign
let compact_named_context sign = List.rev (compact_named_context_reverse sign)
@@ -971,7 +975,7 @@ let global_vars_set_of_decl env = function
let dependency_closure env sign hyps =
if Id.Set.is_empty hyps then [] else
let (_,lh) =
- Context.fold_named_context_reverse
+ Context.Named.fold_inside
(fun (hs,hl) (x,_,_ as d) ->
if Id.Set.mem x hs then
(Id.Set.union (global_vars_set_of_decl env d) (Id.Set.remove x hs),
@@ -987,8 +991,8 @@ let on_judgment f j = { uj_val = f j.uj_val; uj_type = f j.uj_type }
let on_judgment_value f j = { j with uj_val = f j.uj_val }
let on_judgment_type f j = { j with uj_type = f j.uj_type }
-(* Cut a context ctx in 2 parts (ctx1,ctx2) with ctx1 containing k
- variables; skips let-in's *)
+(* Cut a context ctx in 2 parts (ctx1,ctx2) with ctx1 containing k non let-in
+ variables skips let-in's; let-in's in the middle are put in ctx2 *)
let context_chop k ctx =
let rec chop_aux acc = function
| (0, l2) -> (List.rev acc, l2)
diff --git a/pretyping/termops.mli b/engine/termops.mli
index ca98f8d73..720ed3bd6 100644
--- a/pretyping/termops.mli
+++ b/engine/termops.mli
@@ -9,7 +9,6 @@
open Pp
open Names
open Term
-open Context
open Environ
(** printers *)
@@ -22,7 +21,7 @@ val set_print_constr : (env -> constr -> std_ppcmds) -> unit
val print_constr : constr -> std_ppcmds
val print_constr_env : env -> constr -> std_ppcmds
val print_named_context : env -> std_ppcmds
-val pr_rel_decl : env -> rel_declaration -> std_ppcmds
+val pr_rel_decl : env -> Context.Rel.Declaration.t -> std_ppcmds
val print_rel_context : env -> std_ppcmds
val print_env : env -> std_ppcmds
@@ -31,35 +30,31 @@ val push_rel_assum : Name.t * types -> env -> env
val push_rels_assum : (Name.t * types) list -> env -> env
val push_named_rec_types : Name.t array * types array * 'a -> env -> env
-val lookup_rel_id : Id.t -> rel_context -> int * constr option * types
+val lookup_rel_id : Id.t -> Context.Rel.t -> int * constr option * types
(** Associates the contents of an identifier in a [rel_context]. Raise
[Not_found] if there is no such identifier. *)
(** Functions that build argument lists matching a block of binders or a context.
[rel_vect n m] builds [|Rel (n+m);...;Rel(n+1)|]
- [extended_rel_vect n ctx] extends the [ctx] context of length [m]
- with [n] elements.
*)
val rel_vect : int -> int -> constr array
val rel_list : int -> int -> constr list
-val extended_rel_list : int -> rel_context -> constr list
-val extended_rel_vect : int -> rel_context -> constr array
(** iterators/destructors on terms *)
-val mkProd_or_LetIn : rel_declaration -> types -> types
-val mkProd_wo_LetIn : rel_declaration -> types -> types
+val mkProd_or_LetIn : Context.Rel.Declaration.t -> types -> types
+val mkProd_wo_LetIn : Context.Rel.Declaration.t -> types -> types
val it_mkProd : types -> (Name.t * types) list -> types
val it_mkLambda : constr -> (Name.t * types) list -> constr
-val it_mkProd_or_LetIn : types -> rel_context -> types
-val it_mkProd_wo_LetIn : types -> rel_context -> types
-val it_mkLambda_or_LetIn : constr -> rel_context -> constr
-val it_mkNamedProd_or_LetIn : types -> named_context -> types
-val it_mkNamedProd_wo_LetIn : types -> named_context -> types
-val it_mkNamedLambda_or_LetIn : constr -> named_context -> constr
+val it_mkProd_or_LetIn : types -> Context.Rel.t -> types
+val it_mkProd_wo_LetIn : types -> Context.Rel.t -> types
+val it_mkLambda_or_LetIn : constr -> Context.Rel.t -> constr
+val it_mkNamedProd_or_LetIn : types -> Context.Named.t -> types
+val it_mkNamedProd_wo_LetIn : types -> Context.Named.t -> types
+val it_mkNamedLambda_or_LetIn : constr -> Context.Named.t -> constr
(* Ad hoc version reinserting letin, assuming the body is defined in
the context where the letins are expanded *)
-val it_mkLambda_or_LetIn_from_no_LetIn : constr -> rel_context -> constr
+val it_mkLambda_or_LetIn_from_no_LetIn : constr -> Context.Rel.t -> constr
(** {6 Generic iterators on constr} *)
@@ -67,11 +62,11 @@ val map_constr_with_named_binders :
(Name.t -> 'a -> 'a) ->
('a -> constr -> constr) -> 'a -> constr -> constr
val map_constr_with_binders_left_to_right :
- (rel_declaration -> 'a -> 'a) ->
+ (Context.Rel.Declaration.t -> 'a -> 'a) ->
('a -> constr -> constr) ->
'a -> constr -> constr
val map_constr_with_full_binders :
- (rel_declaration -> 'a -> 'a) ->
+ (Context.Rel.Declaration.t -> 'a -> 'a) ->
('a -> constr -> constr) -> 'a -> constr -> constr
(** [fold_constr_with_binders g f n acc c] folds [f n] on the immediate
@@ -85,11 +80,11 @@ val fold_constr_with_binders :
('a -> 'a) -> ('a -> 'b -> constr -> 'b) -> 'a -> 'b -> constr -> 'b
val fold_constr_with_full_binders :
- (rel_declaration -> 'a -> 'a) -> ('a -> 'b -> constr -> 'b) ->
+ (Context.Rel.Declaration.t -> 'a -> 'a) -> ('a -> 'b -> constr -> 'b) ->
'a -> 'b -> constr -> 'b
val iter_constr_with_full_binders :
- (rel_declaration -> 'a -> 'a) -> ('a -> constr -> unit) -> 'a ->
+ (Context.Rel.Declaration.t -> 'a -> 'a) -> ('a -> constr -> unit) -> 'a ->
constr -> unit
(**********************************************************************)
@@ -114,7 +109,7 @@ val dependent : constr -> constr -> bool
val dependent_no_evar : constr -> constr -> bool
val dependent_univs : constr -> constr -> bool
val dependent_univs_no_evar : constr -> constr -> bool
-val dependent_in_decl : constr -> named_declaration -> bool
+val dependent_in_decl : constr -> Context.Named.Declaration.t -> bool
val count_occurrences : constr -> constr -> int
val collect_metas : constr -> int list
val collect_vars : constr -> Id.Set.t (** for visible vars only *)
@@ -134,7 +129,7 @@ val pop : constr -> constr
(** Substitution of an arbitrary large term. Uses equality modulo
reduction of let *)
-(** [subst_term_gen eq d c] replaces [Rel 1] by [d] in [c] using [eq]
+(** [subst_term_gen eq d c] replaces [d] by [Rel 1] in [c] using [eq]
as equality *)
val subst_term_gen :
(constr -> constr -> bool) -> constr -> constr -> constr
@@ -145,7 +140,7 @@ val replace_term_gen :
(constr -> constr -> bool) ->
constr -> constr -> constr -> constr
-(** [subst_term d c] replaces [Rel 1] by [d] in [c] *)
+(** [subst_term d c] replaces [d] by [Rel 1] in [c] *)
val subst_term : constr -> constr -> constr
(** [replace_term d e c] replaces [d] by [e] in [c] *)
@@ -168,11 +163,21 @@ exception CannotFilter
(context,term), or raises [CannotFilter].
Warning: Outer-kernel sort subtyping are taken into account: c1 has
to be smaller than c2 wrt. sorts. *)
-type subst = (rel_context*constr) Evar.Map.t
-val filtering : rel_context -> Reduction.conv_pb -> constr -> constr -> subst
+type subst = (Context.Rel.t * constr) Evar.Map.t
+val filtering : Context.Rel.t -> Reduction.conv_pb -> constr -> constr -> subst
-val decompose_prod_letin : constr -> int * rel_context * constr
-val align_prod_letin : constr -> constr -> rel_context * constr
+val decompose_prod_letin : constr -> int * Context.Rel.t * constr
+val align_prod_letin : constr -> constr -> Context.Rel.t * constr
+
+(** [nb_lam] {% $ %}[x_1:T_1]...[x_n:T_n]c{% $ %} where {% $ %}c{% $ %} is not an abstraction
+ gives {% $ %}n{% $ %} (casts are ignored) *)
+val nb_lam : constr -> int
+
+(** Similar to [nb_lam], but gives the number of products instead *)
+val nb_prod : constr -> int
+
+(** Similar to [nb_prod], but zeta-contracts let-in on the way *)
+val nb_prod_modulo_zeta : constr -> int
(** Get the last arg of a constr intended to be an application *)
val last_arg : constr -> constr
@@ -191,44 +196,51 @@ val add_name : Name.t -> names_context -> names_context
val lookup_name_of_rel : int -> names_context -> Name.t
val lookup_rel_of_name : Id.t -> names_context -> int
val empty_names_context : names_context
-val ids_of_rel_context : rel_context -> Id.t list
-val ids_of_named_context : named_context -> Id.t list
+val ids_of_rel_context : Context.Rel.t -> Id.t list
+val ids_of_named_context : Context.Named.t -> Id.t list
val ids_of_context : env -> Id.t list
val names_of_rel_context : env -> names_context
-val context_chop : int -> rel_context -> rel_context * rel_context
-val env_rel_context_chop : int -> env -> env * rel_context
+(* [context_chop n Γ] returns (Γ₁,Γ₂) such that [Γ]=[Γ₂Γ₁], [Γ₁] has
+ [n] hypotheses, excluding local definitions, and [Γ₁], if not empty,
+ starts with an hypothesis (i.e. [Γ₁] has the form empty or [x:A;Γ₁'] *)
+val context_chop : int -> Context.Rel.t -> Context.Rel.t * Context.Rel.t
+
+(* [env_rel_context_chop n env] extracts out the [n] top declarations
+ of the rel_context part of [env], counting both local definitions and
+ hypotheses *)
+val env_rel_context_chop : int -> env -> env * Context.Rel.t
(** Set of local names *)
val vars_of_env: env -> Id.Set.t
val add_vname : Id.Set.t -> Name.t -> Id.Set.t
(** other signature iterators *)
-val process_rel_context : (rel_declaration -> env -> env) -> env -> env
-val assums_of_rel_context : rel_context -> (Name.t * constr) list
-val lift_rel_context : int -> rel_context -> rel_context
-val substl_rel_context : constr list -> rel_context -> rel_context
-val smash_rel_context : rel_context -> rel_context (** expand lets in context *)
-val adjust_subst_to_rel_context : rel_context -> constr list -> constr list
+val process_rel_context : (Context.Rel.Declaration.t -> env -> env) -> env -> env
+val assums_of_rel_context : Context.Rel.t -> (Name.t * constr) list
+val lift_rel_context : int -> Context.Rel.t -> Context.Rel.t
+val substl_rel_context : constr list -> Context.Rel.t -> Context.Rel.t
+val smash_rel_context : Context.Rel.t -> Context.Rel.t (** expand lets in context *)
+
val map_rel_context_in_env :
- (env -> constr -> constr) -> env -> rel_context -> rel_context
+ (env -> constr -> constr) -> env -> Context.Rel.t -> Context.Rel.t
val map_rel_context_with_binders :
- (int -> constr -> constr) -> rel_context -> rel_context
+ (int -> constr -> constr) -> Context.Rel.t -> Context.Rel.t
val fold_named_context_both_sides :
- ('a -> named_declaration -> named_declaration list -> 'a) ->
- named_context -> init:'a -> 'a
-val mem_named_context : Id.t -> named_context -> bool
-val compact_named_context : named_context -> named_list_context
-val compact_named_context_reverse : named_context -> named_list_context
+ ('a -> Context.Named.Declaration.t -> Context.Named.Declaration.t list -> 'a) ->
+ Context.Named.t -> init:'a -> 'a
+val mem_named_context : Id.t -> Context.Named.t -> bool
+val compact_named_context : Context.Named.t -> Context.NamedList.t
+val compact_named_context_reverse : Context.Named.t -> Context.NamedList.t
val clear_named_body : Id.t -> env -> env
val global_vars : env -> constr -> Id.t list
-val global_vars_set_of_decl : env -> named_declaration -> Id.Set.t
+val global_vars_set_of_decl : env -> Context.Named.Declaration.t -> Id.Set.t
(** Gives an ordered list of hypotheses, closed by dependencies,
containing a given set *)
-val dependency_closure : env -> named_context -> Id.Set.t -> Id.t list
+val dependency_closure : env -> Context.Named.t -> Id.Set.t -> Id.t list
(** Test if an identifier is the basename of a global reference *)
val is_section_variable : Id.t -> bool
diff --git a/engine/uState.ml b/engine/uState.ml
new file mode 100644
index 000000000..75c03bc89
--- /dev/null
+++ b/engine/uState.ml
@@ -0,0 +1,466 @@
+(************************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2015 *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(************************************************************************)
+
+open Pp
+open Errors
+open Util
+open Names
+
+module StringOrd = struct type t = string let compare = String.compare end
+module UNameMap = struct
+
+ include Map.Make(StringOrd)
+
+ let union s t =
+ if s == t then s
+ else
+ merge (fun k l r ->
+ match l, r with
+ | Some _, _ -> l
+ | _, _ -> r) s t
+end
+
+(* 2nd part used to check consistency on the fly. *)
+type t =
+ { uctx_names : Univ.Level.t UNameMap.t * string Univ.LMap.t;
+ uctx_local : Univ.universe_context_set; (** The local context of variables *)
+ uctx_univ_variables : Universes.universe_opt_subst;
+ (** The local universes that are unification variables *)
+ uctx_univ_algebraic : Univ.universe_set;
+ (** The subset of unification variables that can be instantiated with
+ algebraic universes as they appear in inferred types only. *)
+ uctx_universes : UGraph.t; (** The current graph extended with the local constraints *)
+ uctx_initial_universes : UGraph.t; (** The graph at the creation of the evar_map *)
+ }
+
+let empty =
+ { uctx_names = UNameMap.empty, Univ.LMap.empty;
+ uctx_local = Univ.ContextSet.empty;
+ uctx_univ_variables = Univ.LMap.empty;
+ uctx_univ_algebraic = Univ.LSet.empty;
+ uctx_universes = UGraph.initial_universes;
+ uctx_initial_universes = UGraph.initial_universes }
+
+let make u =
+ { empty with
+ uctx_universes = u; uctx_initial_universes = u}
+
+let is_empty ctx =
+ Univ.ContextSet.is_empty ctx.uctx_local &&
+ Univ.LMap.is_empty ctx.uctx_univ_variables
+
+let union ctx ctx' =
+ if ctx == ctx' then ctx
+ else if is_empty ctx' then ctx
+ else
+ let local = Univ.ContextSet.union ctx.uctx_local ctx'.uctx_local in
+ let names = UNameMap.union (fst ctx.uctx_names) (fst ctx'.uctx_names) in
+ let newus = Univ.LSet.diff (Univ.ContextSet.levels ctx'.uctx_local)
+ (Univ.ContextSet.levels ctx.uctx_local) in
+ let newus = Univ.LSet.diff newus (Univ.LMap.domain ctx.uctx_univ_variables) in
+ let declarenew g =
+ Univ.LSet.fold (fun u g -> UGraph.add_universe u false g) newus g
+ in
+ let names_rev = Univ.LMap.union (snd ctx.uctx_names) (snd ctx'.uctx_names) in
+ { uctx_names = (names, names_rev);
+ uctx_local = local;
+ uctx_univ_variables =
+ Univ.LMap.subst_union ctx.uctx_univ_variables ctx'.uctx_univ_variables;
+ uctx_univ_algebraic =
+ Univ.LSet.union ctx.uctx_univ_algebraic ctx'.uctx_univ_algebraic;
+ uctx_initial_universes = declarenew ctx.uctx_initial_universes;
+ uctx_universes =
+ if local == ctx.uctx_local then ctx.uctx_universes
+ else
+ let cstrsr = Univ.ContextSet.constraints ctx'.uctx_local in
+ UGraph.merge_constraints cstrsr (declarenew ctx.uctx_universes) }
+
+let context_set ctx = ctx.uctx_local
+
+let constraints ctx = snd ctx.uctx_local
+
+let context ctx = Univ.ContextSet.to_context ctx.uctx_local
+
+let of_context_set ctx = { empty with uctx_local = ctx }
+
+let subst ctx = ctx.uctx_univ_variables
+
+let ugraph ctx = ctx.uctx_universes
+
+let algebraics ctx = ctx.uctx_univ_algebraic
+
+let constrain_variables diff ctx =
+ Univ.LSet.fold
+ (fun l cstrs ->
+ try
+ match Univ.LMap.find l ctx.uctx_univ_variables with
+ | Some u -> Univ.Constraint.add (l, Univ.Eq, Option.get (Univ.Universe.level u)) cstrs
+ | None -> cstrs
+ with Not_found | Option.IsNone -> cstrs)
+ diff Univ.Constraint.empty
+
+let add_uctx_names s l (names, names_rev) =
+ (UNameMap.add s l names, Univ.LMap.add l s names_rev)
+
+let of_binders b =
+ let ctx = empty in
+ let names =
+ List.fold_left (fun acc (id, l) -> add_uctx_names (Id.to_string id) l acc)
+ ctx.uctx_names b
+ in { ctx with uctx_names = names }
+
+let instantiate_variable l b v =
+ try v := Univ.LMap.update l (Some b) !v
+ with Not_found -> assert false
+
+exception UniversesDiffer
+
+let process_universe_constraints ctx cstrs =
+ let univs = ctx.uctx_universes in
+ let vars = ref ctx.uctx_univ_variables in
+ let normalize = Universes.normalize_universe_opt_subst vars in
+ let rec unify_universes fo l d r local =
+ let l = normalize l and r = normalize r in
+ if Univ.Universe.equal l r then local
+ else
+ let varinfo x =
+ match Univ.Universe.level x with
+ | None -> Inl x
+ | Some l -> Inr (l, Univ.LMap.mem l !vars, Univ.LSet.mem l ctx.uctx_univ_algebraic)
+ in
+ if d == Universes.ULe then
+ if UGraph.check_leq univs l r then
+ (** Keep Prop/Set <= var around if var might be instantiated by prop or set
+ later. *)
+ if Univ.Universe.is_level l then
+ match Univ.Universe.level r with
+ | Some r ->
+ Univ.Constraint.add (Option.get (Univ.Universe.level l),Univ.Le,r) local
+ | _ -> local
+ else local
+ else
+ match Univ.Universe.level r with
+ | None -> error ("Algebraic universe on the right")
+ | Some rl ->
+ if Univ.Level.is_small rl then
+ let levels = Univ.Universe.levels l in
+ Univ.LSet.fold (fun l local ->
+ if Univ.Level.is_small l || Univ.LMap.mem l !vars then
+ unify_universes fo (Univ.Universe.make l) Universes.UEq r local
+ else raise (Univ.UniverseInconsistency (Univ.Le, Univ.Universe.make l, r, None)))
+ levels local
+ else
+ Univ.enforce_leq l r local
+ else if d == Universes.ULub then
+ match varinfo l, varinfo r with
+ | (Inr (l, true, _), Inr (r, _, _))
+ | (Inr (r, _, _), Inr (l, true, _)) ->
+ instantiate_variable l (Univ.Universe.make r) vars;
+ Univ.enforce_eq_level l r local
+ | Inr (_, _, _), Inr (_, _, _) ->
+ unify_universes true l Universes.UEq r local
+ | _, _ -> assert false
+ else (* d = Universes.UEq *)
+ match varinfo l, varinfo r with
+ | Inr (l', lloc, _), Inr (r', rloc, _) ->
+ let () =
+ if lloc then
+ instantiate_variable l' r vars
+ else if rloc then
+ instantiate_variable r' l vars
+ else if not (UGraph.check_eq univs l r) then
+ (* Two rigid/global levels, none of them being local,
+ one of them being Prop/Set, disallow *)
+ if Univ.Level.is_small l' || Univ.Level.is_small r' then
+ raise (Univ.UniverseInconsistency (Univ.Eq, l, r, None))
+ else
+ if fo then
+ raise UniversesDiffer
+ in
+ Univ.enforce_eq_level l' r' local
+ | Inr (l, loc, alg), Inl r
+ | Inl r, Inr (l, loc, alg) ->
+ let inst = Univ.univ_level_rem l r r in
+ if alg then (instantiate_variable l inst vars; local)
+ else
+ let lu = Univ.Universe.make l in
+ if Univ.univ_level_mem l r then
+ Univ.enforce_leq inst lu local
+ else raise (Univ.UniverseInconsistency (Univ.Eq, lu, r, None))
+ | _, _ (* One of the two is algebraic or global *) ->
+ if UGraph.check_eq univs l r then local
+ else raise (Univ.UniverseInconsistency (Univ.Eq, l, r, None))
+ in
+ let local =
+ Universes.Constraints.fold (fun (l,d,r) local -> unify_universes false l d r local)
+ cstrs Univ.Constraint.empty
+ in
+ !vars, local
+
+let add_constraints ctx cstrs =
+ let univs, local = ctx.uctx_local in
+ let cstrs' = Univ.Constraint.fold (fun (l,d,r) acc ->
+ let l = Univ.Universe.make l and r = Univ.Universe.make r in
+ let cstr' =
+ if d == Univ.Lt then (Univ.Universe.super l, Universes.ULe, r)
+ else (l, (if d == Univ.Le then Universes.ULe else Universes.UEq), r)
+ in Universes.Constraints.add cstr' acc)
+ cstrs Universes.Constraints.empty
+ in
+ let vars, local' = process_universe_constraints ctx cstrs' in
+ { ctx with uctx_local = (univs, Univ.Constraint.union local local');
+ uctx_univ_variables = vars;
+ uctx_universes = UGraph.merge_constraints local' ctx.uctx_universes }
+
+(* let addconstrkey = Profile.declare_profile "add_constraints_context";; *)
+(* let add_constraints_context = Profile.profile2 addconstrkey add_constraints_context;; *)
+
+let add_universe_constraints ctx cstrs =
+ let univs, local = ctx.uctx_local in
+ let vars, local' = process_universe_constraints ctx cstrs in
+ { ctx with uctx_local = (univs, Univ.Constraint.union local local');
+ uctx_univ_variables = vars;
+ uctx_universes = UGraph.merge_constraints local' ctx.uctx_universes }
+
+let pr_uctx_level uctx =
+ let map, map_rev = uctx.uctx_names in
+ fun l ->
+ try str(Univ.LMap.find l map_rev)
+ with Not_found ->
+ Universes.pr_with_global_universes l
+
+let universe_context ?names ctx =
+ match names with
+ | None -> [], Univ.ContextSet.to_context ctx.uctx_local
+ | Some pl ->
+ let levels = Univ.ContextSet.levels ctx.uctx_local in
+ let newinst, map, left =
+ List.fold_right
+ (fun (loc,id) (newinst, map, acc) ->
+ let l =
+ try UNameMap.find (Id.to_string id) (fst ctx.uctx_names)
+ with Not_found ->
+ user_err_loc (loc, "universe_context",
+ str"Universe " ++ Nameops.pr_id id ++ str" is not bound anymore.")
+ in (l :: newinst, (id, l) :: map, Univ.LSet.remove l acc))
+ pl ([], [], levels)
+ in
+ if not (Univ.LSet.is_empty left) then
+ let n = Univ.LSet.cardinal left in
+ errorlabstrm "universe_context"
+ (str(CString.plural n "Universe") ++ spc () ++
+ Univ.LSet.pr (pr_uctx_level ctx) left ++
+ spc () ++ str (CString.conjugate_verb_to_be n) ++ str" unbound.")
+ else
+ let inst = Univ.Instance.of_array (Array.of_list newinst) in
+ let ctx = Univ.UContext.make (inst,
+ Univ.ContextSet.constraints ctx.uctx_local)
+ in map, ctx
+
+let restrict ctx vars =
+ let uctx' = Universes.restrict_universe_context ctx.uctx_local vars in
+ { ctx with uctx_local = uctx' }
+
+type rigid =
+ | UnivRigid
+ | UnivFlexible of bool (** Is substitution by an algebraic ok? *)
+
+let univ_rigid = UnivRigid
+let univ_flexible = UnivFlexible false
+let univ_flexible_alg = UnivFlexible true
+
+let merge sideff rigid uctx ctx' =
+ let open Univ in
+ let levels = ContextSet.levels ctx' in
+ let uctx = if sideff then uctx else
+ match rigid with
+ | UnivRigid -> uctx
+ | UnivFlexible b ->
+ let fold u accu =
+ if LMap.mem u accu then accu
+ else LMap.add u None accu
+ in
+ let uvars' = LSet.fold fold levels uctx.uctx_univ_variables in
+ if b then
+ { uctx with uctx_univ_variables = uvars';
+ uctx_univ_algebraic = LSet.union uctx.uctx_univ_algebraic levels }
+ else { uctx with uctx_univ_variables = uvars' }
+ in
+ let uctx_local =
+ if sideff then uctx.uctx_local
+ else ContextSet.append ctx' uctx.uctx_local
+ in
+ let declare g =
+ LSet.fold (fun u g ->
+ try UGraph.add_universe u false g
+ with UGraph.AlreadyDeclared when sideff -> g)
+ levels g
+ in
+ let initial = declare uctx.uctx_initial_universes in
+ let univs = declare uctx.uctx_universes in
+ let uctx_universes = UGraph.merge_constraints (ContextSet.constraints ctx') univs in
+ { uctx with uctx_local; uctx_universes; uctx_initial_universes = initial }
+
+let merge_subst uctx s =
+ { uctx with uctx_univ_variables = Univ.LMap.subst_union uctx.uctx_univ_variables s }
+
+let emit_side_effects eff u =
+ let uctxs = Safe_typing.universes_of_private eff in
+ List.fold_left (merge true univ_rigid) u uctxs
+
+let new_univ_variable rigid name
+ ({ uctx_local = ctx; uctx_univ_variables = uvars; uctx_univ_algebraic = avars} as uctx) =
+ let u = Universes.new_univ_level (Global.current_dirpath ()) in
+ let ctx' = Univ.ContextSet.add_universe u ctx in
+ let uctx', pred =
+ match rigid with
+ | UnivRigid -> uctx, true
+ | UnivFlexible b ->
+ let uvars' = Univ.LMap.add u None uvars in
+ if b then {uctx with uctx_univ_variables = uvars';
+ uctx_univ_algebraic = Univ.LSet.add u avars}, false
+ else {uctx with uctx_univ_variables = uvars'}, false
+ in
+ let names =
+ match name with
+ | Some n -> add_uctx_names n u uctx.uctx_names
+ | None -> uctx.uctx_names
+ in
+ let initial =
+ UGraph.add_universe u false uctx.uctx_initial_universes
+ in
+ let uctx' =
+ {uctx' with uctx_names = names; uctx_local = ctx';
+ uctx_universes = UGraph.add_universe u false uctx.uctx_universes;
+ uctx_initial_universes = initial}
+ in uctx', u
+
+let add_global_univ uctx u =
+ let initial =
+ UGraph.add_universe u true uctx.uctx_initial_universes
+ in
+ let univs =
+ UGraph.add_universe u true uctx.uctx_universes
+ in
+ { uctx with uctx_local = Univ.ContextSet.add_universe u uctx.uctx_local;
+ uctx_initial_universes = initial;
+ uctx_universes = univs }
+
+let make_flexible_variable ctx b u =
+ let {uctx_univ_variables = uvars; uctx_univ_algebraic = avars} = ctx in
+ let uvars' = Univ.LMap.add u None uvars in
+ let avars' =
+ if b then
+ let uu = Univ.Universe.make u in
+ let substu_not_alg u' v =
+ Option.cata (fun vu -> Univ.Universe.equal uu vu && not (Univ.LSet.mem u' avars)) false v
+ in
+ if not (Univ.LMap.exists substu_not_alg uvars)
+ then Univ.LSet.add u avars else avars
+ else avars
+ in
+ {ctx with uctx_univ_variables = uvars';
+ uctx_univ_algebraic = avars'}
+
+let is_sort_variable uctx s =
+ match s with
+ | Sorts.Type u ->
+ (match Univ.universe_level u with
+ | Some l as x ->
+ if Univ.LSet.mem l (Univ.ContextSet.levels uctx.uctx_local) then x
+ else None
+ | None -> None)
+ | _ -> None
+
+let subst_univs_context_with_def def usubst (ctx, cst) =
+ (Univ.LSet.diff ctx def, Univ.subst_univs_constraints usubst cst)
+
+let normalize_variables uctx =
+ let normalized_variables, undef, def, subst =
+ Universes.normalize_univ_variables uctx.uctx_univ_variables
+ in
+ let ctx_local = subst_univs_context_with_def def (Univ.make_subst subst) uctx.uctx_local in
+ let ctx_local', univs = Universes.refresh_constraints uctx.uctx_initial_universes ctx_local in
+ subst, { uctx with uctx_local = ctx_local';
+ uctx_univ_variables = normalized_variables;
+ uctx_universes = univs }
+
+let abstract_undefined_variables uctx =
+ let vars' =
+ Univ.LMap.fold (fun u v acc ->
+ if v == None then Univ.LSet.remove u acc
+ else acc)
+ uctx.uctx_univ_variables uctx.uctx_univ_algebraic
+ in { uctx with uctx_local = Univ.ContextSet.empty;
+ uctx_univ_algebraic = vars' }
+
+let fix_undefined_variables uctx =
+ let algs', vars' =
+ Univ.LMap.fold (fun u v (algs, vars as acc) ->
+ if v == None then (Univ.LSet.remove u algs, Univ.LMap.remove u vars)
+ else acc)
+ uctx.uctx_univ_variables
+ (uctx.uctx_univ_algebraic, uctx.uctx_univ_variables)
+ in
+ { uctx with uctx_univ_variables = vars';
+ uctx_univ_algebraic = algs' }
+
+let refresh_undefined_univ_variables uctx =
+ let subst, ctx' = Universes.fresh_universe_context_set_instance uctx.uctx_local in
+ let alg = Univ.LSet.fold (fun u acc -> Univ.LSet.add (Univ.subst_univs_level_level subst u) acc)
+ uctx.uctx_univ_algebraic Univ.LSet.empty
+ in
+ let vars =
+ Univ.LMap.fold
+ (fun u v acc ->
+ Univ.LMap.add (Univ.subst_univs_level_level subst u)
+ (Option.map (Univ.subst_univs_level_universe subst) v) acc)
+ uctx.uctx_univ_variables Univ.LMap.empty
+ in
+ let declare g = Univ.LSet.fold (fun u g -> UGraph.add_universe u false g)
+ (Univ.ContextSet.levels ctx') g in
+ let initial = declare uctx.uctx_initial_universes in
+ let univs = declare UGraph.initial_universes in
+ let uctx' = {uctx_names = uctx.uctx_names;
+ uctx_local = ctx';
+ uctx_univ_variables = vars; uctx_univ_algebraic = alg;
+ uctx_universes = univs;
+ uctx_initial_universes = initial } in
+ uctx', subst
+
+let normalize uctx =
+ let ((vars',algs'), us') =
+ Universes.normalize_context_set uctx.uctx_local uctx.uctx_univ_variables
+ uctx.uctx_univ_algebraic
+ in
+ if Univ.ContextSet.equal us' uctx.uctx_local then uctx
+ else
+ let us', universes =
+ Universes.refresh_constraints uctx.uctx_initial_universes us'
+ in
+ { uctx_names = uctx.uctx_names;
+ uctx_local = us';
+ uctx_univ_variables = vars';
+ uctx_univ_algebraic = algs';
+ uctx_universes = universes;
+ uctx_initial_universes = uctx.uctx_initial_universes }
+
+let universe_of_name uctx s =
+ UNameMap.find s (fst uctx.uctx_names)
+
+let add_universe_name uctx s l =
+ let names' = add_uctx_names s l uctx.uctx_names in
+ { uctx with uctx_names = names' }
+
+let update_sigma_env uctx env =
+ let univs = Environ.universes env in
+ let eunivs =
+ { uctx with uctx_initial_universes = univs;
+ uctx_universes = univs }
+ in
+ merge true univ_rigid eunivs eunivs.uctx_local
diff --git a/engine/uState.mli b/engine/uState.mli
new file mode 100644
index 000000000..9dc96622e
--- /dev/null
+++ b/engine/uState.mli
@@ -0,0 +1,117 @@
+(************************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2015 *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(************************************************************************)
+
+(** Universe unification states *)
+
+open Names
+
+exception UniversesDiffer
+
+type t
+(** Type of universe unification states. They allow the incremental building of
+ universe constraints during an interactive proof. *)
+
+(** {5 Constructors} *)
+
+val empty : t
+
+val make : UGraph.t -> t
+
+val is_empty : t -> bool
+
+val union : t -> t -> t
+
+val of_context_set : Univ.universe_context_set -> t
+
+val of_binders : Universes.universe_binders -> t
+
+(** {5 Projections} *)
+
+val context_set : t -> Univ.universe_context_set
+(** The local context of the state, i.e. a set of bound variables together
+ with their associated constraints. *)
+
+val subst : t -> Universes.universe_opt_subst
+(** The local universes that are unification variables *)
+
+val ugraph : t -> UGraph.t
+(** The current graph extended with the local constraints *)
+
+val algebraics : t -> Univ.LSet.t
+(** The subset of unification variables that can be instantiated with algebraic
+ universes as they appear in inferred types only. *)
+
+val constraints : t -> Univ.constraints
+(** Shorthand for {!context_set} composed with {!ContextSet.constraints}. *)
+
+val context : t -> Univ.universe_context
+(** Shorthand for {!context_set} with {!Context_set.to_context}. *)
+
+(** {5 Constraints handling} *)
+
+val add_constraints : t -> Univ.constraints -> t
+(**
+ @raise UniversesDiffer when universes differ
+*)
+
+val add_universe_constraints : t -> Universes.universe_constraints -> t
+(**
+ @raise UniversesDiffer when universes differ
+*)
+
+(** {5 Names} *)
+
+val add_universe_name : t -> string -> Univ.Level.t -> t
+(** Associate a human-readable name to a local variable. *)
+
+val universe_of_name : t -> string -> Univ.Level.t
+(** Retrieve the universe associated to the name. *)
+
+(** {5 Unification} *)
+
+val restrict : t -> Univ.universe_set -> t
+
+type rigid =
+ | UnivRigid
+ | UnivFlexible of bool (** Is substitution by an algebraic ok? *)
+
+val univ_rigid : rigid
+val univ_flexible : rigid
+val univ_flexible_alg : rigid
+
+val merge : bool -> rigid -> t -> Univ.universe_context_set -> t
+val merge_subst : t -> Universes.universe_opt_subst -> t
+val emit_side_effects : Safe_typing.private_constants -> t -> t
+
+val new_univ_variable : rigid -> string option -> t -> t * Univ.Level.t
+val add_global_univ : t -> Univ.Level.t -> t
+val make_flexible_variable : t -> bool -> Univ.Level.t -> t
+
+val is_sort_variable : t -> Sorts.t -> Univ.Level.t option
+
+val normalize_variables : t -> Univ.universe_subst * t
+
+val constrain_variables : Univ.LSet.t -> t -> Univ.constraints
+
+val abstract_undefined_variables : t -> t
+
+val fix_undefined_variables : t -> t
+
+val refresh_undefined_univ_variables : t -> t * Univ.universe_level_subst
+
+val normalize : t -> t
+
+(** {5 TODO: Document me} *)
+
+val universe_context : ?names:(Id.t Loc.located) list -> t -> (Id.t * Univ.Level.t) list * Univ.universe_context
+
+val update_sigma_env : t -> Environ.env -> t
+
+(** {5 Pretty-printing} *)
+
+val pr_uctx_level : t -> Univ.Level.t -> Pp.std_ppcmds
diff --git a/grammar/argextend.ml4 b/grammar/argextend.ml4
index 8def9537c..13f761113 100644
--- a/grammar/argextend.ml4
+++ b/grammar/argextend.ml4
@@ -12,6 +12,7 @@ open Genarg
open Q_util
open Egramml
open Compat
+open Extend
open Pcoq
let loc = CompatLoc.ghost
@@ -30,17 +31,6 @@ let mk_extraarg loc s =
<:expr< $lid:"wit_"^s$ >>
let rec make_wit loc = function
- | IntOrVarArgType -> <:expr< Constrarg.wit_int_or_var >>
- | IdentArgType -> <:expr< Constrarg.wit_ident >>
- | VarArgType -> <:expr< Constrarg.wit_var >>
- | QuantHypArgType -> <:expr< Constrarg.wit_quant_hyp >>
- | GenArgType -> <:expr< Constrarg.wit_genarg >>
- | ConstrArgType -> <:expr< Constrarg.wit_constr >>
- | ConstrMayEvalArgType -> <:expr< Constrarg.wit_constr_may_eval >>
- | RedExprArgType -> <:expr< Constrarg.wit_red_expr >>
- | OpenConstrArgType -> <:expr< Constrarg.wit_open_constr >>
- | ConstrWithBindingsArgType -> <:expr< Constrarg.wit_constr_with_bindings >>
- | BindingsArgType -> <:expr< Constrarg.wit_bindings >>
| ListArgType t -> <:expr< Genarg.wit_list $make_wit loc t$ >>
| OptArgType t -> <:expr< Genarg.wit_opt $make_wit loc t$ >>
| PairArgType (t1,t2) ->
@@ -51,44 +41,62 @@ let make_rawwit loc arg = <:expr< Genarg.rawwit $make_wit loc arg$ >>
let make_globwit loc arg = <:expr< Genarg.glbwit $make_wit loc arg$ >>
let make_topwit loc arg = <:expr< Genarg.topwit $make_wit loc arg$ >>
-let has_extraarg =
- List.exists (function GramNonTerminal(_,ExtraArgType _,_,_) -> true | _ -> false)
+let has_extraarg l =
+ let check = function
+ | ExtNonTerminal(ExtraArgType _, _, _) -> true
+ | _ -> false
+ in
+ List.exists check l
let rec is_possibly_empty = function
-| Aopt _ | Alist0 _ | Alist0sep _ | Amodifiers _ -> true
-| Alist1 t | Alist1sep (t, _) -> is_possibly_empty t
+| Uopt _ -> true
+| Ulist0 _ -> true
+| Ulist0sep _ -> true
+| Umodifiers _ -> true
+| Ulist1 t -> is_possibly_empty t
+| Ulist1sep (t, _) -> is_possibly_empty t
| _ -> false
let rec get_empty_entry = function
-| Aopt _ -> <:expr< None >>
-| Alist0 _ | Alist0sep _ | Amodifiers _ -> <:expr< [] >>
-| Alist1 t | Alist1sep (t, _) -> <:expr< [$get_empty_entry t$] >>
+| Uopt _ -> <:expr< None >>
+| Ulist0 _ -> <:expr< [] >>
+| Ulist0sep _ -> <:expr< [] >>
+| Umodifiers _ -> <:expr< [] >>
+| Ulist1 t -> <:expr< [$get_empty_entry t$] >>
+| Ulist1sep (t, _) -> <:expr< [$get_empty_entry t$] >>
| _ -> assert false
let statically_known_possibly_empty s (prods,_) =
List.for_all (function
- | GramNonTerminal(_,ExtraArgType s',_,_) ->
+ | ExtNonTerminal(t, e, _) ->
+ begin match t with
+ | ExtraArgType s' ->
(* For ExtraArg we don't know (we'll have to test dynamically) *)
(* unless it is a recursive call *)
s <> s'
- | GramNonTerminal(_,_,e,_) ->
+ | _ ->
is_possibly_empty e
- | GramTerminal _ ->
+ end
+ | ExtTerminal _ ->
(* This consumes a token for sure *) false)
prods
let possibly_empty_subentries loc (prods,act) =
- let bind_name p v e = match p with
- | None -> e
- | Some id ->
- let s = Names.Id.to_string id in <:expr< let $lid:s$ = $v$ in $e$ >> in
+ let bind_name id v e =
+ let s = Names.Id.to_string id in
+ <:expr< let $lid:s$ = $v$ in $e$ >>
+ in
let rec aux = function
| [] -> <:expr< let loc = $default_loc$ in let _ = loc in $act$ >>
- | GramNonTerminal(_,_,e,p) :: tl when is_possibly_empty e ->
- bind_name p (get_empty_entry e) (aux tl)
- | GramNonTerminal(_,(ExtraArgType _ as t),_,p) :: tl ->
+ | ExtNonTerminal(_, e, id) :: tl when is_possibly_empty e ->
+ bind_name id (get_empty_entry e) (aux tl)
+ | ExtNonTerminal(t, _, id) :: tl ->
+ let t = match t with
+ | ExtraArgType _ as t -> t
+ | _ -> assert false
+ in
(* We check at runtime if extraarg s parses "epsilon" *)
- let s = match p with None -> "_" | Some id -> Names.Id.to_string id in
+ let s = Names.Id.to_string id in
<:expr< let $lid:s$ = match Genarg.default_empty_value $make_wit loc t$ with
[ None -> raise Exit
| Some v -> v ] in $aux tl$ >>
@@ -120,25 +128,27 @@ let make_possibly_empty_subentries loc s cl =
let make_act loc act pil =
let rec make = function
- | [] -> <:expr< Pcoq.Gram.action (fun loc -> ($act$ : 'a)) >>
- | GramNonTerminal (_,t,_,Some p) :: tl ->
+ | [] -> <:expr< (fun loc -> $act$) >>
+ | ExtNonTerminal (t, _, p) :: tl ->
let p = Names.Id.to_string p in
<:expr<
- Pcoq.Gram.action
(fun $lid:p$ ->
let _ = Genarg.in_gen $make_rawwit loc t$ $lid:p$ in $make tl$)
>>
- | (GramTerminal _ | GramNonTerminal (_,_,_,None)) :: tl ->
- <:expr< Pcoq.Gram.action (fun _ -> $make tl$) >> in
+ | ExtTerminal _ :: tl ->
+ <:expr< (fun _ -> $make tl$) >> in
make (List.rev pil)
let make_prod_item = function
- | GramTerminal s -> <:expr< Pcoq.gram_token_of_string $str:s$ >>
- | GramNonTerminal (_,_,g,_) ->
- <:expr< Pcoq.symbol_of_prod_entry_key $mlexpr_of_prod_entry_key g$ >>
+ | ExtTerminal s -> <:expr< Pcoq.Atoken (Lexer.terminal $mlexpr_of_string s$) >>
+ | ExtNonTerminal (_, g, _) -> mlexpr_of_prod_entry_key g
+
+let rec make_prod = function
+| [] -> <:expr< Extend.Stop >>
+| item :: prods -> <:expr< Extend.Next $make_prod prods$ $make_prod_item item$ >>
let make_rule loc (prods,act) =
- <:expr< ($mlexpr_of_list make_prod_item prods$,$make_act loc act prods$) >>
+ <:expr< Extend.Rule $make_prod (List.rev prods)$ $make_act loc act prods$ >>
let declare_tactic_argument loc s (typ, pr, f, g, h) cl =
let rawtyp, rawpr, globtyp, globpr = match typ with
@@ -165,17 +175,22 @@ let declare_tactic_argument loc s (typ, pr, f, g, h) cl =
| None ->
begin match globtyp with
| Genarg.ExtraArgType s' when CString.equal s s' ->
- <:expr< fun ist gl v -> (gl.Evd.sigma, v) >>
+ <:expr< fun ist v -> Ftactic.return v >>
| _ ->
- <:expr< fun ist gl x ->
- let (sigma,a_interp) =
- Tacinterp.interp_genarg ist
- (Tacmach.pf_env gl) (Tacmach.project gl) (Tacmach.pf_concl gl) gl.Evd.it
- (Genarg.in_gen $make_globwit loc globtyp$ x)
- in
- (sigma , out_gen $make_topwit loc globtyp$ a_interp)>>
+ <:expr< fun ist x ->
+ Ftactic.bind
+ (Tacinterp.interp_genarg ist (Genarg.in_gen $make_globwit loc globtyp$ x))
+ (fun v -> Ftactic.return (Tacinterp.Value.cast $make_topwit loc globtyp$ v)) >>
end
- | Some f -> <:expr< $lid:f$>> in
+ | Some f ->
+ (** Compatibility layer, TODO: remove me *)
+ <:expr<
+ let f = $lid:f$ in
+ fun ist v -> Ftactic.nf_s_enter { Proofview.Goal.s_enter = fun gl ->
+ let (sigma, v) = Tacmach.New.of_old (fun gl -> f ist gl v) gl in
+ Sigma.Unsafe.of_pair (Ftactic.return v, sigma)
+ }
+ >> in
let subst = match h with
| None ->
begin match globtyp with
@@ -188,21 +203,33 @@ let declare_tactic_argument loc s (typ, pr, f, g, h) cl =
(Genarg.in_gen $make_globwit loc globtyp$ x)) >>
end
| Some f -> <:expr< $lid:f$>> in
+ let dyn = match typ with
+ | `Uniform typ ->
+ let is_new = match typ with
+ | Genarg.ExtraArgType s' when CString.equal s s' -> true
+ | _ -> false
+ in
+ if is_new then <:expr< None >>
+ else <:expr< Some (Genarg.val_tag $make_topwit loc typ$) >>
+ | `Specialized _ -> <:expr< None >>
+ in
let se = mlexpr_of_string s in
let wit = <:expr< $lid:"wit_"^s$ >> in
let rawwit = <:expr< Genarg.rawwit $wit$ >> in
let rules = mlexpr_of_list (make_rule loc) (List.rev cl) in
let default_value = <:expr< $make_possibly_empty_subentries loc s cl$ >> in
declare_str_items loc
- [ <:str_item< value ($lid:"wit_"^s$) = Genarg.make0 $default_value$ $se$ >>;
+ [ <:str_item<
+ value ($lid:"wit_"^s$) =
+ let dyn = $dyn$ in
+ Genarg.make0 ?dyn $default_value$ $se$ >>;
<:str_item< Genintern.register_intern0 $wit$ $glob$ >>;
<:str_item< Genintern.register_subst0 $wit$ $subst$ >>;
<:str_item< Geninterp.register_interp0 $wit$ $interp$ >>;
<:str_item<
value $lid:s$ = Pcoq.create_generic_entry $se$ $rawwit$ >>;
<:str_item< do {
- Compat.maybe_uncurry (Pcoq.Gram.extend ($lid:s$ : Pcoq.Gram.entry 'a))
- (None, [(None, None, $rules$)]);
+ Pcoq.grammar_extend $lid:s$ None (None, [(None, None, $rules$)]);
Pptactic.declare_extra_genarg_pprule
$wit$ $lid:rawpr$ $lid:globpr$ $lid:pr$ }
>> ]
@@ -222,8 +249,7 @@ let declare_vernac_argument loc s pr cl =
<:str_item<
value $lid:s$ = Pcoq.create_generic_entry $se$ $rawwit$ >>;
<:str_item< do {
- Compat.maybe_uncurry (Pcoq.Gram.extend ($lid:s$ : Pcoq.Gram.entry 'a))
- (None, [(None, None, $rules$)]);
+ Pcoq.grammar_extend $lid:s$ None (None, [(None, None, $rules$)]);
Pptactic.declare_extra_genarg_pprule $wit$
$pr_rules$
(fun _ _ _ _ -> Errors.anomaly (Pp.str "vernac argument needs not globwit printer"))
@@ -272,7 +298,9 @@ EXTEND
[ e = argtype; LIDENT "list" -> ListArgType e
| e = argtype; LIDENT "option" -> OptArgType e ]
| "0"
- [ e = LIDENT -> fst (interp_entry_name false None e "")
+ [ e = LIDENT ->
+ let e = parse_user_entry e "" in
+ type_of_user_symbol e
| "("; e = argtype; ")" -> e ] ]
;
argrule:
@@ -280,15 +308,15 @@ EXTEND
;
genarg:
[ [ e = LIDENT; "("; s = LIDENT; ")" ->
- let t, g = interp_entry_name false None e "" in
- GramNonTerminal (!@loc, t, g, Some (Names.Id.of_string s))
+ let e = parse_user_entry e "" in
+ ExtNonTerminal (type_of_user_symbol e, e, Names.Id.of_string s)
| e = LIDENT; "("; s = LIDENT; ","; sep = STRING; ")" ->
- let t, g = interp_entry_name false None e sep in
- GramNonTerminal (!@loc, t, g, Some (Names.Id.of_string s))
+ let e = parse_user_entry e sep in
+ ExtNonTerminal (type_of_user_symbol e, e, Names.Id.of_string s)
| s = STRING ->
if String.length s > 0 && Util.is_letter s.[0] then
Lexer.add_keyword s;
- GramTerminal s
+ ExtTerminal s
] ]
;
entry_name:
diff --git a/grammar/grammar.mllib b/grammar/grammar.mllib
index 71e5b8ae2..6098de8f0 100644
--- a/grammar/grammar.mllib
+++ b/grammar/grammar.mllib
@@ -8,6 +8,7 @@ Hashcons
CSet
CMap
Int
+Dyn
HMap
Option
Store
@@ -51,6 +52,7 @@ Constrexpr_ops
Compat
Tok
Lexer
+Entry
Pcoq
G_prim
G_tactic
diff --git a/grammar/q_coqast.ml4 b/grammar/q_coqast.ml4
index 304e49923..f6abe12cf 100644
--- a/grammar/q_coqast.ml4
+++ b/grammar/q_coqast.ml4
@@ -223,17 +223,6 @@ let mlexpr_of_red_expr = function
<:expr< Genredexpr.ExtraRedExpr $mlexpr_of_string s$ >>
let rec mlexpr_of_argtype loc = function
- | Genarg.IntOrVarArgType -> <:expr< Genarg.IntOrVarArgType >>
- | Genarg.IdentArgType -> <:expr< Genarg.IdentArgType >>
- | Genarg.VarArgType -> <:expr< Genarg.VarArgType >>
- | Genarg.QuantHypArgType -> <:expr< Genarg.QuantHypArgType >>
- | Genarg.OpenConstrArgType -> <:expr< Genarg.OpenConstrArgType >>
- | Genarg.ConstrWithBindingsArgType -> <:expr< Genarg.ConstrWithBindingsArgType >>
- | Genarg.BindingsArgType -> <:expr< Genarg.BindingsArgType >>
- | Genarg.RedExprArgType -> <:expr< Genarg.RedExprArgType >>
- | Genarg.GenArgType -> <:expr< Genarg.GenArgType >>
- | Genarg.ConstrArgType -> <:expr< Genarg.ConstrArgType >>
- | Genarg.ConstrMayEvalArgType -> <:expr< Genarg.ConstrMayEvalArgType >>
| Genarg.ListArgType t -> <:expr< Genarg.ListArgType $mlexpr_of_argtype loc t$ >>
| Genarg.OptArgType t -> <:expr< Genarg.OptArgType $mlexpr_of_argtype loc t$ >>
| Genarg.PairArgType (t1,t2) ->
@@ -427,19 +416,6 @@ let rec mlexpr_of_atomic_tactic = function
(* Equivalence relations *)
| Tacexpr.TacSymmetry ido -> <:expr< Tacexpr.TacSymmetry $mlexpr_of_clause ido$ >>
- (* Automation tactics *)
- | Tacexpr.TacAuto (debug,n,lems,l) ->
- let d = mlexpr_of_debug debug in
- let n = mlexpr_of_option (mlexpr_of_or_var mlexpr_of_int) n in
- let lems = mlexpr_of_list mlexpr_of_constr lems in
- let l = mlexpr_of_option (mlexpr_of_list mlexpr_of_string) l in
- <:expr< Tacexpr.TacAuto $d$ $n$ $lems$ $l$ >>
- | Tacexpr.TacTrivial (debug,lems,l) ->
- let d = mlexpr_of_debug debug in
- let l = mlexpr_of_option (mlexpr_of_list mlexpr_of_string) l in
- let lems = mlexpr_of_list mlexpr_of_constr lems in
- <:expr< Tacexpr.TacTrivial $d$ $lems$ $l$ >>
-
| _ -> failwith "Quotation of atomic tactic expressions: TODO"
and mlexpr_of_tactic : (Tacexpr.raw_tactic_expr -> MLast.expr) = function
diff --git a/grammar/q_util.ml4 b/grammar/q_util.ml4
index a116b1e8b..4b0be1b1c 100644
--- a/grammar/q_util.ml4
+++ b/grammar/q_util.ml4
@@ -8,8 +8,13 @@
(* This file defines standard combinators to build ml expressions *)
+open Extend
open Compat
+type extend_token =
+| ExtTerminal of string
+| ExtNonTerminal of Genarg.argument_type * Extend.user_symbol * Names.Id.t
+
let mlexpr_of_list f l =
List.fold_right
(fun e1 e2 ->
@@ -49,16 +54,57 @@ let mlexpr_of_option f = function
| None -> <:expr< None >>
| Some e -> <:expr< Some $f e$ >>
+let mlexpr_of_token = function
+| Tok.KEYWORD s -> <:expr< Tok.KEYWORD $mlexpr_of_string s$ >>
+| Tok.METAIDENT s -> <:expr< Tok.METAIDENT $mlexpr_of_string s$ >>
+| Tok.PATTERNIDENT s -> <:expr< Tok.PATTERNIDENT $mlexpr_of_string s$ >>
+| Tok.IDENT s -> <:expr< Tok.IDENT $mlexpr_of_string s$ >>
+| Tok.FIELD s -> <:expr< Tok.FIELD $mlexpr_of_string s$ >>
+| Tok.INT s -> <:expr< Tok.INT $mlexpr_of_string s$ >>
+| Tok.INDEX s -> <:expr< Tok.INDEX $mlexpr_of_string s$ >>
+| Tok.STRING s -> <:expr< Tok.STRING $mlexpr_of_string s$ >>
+| Tok.LEFTQMARK -> <:expr< Tok.LEFTQMARK >>
+| Tok.BULLET s -> <:expr< Tok.BULLET $mlexpr_of_string s$ >>
+| Tok.EOI -> <:expr< Tok.EOI >>
+
+let repr_entry e =
+ let entry u =
+ let _ = Pcoq.get_entry u e in
+ Some (Entry.univ_name u, e)
+ in
+ try entry Pcoq.uprim with Not_found ->
+ try entry Pcoq.uconstr with Not_found ->
+ try entry Pcoq.utactic with Not_found -> None
+
let rec mlexpr_of_prod_entry_key = function
- | Pcoq.Alist1 s -> <:expr< Pcoq.Alist1 $mlexpr_of_prod_entry_key s$ >>
- | Pcoq.Alist1sep (s,sep) -> <:expr< Pcoq.Alist1sep $mlexpr_of_prod_entry_key s$ $str:sep$ >>
- | Pcoq.Alist0 s -> <:expr< Pcoq.Alist0 $mlexpr_of_prod_entry_key s$ >>
- | Pcoq.Alist0sep (s,sep) -> <:expr< Pcoq.Alist0sep $mlexpr_of_prod_entry_key s$ $str:sep$ >>
- | Pcoq.Aopt s -> <:expr< Pcoq.Aopt $mlexpr_of_prod_entry_key s$ >>
- | Pcoq.Amodifiers s -> <:expr< Pcoq.Amodifiers $mlexpr_of_prod_entry_key s$ >>
- | Pcoq.Aself -> <:expr< Pcoq.Aself >>
- | Pcoq.Anext -> <:expr< Pcoq.Anext >>
- | Pcoq.Atactic n -> <:expr< Pcoq.Atactic $mlexpr_of_int n$ >>
- | Pcoq.Agram s -> Errors.anomaly (Pp.str "Agram not supported")
- | Pcoq.Aentry ("",s) -> <:expr< Pcoq.Agram (Pcoq.Gram.Entry.name $lid:s$) >>
- | Pcoq.Aentry (u,s) -> <:expr< Pcoq.Aentry $str:u$ $str:s$ >>
+ | Extend.Ulist1 s -> <:expr< Pcoq.Alist1 $mlexpr_of_prod_entry_key s$ >>
+ | Extend.Ulist1sep (s,sep) -> <:expr< Pcoq.Alist1sep $mlexpr_of_prod_entry_key s$ $str:sep$ >>
+ | Extend.Ulist0 s -> <:expr< Pcoq.Alist0 $mlexpr_of_prod_entry_key s$ >>
+ | Extend.Ulist0sep (s,sep) -> <:expr< Pcoq.Alist0sep $mlexpr_of_prod_entry_key s$ $str:sep$ >>
+ | Extend.Uopt s -> <:expr< Pcoq.Aopt $mlexpr_of_prod_entry_key s$ >>
+ | Extend.Umodifiers s -> <:expr< Pcoq.Amodifiers $mlexpr_of_prod_entry_key s$ >>
+ | Extend.Uentry e ->
+ begin match repr_entry e with
+ | None -> <:expr< Pcoq.Aentry (Pcoq.name_of_entry $lid:e$) >>
+ | Some (u, s) -> <:expr< Pcoq.Aentry (Entry.unsafe_of_name ($str:u$, $str:s$)) >>
+ end
+ | Extend.Uentryl (e, l) ->
+ (** Keep in sync with Pcoq! *)
+ assert (CString.equal e "tactic");
+ if l = 5 then <:expr< Pcoq.Aentry (Pcoq.name_of_entry Pcoq.Tactic.binder_tactic) >>
+ else <:expr< Pcoq.Aentryl (Pcoq.name_of_entry Pcoq.Tactic.tactic_expr) $mlexpr_of_int l$ >>
+
+let type_entry u e =
+ let Pcoq.TypedEntry (t, _) = Pcoq.get_entry u e in
+ Genarg.unquote t
+
+let rec type_of_user_symbol = function
+| Ulist1 s | Ulist1sep (s, _) | Ulist0 s | Ulist0sep (s, _) | Umodifiers s ->
+ Genarg.ListArgType (type_of_user_symbol s)
+| Uopt s ->
+ Genarg.OptArgType (type_of_user_symbol s)
+| Uentry e | Uentryl (e, _) ->
+ try type_entry Pcoq.uprim e with Not_found ->
+ try type_entry Pcoq.uconstr e with Not_found ->
+ try type_entry Pcoq.utactic e with Not_found ->
+ Genarg.ExtraArgType e
diff --git a/grammar/q_util.mli b/grammar/q_util.mli
index a85ad2f6a..50827ead2 100644
--- a/grammar/q_util.mli
+++ b/grammar/q_util.mli
@@ -8,6 +8,10 @@
open Compat (* necessary for camlp4 *)
+type extend_token =
+| ExtTerminal of string
+| ExtNonTerminal of Genarg.argument_type * Extend.user_symbol * Names.Id.t
+
val mlexpr_of_list : ('a -> MLast.expr) -> 'a list -> MLast.expr
val mlexpr_of_pair :
@@ -30,4 +34,6 @@ val mlexpr_of_string : string -> MLast.expr
val mlexpr_of_option : ('a -> MLast.expr) -> 'a option -> MLast.expr
-val mlexpr_of_prod_entry_key : Pcoq.prod_entry_key -> MLast.expr
+val mlexpr_of_prod_entry_key : Extend.user_symbol -> MLast.expr
+
+val type_of_user_symbol : Extend.user_symbol -> Genarg.argument_type
diff --git a/grammar/tacextend.ml4 b/grammar/tacextend.ml4
index 39f605e29..cca734720 100644
--- a/grammar/tacextend.ml4
+++ b/grammar/tacextend.ml4
@@ -27,38 +27,35 @@ let plugin_name = <:expr< __coq_plugin_name >>
let rec make_patt = function
| [] -> <:patt< [] >>
- | GramNonTerminal(loc',_,_,Some p)::l ->
+ | ExtNonTerminal (_, _, p) :: l ->
let p = Names.Id.to_string p in
<:patt< [ $lid:p$ :: $make_patt l$ ] >>
| _::l -> make_patt l
let rec make_when loc = function
| [] -> <:expr< True >>
- | GramNonTerminal(loc',t,_,Some p)::l ->
- let loc' = of_coqloc loc' in
+ | ExtNonTerminal (t, _, p) :: l ->
let p = Names.Id.to_string p in
let l = make_when loc l in
- let loc = CompatLoc.merge loc' loc in
- let t = mlexpr_of_argtype loc' t in
+ let t = mlexpr_of_argtype loc t in
<:expr< Genarg.argument_type_eq (Genarg.genarg_tag $lid:p$) $t$ && $l$ >>
| _::l -> make_when loc l
let rec make_let raw e = function
| [] -> <:expr< fun $lid:"ist"$ -> $e$ >>
- | GramNonTerminal(loc,t,_,Some p)::l ->
- let loc = of_coqloc loc in
+ | ExtNonTerminal (t, _, p) :: l ->
let p = Names.Id.to_string p in
- let loc = CompatLoc.merge loc (MLast.loc_of_expr e) in
+ let loc = MLast.loc_of_expr e in
let e = make_let raw e l in
let v =
if raw then <:expr< Genarg.out_gen $make_rawwit loc t$ $lid:p$ >>
- else <:expr< Genarg.out_gen $make_topwit loc t$ $lid:p$ >> in
+ else <:expr< Tacinterp.Value.cast $make_topwit loc t$ $lid:p$ >> in
<:expr< let $lid:p$ = $v$ in $e$ >>
| _::l -> make_let raw e l
let rec extract_signature = function
| [] -> []
- | GramNonTerminal (_,t,_,_) :: l -> t :: extract_signature l
+ | ExtNonTerminal (t, _, _) :: l -> t :: extract_signature l
| _::l -> extract_signature l
@@ -72,57 +69,42 @@ let check_unicity s l =
let make_clause (pt,_,e) =
(make_patt pt,
- vala (Some (make_when (MLast.loc_of_expr e) pt)),
+ vala None,
make_let false e pt)
let make_fun_clauses loc s l =
check_unicity s l;
- Compat.make_fun loc (List.map make_clause l)
-
-let rec make_args = function
- | [] -> <:expr< [] >>
- | GramNonTerminal(loc,t,_,Some p)::l ->
- let loc = of_coqloc loc in
- let p = Names.Id.to_string p in
- <:expr< [ Genarg.in_gen $make_topwit loc t$ $lid:p$ :: $make_args l$ ] >>
- | _::l -> make_args l
-
-let mlexpr_terminals_of_grammar_tactic_prod_item_expr = function
- | GramTerminal s -> <:expr< Some $mlexpr_of_string s$ >>
- | GramNonTerminal (loc,nt,_,sopt) ->
- let loc = of_coqloc loc in <:expr< None >>
+ let map c = Compat.make_fun loc [make_clause c] in
+ mlexpr_of_list map l
let make_prod_item = function
- | GramTerminal s -> <:expr< Egramml.GramTerminal $str:s$ >>
- | GramNonTerminal (loc,nt,g,sopt) ->
- let loc = of_coqloc loc in
- <:expr< Egramml.GramNonTerminal $default_loc$ $mlexpr_of_argtype loc nt$
- $mlexpr_of_prod_entry_key g$ $mlexpr_of_option mlexpr_of_ident sopt$ >>
+ | ExtTerminal s -> <:expr< Egramml.GramTerminal $str:s$ >>
+ | ExtNonTerminal (nt, g, id) ->
+ <:expr< Egramml.GramNonTerminal $default_loc$ $make_rawwit loc nt$
+ $mlexpr_of_prod_entry_key g$ >>
-let mlexpr_of_clause =
- mlexpr_of_list (fun (a,_,b) -> mlexpr_of_list make_prod_item a)
+let mlexpr_of_clause cl =
+ mlexpr_of_list (fun (a,_,_) -> mlexpr_of_list make_prod_item a) cl
let rec make_tags loc = function
| [] -> <:expr< [] >>
- | GramNonTerminal(loc',t,_,Some p)::l ->
- let loc' = of_coqloc loc' in
+ | ExtNonTerminal (t, _, p) :: l ->
let l = make_tags loc l in
- let loc = CompatLoc.merge loc' loc in
- let t = mlexpr_of_argtype loc' t in
+ let t = mlexpr_of_argtype loc t in
<:expr< [ $t$ :: $l$ ] >>
| _::l -> make_tags loc l
-let make_one_printing_rule se (pt,_,e) =
+let make_one_printing_rule (pt,_,e) =
let level = mlexpr_of_int 0 in (* only level 0 supported here *)
let loc = MLast.loc_of_expr e in
- let prods = mlexpr_of_list mlexpr_terminals_of_grammar_tactic_prod_item_expr pt in
- <:expr< ($se$, { Pptactic.pptac_args = $make_tags loc pt$;
- pptac_prods = ($level$, $prods$) }) >>
+ let prods = mlexpr_of_list make_prod_item pt in
+ <:expr< { Pptactic.pptac_level = $level$;
+ pptac_prods = $prods$ } >>
-let make_printing_rule se = mlexpr_of_list (make_one_printing_rule se)
+let make_printing_rule r = mlexpr_of_list make_one_printing_rule r
let make_empty_check = function
-| GramNonTerminal(_, t, e, _)->
+| ExtNonTerminal (t, e, _)->
let is_extra = match t with ExtraArgType _ -> true | _ -> false in
if is_possibly_empty e || is_extra then
(* This possibly parses epsilon *)
@@ -137,50 +119,37 @@ let make_empty_check = function
else
(* This does not parse epsilon (this Exit is static time) *)
raise Exit
-| GramTerminal _ ->
+| ExtTerminal _ ->
(* Idem *)
raise Exit
-let rec possibly_empty_subentries loc = function
- | [] -> []
- | (s,prodsl) :: l ->
- let rec aux = function
- | [] -> (false,<:expr< None >>)
- | prods :: rest ->
- try
- let l = List.map make_empty_check prods in
- if has_extraarg prods then
- (true,<:expr< try Some $mlexpr_of_list (fun x -> x) l$
- with [ Exit -> $snd (aux rest)$ ] >>)
- else
- (true, <:expr< Some $mlexpr_of_list (fun x -> x) l$ >>)
- with Exit -> aux rest in
- let (nonempty,v) = aux prodsl in
- if nonempty then (s,v) :: possibly_empty_subentries loc l
- else possibly_empty_subentries loc l
-
-let possibly_atomic loc prods =
- let l = List.map_filter (function
- | GramTerminal s :: l, _, _ -> Some (s,l)
- | _ -> None) prods
+let rec possibly_atomic loc = function
+| [] -> []
+| ((ExtNonTerminal _ :: _ | []), _, _) :: rem ->
+ (** This is not parsed by the TACTIC EXTEND rules *)
+ assert false
+| (ExtTerminal s :: prods, _, _) :: rem ->
+ let entry =
+ try
+ let l = List.map make_empty_check prods in
+ let l = mlexpr_of_list (fun x -> x) l in
+ (s, <:expr< try Some $l$ with [ Exit -> None ] >>)
+ with Exit -> (s, <:expr< None >>)
in
- possibly_empty_subentries loc (List.factorize_left String.equal l)
+ entry :: possibly_atomic loc rem
(** Special treatment of constr entries *)
let is_constr_gram = function
-| GramTerminal _ -> false
-| GramNonTerminal (_, _, e, _) ->
- match e with
- | Aentry ("constr", "constr") -> true
- | _ -> false
+| ExtTerminal _ -> false
+| ExtNonTerminal (_, Extend.Uentry "constr", _) -> true
+| _ -> false
let make_var = function
- | GramNonTerminal(loc',_,_,Some p) -> Some p
- | GramNonTerminal(loc',_,_,None) -> Some (Id.of_string "_")
+ | ExtNonTerminal (_, _, p) -> Some p
| _ -> assert false
let declare_tactic loc s c cl = match cl with
-| [(GramTerminal name) :: rem, _, tac] when List.for_all is_constr_gram rem ->
+| [(ExtTerminal name) :: rem, _, tac] when List.for_all is_constr_gram rem ->
(** The extension is only made of a name followed by constr entries: we do not
add any grammar nor printing rule and add it as a true Ltac definition. *)
let patt = make_patt rem in
@@ -188,6 +157,7 @@ let declare_tactic loc s c cl = match cl with
let vars = mlexpr_of_list (mlexpr_of_option mlexpr_of_ident) vars in
let entry = mlexpr_of_string s in
let se = <:expr< { Tacexpr.mltac_tactic = $entry$; Tacexpr.mltac_plugin = $plugin_name$ } >> in
+ let ml = <:expr< { Tacexpr.mltac_name = $se$; Tacexpr.mltac_index = 0 } >> in
let name = mlexpr_of_string name in
let tac =
(** Special handling of tactics without arguments: such tactics do not do
@@ -202,13 +172,13 @@ let declare_tactic loc s c cl = match cl with
(** Arguments are not passed directly to the ML tactic in the TacML node,
the ML tactic retrieves its arguments in the [ist] environment instead.
This is the rôle of the [lift_constr_tac_to_ml_tac] function. *)
- let body = <:expr< Tacexpr.TacFun ($vars$, Tacexpr.TacML ($dloc$, $se$, [])) >> in
+ let body = <:expr< Tacexpr.TacFun ($vars$, Tacexpr.TacML ($dloc$, $ml$, [])) >> in
let name = <:expr< Names.Id.of_string $name$ >> in
declare_str_items loc
[ <:str_item< do {
let obj () = Tacenv.register_ltac True False $name$ $body$ in
try do {
- Tacenv.register_ml_tactic $se$ $tac$;
+ Tacenv.register_ml_tactic $se$ [|$tac$|];
Mltop.declare_cache_obj obj $plugin_name$; }
with [ e when Errors.noncritical e ->
Pp.msg_warning
@@ -221,7 +191,7 @@ let declare_tactic loc s c cl = match cl with
TacML tactic. *)
let entry = mlexpr_of_string s in
let se = <:expr< { Tacexpr.mltac_tactic = $entry$; Tacexpr.mltac_plugin = $plugin_name$ } >> in
- let pp = make_printing_rule se cl in
+ let pp = make_printing_rule cl in
let gl = mlexpr_of_clause cl in
let atom =
mlexpr_of_list (mlexpr_of_pair mlexpr_of_string (fun x -> x))
@@ -230,9 +200,9 @@ let declare_tactic loc s c cl = match cl with
declare_str_items loc
[ <:str_item< do {
try do {
- Tacenv.register_ml_tactic $se$ $make_fun_clauses loc s cl$;
+ Tacenv.register_ml_tactic $se$ (Array.of_list $make_fun_clauses loc s cl$);
Mltop.declare_cache_obj $obj$ $plugin_name$;
- List.iter (fun (s, r) -> Pptactic.declare_ml_tactic_pprule s r) $pp$; }
+ Pptactic.declare_ml_tactic_pprule $se$ (Array.of_list $pp$); }
with [ e when Errors.noncritical e ->
Pp.msg_warning
(Pp.app
@@ -257,7 +227,7 @@ EXTEND
c = OPT [ "=>"; "["; c = Pcaml.expr; "]" -> c ];
"->"; "["; e = Pcaml.expr; "]" ->
(match l with
- | GramNonTerminal _ :: _ ->
+ | ExtNonTerminal _ :: _ ->
(* En attendant la syntaxe de tacticielles *)
failwith "Tactic syntax must start with an identifier"
| _ -> (l,c,e))
@@ -265,14 +235,14 @@ EXTEND
;
tacargs:
[ [ e = LIDENT; "("; s = LIDENT; ")" ->
- let t, g = interp_entry_name false None e "" in
- GramNonTerminal (!@loc, t, g, Some (Names.Id.of_string s))
+ let e = parse_user_entry e "" in
+ ExtNonTerminal (type_of_user_symbol e, e, Names.Id.of_string s)
| e = LIDENT; "("; s = LIDENT; ","; sep = STRING; ")" ->
- let t, g = interp_entry_name false None e sep in
- GramNonTerminal (!@loc, t, g, Some (Names.Id.of_string s))
+ let e = parse_user_entry e sep in
+ ExtNonTerminal (type_of_user_symbol e, e, Names.Id.of_string s)
| s = STRING ->
if String.is_empty s then Errors.user_err_loc (!@loc,"",Pp.str "Empty terminal.");
- GramTerminal s
+ ExtTerminal s
] ]
;
tac_name:
diff --git a/grammar/vernacextend.ml4 b/grammar/vernacextend.ml4
index d789a6c1f..57079fccd 100644
--- a/grammar/vernacextend.ml4
+++ b/grammar/vernacextend.ml4
@@ -22,7 +22,7 @@ open Compat
type rule = {
r_head : string option;
(** The first terminal grammar token *)
- r_patt : grammar_prod_item list;
+ r_patt : extend_token list;
(** The remaining tokens of the parsing rule *)
r_class : MLast.expr option;
(** An optional classifier for the STM *)
@@ -34,10 +34,9 @@ type rule = {
let rec make_let e = function
| [] -> e
- | GramNonTerminal(loc,t,_,Some p)::l ->
- let loc = of_coqloc loc in
+ | ExtNonTerminal (t, _, p) :: l ->
let p = Names.Id.to_string p in
- let loc = CompatLoc.merge loc (MLast.loc_of_expr e) in
+ let loc = MLast.loc_of_expr e in
let e = make_let e l in
<:expr< let $lid:p$ = Genarg.out_gen $make_rawwit loc t$ $lid:p$ in $e$ >>
| _::l -> make_let e l
@@ -50,7 +49,7 @@ let make_clause { r_patt = pt; r_branch = e; } =
(* To avoid warnings *)
let mk_ignore c pt =
let names = CList.map_filter (function
- | GramNonTerminal(_,_,_,Some p) -> Some (Names.Id.to_string p)
+ | ExtNonTerminal (_, _, p) -> Some (Names.Id.to_string p)
| _ -> None) pt in
let fold accu id = <:expr< let _ = $lid:id$ in $accu$ >> in
let names = List.fold_left fold <:expr< () >> names in
@@ -108,7 +107,7 @@ let make_fun_classifiers loc s c l =
let mlexpr_of_clause =
mlexpr_of_list
(fun { r_head = a; r_patt = b; } -> mlexpr_of_list make_prod_item
- (Option.List.cons (Option.map (fun a -> GramTerminal a) a) b))
+ (Option.List.cons (Option.map (fun a -> ExtTerminal a) a) b))
let declare_command loc s c nt cl =
let se = mlexpr_of_string s in
@@ -181,13 +180,13 @@ EXTEND
;
args:
[ [ e = LIDENT; "("; s = LIDENT; ")" ->
- let t, g = interp_entry_name false None e "" in
- GramNonTerminal (!@loc, t, g, Some (Names.Id.of_string s))
+ let e = parse_user_entry e "" in
+ ExtNonTerminal (type_of_user_symbol e, e, Names.Id.of_string s)
| e = LIDENT; "("; s = LIDENT; ","; sep = STRING; ")" ->
- let t, g = interp_entry_name false None e sep in
- GramNonTerminal (!@loc, t, g, Some (Names.Id.of_string s))
+ let e = parse_user_entry e sep in
+ ExtNonTerminal (type_of_user_symbol e, e, Names.Id.of_string s)
| s = STRING ->
- GramTerminal s
+ ExtTerminal s
] ]
;
END
diff --git a/ide/FAQ b/ide/FAQ
index 07b818246..c8b0a5d32 100644
--- a/ide/FAQ
+++ b/ide/FAQ
@@ -1,7 +1,7 @@
CoqIde FAQ
Q0) What is CoqIde?
-R0: A powerfull graphical interface for Coq. See http://coq.inria.fr. for more informations.
+R0: A powerful graphical interface for Coq. See http://coq.inria.fr. for more informations.
Q1) How to enable Emacs keybindings?
R1: Insert
diff --git a/ide/coq.ml b/ide/coq.ml
index 98576a981..0fe316b56 100644
--- a/ide/coq.ml
+++ b/ide/coq.ml
@@ -99,9 +99,6 @@ let display_coqtop_answer cmd lines =
"Command was: "^cmd^"\n"^
"Answer was: "^(String.concat "\n " lines))
-let check_remaining_opt arg =
- if arg <> "" && arg.[0] = '-' then fatal_error_popup ("Illegal option: "^arg)
-
let rec filter_coq_opts args =
let argstr = String.concat " " (List.map Filename.quote args) in
let cmd = Filename.quote (coqtop_path ()) ^" -nois -filteropts " ^ argstr in
@@ -125,7 +122,7 @@ and asks_for_coqtop args =
~message_type:`QUESTION ~buttons:GWindow.Buttons.yes_no () in
match pb_mes#run () with
| `YES ->
- let () = current.cmd_coqtop <- None in
+ let () = cmd_coqtop#set None in
let () = custom_coqtop := None in
let () = pb_mes#destroy () in
filter_coq_opts args
@@ -200,8 +197,6 @@ module GlibMainLoop = struct
let read_all = Ideutils.io_read_all
let async_chan_of_file fd = Glib.Io.channel_of_descr fd
let async_chan_of_socket s = !gio_channel_of_descr_socket s
- let add_timeout ~sec callback =
- ignore(Glib.Timeout.add ~ms:(sec * 1000) ~callback)
end
module CoqTop = Spawn.Async(GlibMainLoop)
@@ -302,13 +297,13 @@ let handle_intermediate_message handle xml =
let logger = match handle.waiting_for with
| Some (_, l) -> l
| None -> function
- | Pp.Error -> Minilib.log ~level:`ERROR
- | Pp.Info -> Minilib.log ~level:`INFO
- | Pp.Notice -> Minilib.log ~level:`NOTICE
- | Pp.Warning -> Minilib.log ~level:`WARNING
- | Pp.Debug _ -> Minilib.log ~level:`DEBUG
+ | Pp.Error -> fun s -> Minilib.log ~level:`ERROR (xml_to_string s)
+ | Pp.Info -> fun s -> Minilib.log ~level:`INFO (xml_to_string s)
+ | Pp.Notice -> fun s -> Minilib.log ~level:`NOTICE (xml_to_string s)
+ | Pp.Warning -> fun s -> Minilib.log ~level:`WARNING (xml_to_string s)
+ | Pp.Debug _ -> fun s -> Minilib.log ~level:`DEBUG (xml_to_string s)
in
- logger level content
+ logger level (Richpp.richpp_of_xml content)
let handle_feedback feedback_processor xml =
let feedback = Feedback.to_feedback xml in
@@ -336,7 +331,7 @@ let unsafe_handle_input handle feedback_processor state conds ~read_all =
let lex = Lexing.from_string s in
let p = Xml_parser.make (Xml_parser.SLexbuf lex) in
let rec loop () =
- let xml = Xml_parser.parse p in
+ let xml = Xml_parser.parse ~do_not_canonicalize:true p in
let l_end = Lexing.lexeme_end lex in
state.fragment <- String.sub s l_end (String.length s - l_end);
state.lexerror <- None;
diff --git a/ide/coqOps.ml b/ide/coqOps.ml
index 89f4e513e..9f36c4e36 100644
--- a/ide/coqOps.ml
+++ b/ide/coqOps.ml
@@ -130,8 +130,6 @@ end = struct
end
open SentenceId
-let prefs = Preferences.current
-
let log msg : unit task =
Coq.lift (fun () -> Minilib.log msg)
@@ -160,12 +158,19 @@ object
end
let flags_to_color f =
- let of_col c = `NAME (Tags.string_of_color c) in
if List.mem `PROCESSING f then `NAME "blue"
else if List.mem `ERROR f then `NAME "red"
else if List.mem `UNSAFE f then `NAME "orange"
else if List.mem `INCOMPLETE f then `NAME "gray"
- else of_col (Tags.get_processed_color ())
+ else `NAME Preferences.processed_color#get
+
+let validate s =
+ let open Xml_datatype in
+ let rec validate = function
+ | PCData s -> Glib.Utf8.validate s
+ | Element (_, _, children) -> List.for_all validate children
+ in
+ validate (Richpp.repr s)
module Doc = Document
@@ -322,7 +327,7 @@ object(self)
method raw_coq_query phrase =
let action = log "raw_coq_query starting now" in
let display_error s =
- if not (Glib.Utf8.validate s) then
+ if not (validate s) then
flash_info "This error is so nasty that I can't even display it."
else messages#add s;
in
@@ -331,7 +336,7 @@ object(self)
let next = function
| Fail (_, _, err) -> display_error err; Coq.return ()
| Good msg ->
- messages#add msg; Coq.return ()
+ messages#add_string msg; Coq.return ()
in
Coq.bind (Coq.seq action query) next
@@ -559,7 +564,7 @@ object(self)
if Queue.is_empty queue then conclude topstack else
match Queue.pop queue, topstack with
| `Skip(start,stop), [] ->
- logger Pp.Error "You must close the proof with Qed or Admitted";
+ logger Pp.Error (Richpp.richpp_of_string "You must close the proof with Qed or Admitted");
self#discard_command_queue queue;
conclude []
| `Skip(start,stop), (_,s) :: topstack ->
@@ -575,7 +580,7 @@ object(self)
let handle_answer = function
| Good (id, (Util.Inl (* NewTip *) (), msg)) ->
Doc.assign_tip_id document id;
- logger Pp.Notice msg;
+ logger Pp.Notice (Richpp.richpp_of_string msg);
self#commit_queue_transaction sentence;
loop id []
| Good (id, (Util.Inr (* Unfocus *) tip, msg)) ->
@@ -583,7 +588,7 @@ object(self)
let topstack, _ = Doc.context document in
self#exit_focus;
self#cleanup (Doc.cut_at document tip);
- logger Pp.Notice msg;
+ logger Pp.Notice (Richpp.richpp_of_string msg);
self#mark_as_needed sentence;
if Queue.is_empty queue then loop tip []
else loop tip (List.rev topstack)
@@ -602,7 +607,7 @@ object(self)
let next = function
| Good _ ->
messages#clear;
- messages#push Pp.Info "All proof terms checked by the kernel";
+ messages#push Pp.Info (Richpp.richpp_of_string "All proof terms checked by the kernel");
Coq.return ()
| Fail x -> self#handle_failure x in
Coq.bind (Coq.status ~logger:messages#push true) next
@@ -630,7 +635,7 @@ object(self)
method private process_until_iter iter =
let until _ start stop =
- if prefs.Preferences.stop_before then stop#compare iter > 0
+ if Preferences.stop_before#get then stop#compare iter > 0
else start#compare iter >= 0
in
self#process_until until false
@@ -696,7 +701,7 @@ object(self)
self#cleanup (Doc.cut_at document to_id);
conclusion ()
| Fail (safe_id, loc, msg) ->
- if loc <> None then messages#push Pp.Error "Fixme LOC";
+ if loc <> None then messages#push Pp.Error (Richpp.richpp_of_string "Fixme LOC");
messages#push Pp.Error msg;
if Stateid.equal safe_id Stateid.dummy then self#show_goals
else undo safe_id
@@ -772,7 +777,7 @@ object(self)
self#show_goals
in
let display_error (loc, s) =
- if not (Glib.Utf8.validate s) then
+ if not (validate s) then
flash_info "This error is so nasty that I can't even display it."
else messages#add s
in
@@ -782,10 +787,10 @@ object(self)
let next = function
| Fail (_, l, str) -> (* FIXME: check *)
display_error (l, str);
- messages#add ("Unsuccessfully tried: "^phrase);
+ messages#add (Richpp.richpp_of_string ("Unsuccessfully tried: "^phrase));
more
| Good msg ->
- messages#add msg;
+ messages#add_string msg;
stop Tags.Script.processed
in
Coq.bind (Coq.seq action query) next
@@ -829,7 +834,7 @@ object(self)
method initialize =
let get_initial_state =
let next = function
- | Fail _ -> messages#set ("Couln't initialize Coq"); Coq.return ()
+ | Fail _ -> messages#set (Richpp.richpp_of_string "Couln't initialize Coq"); Coq.return ()
| Good id -> initial_state <- id; Coq.return () in
Coq.bind (Coq.init (get_filename ())) next in
Coq.seq get_initial_state Coq.PrintOpt.enforce
diff --git a/ide/coqide.ml b/ide/coqide.ml
index 608cf82ff..8a952f260 100644
--- a/ide/coqide.ml
+++ b/ide/coqide.ml
@@ -44,8 +44,6 @@ open Session
(** {2 Some static elements } *)
-let prefs = Preferences.current
-
(** The arguments that will be passed to coqtop. No quoting here, since
no /bin/sh when using create_process instead of open_process. *)
let custom_project_files = ref []
@@ -87,9 +85,9 @@ let make_coqtop_args = function
|None -> "", !sup_args
|Some the_file ->
let get_args f = Project_file.args_from_project f
- !custom_project_files prefs.project_file_name
+ !custom_project_files project_file_name#get
in
- match prefs.read_project with
+ match read_project#get with
|Ignore_args -> "", !sup_args
|Append_args ->
let fname, args = get_args the_file in fname, args @ !sup_args
@@ -164,7 +162,6 @@ let load_file ?(maycreate=false) f =
input_buffer#place_cursor ~where:input_buffer#start_iter;
Sentence.tag_all input_buffer;
session.script#clear_undo ();
- !refresh_editor_hook ();
Minilib.log "Loading: success";
end
with e -> flash_info ("Load failed: "^(Printexc.to_string e))
@@ -250,7 +247,6 @@ module File = struct
let newfile _ =
let session = create_session None in
let index = notebook#append_term session in
- !refresh_editor_hook ();
notebook#goto_page index
let load _ =
@@ -319,13 +315,13 @@ let export kind sn =
| _ -> assert false
in
let cmd =
- local_cd f ^ prefs.cmd_coqdoc ^ " --" ^ kind ^ " -o " ^
+ local_cd f ^ cmd_coqdoc#get ^ " --" ^ kind ^ " -o " ^
(Filename.quote output) ^ " " ^ (Filename.quote basef) ^ " 2>&1"
in
- sn.messages#set ("Running: "^cmd);
+ sn.messages#set (Richpp.richpp_of_string ("Running: "^cmd));
let finally st = flash_info (cmd ^ pr_exit_status st)
in
- run_command sn.messages#add finally cmd
+ run_command (fun msg -> sn.messages#add_string msg) finally cmd
let export kind = cb_on_current_term (export kind)
@@ -334,8 +330,8 @@ let print sn =
|None -> flash_info "Cannot print: this buffer has no name"
|Some f_name ->
let cmd =
- local_cd f_name ^ prefs.cmd_coqdoc ^ " -ps " ^
- Filename.quote (Filename.basename f_name) ^ " | " ^ prefs.cmd_print
+ local_cd f_name ^ cmd_coqdoc#get ^ " -ps " ^
+ Filename.quote (Filename.basename f_name) ^ " | " ^ cmd_print#get
in
let w = GWindow.window ~title:"Print" ~modal:true
~position:`CENTER ~wm_class:"CoqIDE" ~wm_name: "CoqIDE" ()
@@ -378,17 +374,17 @@ end
let reset_revert_timer () =
FileOps.revert_timer.kill ();
- if prefs.global_auto_revert then
+ if global_auto_revert#get then
FileOps.revert_timer.run
- ~ms:prefs.global_auto_revert_delay
+ ~ms:global_auto_revert_delay#get
~callback:(fun () -> File.revert_all (); true)
let reset_autosave_timer () =
let autosave sn = try sn.fileops#auto_save with _ -> () in
let autosave_all () = List.iter autosave notebook#pages; true in
FileOps.autosave_timer.kill ();
- if prefs.auto_save then
- FileOps.autosave_timer.run ~ms:prefs.auto_save_delay ~callback:autosave_all
+ if auto_save#get then
+ FileOps.autosave_timer.run ~ms:auto_save_delay#get ~callback:autosave_all
(** Export of functions used in [coqide_main] : *)
@@ -408,8 +404,8 @@ let coq_makefile sn =
match sn.fileops#filename with
|None -> flash_info "Cannot make makefile: this buffer has no name"
|Some f ->
- let cmd = local_cd f ^ prefs.cmd_coqmakefile in
- let finally st = flash_info (current.cmd_coqmakefile ^ pr_exit_status st)
+ let cmd = local_cd f ^ cmd_coqmakefile#get in
+ let finally st = flash_info (cmd_coqmakefile#get ^ pr_exit_status st)
in
run_command ignore finally cmd
@@ -421,7 +417,7 @@ let editor sn =
|Some f ->
File.save ();
let f = Filename.quote f in
- let cmd = Util.subst_command_placeholder prefs.cmd_editor f in
+ let cmd = Util.subst_command_placeholder cmd_editor#get f in
run_command ignore (fun _ -> sn.fileops#revert) cmd
let editor = cb_on_current_term editor
@@ -431,13 +427,13 @@ let compile sn =
match sn.fileops#filename with
|None -> flash_info "Active buffer has no name"
|Some f ->
- let cmd = prefs.cmd_coqc ^ " -I " ^ (Filename.quote (Filename.dirname f))
+ let cmd = cmd_coqc#get ^ " -I " ^ (Filename.quote (Filename.dirname f))
^ " " ^ (Filename.quote f) ^ " 2>&1"
in
let buf = Buffer.create 1024 in
- sn.messages#set ("Running: "^cmd);
+ sn.messages#set (Richpp.richpp_of_string ("Running: "^cmd));
let display s =
- sn.messages#add s;
+ sn.messages#add_string s;
Buffer.add_string buf s
in
let finally st =
@@ -445,8 +441,8 @@ let compile sn =
flash_info (f ^ " successfully compiled")
else begin
flash_info (f ^ " failed to compile");
- sn.messages#set "Compilation output:\n";
- sn.messages#add (Buffer.contents buf);
+ sn.messages#set (Richpp.richpp_of_string "Compilation output:\n");
+ sn.messages#add (Richpp.richpp_of_string (Buffer.contents buf));
end
in
run_command display finally cmd
@@ -467,17 +463,17 @@ let make sn =
|None -> flash_info "Cannot make: this buffer has no name"
|Some f ->
File.saveall ();
- let cmd = local_cd f ^ prefs.cmd_make ^ " 2>&1" in
- sn.messages#set "Compilation output:\n";
+ let cmd = local_cd f ^ cmd_make#get ^ " 2>&1" in
+ sn.messages#set (Richpp.richpp_of_string "Compilation output:\n");
Buffer.reset last_make_buf;
last_make := "";
last_make_index := 0;
last_make_dir := Filename.dirname f;
let display s =
- sn.messages#add s;
+ sn.messages#add_string s;
Buffer.add_string last_make_buf s
in
- let finally st = flash_info (current.cmd_make ^ pr_exit_status st)
+ let finally st = flash_info (cmd_make#get ^ pr_exit_status st)
in
run_command display finally cmd
@@ -512,11 +508,11 @@ let next_error sn =
let stopi = b#get_iter_at_byte ~line:(line-1) stop in
b#apply_tag Tags.Script.error ~start:starti ~stop:stopi;
b#place_cursor ~where:starti;
- sn.messages#set error_msg;
+ sn.messages#set (Richpp.richpp_of_string error_msg);
sn.script#misc#grab_focus ()
with Not_found ->
last_make_index := 0;
- sn.messages#set "No more errors.\n"
+ sn.messages#set (Richpp.richpp_of_string "No more errors.\n")
let next_error = cb_on_current_term next_error
@@ -537,7 +533,7 @@ let update_status sn =
| None -> ""
| Some n -> ", proving " ^ n
in
- display ("Ready"^ (if current.nanoPG then ", [μPG]" else "") ^ path ^ name);
+ display ("Ready"^ (if nanoPG#get then ", [μPG]" else "") ^ path ^ name);
Coq.return ()
in
Coq.bind (Coq.status ~logger:sn.messages#push false) next
@@ -722,7 +718,7 @@ let initial_about () =
else ""
in
let msg = initial_string ^ version_info ^ log_file_message () in
- on_current_term (fun term -> term.messages#add msg)
+ on_current_term (fun term -> term.messages#add_string msg)
let coq_icon () =
(* May raise Nof_found *)
@@ -787,7 +783,7 @@ let coqtop_arguments sn =
let args = String.concat " " args in
let msg = Printf.sprintf "Invalid arguments: %s" args in
let () = sn.messages#clear in
- sn.messages#push Pp.Error msg
+ sn.messages#push Pp.Error (Richpp.richpp_of_string msg)
else dialog#destroy ()
in
let _ = entry#connect#activate ok_cb in
@@ -809,69 +805,19 @@ let zoom_fit sn =
let cols = script#right_margin_position in
let pango_ctx = script#misc#pango_context in
let layout = pango_ctx#create_layout in
- let fsize = Pango.Font.get_size current.text_font in
+ let fsize = Pango.Font.get_size (Pango.Font.from_string text_font#get) in
Pango.Layout.set_text layout (String.make cols 'X');
let tlen = fst (Pango.Layout.get_pixel_size layout) in
- Pango.Font.set_size current.text_font
+ Pango.Font.set_size (Pango.Font.from_string text_font#get)
(fsize * space / tlen / Pango.scale * Pango.scale);
- save_pref ();
- !refresh_editor_hook ()
+ save_pref ()
end
(** Refresh functions *)
-let refresh_editor_prefs () =
- let wrap_mode = if prefs.dynamic_word_wrap then `WORD else `NONE in
- let show_spaces =
- if prefs.show_spaces then 0b1001011 (* SPACE, TAB, NBSP, TRAILING *)
- else 0
- in
- let fd = prefs.text_font in
- let clr = Tags.color_of_string prefs.background_color
- in
- let iter_session sn =
- (* Editor settings *)
- sn.script#set_wrap_mode wrap_mode;
- sn.script#set_show_line_numbers prefs.show_line_number;
- sn.script#set_auto_indent prefs.auto_indent;
- sn.script#set_highlight_current_line prefs.highlight_current_line;
-
- (* Hack to handle missing binding in lablgtk *)
- let conv = { Gobject.name = "draw-spaces"; Gobject.conv = Gobject.Data.int }
- in
- Gobject.set conv sn.script#as_widget show_spaces;
-
- sn.script#set_show_right_margin prefs.show_right_margin;
- if prefs.show_progress_bar then sn.segment#misc#show () else sn.segment#misc#hide ();
- sn.script#set_insert_spaces_instead_of_tabs
- prefs.spaces_instead_of_tabs;
- sn.script#set_tab_width prefs.tab_length;
- sn.script#set_auto_complete prefs.auto_complete;
-
- (* Fonts *)
- sn.script#misc#modify_font fd;
- sn.proof#misc#modify_font fd;
- sn.messages#modify_font fd;
- sn.command#refresh_font ();
-
- (* Colors *)
- Tags.set_processing_color (Tags.color_of_string current.processing_color);
- Tags.set_processed_color (Tags.color_of_string current.processed_color);
- Tags.set_error_color (Tags.color_of_string current.error_color);
- Tags.set_error_fg_color (Tags.color_of_string current.error_fg_color);
- sn.script#misc#modify_base [`NORMAL, `COLOR clr];
- sn.proof#misc#modify_base [`NORMAL, `COLOR clr];
- sn.messages#refresh_color ();
- sn.command#refresh_color ();
- sn.errpage#refresh_color ();
- sn.jobpage#refresh_color ();
-
- in
- List.iter iter_session notebook#pages
-
let refresh_notebook_pos () =
- let pos = match prefs.vertical_tabs, prefs.opposite_tabs with
+ let pos = match vertical_tabs#get, opposite_tabs#get with
| false, false -> `TOP
| false, true -> `BOTTOM
| true , false -> `LEFT
@@ -906,7 +852,7 @@ let toggle_items menu_name l =
let f d =
let label = d.Opt.label in
let k, name = get_shortcut label in
- let accel = Option.map ((^) prefs.modifier_for_display) k in
+ let accel = Option.map ((^) modifier_for_display#get) k in
toggle_item name ~label ?accel ~active:d.Opt.init
~callback:(printopts_callback d.Opt.opts)
menu_name
@@ -948,7 +894,7 @@ let alpha_items menu_name item_name l =
Caveat: the offset is now from the start of the text. *)
let template_item (text, offset, len, key) =
- let modifier = prefs.modifier_for_templates in
+ let modifier = modifier_for_templates#get in
let idx = String.index text ' ' in
let name = String.sub text 0 idx in
let label = "_"^name^" __" in
@@ -976,7 +922,7 @@ let build_ui () =
let w = GWindow.window
~wm_class:"CoqIde" ~wm_name:"CoqIde"
~allow_grow:true ~allow_shrink:true
- ~width:prefs.window_width ~height:prefs.window_height
+ ~width:window_width#get ~height:window_height#get
~title:"CoqIde" ()
in
let () =
@@ -1074,77 +1020,60 @@ let build_ui () =
~callback:(fun _ -> notebook#next_page ());
item "Zoom in" ~label:"_Zoom in" ~accel:("<Control>plus")
~stock:`ZOOM_IN ~callback:(fun _ ->
- Pango.Font.set_size current.text_font
- (Pango.Font.get_size current.text_font + Pango.scale);
- save_pref ();
- !refresh_editor_hook ());
+ let ft = Pango.Font.from_string text_font#get in
+ Pango.Font.set_size ft (Pango.Font.get_size ft + Pango.scale);
+ text_font#set (Pango.Font.to_string ft);
+ save_pref ());
item "Zoom out" ~label:"_Zoom out" ~accel:("<Control>minus")
~stock:`ZOOM_OUT ~callback:(fun _ ->
- Pango.Font.set_size current.text_font
- (Pango.Font.get_size current.text_font - Pango.scale);
- save_pref ();
- !refresh_editor_hook ());
+ let ft = Pango.Font.from_string text_font#get in
+ Pango.Font.set_size ft (Pango.Font.get_size ft - Pango.scale);
+ text_font#set (Pango.Font.to_string ft);
+ save_pref ());
item "Zoom fit" ~label:"_Zoom fit" ~accel:("<Control>0")
~stock:`ZOOM_FIT ~callback:(cb_on_current_term MiscMenu.zoom_fit);
toggle_item "Show Toolbar" ~label:"Show _Toolbar"
- ~active:(prefs.show_toolbar)
- ~callback:(fun _ ->
- prefs.show_toolbar <- not prefs.show_toolbar;
- !refresh_toolbar_hook ());
+ ~active:(show_toolbar#get)
+ ~callback:(fun _ -> show_toolbar#set (not show_toolbar#get));
item "Query Pane" ~label:"_Query Pane"
~accel:"F1"
~callback:(cb_on_current_term MiscMenu.show_hide_query_pane)
];
toggle_items view_menu Coq.PrintOpt.bool_items;
- menu navigation_menu [
- item "Navigation" ~label:"_Navigation";
- item "Forward" ~label:"_Forward" ~stock:`GO_DOWN ~callback:Nav.forward_one
- ~tooltip:"Forward one command"
- ~accel:(prefs.modifier_for_navigation^"Down");
- item "Backward" ~label:"_Backward" ~stock:`GO_UP ~callback:Nav.backward_one
- ~tooltip:"Backward one command"
- ~accel:(prefs.modifier_for_navigation^"Up");
- item "Go to" ~label:"_Go to" ~stock:`JUMP_TO ~callback:Nav.goto
- ~tooltip:"Go to cursor"
- ~accel:(prefs.modifier_for_navigation^"Right");
- item "Start" ~label:"_Start" ~stock:`GOTO_TOP ~callback:Nav.restart
- ~tooltip:"Restart coq"
- ~accel:(prefs.modifier_for_navigation^"Home");
- item "End" ~label:"_End" ~stock:`GOTO_BOTTOM ~callback:Nav.goto_end
- ~tooltip:"Go to end"
- ~accel:(prefs.modifier_for_navigation^"End");
- item "Interrupt" ~label:"_Interrupt" ~stock:`STOP ~callback:Nav.interrupt
- ~tooltip:"Interrupt computations"
- ~accel:(prefs.modifier_for_navigation^"Break");
-(* wait for this available in GtkSourceView !
- item "Hide" ~label:"_Hide" ~stock:`MISSING_IMAGE
- ~callback:(fun _ -> let sess = notebook#current_term in
- toggle_proof_visibility sess.buffer
- sess.analyzed_view#get_insert) ~tooltip:"Hide proof"
- ~accel:(prefs.modifier_for_navigation^"h");*)
- item "Previous" ~label:"_Previous" ~stock:`GO_BACK
- ~callback:Nav.previous_occ
- ~tooltip:"Previous occurrence"
- ~accel:(prefs.modifier_for_navigation^"less");
- item "Next" ~label:"_Next" ~stock:`GO_FORWARD ~callback:Nav.next_occ
- ~tooltip:"Next occurrence"
- ~accel:(prefs.modifier_for_navigation^"greater");
- item "Force" ~label:"_Force" ~stock:`EXECUTE ~callback:Nav.join_document
- ~tooltip:"Fully check the document"
- ~accel:(current.modifier_for_navigation^"f");
- ];
+ let navitem (text, label, stock, callback, tooltip, accel) =
+ let accel = modifier_for_navigation#get ^ accel in
+ item text ~label ~stock ~callback ~tooltip ~accel
+ in
+ menu navigation_menu begin
+ [
+ (fun e -> item "Navigation" ~label:"_Navigation" e);
+ ] @ List.map navitem [
+ ("Forward", "_Forward", `GO_DOWN, Nav.forward_one, "Forward one command", "Down");
+ ("Backward", "_Backward", `GO_UP, Nav.backward_one, "Backward one command", "Up");
+ ("Go to", "_Go to", `JUMP_TO, Nav.goto, "Go to cursor", "Right");
+ ("Start", "_Start", `GOTO_TOP, Nav.restart, "Restart coq", "Home");
+ ("End", "_End", `GOTO_BOTTOM, Nav.goto_end, "Go to end", "End");
+ ("Interrupt", "_Interrupt", `STOP, Nav.interrupt, "Interrupt computations", "Break");
+ (* wait for this available in GtkSourceView !
+ ("Hide", "_Hide", `MISSING_IMAGE,
+ ~callback:(fun _ -> let sess = notebook#current_term in
+ toggle_proof_visibility sess.buffer sess.analyzed_view#get_insert), "Hide proof", "h"); *)
+ ("Previous", "_Previous", `GO_BACK, Nav.previous_occ, "Previous occurrence", "less");
+ ("Next", "_Next", `GO_FORWARD, Nav.next_occ, "Next occurrence", "greater");
+ ("Force", "_Force", `EXECUTE, Nav.join_document, "Fully check the document", "f");
+ ] end;
let tacitem s sc =
item s ~label:("_"^s)
- ~accel:(prefs.modifier_for_tactics^sc)
+ ~accel:(modifier_for_tactics#get^sc)
~callback:(tactic_wizard_callback [s])
in
menu tactics_menu [
item "Try Tactics" ~label:"_Try Tactics";
item "Wizard" ~label:"<Proof Wizard>" ~stock:`DIALOG_INFO
- ~tooltip:"Proof Wizard" ~accel:(prefs.modifier_for_tactics^"dollar")
- ~callback:(tactic_wizard_callback prefs.automatic_tactics);
+ ~tooltip:"Proof Wizard" ~accel:(modifier_for_tactics#get^"dollar")
+ ~callback:(tactic_wizard_callback automatic_tactics#get);
tacitem "auto" "a";
tacitem "auto with *" "asterisk";
tacitem "eauto" "e";
@@ -1166,7 +1095,7 @@ let build_ui () =
template_item ("Fixpoint ident (_ : _) {struct _} : _ :=\n.\n", 9,5, "F");
template_item ("Scheme new_scheme := Induction for _ Sort _\n" ^
"with _ := Induction for _ Sort _.\n", 7,10, "S");
- item "match" ~label:"match ..." ~accel:(prefs.modifier_for_templates^"M")
+ item "match" ~label:"match ..." ~accel:(modifier_for_templates#get^"M")
~callback:match_callback
];
alpha_items templates_menu "Template" Coq_commands.commands;
@@ -1211,17 +1140,17 @@ let build_ui () =
item "Help" ~label:"_Help";
item "Browse Coq Manual" ~label:"Browse Coq _Manual"
~callback:(fun _ ->
- browse notebook#current_term.messages#add (doc_url ()));
+ browse notebook#current_term.messages#add_string (doc_url ()));
item "Browse Coq Library" ~label:"Browse Coq _Library"
~callback:(fun _ ->
- browse notebook#current_term.messages#add prefs.library_url);
+ browse notebook#current_term.messages#add_string library_url#get);
item "Help for keyword" ~label:"Help for _keyword" ~stock:`HELP
~callback:(fun _ -> on_current_term (fun sn ->
- browse_keyword sn.messages#add (get_current_word sn)));
+ browse_keyword sn.messages#add_string (get_current_word sn)));
item "Help for μPG mode" ~label:"Help for μPG mode"
~callback:(fun _ -> on_current_term (fun sn ->
sn.messages#clear;
- sn.messages#add (NanoPG.get_documentation ())));
+ sn.messages#add_string (NanoPG.get_documentation ())));
item "About Coq" ~label:"_About" ~stock:`ABOUT
~callback:MiscMenu.about
];
@@ -1259,7 +1188,7 @@ let build_ui () =
(* Reset on tab switch *)
let _ = notebook#connect#switch_page ~callback:(fun _ ->
- if prefs.reset_on_tab_switch then Nav.restart ())
+ if reset_on_tab_switch#get then Nav.restart ())
in
(* Vertical Separator between Scripts and Goals *)
@@ -1267,7 +1196,7 @@ let build_ui () =
let () = refresh_notebook_pos () in
let lower_hbox = GPack.hbox ~homogeneous:false ~packing:vbox#pack () in
let () = lower_hbox#pack ~expand:true status#coerce in
- let () = push_info ("Ready"^ if current.nanoPG then ", [μPG]" else "") in
+ let () = push_info ("Ready"^ if nanoPG#get then ", [μPG]" else "") in
(* Location display *)
let l = GMisc.label
@@ -1310,43 +1239,33 @@ let build_ui () =
let _ = Glib.Timeout.add ~ms:300 ~callback in
(* Initializing hooks *)
- let refresh_toolbar () =
- if prefs.show_toolbar
- then toolbar#misc#show ()
- else toolbar#misc#hide ()
- in
- let refresh_style () =
- let style = style_manager#style_scheme prefs.source_style in
+ let refresh_style style =
+ let style = style_manager#style_scheme style in
let iter_session v = v.script#source_buffer#set_style_scheme style in
List.iter iter_session notebook#pages
in
- let refresh_language () =
- let lang = lang_manager#language prefs.source_language in
+ let refresh_language lang =
+ let lang = lang_manager#language lang in
let iter_session v = v.script#source_buffer#set_language lang in
List.iter iter_session notebook#pages
in
- let resize_window () =
- w#resize ~width:prefs.window_width ~height:prefs.window_height
+ let refresh_toolbar b =
+ if b then toolbar#misc#show () else toolbar#misc#hide ()
in
- refresh_toolbar ();
- refresh_toolbar_hook := refresh_toolbar;
- refresh_style_hook := refresh_style;
- refresh_language_hook := refresh_language;
- refresh_editor_hook := refresh_editor_prefs;
- resize_window_hook := resize_window;
- refresh_tabs_hook := refresh_notebook_pos;
+ stick show_toolbar toolbar refresh_toolbar;
+ let _ = source_style#connect#changed refresh_style in
+ let _ = source_language#connect#changed refresh_language in
(* Color configuration *)
Tags.Script.incomplete#set_property
(`BACKGROUND_STIPPLE
(Gdk.Bitmap.create_from_data ~width:2 ~height:2 "\x01\x02"));
- Tags.Script.incomplete#set_property
- (`BACKGROUND_GDK (Tags.get_processed_color ()));
(* Showtime ! *)
w#show ()
+
(** {2 Coqide main function } *)
let make_file_buffer f =
@@ -1356,7 +1275,7 @@ let make_file_buffer f =
let make_scratch_buffer () =
let session = create_session None in
let _ = notebook#append_term session in
- !refresh_editor_hook ()
+ ()
let main files =
build_ui ();
diff --git a/ide/document.ml b/ide/document.ml
index 9823e7576..bb431e791 100644
--- a/ide/document.ml
+++ b/ide/document.ml
@@ -124,12 +124,6 @@ let context d =
let pair _ x y = try Option.get x, y with Option.IsNone -> assert false in
List.map (flat pair true) top, List.map (flat pair true) bot
-let iter d f =
- let a, s, b = to_lists d in
- List.iter (flat f false) a;
- List.iter (flat f true) s;
- List.iter (flat f false) b
-
let stateid_opt_equal = Option.equal Stateid.equal
let is_in_focus d id =
@@ -154,7 +148,7 @@ let cut_at d id =
if stateid_opt_equal state_id (Some id) then CSig.Stop (n, zone)
else CSig.Cont (n + 1, data :: zone) in
let n, zone = CList.fold_left_until aux (0, []) d.stack in
- for i = 1 to n do ignore(pop d) done;
+ for _i = 1 to n do ignore(pop d) done;
List.rev zone
let find_id d f =
diff --git a/ide/fileOps.ml b/ide/fileOps.ml
index 835ea0140..7be1bdb92 100644
--- a/ide/fileOps.ml
+++ b/ide/fileOps.ml
@@ -8,8 +8,6 @@
open Ideutils
-let prefs = Preferences.current
-
let revert_timer = mktimer ()
let autosave_timer = mktimer ()
@@ -87,7 +85,7 @@ object(self)
flash_info "Could not overwrite file"
| _ ->
Minilib.log "Auto revert set to false";
- prefs.Preferences.global_auto_revert <- false;
+ Preferences.global_auto_revert#set false;
revert_timer.kill ()
method save f =
@@ -120,9 +118,9 @@ object(self)
| None -> None
| Some f ->
let dir = Filename.dirname f in
- let base = (fst prefs.Preferences.auto_save_name) ^
+ let base = (fst Preferences.auto_save_name#get) ^
(Filename.basename f) ^
- (snd prefs.Preferences.auto_save_name)
+ (snd Preferences.auto_save_name#get)
in Some (Filename.concat dir base)
method private need_auto_save =
diff --git a/ide/ide.mllib b/ide/ide.mllib
index e082bd18c..83b314283 100644
--- a/ide/ide.mllib
+++ b/ide/ide.mllib
@@ -9,7 +9,6 @@ Configwin
Editable_cells
Config_parser
Tags
-Wg_Segment
Wg_Notebook
Config_lexer
Utf8_convert
@@ -21,6 +20,7 @@ Coq
Coq_lex
Sentence
Gtk_parsing
+Wg_Segment
Wg_ProofView
Wg_MessageView
Wg_Detachable
diff --git a/ide/ide_slave.ml b/ide/ide_slave.ml
index bd98fe16e..20cf48d7f 100644
--- a/ide/ide_slave.ml
+++ b/ide/ide_slave.ml
@@ -184,14 +184,15 @@ let process_goal sigma g =
let id = Goal.uid g in
let ccl =
let norm_constr = Reductionops.nf_evar sigma (Goal.V82.concl sigma g) in
- string_of_ppcmds (pr_goal_concl_style_env env sigma norm_constr) in
+ Richpp.richpp_of_pp (pr_goal_concl_style_env env sigma norm_constr)
+ in
let process_hyp d (env,l) =
- let d = Context.map_named_list_declaration (Reductionops.nf_evar sigma) d in
+ let d = Context.NamedList.Declaration.map (Reductionops.nf_evar sigma) d in
let d' = List.map (fun x -> (x, pi2 d, pi3 d)) (pi1 d) in
(List.fold_right Environ.push_named d' env,
- (string_of_ppcmds (pr_var_list_decl env sigma d)) :: l) in
+ (Richpp.richpp_of_pp (pr_var_list_decl env sigma d)) :: l) in
let (_env, hyps) =
- Context.fold_named_list_context process_hyp
+ Context.NamedList.fold process_hyp
(Termops.compact_named_context (Environ.named_context env)) ~init:(min_env,[]) in
{ Interface.goal_hyp = List.rev hyps; Interface.goal_ccl = ccl; Interface.goal_id = id; }
@@ -333,10 +334,14 @@ let handle_exn (e, info) =
let loc_of e = match Loc.get_loc e with
| Some loc when not (Loc.is_ghost loc) -> Some (Loc.unloc loc)
| _ -> None in
- let mk_msg () = read_stdout ()^"\n"^string_of_ppcmds (Errors.print ~info e) in
+ let mk_msg () =
+ let msg = read_stdout () in
+ let msg = str msg ++ fnl () ++ Errors.print ~info e in
+ Richpp.richpp_of_pp msg
+ in
match e with
- | Errors.Drop -> dummy, None, "Drop is not allowed by coqide!"
- | Errors.Quit -> dummy, None, "Quit is not allowed by coqide!"
+ | Errors.Drop -> dummy, None, Richpp.richpp_of_string "Drop is not allowed by coqide!"
+ | Errors.Quit -> dummy, None, Richpp.richpp_of_string "Quit is not allowed by coqide!"
| e ->
match Stateid.get info with
| Some (valid, _) -> valid, loc_of info, mk_msg ()
@@ -432,12 +437,12 @@ let print_xml =
let slave_logger xml_oc level message =
(* convert the message into XML *)
- let msg = string_of_ppcmds (hov 0 message) in
+ let msg = hov 0 message in
let message = {
Pp.message_level = level;
- Pp.message_content = msg;
+ Pp.message_content = (Richpp.repr (Richpp.richpp_of_pp msg));
} in
- let () = pr_debug (Printf.sprintf "-> %S" msg) in
+ let () = pr_debug (Printf.sprintf "-> %S" (string_of_ppcmds msg)) in
let xml = Pp.of_message message in
print_xml xml_oc xml
@@ -469,7 +474,7 @@ let loop () =
try
let xml_query = Xml_parser.parse xml_ic in
(* pr_with_pid (Xml_printer.to_string_fmt xml_query); *)
- let q = Xmlprotocol.to_call xml_query in
+ let Xmlprotocol.Unknown q = Xmlprotocol.to_call xml_query in
let () = pr_debug_call q in
let r = eval_call xml_oc (slave_logger xml_oc Pp.Notice) q in
let () = pr_debug_answer q r in
diff --git a/ide/ideutils.ml b/ide/ideutils.ml
index 44a86556a..508881cad 100644
--- a/ide/ideutils.ml
+++ b/ide/ideutils.ml
@@ -9,8 +9,6 @@
open Preferences
-exception Forbidden
-
let warn_image () =
let img = GMisc.image () in
img#set_stock `DIALOG_WARNING;
@@ -31,13 +29,40 @@ let push_info,pop_info,clear_info =
let size = ref 0 in
(fun s -> incr size; ignore (status_context#push s)),
(fun () -> decr size; status_context#pop ()),
- (fun () -> for i = 1 to !size do status_context#pop () done; size := 0)
+ (fun () -> for _i = 1 to !size do status_context#pop () done; size := 0)
let flash_info =
let flash_context = status#new_context ~name:"Flash" in
(fun ?(delay=5000) s -> flash_context#flash ~delay s)
-
+let xml_to_string xml =
+ let open Xml_datatype in
+ let buf = Buffer.create 1024 in
+ let rec iter = function
+ | PCData s -> Buffer.add_string buf s
+ | Element (_, _, children) ->
+ List.iter iter children
+ in
+ let () = iter (Richpp.repr xml) in
+ Buffer.contents buf
+
+let translate s = s
+
+let insert_xml ?(tags = []) (buf : #GText.buffer_skel) msg =
+ let open Xml_datatype in
+ let tag name =
+ let name = translate name in
+ match GtkText.TagTable.lookup buf#tag_table name with
+ | None -> raise Not_found
+ | Some tag -> new GText.tag tag
+ in
+ let rec insert tags = function
+ | PCData s -> buf#insert ~tags:(List.rev tags) s
+ | Element (t, _, children) ->
+ let tags = try tag t :: tags with Not_found -> tags in
+ List.iter (fun xml -> insert tags xml) children
+ in
+ insert tags (Richpp.repr msg)
let set_location = ref (function s -> failwith "not ready")
@@ -74,7 +99,7 @@ let do_convert s =
in
let s =
if Glib.Utf8.validate s then (Minilib.log "Input is UTF-8"; s)
- else match current.encoding with
+ else match encoding#get with
|Preferences.Eutf8 | Preferences.Elocale -> from_loc ()
|Emanual enc -> try from_manual enc with _ -> from_loc ()
in
@@ -90,7 +115,7 @@ Please choose a correct encoding in the preference panel.*)";;
let try_export file_name s =
let s =
- try match current.encoding with
+ try match encoding#get with
|Eutf8 -> Minilib.log "UTF-8 is enforced" ; s
|Elocale ->
let is_unicode,char_set = Glib.Convert.get_charset () in
@@ -140,7 +165,7 @@ let filter_coq_files () = GFile.filter
~name:"Coq source code"
~patterns:[ "*.v"] ()
-let current_dir () = match current.project_path with
+let current_dir () = match project_path#get with
| None -> ""
| Some dir -> dir
@@ -164,7 +189,7 @@ let select_file_for_open ~title ?filename () =
match file_chooser#filename with
| None -> None
| Some _ as f ->
- current.project_path <- file_chooser#current_folder; f
+ project_path#set file_chooser#current_folder; f
end
| `DELETE_EVENT | `CANCEL -> None in
file_chooser#destroy ();
@@ -193,7 +218,7 @@ let select_file_for_save ~title ?filename () =
file := file_chooser#filename;
match !file with
None -> ()
- | Some s -> current.project_path <- file_chooser#current_folder
+ | Some s -> project_path#set file_chooser#current_folder
end
| `DELETE_EVENT | `CANCEL -> ()
end ;
@@ -238,7 +263,7 @@ let coqtop_path () =
let file = match !custom_coqtop with
| Some s -> s
| None ->
- match current.cmd_coqtop with
+ match cmd_coqtop#get with
| Some s -> s
| None ->
let prog = String.copy Sys.executable_name in
@@ -272,7 +297,7 @@ let textview_width (view : #GText.view_skel) =
let char_width = GPango.to_pixels metrics#approx_char_width in
pixel_width / char_width
-type logger = Pp.message_level -> string -> unit
+type logger = Pp.message_level -> Richpp.richpp -> unit
let default_logger level message =
let level = match level with
@@ -282,7 +307,7 @@ let default_logger level message =
| Pp.Warning -> `WARNING
| Pp.Error -> `ERROR
in
- Minilib.log ~level message
+ Minilib.log ~level (xml_to_string message)
(** {6 File operations} *)
@@ -364,7 +389,7 @@ let run_command display finally cmd =
(** Web browsing *)
let browse prerr url =
- let com = Util.subst_command_placeholder current.cmd_browse url in
+ let com = Util.subst_command_placeholder cmd_browse#get url in
let finally = function
| Unix.WEXITED 127 ->
prerr
@@ -375,13 +400,13 @@ let browse prerr url =
run_command (fun _ -> ()) finally com
let doc_url () =
- if current.doc_url = use_default_doc_url || current.doc_url = ""
+ if doc_url#get = use_default_doc_url || doc_url#get = ""
then
let addr = List.fold_left Filename.concat (Coq_config.docdir)
["html";"refman";"index.html"]
in
if Sys.file_exists addr then "file://"^addr else Coq_config.wwwrefman
- else current.doc_url
+ else doc_url#get
let url_for_keyword =
let ht = Hashtbl.create 97 in
diff --git a/ide/ideutils.mli b/ide/ideutils.mli
index e53072187..4e35a6f9f 100644
--- a/ide/ideutils.mli
+++ b/ide/ideutils.mli
@@ -52,6 +52,11 @@ val pop_info : unit -> unit
val clear_info : unit -> unit
val flash_info : ?delay:int -> string -> unit
+val xml_to_string : Richpp.richpp -> string
+
+val insert_xml : ?tags:GText.tag list ->
+ #GText.buffer_skel -> Richpp.richpp -> unit
+
val set_location : (string -> unit) ref
(* In win32, when a command-line is to be executed via cmd.exe
@@ -64,9 +69,9 @@ val requote : string -> string
val textview_width : #GText.view_skel -> int
(** Returns an approximate value of the character width of a textview *)
-type logger = Pp.message_level -> string -> unit
+type logger = Pp.message_level -> Richpp.richpp -> unit
-val default_logger : Pp.message_level -> string -> unit
+val default_logger : logger
(** Default logger. It logs messages that the casual user should not see. *)
(** {6 I/O operations} *)
diff --git a/ide/interface.mli b/ide/interface.mli
index 6f7f1bcdb..2a9b8b241 100644
--- a/ide/interface.mli
+++ b/ide/interface.mli
@@ -12,14 +12,15 @@
type raw = bool
type verbose = bool
+type richpp = Richpp.richpp
(** The type of coqtop goals *)
type goal = {
goal_id : string;
(** Unique goal identifier *)
- goal_hyp : string list;
+ goal_hyp : richpp list;
(** List of hypotheses *)
- goal_ccl : string;
+ goal_ccl : richpp;
(** Goal conclusion *)
}
@@ -118,7 +119,7 @@ type edit_id = Feedback.edit_id
should probably retract to that point *)
type 'a value =
| Good of 'a
- | Fail of (state_id * location * string)
+ | Fail of (state_id * location * richpp)
type ('a, 'b) union = ('a, 'b) Util.union
@@ -202,7 +203,7 @@ type about_sty = unit
type about_rty = coq_info
type handle_exn_sty = Exninfo.iexn
-type handle_exn_rty = state_id * location * string
+type handle_exn_rty = state_id * location * richpp
(* Retrocompatibility stuff *)
type interp_sty = (raw * verbose) * string
diff --git a/ide/nanoPG.ml b/ide/nanoPG.ml
index 42d65cec1..93bdeb324 100644
--- a/ide/nanoPG.ml
+++ b/ide/nanoPG.ml
@@ -303,7 +303,7 @@ let init w nb ags =
then false
else begin
eprintf "got key %s\n%!" (pr_key t);
- if current.nanoPG then begin
+ if nanoPG#get then begin
match find gui !cur t with
| `Do e ->
eprintf "run (%s) %s on %s\n%!" e.keyname e.doc (pr_status !status);
diff --git a/ide/preferences.ml b/ide/preferences.ml
index f7cc27a55..addea9074 100644
--- a/ide/preferences.ml
+++ b/ide/preferences.ml
@@ -17,19 +17,66 @@ let style_manager = GSourceView2.source_style_scheme_manager ~default:true
let () = style_manager#set_search_path
((Minilib.coqide_data_dirs ())@style_manager#search_path)
-let get_config_file name =
- let find_config dir = Sys.file_exists (Filename.concat dir name) in
- let config_dir = List.find find_config (Minilib.coqide_config_dirs ()) in
- Filename.concat config_dir name
+type tag = {
+ tag_fg_color : string option;
+ tag_bg_color : string option;
+ tag_bold : bool;
+ tag_italic : bool;
+ tag_underline : bool;
+}
-(* Small hack to handle v8.3 to v8.4 change in configuration file *)
-let loaded_pref_file =
- try get_config_file "coqiderc"
- with Not_found -> Filename.concat (Option.default "" (Glib.get_home_dir ())) ".coqiderc"
+(** Generic preferences *)
-let loaded_accel_file =
- try get_config_file "coqide.keys"
- with Not_found -> Filename.concat (Option.default "" (Glib.get_home_dir ())) ".coqide.keys"
+type obj = {
+ set : string list -> unit;
+ get : unit -> string list;
+}
+
+let preferences : obj Util.String.Map.t ref = ref Util.String.Map.empty
+
+class type ['a] repr =
+object
+ method into : string list -> 'a option
+ method from : 'a -> string list
+end
+
+class ['a] preference_signals ~(changed : 'a GUtil.signal) =
+object
+ inherit GUtil.ml_signals [changed#disconnect]
+ method changed = changed#connect ~after
+end
+
+class ['a] preference ~(name : string list) ~(init : 'a) ~(repr : 'a repr) =
+object (self)
+ initializer
+ let set v = match repr#into v with None -> () | Some s -> self#set s in
+ let get () = repr#from self#get in
+ let obj = { set = set; get = get; } in
+ let name = String.concat "." name in
+ if Util.String.Map.mem name !preferences then
+ invalid_arg ("Preference " ^ name ^ " already exists")
+ else
+ preferences := Util.String.Map.add name obj !preferences
+
+ val default = init
+ val mutable data = init
+ val changed : 'a GUtil.signal = new GUtil.signal ()
+ val name : string list = name
+ method connect = new preference_signals ~changed
+ method get = data
+ method set (n : 'a) = data <- n; changed#call n
+ method reset () = self#set default
+ method default = default
+end
+
+let stick (pref : 'a preference) (obj : #GObj.widget as 'obj)
+ (cb : 'a -> unit) =
+ let _ = cb pref#get in
+ let p_id = pref#connect#changed (fun v -> cb v) in
+ let _ = obj#misc#connect#destroy (fun () -> pref#connect#disconnect p_id) in
+ ()
+
+(** Useful marshallers *)
let mod_to_str m =
match m with
@@ -74,359 +121,510 @@ let inputenc_of_string s =
else if s = "LOCALE" then Elocale
else Emanual s)
+let use_default_doc_url = "(automatic)"
+
+module Repr =
+struct
+
+let string : string repr =
+object
+ method from s = [s]
+ method into = function [s] -> Some s | _ -> None
+end
+
+let string_pair : (string * string) repr =
+object
+ method from (s1, s2) = [s1; s2]
+ method into = function [s1; s2] -> Some (s1, s2) | _ -> None
+end
+
+let string_list : string list repr =
+object
+ method from s = s
+ method into s = Some s
+end
+
+let bool : bool repr =
+object
+ method from s = [string_of_bool s]
+ method into = function
+ | ["true"] -> Some true
+ | ["false"] -> Some false
+ | _ -> None
+end
+
+let int : int repr =
+object
+ method from s = [string_of_int s]
+ method into = function
+ | [i] -> (try Some (int_of_string i) with _ -> None)
+ | _ -> None
+end
+
+let option (r : 'a repr) : 'a option repr =
+object
+ method from = function None -> [] | Some v -> "" :: r#from v
+ method into = function
+ | [] -> Some None
+ | "" :: s -> Some (r#into s)
+ | _ -> None
+end
+
+let custom (from : 'a -> string) (into : string -> 'a) : 'a repr =
+object
+ method from x = try [from x] with _ -> []
+ method into = function
+ | [s] -> (try Some (into s) with _ -> None)
+ | _ -> None
+end
+
+let tag : tag repr =
+let _to s = if s = "" then None else Some s in
+let _of = function None -> "" | Some s -> s in
+object
+ method from tag = [
+ _of tag.tag_fg_color;
+ _of tag.tag_bg_color;
+ string_of_bool tag.tag_bold;
+ string_of_bool tag.tag_italic;
+ string_of_bool tag.tag_underline;
+ ]
+ method into = function
+ | [fg; bg; bd; it; ul] ->
+ (try Some {
+ tag_fg_color = _to fg;
+ tag_bg_color = _to bg;
+ tag_bold = bool_of_string bd;
+ tag_italic = bool_of_string it;
+ tag_underline = bool_of_string ul;
+ }
+ with _ -> None)
+ | _ -> None
+end
+
+end
+
+let get_config_file name =
+ let find_config dir = Sys.file_exists (Filename.concat dir name) in
+ let config_dir = List.find find_config (Minilib.coqide_config_dirs ()) in
+ Filename.concat config_dir name
+
+(* Small hack to handle v8.3 to v8.4 change in configuration file *)
+let loaded_pref_file =
+ try get_config_file "coqiderc"
+ with Not_found -> Filename.concat (Option.default "" (Glib.get_home_dir ())) ".coqiderc"
+
+let loaded_accel_file =
+ try get_config_file "coqide.keys"
+ with Not_found -> Filename.concat (Option.default "" (Glib.get_home_dir ())) ".coqide.keys"
(** Hooks *)
-let refresh_style_hook = ref (fun () -> ())
-let refresh_language_hook = ref (fun () -> ())
-let refresh_editor_hook = ref (fun () -> ())
-let refresh_toolbar_hook = ref (fun () -> ())
-let contextual_menus_on_goal_hook = ref (fun x -> ())
-let resize_window_hook = ref (fun () -> ())
-let refresh_tabs_hook = ref (fun () -> ())
+(** New style preferences *)
-type pref =
- {
- mutable cmd_coqtop : string option;
- mutable cmd_coqc : string;
- mutable cmd_make : string;
- mutable cmd_coqmakefile : string;
- mutable cmd_coqdoc : string;
+let cmd_coqtop =
+ new preference ~name:["cmd_coqtop"] ~init:None ~repr:Repr.(option string)
- mutable source_language : string;
- mutable source_style : string;
+let cmd_coqc =
+ new preference ~name:["cmd_coqc"] ~init:"coqc" ~repr:Repr.(string)
- mutable global_auto_revert : bool;
- mutable global_auto_revert_delay : int;
+let cmd_make =
+ new preference ~name:["cmd_make"] ~init:"make" ~repr:Repr.(string)
- mutable auto_save : bool;
- mutable auto_save_delay : int;
- mutable auto_save_name : string * string;
+let cmd_coqmakefile =
+ new preference ~name:["cmd_coqmakefile"] ~init:"coq_makefile -o makefile *.v" ~repr:Repr.(string)
- mutable read_project : project_behavior;
- mutable project_file_name : string;
- mutable project_path : string option;
+let cmd_coqdoc =
+ new preference ~name:["cmd_coqdoc"] ~init:"coqdoc -q -g" ~repr:Repr.(string)
- mutable encoding : inputenc;
+let source_language =
+ new preference ~name:["source_language"] ~init:"coq" ~repr:Repr.(string)
- mutable automatic_tactics : string list;
- mutable cmd_print : string;
+let source_style =
+ new preference ~name:["source_style"] ~init:"coq_style" ~repr:Repr.(string)
- mutable modifier_for_navigation : string;
- mutable modifier_for_templates : string;
- mutable modifier_for_tactics : string;
- mutable modifier_for_display : string;
- mutable modifiers_valid : string;
+let global_auto_revert =
+ new preference ~name:["global_auto_revert"] ~init:false ~repr:Repr.(bool)
- mutable cmd_browse : string;
- mutable cmd_editor : string;
+let global_auto_revert_delay =
+ new preference ~name:["global_auto_revert_delay"] ~init:10000 ~repr:Repr.(int)
- mutable text_font : Pango.font_description;
+let auto_save =
+ new preference ~name:["auto_save"] ~init:true ~repr:Repr.(bool)
- mutable doc_url : string;
- mutable library_url : string;
+let auto_save_delay =
+ new preference ~name:["auto_save_delay"] ~init:10000 ~repr:Repr.(int)
- mutable show_toolbar : bool;
- mutable contextual_menus_on_goal : bool;
- mutable window_width : int;
- mutable window_height :int;
- mutable query_window_width : int;
- mutable query_window_height : int;
-(*
- mutable use_utf8_notation : bool;
-*)
- mutable auto_complete : bool;
- mutable stop_before : bool;
- mutable reset_on_tab_switch : bool;
- mutable vertical_tabs : bool;
- mutable opposite_tabs : bool;
-
- mutable background_color : string;
- mutable processing_color : string;
- mutable processed_color : string;
- mutable error_color : string;
- mutable error_fg_color : string;
-
- mutable dynamic_word_wrap : bool;
- mutable show_line_number : bool;
- mutable auto_indent : bool;
- mutable show_spaces : bool;
- mutable show_right_margin : bool;
- mutable show_progress_bar : bool;
- mutable spaces_instead_of_tabs : bool;
- mutable tab_length : int;
- mutable highlight_current_line : bool;
-
- mutable nanoPG : bool;
+let auto_save_name =
+ new preference ~name:["auto_save_name"] ~init:("#","#") ~repr:Repr.(string_pair)
-}
+let read_project =
+ let repr = Repr.custom string_of_project_behavior project_behavior_of_string in
+ new preference ~name:["read_project"] ~init:Append_args ~repr
-let use_default_doc_url = "(automatic)"
+let project_file_name =
+ new preference ~name:["project_file_name"] ~init:"_CoqProject" ~repr:Repr.(string)
-let current = {
- cmd_coqtop = None;
- cmd_coqc = "coqc";
- cmd_make = "make";
- cmd_coqmakefile = "coq_makefile -o makefile *.v";
- cmd_coqdoc = "coqdoc -q -g";
- cmd_print = "lpr";
+let project_path =
+ new preference ~name:["project_path"] ~init:None ~repr:Repr.(option string)
- global_auto_revert = false;
- global_auto_revert_delay = 10000;
+let encoding =
+ let repr = Repr.custom string_of_inputenc inputenc_of_string in
+ let init = if Sys.os_type = "Win32" then Eutf8 else Elocale in
+ new preference ~name:["encoding"] ~init ~repr
- auto_save = true;
- auto_save_delay = 10000;
- auto_save_name = "#","#";
+let automatic_tactics =
+ let init = ["trivial"; "tauto"; "auto"; "omega"; "auto with *"; "intuition" ] in
+ new preference ~name:["automatic_tactics"] ~init ~repr:Repr.(string_list)
- source_language = "coq";
- source_style = "coq_style";
+let cmd_print =
+ new preference ~name:["cmd_print"] ~init:"lpr" ~repr:Repr.(string)
- read_project = Append_args;
- project_file_name = "_CoqProject";
- project_path = None;
+let attach_modifiers (pref : string preference) prefix =
+ let cb mds =
+ let mds = str_to_mod_list mds in
+ let change ~path ~key ~modi ~changed =
+ if CString.is_sub prefix path 0 then
+ ignore (GtkData.AccelMap.change_entry ~key ~modi:mds ~replace:true path)
+ in
+ GtkData.AccelMap.foreach change
+ in
+ pref#connect#changed cb
- encoding = if Sys.os_type = "Win32" then Eutf8 else Elocale;
+let modifier_for_navigation =
+ new preference ~name:["modifier_for_navigation"] ~init:"<Control>" ~repr:Repr.(string)
- automatic_tactics = ["trivial"; "tauto"; "auto"; "omega";
- "auto with *"; "intuition" ];
+let modifier_for_templates =
+ new preference ~name:["modifier_for_templates"] ~init:"<Control><Shift>" ~repr:Repr.(string)
+
+let modifier_for_tactics =
+ new preference ~name:["modifier_for_tactics"] ~init:"<Control><Alt>" ~repr:Repr.(string)
- modifier_for_navigation = "<Control>";
- modifier_for_templates = "<Control><Shift>";
- modifier_for_tactics = "<Control><Alt>";
- modifier_for_display = "<Alt><Shift>";
- modifiers_valid = "<Alt><Control><Shift>";
+let modifier_for_display =
+ new preference ~name:["modifier_for_display"] ~init:"<Alt><Shift>" ~repr:Repr.(string)
+let _ = attach_modifiers modifier_for_navigation "<Actions>/Navigation/"
+let _ = attach_modifiers modifier_for_templates "<Actions>/Templates/"
+let _ = attach_modifiers modifier_for_tactics "<Actions>/Tactics/"
+let _ = attach_modifiers modifier_for_display "<Actions>/View/"
- cmd_browse = Flags.browser_cmd_fmt;
- cmd_editor = if Sys.os_type = "Win32" then "NOTEPAD %s" else "emacs %s";
+let modifiers_valid =
+ new preference ~name:["modifiers_valid"] ~init:"<Alt><Control><Shift>" ~repr:Repr.(string)
-(* text_font = Pango.Font.from_string "sans 12";*)
- text_font = Pango.Font.from_string (match Coq_config.gtk_platform with
- |`QUARTZ -> "Arial Unicode MS 11"
- |_ -> "Monospace 10");
+let cmd_browse =
+ new preference ~name:["cmd_browse"] ~init:Flags.browser_cmd_fmt ~repr:Repr.(string)
- doc_url = Coq_config.wwwrefman;
- library_url = Coq_config.wwwstdlib;
+let cmd_editor =
+ let init = if Sys.os_type = "Win32" then "NOTEPAD %s" else "emacs %s" in
+ new preference ~name:["cmd_editor"] ~init ~repr:Repr.(string)
- show_toolbar = true;
- contextual_menus_on_goal = true;
- window_width = 800;
- window_height = 600;
- query_window_width = 600;
- query_window_height = 400;
-(*
- use_utf8_notation = false;
-*)
- auto_complete = false;
- stop_before = true;
- reset_on_tab_switch = false;
- vertical_tabs = false;
- opposite_tabs = false;
-
- background_color = Tags.default_color;
- processed_color = Tags.default_processed_color;
- processing_color = Tags.default_processing_color;
- error_color = Tags.default_error_color;
- error_fg_color = Tags.default_error_fg_color;
-
- dynamic_word_wrap = false;
- show_line_number = false;
- auto_indent = false;
- show_spaces = true;
- show_right_margin = false;
- show_progress_bar = true;
- spaces_instead_of_tabs = true;
- tab_length = 2;
- highlight_current_line = false;
-
- nanoPG = false;
- }
+let text_font =
+ let init = match Coq_config.gtk_platform with
+ | `QUARTZ -> "Arial Unicode MS 11"
+ | _ -> "Monospace 10"
+ in
+ new preference ~name:["text_font"] ~init ~repr:Repr.(string)
+
+let doc_url =
+object
+ inherit [string] preference
+ ~name:["doc_url"] ~init:Coq_config.wwwrefman ~repr:Repr.(string)
+ as super
+
+ method set v =
+ if not (Flags.is_standard_doc_url v) &&
+ v <> use_default_doc_url &&
+ (* Extra hack to support links to last released doc version *)
+ v <> Coq_config.wwwcoq ^ "doc" &&
+ v <> Coq_config.wwwcoq ^ "doc/"
+ then super#set v
+
+end
+
+let library_url =
+ new preference ~name:["library_url"] ~init:Coq_config.wwwstdlib ~repr:Repr.(string)
+
+let show_toolbar =
+ new preference ~name:["show_toolbar"] ~init:true ~repr:Repr.(bool)
+
+let contextual_menus_on_goal =
+ new preference ~name:["contextual_menus_on_goal"] ~init:true ~repr:Repr.(bool)
+
+let window_width =
+ new preference ~name:["window_width"] ~init:800 ~repr:Repr.(int)
+
+let window_height =
+ new preference ~name:["window_height"] ~init:600 ~repr:Repr.(int)
+
+let auto_complete =
+ new preference ~name:["auto_complete"] ~init:false ~repr:Repr.(bool)
+
+let stop_before =
+ new preference ~name:["stop_before"] ~init:true ~repr:Repr.(bool)
+
+let reset_on_tab_switch =
+ new preference ~name:["reset_on_tab_switch"] ~init:false ~repr:Repr.(bool)
+
+let vertical_tabs =
+ new preference ~name:["vertical_tabs"] ~init:false ~repr:Repr.(bool)
+
+let opposite_tabs =
+ new preference ~name:["opposite_tabs"] ~init:false ~repr:Repr.(bool)
+
+let background_color =
+ new preference ~name:["background_color"] ~init:"cornsilk" ~repr:Repr.(string)
+
+let attach_bg (pref : string preference) (tag : GText.tag) =
+ pref#connect#changed (fun c -> tag#set_property (`BACKGROUND c))
+
+let attach_fg (pref : string preference) (tag : GText.tag) =
+ pref#connect#changed (fun c -> tag#set_property (`FOREGROUND c))
+
+let processing_color =
+ new preference ~name:["processing_color"] ~init:"light blue" ~repr:Repr.(string)
+
+let _ = attach_bg processing_color Tags.Script.to_process
+let _ = attach_bg processing_color Tags.Script.incomplete
+
+let default_tag = {
+ tag_fg_color = None;
+ tag_bg_color = None;
+ tag_bold = false;
+ tag_italic = false;
+ tag_underline = false;
+}
+
+let tags = ref Util.String.Map.empty
+
+let list_tags () = !tags
+
+let make_tag ?fg ?bg ?(bold = false) ?(italic = false) ?(underline = false) () = {
+ tag_fg_color = fg;
+ tag_bg_color = bg;
+ tag_bold = bold;
+ tag_italic = italic;
+ tag_underline = underline;
+}
+
+let create_tag name default =
+ let pref = new preference ~name:[name] ~init:default ~repr:Repr.(tag) in
+ let set_tag tag =
+ begin match pref#get.tag_bg_color with
+ | None -> tag#set_property (`BACKGROUND_SET false)
+ | Some c ->
+ tag#set_property (`BACKGROUND_SET true);
+ tag#set_property (`BACKGROUND c)
+ end;
+ begin match pref#get.tag_fg_color with
+ | None -> tag#set_property (`FOREGROUND_SET false)
+ | Some c ->
+ tag#set_property (`FOREGROUND_SET true);
+ tag#set_property (`FOREGROUND c)
+ end;
+ begin match pref#get.tag_bold with
+ | false -> tag#set_property (`WEIGHT_SET false)
+ | true ->
+ tag#set_property (`WEIGHT_SET true);
+ tag#set_property (`WEIGHT `BOLD)
+ end;
+ begin match pref#get.tag_italic with
+ | false -> tag#set_property (`STYLE_SET false)
+ | true ->
+ tag#set_property (`STYLE_SET true);
+ tag#set_property (`STYLE `ITALIC)
+ end;
+ begin match pref#get.tag_underline with
+ | false -> tag#set_property (`UNDERLINE_SET false)
+ | true ->
+ tag#set_property (`UNDERLINE_SET true);
+ tag#set_property (`UNDERLINE `SINGLE)
+ end;
+ in
+ let iter table =
+ let tag = GText.tag ~name () in
+ table#add tag#as_tag;
+ pref#connect#changed (fun _ -> set_tag tag);
+ set_tag tag;
+ in
+ List.iter iter [Tags.Script.table; Tags.Proof.table; Tags.Message.table];
+ tags := Util.String.Map.add name pref !tags
+
+let () =
+ let iter (name, tag) = create_tag name tag in
+ List.iter iter [
+ ("constr.evar", make_tag ());
+ ("constr.keyword", make_tag ~fg:"dark green" ());
+ ("constr.notation", make_tag ());
+ ("constr.path", make_tag ());
+ ("constr.reference", make_tag ~fg:"navy"());
+ ("constr.type", make_tag ~fg:"#008080" ());
+ ("constr.variable", make_tag ());
+ ("message.debug", make_tag ());
+ ("message.error", make_tag ());
+ ("message.warning", make_tag ());
+ ("module.definition", make_tag ~fg:"orange red" ~bold:true ());
+ ("module.keyword", make_tag ());
+ ("tactic.keyword", make_tag ());
+ ("tactic.primitive", make_tag ());
+ ("tactic.string", make_tag ());
+ ]
+
+let processed_color =
+ new preference ~name:["processed_color"] ~init:"light green" ~repr:Repr.(string)
+
+let _ = attach_bg processed_color Tags.Script.processed
+let _ = attach_bg processed_color Tags.Proof.highlight
+
+let error_color =
+ new preference ~name:["error_color"] ~init:"#FFCCCC" ~repr:Repr.(string)
+
+let _ = attach_bg error_color Tags.Script.error_bg
+
+let error_fg_color =
+ new preference ~name:["error_fg_color"] ~init:"red" ~repr:Repr.(string)
+
+let _ = attach_fg error_fg_color Tags.Script.error
+
+let dynamic_word_wrap =
+ new preference ~name:["dynamic_word_wrap"] ~init:false ~repr:Repr.(bool)
+
+let show_line_number =
+ new preference ~name:["show_line_number"] ~init:false ~repr:Repr.(bool)
+
+let auto_indent =
+ new preference ~name:["auto_indent"] ~init:false ~repr:Repr.(bool)
+
+let show_spaces =
+ new preference ~name:["show_spaces"] ~init:true ~repr:Repr.(bool)
+
+let show_right_margin =
+ new preference ~name:["show_right_margin"] ~init:false ~repr:Repr.(bool)
+
+let show_progress_bar =
+ new preference ~name:["show_progress_bar"] ~init:true ~repr:Repr.(bool)
+
+let spaces_instead_of_tabs =
+ new preference ~name:["spaces_instead_of_tabs"] ~init:true ~repr:Repr.(bool)
+
+let tab_length =
+ new preference ~name:["tab_length"] ~init:2 ~repr:Repr.(int)
+
+let highlight_current_line =
+ new preference ~name:["highlight_current_line"] ~init:false ~repr:Repr.(bool)
+
+let nanoPG =
+ new preference ~name:["nanoPG"] ~init:false ~repr:Repr.(bool)
+
+class tag_button (box : Gtk.box Gtk.obj) =
+object (self)
+
+ inherit GObj.widget box
+
+ val fg_color = GButton.color_button ()
+ val fg_unset = GButton.toggle_button ()
+ val bg_color = GButton.color_button ()
+ val bg_unset = GButton.toggle_button ()
+ val bold = GButton.toggle_button ()
+ val italic = GButton.toggle_button ()
+ val underline = GButton.toggle_button ()
+
+ method set_tag tag =
+ let track c but set = match c with
+ | None -> set#set_active true
+ | Some c ->
+ set#set_active false;
+ but#set_color (Tags.color_of_string c)
+ in
+ track tag.tag_bg_color bg_color bg_unset;
+ track tag.tag_fg_color fg_color fg_unset;
+ bold#set_active tag.tag_bold;
+ italic#set_active tag.tag_italic;
+ underline#set_active tag.tag_underline;
+
+ method tag =
+ let get but set =
+ if set#active then None
+ else Some (Tags.string_of_color but#color)
+ in
+ {
+ tag_bg_color = get bg_color bg_unset;
+ tag_fg_color = get fg_color fg_unset;
+ tag_bold = bold#active;
+ tag_italic = italic#active;
+ tag_underline = underline#active;
+ }
+
+ initializer
+ let box = new GPack.box box in
+ let set_stock button stock =
+ let stock = GMisc.image ~stock ~icon_size:`BUTTON () in
+ button#set_image stock#coerce
+ in
+ set_stock fg_unset `CANCEL;
+ set_stock bg_unset `CANCEL;
+ set_stock bold `BOLD;
+ set_stock italic `ITALIC;
+ set_stock underline `UNDERLINE;
+ box#pack fg_color#coerce;
+ box#pack fg_unset#coerce;
+ box#pack bg_color#coerce;
+ box#pack bg_unset#coerce;
+ box#pack bold#coerce;
+ box#pack italic#coerce;
+ box#pack underline#coerce;
+ let cb but obj = obj#set_sensitive (not but#active) in
+ let _ = fg_unset#connect#toggled (fun () -> cb fg_unset fg_color#misc) in
+ let _ = bg_unset#connect#toggled (fun () -> cb bg_unset bg_color#misc) in
+ ()
+
+end
+
+let tag_button () =
+ let box = GPack.hbox () in
+ new tag_button (Gobject.unsafe_cast box#as_widget)
+
+(** Old style preferences *)
let save_pref () =
if not (Sys.file_exists (Minilib.coqide_config_home ()))
then Unix.mkdir (Minilib.coqide_config_home ()) 0o700;
let () = try GtkData.AccelMap.save accel_file with _ -> () in
- let p = current in
-
- let add = Util.String.Map.add in
- let (++) x f = f x in
- Util.String.Map.empty ++
- add "cmd_coqtop" (match p.cmd_coqtop with | None -> [] | Some v-> [v]) ++
- add "cmd_coqc" [p.cmd_coqc] ++
- add "cmd_make" [p.cmd_make] ++
- add "cmd_coqmakefile" [p.cmd_coqmakefile] ++
- add "cmd_coqdoc" [p.cmd_coqdoc] ++
- add "source_language" [p.source_language] ++
- add "source_style" [p.source_style] ++
- add "global_auto_revert" [string_of_bool p.global_auto_revert] ++
- add "global_auto_revert_delay"
- [string_of_int p.global_auto_revert_delay] ++
- add "auto_save" [string_of_bool p.auto_save] ++
- add "auto_save_delay" [string_of_int p.auto_save_delay] ++
- add "auto_save_name" [fst p.auto_save_name; snd p.auto_save_name] ++
-
- add "project_options" [string_of_project_behavior p.read_project] ++
- add "project_file_name" [p.project_file_name] ++
- add "project_path" (match p.project_path with None -> [] | Some s -> [s]) ++
-
- add "encoding" [string_of_inputenc p.encoding] ++
-
- add "automatic_tactics" p.automatic_tactics ++
- add "cmd_print" [p.cmd_print] ++
- add "modifier_for_navigation" [p.modifier_for_navigation] ++
- add "modifier_for_templates" [p.modifier_for_templates] ++
- add "modifier_for_tactics" [p.modifier_for_tactics] ++
- add "modifier_for_display" [p.modifier_for_display] ++
- add "modifiers_valid" [p.modifiers_valid] ++
- add "cmd_browse" [p.cmd_browse] ++
- add "cmd_editor" [p.cmd_editor] ++
-
- add "text_font" [Pango.Font.to_string p.text_font] ++
-
- add "doc_url" [p.doc_url] ++
- add "library_url" [p.library_url] ++
- add "show_toolbar" [string_of_bool p.show_toolbar] ++
- add "contextual_menus_on_goal"
- [string_of_bool p.contextual_menus_on_goal] ++
- add "window_height" [string_of_int p.window_height] ++
- add "window_width" [string_of_int p.window_width] ++
- add "query_window_height" [string_of_int p.query_window_height] ++
- add "query_window_width" [string_of_int p.query_window_width] ++
- add "auto_complete" [string_of_bool p.auto_complete] ++
- add "stop_before" [string_of_bool p.stop_before] ++
- add "reset_on_tab_switch" [string_of_bool p.reset_on_tab_switch] ++
- add "vertical_tabs" [string_of_bool p.vertical_tabs] ++
- add "opposite_tabs" [string_of_bool p.opposite_tabs] ++
- add "background_color" [p.background_color] ++
- add "processing_color" [p.processing_color] ++
- add "processed_color" [p.processed_color] ++
- add "error_color" [p.error_color] ++
- add "error_fg_color" [p.error_fg_color] ++
- add "dynamic_word_wrap" [string_of_bool p.dynamic_word_wrap] ++
- add "show_line_number" [string_of_bool p.show_line_number] ++
- add "auto_indent" [string_of_bool p.auto_indent] ++
- add "show_spaces" [string_of_bool p.show_spaces] ++
- add "show_right_margin" [string_of_bool p.show_right_margin] ++
- add "show_progress_bar" [string_of_bool p.show_progress_bar] ++
- add "spaces_instead_of_tabs" [string_of_bool p.spaces_instead_of_tabs] ++
- add "tab_length" [string_of_int p.tab_length] ++
- add "highlight_current_line" [string_of_bool p.highlight_current_line] ++
- add "nanoPG" [string_of_bool p.nanoPG] ++
+ let add = Util.String.Map.add in
+ let (++) x f = f x in
+ let fold key obj accu = add key (obj.get ()) accu in
+
+ (Util.String.Map.fold fold !preferences Util.String.Map.empty) ++
Config_lexer.print_file pref_file
let load_pref () =
let () = try GtkData.AccelMap.load loaded_accel_file with _ -> () in
let m = Config_lexer.load_file loaded_pref_file in
- let np = current in
- let set k f = try let v = Util.String.Map.find k m in f v with _ -> () in
- let set_hd k f = set k (fun v -> f (List.hd v)) in
- let set_bool k f = set_hd k (fun v -> f (bool_of_string v)) in
- let set_int k f = set_hd k (fun v -> f (int_of_string v)) in
- let set_pair k f = set k (function [v1;v2] -> f v1 v2 | _ -> raise Exit) in
- let set_command_with_pair_compat k f =
- set k (function [v1;v2] -> f (v1^"%s"^v2) | [v] -> f v | _ -> raise Exit)
+ let iter name v =
+ try (Util.String.Map.find name !preferences).set v
+ with _ -> ()
in
- let set_option k f = set k (fun v -> f (match v with |[] -> None |h::_ -> Some h)) in
- set_option "cmd_coqtop" (fun v -> np.cmd_coqtop <- v);
- set_hd "cmd_coqc" (fun v -> np.cmd_coqc <- v);
- set_hd "cmd_make" (fun v -> np.cmd_make <- v);
- set_hd "cmd_coqmakefile" (fun v -> np.cmd_coqmakefile <- v);
- set_hd "cmd_coqdoc" (fun v -> np.cmd_coqdoc <- v);
- set_hd "source_language" (fun v -> np.source_language <- v);
- set_hd "source_style" (fun v -> np.source_style <- v);
- set_bool "global_auto_revert" (fun v -> np.global_auto_revert <- v);
- set_int "global_auto_revert_delay"
- (fun v -> np.global_auto_revert_delay <- v);
- set_bool "auto_save" (fun v -> np.auto_save <- v);
- set_int "auto_save_delay" (fun v -> np.auto_save_delay <- v);
- set_pair "auto_save_name" (fun v1 v2 -> np.auto_save_name <- (v1,v2));
- set_hd "encoding" (fun v -> np.encoding <- (inputenc_of_string v));
- set_hd "project_options"
- (fun v -> np.read_project <- (project_behavior_of_string v));
- set_hd "project_file_name" (fun v -> np.project_file_name <- v);
- set_option "project_path" (fun v -> np.project_path <- v);
- set "automatic_tactics"
- (fun v -> np.automatic_tactics <- v);
- set_hd "cmd_print" (fun v -> np.cmd_print <- v);
- set_hd "modifier_for_navigation"
- (fun v -> np.modifier_for_navigation <- v);
- set_hd "modifier_for_templates"
- (fun v -> np.modifier_for_templates <- v);
- set_hd "modifier_for_tactics"
- (fun v -> np.modifier_for_tactics <- v);
- set_hd "modifier_for_display"
- (fun v -> np.modifier_for_display <- v);
- set_hd "modifiers_valid"
- (fun v ->
- np.modifiers_valid <- v);
- set_command_with_pair_compat "cmd_browse" (fun v -> np.cmd_browse <- v);
- set_command_with_pair_compat "cmd_editor" (fun v -> np.cmd_editor <- v);
- set_hd "text_font" (fun v -> np.text_font <- Pango.Font.from_string v);
- set_hd "doc_url" (fun v ->
- if not (Flags.is_standard_doc_url v) &&
- v <> use_default_doc_url &&
- (* Extra hack to support links to last released doc version *)
- v <> Coq_config.wwwcoq ^ "doc" &&
- v <> Coq_config.wwwcoq ^ "doc/"
- then
- (* ("Warning: Non-standard URL for Coq documentation in preference file: "^v);*)
- np.doc_url <- v);
- set_hd "library_url" (fun v -> np.library_url <- v);
- set_bool "show_toolbar" (fun v -> np.show_toolbar <- v);
- set_bool "contextual_menus_on_goal"
- (fun v -> np.contextual_menus_on_goal <- v);
- set_int "window_width" (fun v -> np.window_width <- v);
- set_int "window_height" (fun v -> np.window_height <- v);
- set_int "query_window_width" (fun v -> np.query_window_width <- v);
- set_int "query_window_height" (fun v -> np.query_window_height <- v);
- set_bool "auto_complete" (fun v -> np.auto_complete <- v);
- set_bool "stop_before" (fun v -> np.stop_before <- v);
- set_bool "reset_on_tab_switch" (fun v -> np.reset_on_tab_switch <- v);
- set_bool "vertical_tabs" (fun v -> np.vertical_tabs <- v);
- set_bool "opposite_tabs" (fun v -> np.opposite_tabs <- v);
- set_hd "background_color" (fun v -> np.background_color <- v);
- set_hd "processing_color" (fun v -> np.processing_color <- v);
- set_hd "processed_color" (fun v -> np.processed_color <- v);
- set_hd "error_color" (fun v -> np.error_color <- v);
- set_hd "error_fg_color" (fun v -> np.error_fg_color <- v);
- set_bool "dynamic_word_wrap" (fun v -> np.dynamic_word_wrap <- v);
- set_bool "show_line_number" (fun v -> np.show_line_number <- v);
- set_bool "auto_indent" (fun v -> np.auto_indent <- v);
- set_bool "show_spaces" (fun v -> np.show_spaces <- v);
- set_bool "show_right_margin" (fun v -> np.show_right_margin <- v);
- set_bool "show_progress_bar" (fun v -> np.show_progress_bar <- v);
- set_bool "spaces_instead_of_tabs" (fun v -> np.spaces_instead_of_tabs <- v);
- set_int "tab_length" (fun v -> np.tab_length <- v);
- set_bool "highlight_current_line" (fun v -> np.highlight_current_line <- v);
- set_bool "nanoPG" (fun v -> np.nanoPG <- v);
- ()
+ Util.String.Map.iter iter m
+
+let pstring name p = string ~f:p#set name p#get
+let pbool name p = bool ~f:p#set name p#get
+let pmodifiers ?(all = false) name p = modifiers
+ ?allow:(if all then None else Some (str_to_mod_list modifiers_valid#get))
+ ~f:(fun l -> p#set (mod_list_to_str l))
+ ~help:"restart to apply"
+ name
+ (str_to_mod_list p#get)
let configure ?(apply=(fun () -> ())) () =
let cmd_coqtop =
string
- ~f:(fun s -> current.cmd_coqtop <- if s = "AUTO" then None else Some s)
- " coqtop" (match current.cmd_coqtop with |None -> "AUTO" | Some x -> x) in
- let cmd_coqc =
- string
- ~f:(fun s -> current.cmd_coqc <- s)
- " coqc" current.cmd_coqc in
- let cmd_make =
- string
- ~f:(fun s -> current.cmd_make <- s)
- " make" current.cmd_make in
- let cmd_coqmakefile =
- string
- ~f:(fun s -> current.cmd_coqmakefile <- s)
- "coqmakefile" current.cmd_coqmakefile in
- let cmd_coqdoc =
- string
- ~f:(fun s -> current.cmd_coqdoc <- s)
- " coqdoc" current.cmd_coqdoc in
- let cmd_print =
- string
- ~f:(fun s -> current.cmd_print <- s)
- " Print ps" current.cmd_print in
+ ~f:(fun s -> cmd_coqtop#set (if s = "AUTO" then None else Some s))
+ " coqtop" (match cmd_coqtop#get with |None -> "AUTO" | Some x -> x) in
+ let cmd_coqc = pstring " coqc" cmd_coqc in
+ let cmd_make = pstring " make" cmd_make in
+ let cmd_coqmakefile = pstring "coqmakefile" cmd_coqmakefile in
+ let cmd_coqdoc = pstring " coqdoc" cmd_coqdoc in
+ let cmd_print = pstring " Print ps" cmd_print in
let config_font =
let box = GPack.hbox () in
@@ -435,18 +633,13 @@ let configure ?(apply=(fun () -> ())) () =
"Goal (∃n : nat, n ≤ 0)∧(∀x,y,z, x∈y⋃z↔x∈y∨x∈z).";
box#pack ~expand:true w#coerce;
ignore (w#misc#connect#realize
- ~callback:(fun () -> w#set_font_name
- (Pango.Font.to_string current.text_font)));
+ ~callback:(fun () -> w#set_font_name text_font#get));
custom
~label:"Fonts for text"
box
(fun () ->
let fd = w#font_name in
- current.text_font <- (Pango.Font.from_string fd) ;
-(*
- Format.printf "in config_font: current.text_font = %s@." (Pango.Font.to_string current.text_font);
-*)
- !refresh_editor_hook ())
+ text_font#set fd)
true
in
@@ -458,121 +651,94 @@ let configure ?(apply=(fun () -> ())) () =
~border_width:2
~packing:(box#pack ~expand:true) ()
in
- let background_label = GMisc.label
- ~text:"Background color"
- ~packing:(table#attach ~expand:`X ~left:0 ~top:0) ()
- in
- let processed_label = GMisc.label
- ~text:"Background color of processed text"
- ~packing:(table#attach ~expand:`X ~left:0 ~top:1) ()
- in
- let processing_label = GMisc.label
- ~text:"Background color of text being processed"
- ~packing:(table#attach ~expand:`X ~left:0 ~top:2) ()
- in
- let error_label = GMisc.label
- ~text:"Background color of errors"
- ~packing:(table#attach ~expand:`X ~left:0 ~top:3) ()
- in
- let error_fg_label = GMisc.label
- ~text:"Foreground color of errors"
- ~packing:(table#attach ~expand:`X ~left:0 ~top:4) ()
- in
- let () = background_label#set_xalign 0. in
- let () = processed_label#set_xalign 0. in
- let () = processing_label#set_xalign 0. in
- let () = error_label#set_xalign 0. in
- let () = error_fg_label#set_xalign 0. in
- let background_button = GButton.color_button
- ~color:(Tags.color_of_string (current.background_color))
- ~packing:(table#attach ~left:1 ~top:0) ()
- in
- let processed_button = GButton.color_button
- ~color:(Tags.get_processed_color ())
- ~packing:(table#attach ~left:1 ~top:1) ()
- in
- let processing_button = GButton.color_button
- ~color:(Tags.get_processing_color ())
- ~packing:(table#attach ~left:1 ~top:2) ()
- in
- let error_button = GButton.color_button
- ~color:(Tags.get_error_color ())
- ~packing:(table#attach ~left:1 ~top:3) ()
- in
- let error_fg_button = GButton.color_button
- ~color:(Tags.get_error_fg_color ())
- ~packing:(table#attach ~left:1 ~top:4) ()
- in
let reset_button = GButton.button
~label:"Reset"
~packing:box#pack ()
in
- let reset_cb () =
- background_button#set_color Tags.(color_of_string default_color);
- processing_button#set_color Tags.(color_of_string default_processing_color);
- processed_button#set_color Tags.(color_of_string default_processed_color);
- error_button#set_color Tags.(color_of_string default_error_color);
+ let iter i (text, pref) =
+ let label = GMisc.label
+ ~text ~packing:(table#attach ~expand:`X ~left:0 ~top:i) ()
+ in
+ let () = label#set_xalign 0. in
+ let button = GButton.color_button
+ ~color:(Tags.color_of_string pref#get)
+ ~packing:(table#attach ~left:1 ~top:i) ()
+ in
+ let _ = button#connect#color_set begin fun () ->
+ pref#set (Tags.string_of_color button#color)
+ end in
+ let reset _ =
+ pref#reset ();
+ button#set_color Tags.(color_of_string pref#get)
+ in
+ let _ = reset_button#connect#clicked ~callback:reset in
+ ()
in
- let _ = reset_button#connect#clicked ~callback:reset_cb in
+ let () = Util.List.iteri iter [
+ ("Background color", background_color);
+ ("Background color of processed text", processed_color);
+ ("Background color of text being processed", processing_color);
+ ("Background color of errors", error_color);
+ ("Foreground color of errors", error_fg_color);
+ ] in
let label = "Color configuration" in
- let callback () =
- current.background_color <- Tags.string_of_color background_button#color;
- current.processing_color <- Tags.string_of_color processing_button#color;
- current.processed_color <- Tags.string_of_color processed_button#color;
- current.error_color <- Tags.string_of_color error_button#color;
- current.error_fg_color <- Tags.string_of_color error_fg_button#color;
- !refresh_editor_hook ();
- Tags.set_processing_color processing_button#color;
- Tags.set_processed_color processed_button#color;
- Tags.set_error_color error_button#color;
- Tags.set_error_fg_color error_fg_button#color
+ let callback () = () in
+ custom ~label box callback true
+ in
+
+ let config_tags =
+ let box = GPack.vbox () in
+ let scroll = GBin.scrolled_window
+ ~hpolicy:`NEVER
+ ~vpolicy:`AUTOMATIC
+ ~packing:(box#pack ~expand:true)
+ ()
+ in
+ let table = GPack.table
+ ~row_spacings:5
+ ~col_spacings:5
+ ~border_width:2
+ ~packing:scroll#add_with_viewport ()
in
+ let i = ref 0 in
+ let cb = ref [] in
+ let iter text tag =
+ let label = GMisc.label
+ ~text ~packing:(table#attach ~expand:`X ~left:0 ~top:!i) ()
+ in
+ let () = label#set_xalign 0. in
+ let button = tag_button () in
+ let callback () = tag#set button#tag in
+ button#set_tag tag#get;
+ table#attach ~left:1 ~top:!i button#coerce;
+ incr i;
+ cb := callback :: !cb;
+ in
+ let () = Util.String.Map.iter iter !tags in
+ let label = "Tag configuration" in
+ let callback () = List.iter (fun f -> f ()) !cb in
custom ~label box callback true
in
let config_editor =
let label = "Editor configuration" in
let box = GPack.vbox () in
- let gen_button text active =
- GButton.check_button ~label:text ~active ~packing:box#pack () in
- let wrap = gen_button "Dynamic word wrap" current.dynamic_word_wrap in
- let line = gen_button "Show line number" current.show_line_number in
- let auto_indent = gen_button "Auto indentation" current.auto_indent in
- let auto_complete = gen_button "Auto completion" current.auto_complete in
- let show_spaces = gen_button "Show spaces" current.show_spaces in
- let show_right_margin = gen_button "Show right margin" current.show_right_margin in
- let show_progress_bar = gen_button "Show progress bar" current.show_progress_bar in
- let spaces_instead_of_tabs =
- gen_button "Insert spaces instead of tabs"
- current.spaces_instead_of_tabs
- in
- let highlight_current_line =
- gen_button "Highlight current line"
- current.highlight_current_line
- in
- let nanoPG = gen_button "Emacs/PG keybindings (μPG mode)" current.nanoPG in
-(* let lbox = GPack.hbox ~packing:box#pack () in *)
-(* let _ = GMisc.label ~text:"Tab width" *)
-(* ~xalign:0. *)
-(* ~packing:(lbox#pack ~expand:true) () *)
-(* in *)
-(* let tab_width = GEdit.spin_button *)
-(* ~digits:0 ~packing:lbox#pack () *)
-(* in *)
- let callback () =
- current.dynamic_word_wrap <- wrap#active;
- current.show_line_number <- line#active;
- current.auto_indent <- auto_indent#active;
- current.show_spaces <- show_spaces#active;
- current.show_right_margin <- show_right_margin#active;
- current.show_progress_bar <- show_progress_bar#active;
- current.spaces_instead_of_tabs <- spaces_instead_of_tabs#active;
- current.highlight_current_line <- highlight_current_line#active;
- current.nanoPG <- nanoPG#active;
- current.auto_complete <- auto_complete#active;
-(* current.tab_length <- tab_width#value_as_int; *)
- !refresh_editor_hook ()
+ let button text (pref : bool preference) =
+ let active = pref#get in
+ let but = GButton.check_button ~label:text ~active ~packing:box#pack () in
+ ignore (but#connect#toggled (fun () -> pref#set but#active))
in
+ let () = button "Dynamic word wrap" dynamic_word_wrap in
+ let () = button "Show line number" show_line_number in
+ let () = button "Auto indentation" auto_indent in
+ let () = button "Auto completion" auto_complete in
+ let () = button "Show spaces" show_spaces in
+ let () = button "Show right margin" show_right_margin in
+ let () = button "Show progress bar" show_progress_bar in
+ let () = button "Insert spaces instead of tabs" spaces_instead_of_tabs in
+ let () = button "Highlight current line" highlight_current_line in
+ let () = button "Emacs/PG keybindings (μPG mode)" nanoPG in
+ let callback () = () in
custom ~label box callback true
in
@@ -600,177 +766,98 @@ let configure ?(apply=(fun () -> ())) () =
(string_of_int current.window_width)
in
*)
-(* let use_utf8_notation =
- bool
- ~f:(fun b ->
- current.use_utf8_notation <- b;
- )
- "Use Unicode Notation: " current.use_utf8_notation
- in
-*)
(*
let config_appearance = [show_toolbar; window_width; window_height] in
*)
- let global_auto_revert =
- bool
- ~f:(fun s -> current.global_auto_revert <- s)
- "Enable global auto revert" current.global_auto_revert
- in
+ let global_auto_revert = pbool "Enable global auto revert" global_auto_revert in
let global_auto_revert_delay =
string
- ~f:(fun s -> current.global_auto_revert_delay <-
+ ~f:(fun s -> global_auto_revert_delay#set
(try int_of_string s with _ -> 10000))
"Global auto revert delay (ms)"
- (string_of_int current.global_auto_revert_delay)
+ (string_of_int global_auto_revert_delay#get)
in
- let auto_save =
- bool
- ~f:(fun s -> current.auto_save <- s)
- "Enable auto save" current.auto_save
- in
+ let auto_save = pbool "Enable auto save" auto_save in
let auto_save_delay =
string
- ~f:(fun s -> current.auto_save_delay <-
+ ~f:(fun s -> auto_save_delay#set
(try int_of_string s with _ -> 10000))
"Auto save delay (ms)"
- (string_of_int current.auto_save_delay)
+ (string_of_int auto_save_delay#get)
in
- let stop_before =
- bool
- ~f:(fun s -> current.stop_before <- s)
- "Stop interpreting before the current point" current.stop_before
- in
+ let stop_before = pbool "Stop interpreting before the current point" stop_before in
- let reset_on_tab_switch =
- bool
- ~f:(fun s -> current.reset_on_tab_switch <- s)
- "Reset coqtop on tab switch" current.reset_on_tab_switch
- in
+ let reset_on_tab_switch = pbool "Reset coqtop on tab switch" reset_on_tab_switch in
- let vertical_tabs =
- bool
- ~f:(fun s -> current.vertical_tabs <- s; !refresh_tabs_hook ())
- "Vertical tabs" current.vertical_tabs
- in
+ let vertical_tabs = pbool "Vertical tabs" vertical_tabs in
- let opposite_tabs =
- bool
- ~f:(fun s -> current.opposite_tabs <- s; !refresh_tabs_hook ())
- "Tabs on opposite side" current.opposite_tabs
- in
+ let opposite_tabs = pbool "Tabs on opposite side" opposite_tabs in
let encodings =
combo
"File charset encoding "
- ~f:(fun s -> current.encoding <- (inputenc_of_string s))
+ ~f:(fun s -> encoding#set (inputenc_of_string s))
~new_allowed: true
- ("UTF-8"::"LOCALE":: match current.encoding with
+ ("UTF-8"::"LOCALE":: match encoding#get with
|Emanual s -> [s]
|_ -> []
)
- (string_of_inputenc current.encoding)
+ (string_of_inputenc encoding#get)
in
let source_style =
- let f s =
- current.source_style <- s;
- !refresh_style_hook ()
- in
combo "Highlighting style:"
- ~f ~new_allowed:false
- style_manager#style_scheme_ids current.source_style
+ ~f:source_style#set ~new_allowed:false
+ style_manager#style_scheme_ids source_style#get
in
let source_language =
- let f s =
- current.source_language <- s;
- !refresh_language_hook ()
- in
combo "Language:"
- ~f ~new_allowed:false
+ ~f:source_language#set ~new_allowed:false
(List.filter
(fun x -> Str.string_match (Str.regexp "^coq") x 0)
lang_manager#language_ids)
- current.source_language
+ source_language#get
in
let read_project =
combo
"Project file options are"
- ~f:(fun s -> current.read_project <- project_behavior_of_string s)
+ ~f:(fun s -> read_project#set (project_behavior_of_string s))
~editable:false
[string_of_project_behavior Subst_args;
string_of_project_behavior Append_args;
string_of_project_behavior Ignore_args]
- (string_of_project_behavior current.read_project)
- in
- let project_file_name =
- string "Default name for project file"
- ~f:(fun s -> current.project_file_name <- s)
- current.project_file_name
- in
- let help_string =
- "restart to apply"
+ (string_of_project_behavior read_project#get)
in
- let the_valid_mod = str_to_mod_list current.modifiers_valid in
+ let project_file_name = pstring "Default name for project file" project_file_name in
let modifier_for_tactics =
- modifiers
- ~allow:the_valid_mod
- ~f:(fun l -> current.modifier_for_tactics <- mod_list_to_str l)
- ~help:help_string
- "Modifiers for Tactics Menu"
- (str_to_mod_list current.modifier_for_tactics)
+ pmodifiers "Modifiers for Tactics Menu" modifier_for_tactics
in
let modifier_for_templates =
- modifiers
- ~allow:the_valid_mod
- ~f:(fun l -> current.modifier_for_templates <- mod_list_to_str l)
- ~help:help_string
- "Modifiers for Templates Menu"
- (str_to_mod_list current.modifier_for_templates)
+ pmodifiers "Modifiers for Templates Menu" modifier_for_templates
in
let modifier_for_navigation =
- modifiers
- ~allow:the_valid_mod
- ~f:(fun l -> current.modifier_for_navigation <- mod_list_to_str l)
- ~help:help_string
- "Modifiers for Navigation Menu"
- (str_to_mod_list current.modifier_for_navigation)
+ pmodifiers "Modifiers for Navigation Menu" modifier_for_navigation
in
let modifier_for_display =
- modifiers
- ~allow:the_valid_mod
- ~f:(fun l -> current.modifier_for_display <- mod_list_to_str l)
- ~help:help_string
- "Modifiers for View Menu"
- (str_to_mod_list current.modifier_for_display)
+ pmodifiers "Modifiers for View Menu" modifier_for_display
in
let modifiers_valid =
- modifiers
- ~f:(fun l ->
- current.modifiers_valid <- mod_list_to_str l)
- "Allowed modifiers"
- the_valid_mod
- in
- let modifier_notice =
- let b = GPack.hbox () in
- let _lbl =
- GMisc.label ~markup:"You need to <b>restart CoqIDE</b> after changing these settings"
- ~packing:b#add () in
- custom b (fun () -> ()) true
+ pmodifiers ~all:true "Allowed modifiers" modifiers_valid
in
let cmd_editor =
let predefined = [ "emacs %s"; "vi %s"; "NOTEPAD %s" ] in
combo
~help:"(%s for file name)"
"External editor"
- ~f:(fun s -> current.cmd_editor <- s)
+ ~f:cmd_editor#set
~new_allowed: true
- (predefined@[if List.mem current.cmd_editor predefined then ""
- else current.cmd_editor])
- current.cmd_editor
+ (predefined@[if List.mem cmd_editor#get predefined then ""
+ else cmd_editor#get])
+ cmd_editor#get
in
let cmd_browse =
let predefined = [
@@ -783,11 +870,11 @@ let configure ?(apply=(fun () -> ())) () =
combo
~help:"(%s for url)"
"Browser"
- ~f:(fun s -> current.cmd_browse <- s)
+ ~f:cmd_browse#set
~new_allowed: true
- (predefined@[if List.mem current.cmd_browse predefined then ""
- else current.cmd_browse])
- current.cmd_browse
+ (predefined@[if List.mem cmd_browse#get predefined then ""
+ else cmd_browse#get])
+ cmd_browse#get
in
let doc_url =
let predefined = [
@@ -797,11 +884,11 @@ let configure ?(apply=(fun () -> ())) () =
] in
combo
"Manual URL"
- ~f:(fun s -> current.doc_url <- s)
+ ~f:doc_url#set
~new_allowed: true
- (predefined@[if List.mem current.doc_url predefined then ""
- else current.doc_url])
- current.doc_url in
+ (predefined@[if List.mem doc_url#get predefined then ""
+ else doc_url#get])
+ doc_url#get in
let library_url =
let predefined = [
"file://"^(List.fold_left Filename.concat (Coq_config.docdir) ["html";"stdlib";""]);
@@ -809,28 +896,22 @@ let configure ?(apply=(fun () -> ())) () =
] in
combo
"Library URL"
- ~f:(fun s -> current.library_url <- s)
+ ~f:(fun s -> library_url#set s)
~new_allowed: true
- (predefined@[if List.mem current.library_url predefined then ""
- else current.library_url])
- current.library_url
+ (predefined@[if List.mem library_url#get predefined then ""
+ else library_url#get])
+ library_url#get
in
let automatic_tactics =
strings
- ~f:(fun l -> current.automatic_tactics <- l)
+ ~f:automatic_tactics#set
~add:(fun () -> ["<edit me>"])
"Wizard tactics to try in order"
- current.automatic_tactics
+ automatic_tactics#get
in
- let contextual_menus_on_goal =
- bool
- ~f:(fun s ->
- current.contextual_menus_on_goal <- s;
- !contextual_menus_on_goal_hook s)
- "Contextual menus on goal" current.contextual_menus_on_goal
- in
+ let contextual_menus_on_goal = pbool "Contextual menus on goal" contextual_menus_on_goal in
let misc = [contextual_menus_on_goal;stop_before;reset_on_tab_switch;
vertical_tabs;opposite_tabs] in
@@ -842,6 +923,8 @@ let configure ?(apply=(fun () -> ())) () =
[config_font]);
Section("Colors", Some `SELECT_COLOR,
[config_color; source_language; source_style]);
+ Section("Tags", Some `SELECT_COLOR,
+ [config_tags]);
Section("Editor", Some `EDIT, [config_editor]);
Section("Files", Some `DIRECTORY,
[global_auto_revert;global_auto_revert_delay;
@@ -862,7 +945,7 @@ let configure ?(apply=(fun () -> ())) () =
[automatic_tactics]);
Section("Shortcuts", Some `PREFERENCES,
[modifiers_valid; modifier_for_tactics;
- modifier_for_templates; modifier_for_display; modifier_for_navigation; modifier_notice]);
+ modifier_for_templates; modifier_for_display; modifier_for_navigation]);
Section("Misc", Some `ADD,
misc)]
in
diff --git a/ide/preferences.mli b/ide/preferences.mli
index 4095eb668..1733091a5 100644
--- a/ide/preferences.mli
+++ b/ide/preferences.mli
@@ -12,95 +12,96 @@ val style_manager : GSourceView2.source_style_scheme_manager
type project_behavior = Ignore_args | Append_args | Subst_args
type inputenc = Elocale | Eutf8 | Emanual of string
-type pref =
- {
- mutable cmd_coqtop : string option;
- mutable cmd_coqc : string;
- mutable cmd_make : string;
- mutable cmd_coqmakefile : string;
- mutable cmd_coqdoc : string;
-
- mutable source_language : string;
- mutable source_style : string;
-
- mutable global_auto_revert : bool;
- mutable global_auto_revert_delay : int;
-
- mutable auto_save : bool;
- mutable auto_save_delay : int;
- mutable auto_save_name : string * string;
-
- mutable read_project : project_behavior;
- mutable project_file_name : string;
- mutable project_path : string option;
-
- mutable encoding : inputenc;
-
- mutable automatic_tactics : string list;
- mutable cmd_print : string;
-
- mutable modifier_for_navigation : string;
- mutable modifier_for_templates : string;
- mutable modifier_for_tactics : string;
- mutable modifier_for_display : string;
- mutable modifiers_valid : string;
-
- mutable cmd_browse : string;
- mutable cmd_editor : string;
-
- mutable text_font : Pango.font_description;
-
- mutable doc_url : string;
- mutable library_url : string;
-
- mutable show_toolbar : bool;
- mutable contextual_menus_on_goal : bool;
- mutable window_width : int;
- mutable window_height : int;
- mutable query_window_width : int;
- mutable query_window_height : int;
-(*
- mutable use_utf8_notation : bool;
-*)
- mutable auto_complete : bool;
- mutable stop_before : bool;
- mutable reset_on_tab_switch : bool;
- mutable vertical_tabs : bool;
- mutable opposite_tabs : bool;
-
- mutable background_color : string;
- mutable processing_color : string;
- mutable processed_color : string;
- mutable error_color : string;
- mutable error_fg_color : string;
-
- mutable dynamic_word_wrap : bool;
- mutable show_line_number : bool;
- mutable auto_indent : bool;
- mutable show_spaces : bool;
- mutable show_right_margin : bool;
- mutable show_progress_bar : bool;
- mutable spaces_instead_of_tabs : bool;
- mutable tab_length : int;
- mutable highlight_current_line : bool;
-
- mutable nanoPG : bool;
-
- }
+type tag = {
+ tag_fg_color : string option;
+ tag_bg_color : string option;
+ tag_bold : bool;
+ tag_italic : bool;
+ tag_underline : bool;
+}
+
+class type ['a] repr =
+object
+ method into : string list -> 'a option
+ method from : 'a -> string list
+end
+
+class ['a] preference_signals : changed:'a GUtil.signal ->
+object
+ inherit GUtil.ml_signals
+ method changed : callback:('a -> unit) -> GtkSignal.id
+end
+
+class ['a] preference : name:string list -> init:'a -> repr:'a repr ->
+object
+ method connect : 'a preference_signals
+ method get : 'a
+ method set : 'a -> unit
+ method reset : unit -> unit
+ method default : 'a
+end
+
+val list_tags : unit -> tag preference Util.String.Map.t
+
+val cmd_coqtop : string option preference
+val cmd_coqc : string preference
+val cmd_make : string preference
+val cmd_coqmakefile : string preference
+val cmd_coqdoc : string preference
+val source_language : string preference
+val source_style : string preference
+val global_auto_revert : bool preference
+val global_auto_revert_delay : int preference
+val auto_save : bool preference
+val auto_save_delay : int preference
+val auto_save_name : (string * string) preference
+val read_project : project_behavior preference
+val project_file_name : string preference
+val project_path : string option preference
+val encoding : inputenc preference
+val automatic_tactics : string list preference
+val cmd_print : string preference
+val modifier_for_navigation : string preference
+val modifier_for_templates : string preference
+val modifier_for_tactics : string preference
+val modifier_for_display : string preference
+val modifiers_valid : string preference
+val cmd_browse : string preference
+val cmd_editor : string preference
+val text_font : string preference
+val doc_url : string preference
+val library_url : string preference
+val show_toolbar : bool preference
+val contextual_menus_on_goal : bool preference
+val window_width : int preference
+val window_height : int preference
+val auto_complete : bool preference
+val stop_before : bool preference
+val reset_on_tab_switch : bool preference
+val vertical_tabs : bool preference
+val opposite_tabs : bool preference
+val background_color : string preference
+val processing_color : string preference
+val processed_color : string preference
+val error_color : string preference
+val error_fg_color : string preference
+val dynamic_word_wrap : bool preference
+val show_line_number : bool preference
+val auto_indent : bool preference
+val show_spaces : bool preference
+val show_right_margin : bool preference
+val show_progress_bar : bool preference
+val spaces_instead_of_tabs : bool preference
+val tab_length : int preference
+val highlight_current_line : bool preference
+val nanoPG : bool preference
val save_pref : unit -> unit
val load_pref : unit -> unit
-val current : pref
-
val configure : ?apply:(unit -> unit) -> unit -> unit
-(* Hooks *)
-val refresh_editor_hook : (unit -> unit) ref
-val refresh_style_hook : (unit -> unit) ref
-val refresh_language_hook : (unit -> unit) ref
-val refresh_toolbar_hook : (unit -> unit) ref
-val resize_window_hook : (unit -> unit) ref
-val refresh_tabs_hook : (unit -> unit) ref
+val stick : 'a preference ->
+ (#GObj.widget as 'obj) -> ('a -> unit) -> unit
val use_default_doc_url : string
diff --git a/ide/project_file.ml4 b/ide/project_file.ml4
index 07ab5344d..081094e2b 100644
--- a/ide/project_file.ml4
+++ b/ide/project_file.ml4
@@ -86,7 +86,6 @@ let rec process_cmd_line orig_dir ((project_file,makefile,install,opt) as opts)
process_cmd_line orig_dir opts ((Include (CUnix.correct_path d orig_dir, lp)) :: l) r
| "-I" :: d :: r ->
process_cmd_line orig_dir opts ((MLInclude (CUnix.correct_path d orig_dir)) :: l) r
- | "-R" :: p :: "-as" :: lp :: r
| "-R" :: p :: lp :: r ->
process_cmd_line orig_dir opts (RInclude (CUnix.correct_path p orig_dir,lp) :: l) r
| ("-Q"|"-R"|"-I"|"-custom"|"-extra"|"-extra-phony") :: _ ->
@@ -139,48 +138,44 @@ let rec post_canonize f =
else f
(* Return: ((v,(mli,ml4,ml,mllib,mlpack),special,subdir),(ml_inc,q_inc,r_inc),(args,defs)) *)
-let split_arguments =
- let rec aux = function
- | V n :: r ->
- let (v,m,o,s),i,d = aux r in ((CUnix.remove_path_dot n::v,m,o,s),i,d)
- | ML n :: r ->
- let (v,(mli,ml4,ml,mllib,mlpack),o,s),i,d = aux r in
- ((v,(mli,ml4,CUnix.remove_path_dot n::ml,mllib,mlpack),o,s),i,d)
- | MLI n :: r ->
- let (v,(mli,ml4,ml,mllib,mlpack),o,s),i,d = aux r in
- ((v,(CUnix.remove_path_dot n::mli,ml4,ml,mllib,mlpack),o,s),i,d)
- | ML4 n :: r ->
- let (v,(mli,ml4,ml,mllib,mlpack),o,s),i,d = aux r in
- ((v,(mli,CUnix.remove_path_dot n::ml4,ml,mllib,mlpack),o,s),i,d)
- | MLLIB n :: r ->
- let (v,(mli,ml4,ml,mllib,mlpack),o,s),i,d = aux r in
- ((v,(mli,ml4,ml,CUnix.remove_path_dot n::mllib,mlpack),o,s),i,d)
- | MLPACK n :: r ->
- let (v,(mli,ml4,ml,mllib,mlpack),o,s),i,d = aux r in
- ((v,(mli,ml4,ml,mllib,CUnix.remove_path_dot n::mlpack),o,s),i,d)
- | Special (n,dep,is_phony,c) :: r ->
- let (v,m,o,s),i,d = aux r in ((v,m,(n,dep,is_phony,c)::o,s),i,d)
- | Subdir n :: r ->
- let (v,m,o,s),i,d = aux r in ((v,m,o,n::s),i,d)
- | MLInclude p :: r ->
- let t,(ml,q,r),d = aux r in (t,((CUnix.remove_path_dot (post_canonize p),
- CUnix.canonical_path_name p)::ml,q,r),d)
- | Include (p,l) :: r ->
- let t,(ml,i,r),d = aux r in
- let i_new = (CUnix.remove_path_dot (post_canonize p),l,
- CUnix.canonical_path_name p) in
- (t,(ml,i_new::i,r),d)
- | RInclude (p,l) :: r ->
- let t,(ml,i,r),d = aux r in
- let r_new = (CUnix.remove_path_dot (post_canonize p),l,
- CUnix.canonical_path_name p) in
- (t,(ml,i,r_new::r),d)
- | Def (v,def) :: r ->
- let t,i,(args,defs) = aux r in (t,i,(args,(v,def)::defs))
- | Arg a :: r ->
- let t,i,(args,defs) = aux r in (t,i,(a::args,defs))
- | [] -> ([],([],[],[],[],[]),[],[]),([],[],[]),([],[])
- in aux
+let split_arguments args =
+ List.fold_right
+ (fun a ((v,(mli,ml4,ml,mllib,mlpack as m),o,s as t),
+ (ml_inc,q_inc,r_inc as i),(args,defs as d)) ->
+ match a with
+ | V n ->
+ ((CUnix.remove_path_dot n::v,m,o,s),i,d)
+ | ML n ->
+ ((v,(mli,ml4,CUnix.remove_path_dot n::ml,mllib,mlpack),o,s),i,d)
+ | MLI n ->
+ ((v,(CUnix.remove_path_dot n::mli,ml4,ml,mllib,mlpack),o,s),i,d)
+ | ML4 n ->
+ ((v,(mli,CUnix.remove_path_dot n::ml4,ml,mllib,mlpack),o,s),i,d)
+ | MLLIB n ->
+ ((v,(mli,ml4,ml,CUnix.remove_path_dot n::mllib,mlpack),o,s),i,d)
+ | MLPACK n ->
+ ((v,(mli,ml4,ml,mllib,CUnix.remove_path_dot n::mlpack),o,s),i,d)
+ | Special (n,dep,is_phony,c) ->
+ ((v,m,(n,dep,is_phony,c)::o,s),i,d)
+ | Subdir n ->
+ ((v,m,o,n::s),i,d)
+ | MLInclude p ->
+ let ml_new = (CUnix.remove_path_dot (post_canonize p),
+ CUnix.canonical_path_name p) in
+ (t,(ml_new::ml_inc,q_inc,r_inc),d)
+ | Include (p,l) ->
+ let q_new = (CUnix.remove_path_dot (post_canonize p),l,
+ CUnix.canonical_path_name p) in
+ (t,(ml_inc,q_new::q_inc,r_inc),d)
+ | RInclude (p,l) ->
+ let r_new = (CUnix.remove_path_dot (post_canonize p),l,
+ CUnix.canonical_path_name p) in
+ (t,(ml_inc,q_inc,r_new::r_inc),d)
+ | Def (v,def) ->
+ (t,i,(args,(v,def)::defs))
+ | Arg a ->
+ (t,i,(a::args,defs)))
+ args (([],([],[],[],[],[]),[],[]),([],[],[]),([],[]))
let read_project_file f =
split_arguments
diff --git a/ide/sentence.ml b/ide/sentence.ml
index 0f6c1168d..6897779e8 100644
--- a/ide/sentence.ml
+++ b/ide/sentence.ml
@@ -63,13 +63,13 @@ let grab_sentence_start (iter:GText.iter) soi =
(** Search forward the first character immediately after a sentence end *)
-let rec grab_sentence_stop (start:GText.iter) =
+let grab_sentence_stop (start:GText.iter) =
(forward_search is_sentence_end start)#forward_char
(** Search forward the first character immediately after a "." sentence end
(and not just a "\{" or "\}" or comment end *)
-let rec grab_ending_dot (start:GText.iter) =
+let grab_ending_dot (start:GText.iter) =
let is_ending_dot s = is_sentence_end s && s#char = Char.code '.' in
(forward_search is_ending_dot start)#forward_char
diff --git a/ide/session.ml b/ide/session.ml
index 34c533b8e..058a422b9 100644
--- a/ide/session.ml
+++ b/ide/session.ml
@@ -8,8 +8,6 @@
open Preferences
-let prefs = Preferences.current
-
(** A session is a script buffer + proof + messages,
interacting with a coqtop, and a few other elements around *)
@@ -18,7 +16,6 @@ class type ['a] page =
inherit GObj.widget
method update : 'a -> unit
method on_update : callback:('a -> unit) -> unit
- method refresh_color : unit -> unit
end
class type control =
@@ -50,8 +47,8 @@ let create_buffer () =
let buffer = GSourceView2.source_buffer
~tag_table:Tags.Script.table
~highlight_matching_brackets:true
- ?language:(lang_manager#language prefs.source_language)
- ?style_scheme:(style_manager#style_scheme prefs.source_style)
+ ?language:(lang_manager#language source_language#get)
+ ?style_scheme:(style_manager#style_scheme source_style#get)
()
in
let _ = buffer#create_mark ~name:"start_of_input" buffer#start_iter in
@@ -254,10 +251,9 @@ let make_table_widget ?sort cd cb =
~model:store ~packing:frame#add () in
let () = data#set_headers_visible true in
let () = data#set_headers_clickable true in
- let refresh () =
- let clr = Tags.color_of_string current.background_color in
- data#misc#modify_base [`NORMAL, `COLOR clr]
- in
+ let refresh clr = data#misc#modify_base [`NORMAL, `NAME clr] in
+ let _ = background_color#connect#changed refresh in
+ let _ = data#misc#connect#realize (fun () -> refresh background_color#get) in
let mk_rend c = GTree.cell_renderer_text [], ["text",c] in
let cols =
List.map2 (fun (_,c) (_,n,v) ->
@@ -285,10 +281,10 @@ let make_table_widget ?sort cd cb =
data#connect#row_activated ~callback:(fun tp vc -> cb columns store tp vc)
);
let () = match sort with None -> () | Some (i, t) -> store#set_sort_column_id i t in
- frame, (fun f -> f columns store), refresh
+ frame, (fun f -> f columns store)
let create_errpage (script : Wg_ScriptView.script_view) : errpage =
- let table, access, refresh =
+ let table, access =
make_table_widget ~sort:(0, `ASCENDING)
[`Int,"Line",true; `String,"Error message",true]
(fun columns store tp vc ->
@@ -320,11 +316,10 @@ let create_errpage (script : Wg_ScriptView.script_view) : errpage =
errs
end
method on_update ~callback:cb = callback := cb
- method refresh_color () = refresh ()
end
let create_jobpage coqtop coqops : jobpage =
- let table, access, refresh =
+ let table, access =
make_table_widget ~sort:(0, `ASCENDING)
[`String,"Worker",true; `String,"Job name",true]
(fun columns store tp vc ->
@@ -360,7 +355,6 @@ let create_jobpage coqtop coqops : jobpage =
jobs
end
method on_update ~callback:cb = callback := cb
- method refresh_color () = refresh ()
end
let create_proof () =
diff --git a/ide/session.mli b/ide/session.mli
index 0881e4039..8f7c79bec 100644
--- a/ide/session.mli
+++ b/ide/session.mli
@@ -14,7 +14,6 @@ class type ['a] page =
inherit GObj.widget
method update : 'a -> unit
method on_update : callback:('a -> unit) -> unit
- method refresh_color : unit -> unit
end
class type control =
diff --git a/ide/tags.ml b/ide/tags.ml
index 0e4ab96d7..9ccff9fb5 100644
--- a/ide/tags.ml
+++ b/ide/tags.ml
@@ -13,28 +13,15 @@ let make_tag (tt:GText.tag_table) ~name prop =
tt#add new_tag#as_tag;
new_tag
-(* These work fine for colorblind people too *)
-let default_processed_color = "light green"
-let default_processing_color = "light blue"
-let default_error_color = "#FFCCCC"
-let default_error_fg_color = "red"
-let default_color = "cornsilk"
-
-let processed_color = ref default_processed_color
-let processing_color = ref default_processing_color
-let error_color = ref default_error_color
-let error_fg_color = ref default_error_fg_color
-
module Script =
struct
let table = GText.tag_table ()
let comment = make_tag table ~name:"comment" []
- let error = make_tag table ~name:"error" [`UNDERLINE `SINGLE ; `FOREGROUND !error_fg_color]
- let error_bg = make_tag table ~name:"error_bg" [`BACKGROUND !error_color]
- let to_process = make_tag table ~name:"to_process" [`BACKGROUND !processing_color]
- let processed = make_tag table ~name:"processed" [`BACKGROUND !processed_color]
+ let error = make_tag table ~name:"error" [`UNDERLINE `SINGLE]
+ let error_bg = make_tag table ~name:"error_bg" []
+ let to_process = make_tag table ~name:"to_process" []
+ let processed = make_tag table ~name:"processed" []
let incomplete = make_tag table ~name:"incomplete" [
- `BACKGROUND !processing_color;
`BACKGROUND_STIPPLE_SET true;
]
let unjustified = make_tag table ~name:"unjustified" [`BACKGROUND "gold"]
@@ -56,7 +43,7 @@ end
module Proof =
struct
let table = GText.tag_table ()
- let highlight = make_tag table ~name:"highlight" [`BACKGROUND !processed_color]
+ let highlight = make_tag table ~name:"highlight" []
let hypothesis = make_tag table ~name:"hypothesis" []
let goal = make_tag table ~name:"goal" []
end
@@ -77,34 +64,3 @@ let string_of_color clr =
let color_of_string s =
let colormap = Gdk.Color.get_system_colormap () in
Gdk.Color.alloc ~colormap (`NAME s)
-
-let get_processed_color () = color_of_string !processed_color
-
-let set_processed_color clr =
- let s = string_of_color clr in
- processed_color := s;
- Script.processed#set_property (`BACKGROUND s);
- Proof.highlight#set_property (`BACKGROUND s)
-
-let get_processing_color () = color_of_string !processing_color
-
-let set_processing_color clr =
- let s = string_of_color clr in
- processing_color := s;
- Script.incomplete#set_property (`BACKGROUND s);
- Script.to_process#set_property (`BACKGROUND s)
-
-let get_error_color () = color_of_string !error_color
-
-let set_error_color clr =
- let s = string_of_color clr in
- error_color := s;
- Script.error_bg#set_property (`BACKGROUND s)
-
-let get_error_fg_color () = color_of_string !error_fg_color
-
-let set_error_fg_color clr =
- let s = string_of_color clr in
- error_fg_color := s;
- Script.error#set_property (`FOREGROUND s)
-
diff --git a/ide/tags.mli b/ide/tags.mli
index 00583f1bd..5a932f330 100644
--- a/ide/tags.mli
+++ b/ide/tags.mli
@@ -41,22 +41,3 @@ end
val string_of_color : Gdk.color -> string
val color_of_string : string -> Gdk.color
-
-val get_processed_color : unit -> Gdk.color
-val set_processed_color : Gdk.color -> unit
-
-val get_processing_color : unit -> Gdk.color
-val set_processing_color : Gdk.color -> unit
-
-val get_error_color : unit -> Gdk.color
-val set_error_color : Gdk.color -> unit
-
-val get_error_fg_color : unit -> Gdk.color
-val set_error_fg_color : Gdk.color -> unit
-
-val default_processed_color : string
-val default_processing_color : string
-val default_error_color : string
-val default_error_fg_color : string
-val default_color : string
-
diff --git a/ide/wg_Command.ml b/ide/wg_Command.ml
index a3e5ea3f5..946aaf010 100644
--- a/ide/wg_Command.ml
+++ b/ide/wg_Command.ml
@@ -85,9 +85,11 @@ object(self)
~packing:(vbox#pack ~fill:true ~expand:true) () in
let result = GText.view ~packing:r_bin#add () in
views <- (frame#coerce, result, combo#entry) :: views;
- result#misc#modify_font current.text_font;
- let clr = Tags.color_of_string current.background_color in
- result#misc#modify_base [`NORMAL, `COLOR clr];
+ let cb clr = result#misc#modify_base [`NORMAL, `NAME clr] in
+ let _ = background_color#connect#changed cb in
+ let _ = result#misc#connect#realize (fun () -> cb background_color#get) in
+ let cb ft = result#misc#modify_font (Pango.Font.from_string ft) in
+ stick text_font result cb;
result#misc#set_can_focus true; (* false causes problems for selection *)
result#set_editable false;
let callback () =
@@ -98,11 +100,14 @@ object(self)
if Str.string_match (Str.regexp "\\. *$") com 0 then com
else com ^ " " ^ arg ^" . "
in
- let log level message = result#buffer#insert (message^"\n") in
+ let log level message =
+ Ideutils.insert_xml result#buffer message;
+ result#buffer#insert "\n";
+ in
let process =
Coq.bind (Coq.query ~logger:log (phrase,Stateid.dummy)) (function
| Interface.Fail (_,l,str) ->
- result#buffer#insert str;
+ Ideutils.insert_xml result#buffer str;
notebook#set_page ~tab_label:(new_tab_lbl "Error") frame#coerce;
Coq.return ()
| Interface.Good res ->
@@ -144,13 +149,9 @@ object(self)
method visible =
frame#visible
-
- method refresh_font () =
- let iter (_,view,_) = view#misc#modify_font current.text_font in
- List.iter iter views
- method refresh_color () =
- let clr = Tags.color_of_string current.background_color in
+ method private refresh_color clr =
+ let clr = Tags.color_of_string clr in
let iter (_,view,_) = view#misc#modify_base [`NORMAL, `COLOR clr] in
List.iter iter views
@@ -158,6 +159,8 @@ object(self)
self#new_page_maker;
self#new_query_aux ~grab_now:false ();
frame#misc#hide ();
+ let _ = background_color#connect#changed self#refresh_color in
+ self#refresh_color background_color#get;
ignore(notebook#event#connect#key_press ~callback:(fun ev ->
if GdkEvent.Key.keyval ev = GdkKeysyms._Escape then (self#hide; true)
else false
diff --git a/ide/wg_Command.mli b/ide/wg_Command.mli
index 97f96f458..fa50ba5fd 100644
--- a/ide/wg_Command.mli
+++ b/ide/wg_Command.mli
@@ -10,8 +10,6 @@ class command_window : string -> Coq.coqtop ->
object
method new_query : ?command:string -> ?term:string -> unit -> unit
method pack_in : (GObj.widget -> unit) -> unit
- method refresh_font : unit -> unit
- method refresh_color : unit -> unit
method show : unit
method hide : unit
method visible : bool
diff --git a/ide/wg_Completion.ml b/ide/wg_Completion.ml
index 3c2289985..6c53fc013 100644
--- a/ide/wg_Completion.ml
+++ b/ide/wg_Completion.ml
@@ -258,7 +258,7 @@ object (self)
method private refresh_style () =
let (renderer, _) = renderer in
- let font = Preferences.current.Preferences.text_font in
+ let font = Pango.Font.from_string Preferences.text_font#get in
renderer#set_properties [`FONT_DESC font; `XPAD 10]
method private coordinates pos =
diff --git a/ide/wg_Find.ml b/ide/wg_Find.ml
index 479012378..3d847ddcc 100644
--- a/ide/wg_Find.ml
+++ b/ide/wg_Find.ml
@@ -6,8 +6,6 @@
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
-type mode = [ `FIND | `REPLACE ]
-
let b2c = Ideutils.byte_offset_to_char_offset
class finder name (view : GText.view) =
diff --git a/ide/wg_MessageView.ml b/ide/wg_MessageView.ml
index f2b8336c1..7728ad236 100644
--- a/ide/wg_MessageView.ml
+++ b/ide/wg_MessageView.ml
@@ -6,11 +6,13 @@
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
+open Preferences
+
class type message_view_signals =
object
inherit GObj.misc_signals
inherit GUtil.add_ml_signals
- method pushed : callback:(Pp.message_level -> string -> unit) -> GtkSignal.id
+ method pushed : callback:Ideutils.logger -> GtkSignal.id
end
class message_view_signals_impl obj (pushed : 'a GUtil.signal) : message_view_signals =
@@ -26,14 +28,13 @@ class type message_view =
inherit GObj.widget
method connect : message_view_signals
method clear : unit
- method add : string -> unit
- method set : string -> unit
- method push : Pp.message_level -> string -> unit
+ method add : Richpp.richpp -> unit
+ method add_string : string -> unit
+ method set : Richpp.richpp -> unit
+ method push : Ideutils.logger
(** same as [add], but with an explicit level instead of [Notice] *)
method buffer : GText.buffer
(** for more advanced text edition *)
- method modify_font : Pango.font_description -> unit
- method refresh_color : unit -> unit
end
let message_view () : message_view =
@@ -53,6 +54,12 @@ let message_view () : message_view =
let default_clipboard = GData.clipboard Gdk.Atom.primary in
let _ = buffer#add_selection_clipboard default_clipboard in
let () = view#set_left_margin 2 in
+ view#misc#show ();
+ let cb clr = view#misc#modify_base [`NORMAL, `NAME clr] in
+ let _ = background_color#connect#changed cb in
+ let _ = view#misc#connect#realize (fun () -> cb background_color#get) in
+ let cb ft = view#misc#modify_font (Pango.Font.from_string ft) in
+ stick text_font view cb;
object (self)
inherit GObj.widget box#as_widget
@@ -70,23 +77,23 @@ let message_view () : message_view =
| Pp.Warning -> [Tags.Message.warning]
| _ -> []
in
- if msg <> "" then begin
- buffer#insert ~tags msg;
- buffer#insert ~tags "\n";
+ let rec non_empty = function
+ | Xml_datatype.PCData "" -> false
+ | Xml_datatype.PCData _ -> true
+ | Xml_datatype.Element (_, _, children) -> List.exists non_empty children
+ in
+ if non_empty (Richpp.repr msg) then begin
+ Ideutils.insert_xml buffer ~tags msg;
+ buffer#insert (*~tags*) "\n";
push#call (level, msg)
end
method add msg = self#push Pp.Notice msg
+ method add_string s = self#add (Richpp.richpp_of_string s)
+
method set msg = self#clear; self#add msg
method buffer = text_buffer
- method modify_font fd = view#misc#modify_font fd
-
- method refresh_color () =
- let open Preferences in
- let clr = Tags.color_of_string current.background_color in
- view#misc#modify_base [`NORMAL, `COLOR clr]
-
end
diff --git a/ide/wg_MessageView.mli b/ide/wg_MessageView.mli
index ebcb21634..2d34533de 100644
--- a/ide/wg_MessageView.mli
+++ b/ide/wg_MessageView.mli
@@ -10,7 +10,7 @@ class type message_view_signals =
object
inherit GObj.misc_signals
inherit GUtil.add_ml_signals
- method pushed : callback:(Pp.message_level -> string -> unit) -> GtkSignal.id
+ method pushed : callback:Ideutils.logger -> GtkSignal.id
end
class type message_view =
@@ -18,14 +18,13 @@ class type message_view =
inherit GObj.widget
method connect : message_view_signals
method clear : unit
- method add : string -> unit
- method set : string -> unit
- method push : Pp.message_level -> string -> unit
+ method add : Richpp.richpp -> unit
+ method add_string : string -> unit
+ method set : Richpp.richpp -> unit
+ method push : Ideutils.logger
(** same as [add], but with an explicit level instead of [Notice] *)
method buffer : GText.buffer
(** for more advanced text edition *)
- method modify_font : Pango.font_description -> unit
- method refresh_color : unit -> unit
end
val message_view : unit -> message_view
diff --git a/ide/wg_ProofView.ml b/ide/wg_ProofView.ml
index 0007203e3..4d95fdd0d 100644
--- a/ide/wg_ProofView.ml
+++ b/ide/wg_ProofView.ml
@@ -7,6 +7,8 @@
(************************************************************************)
open Util
+open Preferences
+open Ideutils
class type proof_view =
object
@@ -82,7 +84,8 @@ let mode_tactic sel_cb (proof : #GText.view_skel) goals hints = match goals with
let () = hook_tag_cb tag hint sel_cb on_hover in
[tag], hints
in
- let () = proof#buffer#insert ~tags (hyp ^ "\n") in
+ let () = insert_xml ~tags proof#buffer hyp in
+ proof#buffer#insert "\n";
insert_hyp rem_hints hs
in
let () = proof#buffer#insert head_str in
@@ -95,13 +98,14 @@ let mode_tactic sel_cb (proof : #GText.view_skel) goals hints = match goals with
else []
in
proof#buffer#insert (goal_str 1 goals_cnt);
- proof#buffer#insert ~tags cur_goal;
+ insert_xml proof#buffer cur_goal;
proof#buffer#insert "\n"
in
(* Insert remaining goals (no hypotheses) *)
let fold_goal i _ { Interface.goal_ccl = g } =
proof#buffer#insert (goal_str i goals_cnt);
- proof#buffer#insert (g ^ "\n")
+ insert_xml proof#buffer g;
+ proof#buffer#insert "\n"
in
let () = Util.List.fold_left_i fold_goal 2 () rem_goals in
@@ -110,17 +114,6 @@ let mode_tactic sel_cb (proof : #GText.view_skel) goals hints = match goals with
(Some Tags.Proof.goal)));
ignore(proof#scroll_to_mark ~use_align:true ~yalign:0.95 `INSERT)
-let mode_cesar (proof : #GText.view_skel) = function
- | [] -> assert false
- | { Interface.goal_hyp = hyps; Interface.goal_ccl = cur_goal; } :: _ ->
- proof#buffer#insert " *** Declarative Mode ***\n";
- List.iter
- (fun hyp -> proof#buffer#insert (hyp^"\n"))
- hyps;
- proof#buffer#insert "______________________________________\n";
- proof#buffer#insert ("thesis := \n "^cur_goal^"\n");
- ignore (proof#scroll_to_iter (proof#buffer#get_iter_at_mark `INSERT))
-
let rec flatten = function
| [] -> []
| (lg, rg) :: l ->
@@ -151,8 +144,8 @@ let display mode (view : #GText.view_skel) goals hints evars =
(* The proof is finished, with the exception of given up goals. *)
view#buffer#insert "No more subgoals, but there are some goals you gave up:\n\n";
let iter goal =
- let msg = Printf.sprintf "%s\n" goal.Interface.goal_ccl in
- view#buffer#insert msg
+ insert_xml view#buffer goal.Interface.goal_ccl;
+ view#buffer#insert "\n"
in
List.iter iter given_up_goals;
view#buffer#insert "\nYou need to go back and solve them."
@@ -160,8 +153,8 @@ let display mode (view : #GText.view_skel) goals hints evars =
(* All the goals have been resolved but those on the shelf. *)
view#buffer#insert "All the remaining goals are on the shelf:\n\n";
let iter goal =
- let msg = Printf.sprintf "%s\n" goal.Interface.goal_ccl in
- view#buffer#insert msg
+ insert_xml view#buffer goal.Interface.goal_ccl;
+ view#buffer#insert "\n"
in
List.iter iter shelved_goals
| _, _, _, _ ->
@@ -173,8 +166,8 @@ let display mode (view : #GText.view_skel) goals hints evars =
view#buffer#insert "This subproof is complete, but there are some unfocused goals:\n\n";
let iter i goal =
let () = view#buffer#insert (goal_str (succ i)) in
- let msg = Printf.sprintf "%s\n" goal.Interface.goal_ccl in
- view#buffer#insert msg
+ insert_xml view#buffer goal.Interface.goal_ccl;
+ view#buffer#insert "\n"
in
List.iteri iter bg
end
@@ -193,6 +186,12 @@ let proof_view () =
let () = Gtk_parsing.fix_double_click view in
let default_clipboard = GData.clipboard Gdk.Atom.primary in
let _ = buffer#add_selection_clipboard default_clipboard in
+ let cb clr = view#misc#modify_base [`NORMAL, `NAME clr] in
+ let _ = background_color#connect#changed cb in
+ let _ = view#misc#connect#realize (fun () -> cb background_color#get) in
+ let cb ft = view#misc#modify_font (Pango.Font.from_string ft) in
+ stick text_font view cb;
+
object
inherit GObj.widget view#as_widget
val mutable goals = None
diff --git a/ide/wg_ScriptView.ml b/ide/wg_ScriptView.ml
index 5cdf8464b..83fbda487 100644
--- a/ide/wg_ScriptView.ml
+++ b/ide/wg_ScriptView.ml
@@ -6,6 +6,8 @@
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
+open Preferences
+
type insert_action = {
ins_val : string;
ins_off : int;
@@ -456,6 +458,33 @@ object (self)
if not proceed then GtkSignal.stop_emit ()
in
let _ = GtkSignal.connect ~sgn:move_line_signal ~callback obj in
+ (** Plug on preferences *)
+ let cb clr = self#misc#modify_base [`NORMAL, `NAME clr] in
+ let _ = background_color#connect#changed cb in
+ let _ = self#misc#connect#realize (fun () -> cb background_color#get) in
+
+ let cb b = self#set_wrap_mode (if b then `WORD else `NONE) in
+ stick dynamic_word_wrap self cb;
+ stick show_line_number self self#set_show_line_numbers;
+ stick auto_indent self self#set_auto_indent;
+ stick highlight_current_line self self#set_highlight_current_line;
+
+ (* Hack to handle missing binding in lablgtk *)
+ let cb b =
+ let flag = if b then 0b1001011 (* SPACE, TAB, NBSP, TRAILING *) else 0 in
+ let conv = Gobject.({ name = "draw-spaces"; conv = Data.int }) in
+ Gobject.set conv self#as_widget flag
+ in
+ stick show_spaces self cb;
+
+ stick show_right_margin self self#set_show_right_margin;
+ stick spaces_instead_of_tabs self self#set_insert_spaces_instead_of_tabs;
+ stick tab_length self self#set_tab_width;
+ stick auto_complete self self#set_auto_complete;
+
+ let cb ft = self#misc#modify_font (Pango.Font.from_string ft) in
+ stick text_font self cb;
+
()
end
diff --git a/ide/wg_Segment.ml b/ide/wg_Segment.ml
index b4b02a7fa..71825d81e 100644
--- a/ide/wg_Segment.ml
+++ b/ide/wg_Segment.ml
@@ -7,6 +7,7 @@
(************************************************************************)
open Util
+open Preferences
type color = GDraw.color
@@ -122,6 +123,8 @@ object (self)
true
in
let _ = eventbox#event#connect#button_press clicked_cb in
+ let cb show = if show then self#misc#show () else self#misc#hide () in
+ stick show_progress_bar self cb;
(** Initial pixmap *)
draw#set_pixmap pixmap
diff --git a/ide/xmlprotocol.ml b/ide/xmlprotocol.ml
index 88bd2c17f..232630e5b 100644
--- a/ide/xmlprotocol.ml
+++ b/ide/xmlprotocol.ml
@@ -10,7 +10,7 @@
(** WARNING: TO BE UPDATED WHEN MODIFIED! *)
-let protocol_version = "20140312"
+let protocol_version = "20150913"
(** * Interface of calls to Coq by CoqIde *)
@@ -92,7 +92,7 @@ let of_value f = function
| None -> []
| Some (s, e) -> [("loc_s", string_of_int s); ("loc_e", string_of_int e)] in
let id = Stateid.to_xml id in
- Element ("value", ["val", "fail"] @ loc, [id;PCData msg])
+ Element ("value", ["val", "fail"] @ loc, [id; Richpp.of_richpp msg])
let to_value f = function
| Element ("value", attrs, l) ->
let ans = massoc "val" attrs in
@@ -105,8 +105,9 @@ let to_value f = function
Some (loc_s, loc_e)
with Marshal_error | Failure _ -> None
in
- let id = Stateid.of_xml (List.hd l) in
- let msg = raw_string (List.tl l) in
+ let (id, msg) = match l with [id; msg] -> (id, msg) | _ -> raise Marshal_error in
+ let id = Stateid.of_xml id in
+ let msg = Richpp.to_richpp msg in
Fail (id, loc, msg)
else raise Marshal_error
| _ -> raise Marshal_error
@@ -133,14 +134,14 @@ let to_evar = function
| _ -> raise Marshal_error
let of_goal g =
- let hyp = of_list of_string g.goal_hyp in
- let ccl = of_string g.goal_ccl in
+ let hyp = of_list Richpp.of_richpp g.goal_hyp in
+ let ccl = Richpp.of_richpp g.goal_ccl in
let id = of_string g.goal_id in
Element ("goal", [], [id; hyp; ccl])
let to_goal = function
| Element ("goal", [], [id; hyp; ccl]) ->
- let hyp = to_list to_string hyp in
- let ccl = to_string ccl in
+ let hyp = to_list Richpp.to_richpp hyp in
+ let ccl = Richpp.to_richpp ccl in
let id = to_string id in
{ goal_hyp = hyp; goal_ccl = ccl; goal_id = id; }
| _ -> raise Marshal_error
@@ -220,22 +221,31 @@ module ReifType : sig
end = struct
- type value_type =
- | Unit | String | Int | Bool | Xml
+ type _ val_t =
+ | Unit : unit val_t
+ | String : string val_t
+ | Int : int val_t
+ | Bool : bool val_t
+ | Xml : Xml_datatype.xml val_t
- | Option of value_type
- | List of value_type
- | Pair of value_type * value_type
- | Union of value_type * value_type
+ | Option : 'a val_t -> 'a option val_t
+ | List : 'a val_t -> 'a list val_t
+ | Pair : 'a val_t * 'b val_t -> ('a * 'b) val_t
+ | Union : 'a val_t * 'b val_t -> ('a, 'b) union val_t
- | Goals | Evar | State | Option_state | Option_value | Coq_info
- | Coq_object of value_type
- | State_id
- | Search_cst
+ | Goals : goals val_t
+ | Evar : evar val_t
+ | State : status val_t
+ | Option_state : option_state val_t
+ | Option_value : option_value val_t
+ | Coq_info : coq_info val_t
+ | Coq_object : 'a val_t -> 'a coq_object val_t
+ | State_id : state_id val_t
+ | Search_cst : search_constraint val_t
- type 'a val_t = value_type
+ type value_type = Value_type : 'a val_t -> value_type
- let erase (x : 'a val_t) : value_type = x
+ let erase (x : 'a val_t) = Value_type x
let unit_t = Unit
let string_t = String
@@ -259,48 +269,48 @@ end = struct
let search_cst_t = Search_cst
let of_value_type (ty : 'a val_t) : 'a -> xml =
- let rec convert ty : 'a -> xml = match ty with
- | Unit -> Obj.magic of_unit
- | Bool -> Obj.magic of_bool
- | Xml -> Obj.magic (fun x -> x)
- | String -> Obj.magic of_string
- | Int -> Obj.magic of_int
- | State -> Obj.magic of_status
- | Option_state -> Obj.magic of_option_state
- | Option_value -> Obj.magic of_option_value
- | Coq_info -> Obj.magic of_coq_info
- | Goals -> Obj.magic of_goals
- | Evar -> Obj.magic of_evar
- | List t -> Obj.magic (of_list (convert t))
- | Option t -> Obj.magic (of_option (convert t))
- | Coq_object t -> Obj.magic (of_coq_object (convert t))
- | Pair (t1,t2) -> Obj.magic (of_pair (convert t1) (convert t2))
- | Union (t1,t2) -> Obj.magic (of_union (convert t1) (convert t2))
- | State_id -> Obj.magic Stateid.to_xml
- | Search_cst -> Obj.magic of_search_cst
+ let rec convert : type a. a val_t -> a -> xml = function
+ | Unit -> of_unit
+ | Bool -> of_bool
+ | Xml -> (fun x -> x)
+ | String -> of_string
+ | Int -> of_int
+ | State -> of_status
+ | Option_state -> of_option_state
+ | Option_value -> of_option_value
+ | Coq_info -> of_coq_info
+ | Goals -> of_goals
+ | Evar -> of_evar
+ | List t -> (of_list (convert t))
+ | Option t -> (of_option (convert t))
+ | Coq_object t -> (of_coq_object (convert t))
+ | Pair (t1,t2) -> (of_pair (convert t1) (convert t2))
+ | Union (t1,t2) -> (of_union (convert t1) (convert t2))
+ | State_id -> Stateid.to_xml
+ | Search_cst -> of_search_cst
in
convert ty
let to_value_type (ty : 'a val_t) : xml -> 'a =
- let rec convert ty : xml -> 'a = match ty with
- | Unit -> Obj.magic to_unit
- | Bool -> Obj.magic to_bool
- | Xml -> Obj.magic (fun x -> x)
- | String -> Obj.magic to_string
- | Int -> Obj.magic to_int
- | State -> Obj.magic to_status
- | Option_state -> Obj.magic to_option_state
- | Option_value -> Obj.magic to_option_value
- | Coq_info -> Obj.magic to_coq_info
- | Goals -> Obj.magic to_goals
- | Evar -> Obj.magic to_evar
- | List t -> Obj.magic (to_list (convert t))
- | Option t -> Obj.magic (to_option (convert t))
- | Coq_object t -> Obj.magic (to_coq_object (convert t))
- | Pair (t1,t2) -> Obj.magic (to_pair (convert t1) (convert t2))
- | Union (t1,t2) -> Obj.magic (to_union (convert t1) (convert t2))
- | State_id -> Obj.magic Stateid.of_xml
- | Search_cst -> Obj.magic to_search_cst
+ let rec convert : type a. a val_t -> xml -> a = function
+ | Unit -> to_unit
+ | Bool -> to_bool
+ | Xml -> (fun x -> x)
+ | String -> to_string
+ | Int -> to_int
+ | State -> to_status
+ | Option_state -> to_option_state
+ | Option_value -> to_option_value
+ | Coq_info -> to_coq_info
+ | Goals -> to_goals
+ | Evar -> to_evar
+ | List t -> (to_list (convert t))
+ | Option t -> (to_option (convert t))
+ | Coq_object t -> (to_coq_object (convert t))
+ | Pair (t1,t2) -> (to_pair (convert t1) (convert t2))
+ | Union (t1,t2) -> (to_union (convert t1) (convert t2))
+ | State_id -> Stateid.of_xml
+ | Search_cst -> to_search_cst
in
convert ty
@@ -320,10 +330,9 @@ end = struct
(List.length lg + List.length rg) pr_focus l in
Printf.sprintf "Still focussed: [%a]." pr_focus g.bg_goals
else
- let pr_menu s = s in
let pr_goal { goal_hyp = hyps; goal_ccl = goal } =
- "[" ^ String.concat "; " (List.map pr_menu hyps) ^ " |- " ^
- pr_menu goal ^ "]" in
+ "[" ^ String.concat "; " (List.map Richpp.raw_print hyps) ^ " |- " ^
+ Richpp.raw_print goal ^ "]" in
String.concat " " (List.map pr_goal g.fg_goals)
let pr_evar (e : evar) = "[" ^ e.evar_info ^ "]"
let pr_status (s : status) =
@@ -350,6 +359,7 @@ end = struct
let pr_coq_object (o : 'a coq_object) = "FIXME"
let pr_pair pr1 pr2 (a,b) = "("^pr1 a^","^pr2 b^")"
let pr_union pr1 pr2 = function Inl x -> "Inl "^pr1 x | Inr x -> "Inr "^pr2 x
+ let pr_state_id = Stateid.to_string
let pr_search_cst = function
| Name_Pattern s -> "Name_Pattern " ^ s
@@ -358,30 +368,30 @@ end = struct
| In_Module s -> "In_Module " ^ String.concat "." s
| Include_Blacklist -> "Include_Blacklist"
- let rec print = function
- | Unit -> Obj.magic pr_unit
- | Bool -> Obj.magic pr_bool
- | String -> Obj.magic pr_string
- | Xml -> Obj.magic Xml_printer.to_string_fmt
- | Int -> Obj.magic pr_int
- | State -> Obj.magic pr_status
- | Option_state -> Obj.magic pr_option_state
- | Option_value -> Obj.magic pr_option_value
- | Search_cst -> Obj.magic pr_search_cst
- | Coq_info -> Obj.magic pr_coq_info
- | Goals -> Obj.magic pr_goal
- | Evar -> Obj.magic pr_evar
- | List t -> Obj.magic (pr_list (print t))
- | Option t -> Obj.magic (pr_option (print t))
- | Coq_object t -> Obj.magic pr_coq_object
- | Pair (t1,t2) -> Obj.magic (pr_pair (print t1) (print t2))
- | Union (t1,t2) -> Obj.magic (pr_union (print t1) (print t2))
- | State_id -> Obj.magic pr_int
+ let rec print : type a. a val_t -> a -> string = function
+ | Unit -> pr_unit
+ | Bool -> pr_bool
+ | String -> pr_string
+ | Xml -> Xml_printer.to_string_fmt
+ | Int -> pr_int
+ | State -> pr_status
+ | Option_state -> pr_option_state
+ | Option_value -> pr_option_value
+ | Search_cst -> pr_search_cst
+ | Coq_info -> pr_coq_info
+ | Goals -> pr_goal
+ | Evar -> pr_evar
+ | List t -> (pr_list (print t))
+ | Option t -> (pr_option (print t))
+ | Coq_object t -> pr_coq_object
+ | Pair (t1,t2) -> (pr_pair (print t1) (print t2))
+ | Union (t1,t2) -> (pr_union (print t1) (print t2))
+ | State_id -> pr_state_id
(* This is to break if a rename/refactoring makes the strings below outdated *)
type 'a exists = bool
- let rec print_type = function
+ let rec print_val_t : type a. a val_t -> string = function
| Unit -> "unit"
| Bool -> "bool"
| String -> "string"
@@ -394,33 +404,35 @@ end = struct
| Coq_info -> assert(true : coq_info exists); "Interface.coq_info"
| Goals -> assert(true : goals exists); "Interface.goals"
| Evar -> assert(true : evar exists); "Interface.evar"
- | List t -> Printf.sprintf "(%s list)" (print_type t)
- | Option t -> Printf.sprintf "(%s option)" (print_type t)
+ | List t -> Printf.sprintf "(%s list)" (print_val_t t)
+ | Option t -> Printf.sprintf "(%s option)" (print_val_t t)
| Coq_object t -> assert(true : 'a coq_object exists);
- Printf.sprintf "(%s Interface.coq_object)" (print_type t)
- | Pair (t1,t2) -> Printf.sprintf "(%s * %s)" (print_type t1) (print_type t2)
+ Printf.sprintf "(%s Interface.coq_object)" (print_val_t t)
+ | Pair (t1,t2) -> Printf.sprintf "(%s * %s)" (print_val_t t1) (print_val_t t2)
| Union (t1,t2) -> assert(true : ('a,'b) CSig.union exists);
- Printf.sprintf "((%s, %s) CSig.union)" (print_type t1) (print_type t2)
+ Printf.sprintf "((%s, %s) CSig.union)" (print_val_t t1) (print_val_t t2)
| State_id -> assert(true : Stateid.t exists); "Stateid.t"
+ let print_type = function Value_type ty -> print_val_t ty
+
let document_type_encoding pr_xml =
Printf.printf "\n=== Data encoding by examples ===\n\n";
- Printf.printf "%s:\n\n%s\n\n" (print_type Unit) (pr_xml (of_unit ()));
- Printf.printf "%s:\n\n%s\n%s\n\n" (print_type Bool)
+ Printf.printf "%s:\n\n%s\n\n" (print_val_t Unit) (pr_xml (of_unit ()));
+ Printf.printf "%s:\n\n%s\n%s\n\n" (print_val_t Bool)
(pr_xml (of_bool true)) (pr_xml (of_bool false));
- Printf.printf "%s:\n\n%s\n\n" (print_type String) (pr_xml (of_string "hello"));
- Printf.printf "%s:\n\n%s\n\n" (print_type Int) (pr_xml (of_int 256));
- Printf.printf "%s:\n\n%s\n\n" (print_type State_id) (pr_xml (Stateid.to_xml Stateid.initial));
- Printf.printf "%s:\n\n%s\n\n" (print_type (List Int)) (pr_xml (of_list of_int [3;4;5]));
- Printf.printf "%s:\n\n%s\n%s\n\n" (print_type (Option Int))
+ Printf.printf "%s:\n\n%s\n\n" (print_val_t String) (pr_xml (of_string "hello"));
+ Printf.printf "%s:\n\n%s\n\n" (print_val_t Int) (pr_xml (of_int 256));
+ Printf.printf "%s:\n\n%s\n\n" (print_val_t State_id) (pr_xml (Stateid.to_xml Stateid.initial));
+ Printf.printf "%s:\n\n%s\n\n" (print_val_t (List Int)) (pr_xml (of_list of_int [3;4;5]));
+ Printf.printf "%s:\n\n%s\n%s\n\n" (print_val_t (Option Int))
(pr_xml (of_option of_int (Some 3))) (pr_xml (of_option of_int None));
- Printf.printf "%s:\n\n%s\n\n" (print_type (Pair (Bool,Int)))
+ Printf.printf "%s:\n\n%s\n\n" (print_val_t (Pair (Bool,Int)))
(pr_xml (of_pair of_bool of_int (false,3)));
- Printf.printf "%s:\n\n%s\n\n" (print_type (Union (Bool,Int)))
+ Printf.printf "%s:\n\n%s\n\n" (print_val_t (Union (Bool,Int)))
(pr_xml (of_union of_bool of_int (Inl false)));
print_endline ("All other types are records represented by a node named like the OCaml\n"^
"type which contains a flattened n-tuple. We provide one example.\n");
- Printf.printf "%s:\n\n%s\n\n" (print_type Option_state)
+ Printf.printf "%s:\n\n%s\n\n" (print_val_t Option_state)
(pr_xml (of_option_state { opt_sync = true; opt_depr = false;
opt_name = "name1"; opt_value = IntValue (Some 37) }));
@@ -496,27 +508,27 @@ let calls = [|
|]
type 'a call =
- | Add of add_sty
- | Edit_at of edit_at_sty
- | Query of query_sty
- | Goal of goals_sty
- | Evars of evars_sty
- | Hints of hints_sty
- | Status of status_sty
- | Search of search_sty
- | GetOptions of get_options_sty
- | SetOptions of set_options_sty
- | MkCases of mkcases_sty
- | Quit of quit_sty
- | About of about_sty
- | Init of init_sty
- | StopWorker of stop_worker_sty
+ | Add : add_sty -> add_rty call
+ | Edit_at : edit_at_sty -> edit_at_rty call
+ | Query : query_sty -> query_rty call
+ | Goal : goals_sty -> goals_rty call
+ | Evars : evars_sty -> evars_rty call
+ | Hints : hints_sty -> hints_rty call
+ | Status : status_sty -> status_rty call
+ | Search : search_sty -> search_rty call
+ | GetOptions : get_options_sty -> get_options_rty call
+ | SetOptions : set_options_sty -> set_options_rty call
+ | MkCases : mkcases_sty -> mkcases_rty call
+ | Quit : quit_sty -> quit_rty call
+ | About : about_sty -> about_rty call
+ | Init : init_sty -> init_rty call
+ | StopWorker : stop_worker_sty -> stop_worker_rty call
(* retrocompatibility *)
- | Interp of interp_sty
- | PrintAst of print_ast_sty
- | Annotate of annotate_sty
+ | Interp : interp_sty -> interp_rty call
+ | PrintAst : print_ast_sty -> print_ast_rty call
+ | Annotate : annotate_sty -> annotate_rty call
-let id_of_call = function
+let id_of_call : type a. a call -> int = function
| Add _ -> 0
| Edit_at _ -> 1
| Query _ -> 2
@@ -538,7 +550,7 @@ let id_of_call = function
let str_of_call c = pi1 calls.(id_of_call c)
-type unknown
+type unknown_call = Unknown : 'a call -> unknown_call
(** We use phantom types and GADT to protect ourselves against wild casts *)
let add x : add_rty call = Add x
@@ -559,8 +571,8 @@ let stop_worker x : stop_worker_rty call = StopWorker x
let print_ast x : print_ast_rty call = PrintAst x
let annotate x : annotate_rty call = Annotate x
-let abstract_eval_call handler (c : 'a call) : 'a value =
- let mkGood x : 'a value = Good (Obj.magic x) in
+let abstract_eval_call : type a. _ -> a call -> a value = fun handler c ->
+ let mkGood : type a. a -> a value = fun x -> Good x in
try
match c with
| Add x -> mkGood (handler.add x)
@@ -586,47 +598,47 @@ let abstract_eval_call handler (c : 'a call) : 'a value =
Fail (handler.handle_exn any)
(** brain dead code, edit if protocol messages are added/removed *)
-let of_answer (q : 'a call) (v : 'a value) : xml = match q with
- | Add _ -> of_value (of_value_type add_rty_t ) (Obj.magic v)
- | Edit_at _ -> of_value (of_value_type edit_at_rty_t ) (Obj.magic v)
- | Query _ -> of_value (of_value_type query_rty_t ) (Obj.magic v)
- | Goal _ -> of_value (of_value_type goals_rty_t ) (Obj.magic v)
- | Evars _ -> of_value (of_value_type evars_rty_t ) (Obj.magic v)
- | Hints _ -> of_value (of_value_type hints_rty_t ) (Obj.magic v)
- | Status _ -> of_value (of_value_type status_rty_t ) (Obj.magic v)
- | Search _ -> of_value (of_value_type search_rty_t ) (Obj.magic v)
- | GetOptions _ -> of_value (of_value_type get_options_rty_t) (Obj.magic v)
- | SetOptions _ -> of_value (of_value_type set_options_rty_t) (Obj.magic v)
- | MkCases _ -> of_value (of_value_type mkcases_rty_t ) (Obj.magic v)
- | Quit _ -> of_value (of_value_type quit_rty_t ) (Obj.magic v)
- | About _ -> of_value (of_value_type about_rty_t ) (Obj.magic v)
- | Init _ -> of_value (of_value_type init_rty_t ) (Obj.magic v)
- | Interp _ -> of_value (of_value_type interp_rty_t ) (Obj.magic v)
- | StopWorker _ -> of_value (of_value_type stop_worker_rty_t) (Obj.magic v)
- | PrintAst _ -> of_value (of_value_type print_ast_rty_t ) (Obj.magic v)
- | Annotate _ -> of_value (of_value_type annotate_rty_t ) (Obj.magic v)
-
-let to_answer (q : 'a call) (x : xml) : 'a value = match q with
- | Add _ -> Obj.magic (to_value (to_value_type add_rty_t ) x)
- | Edit_at _ -> Obj.magic (to_value (to_value_type edit_at_rty_t ) x)
- | Query _ -> Obj.magic (to_value (to_value_type query_rty_t ) x)
- | Goal _ -> Obj.magic (to_value (to_value_type goals_rty_t ) x)
- | Evars _ -> Obj.magic (to_value (to_value_type evars_rty_t ) x)
- | Hints _ -> Obj.magic (to_value (to_value_type hints_rty_t ) x)
- | Status _ -> Obj.magic (to_value (to_value_type status_rty_t ) x)
- | Search _ -> Obj.magic (to_value (to_value_type search_rty_t ) x)
- | GetOptions _ -> Obj.magic (to_value (to_value_type get_options_rty_t) x)
- | SetOptions _ -> Obj.magic (to_value (to_value_type set_options_rty_t) x)
- | MkCases _ -> Obj.magic (to_value (to_value_type mkcases_rty_t ) x)
- | Quit _ -> Obj.magic (to_value (to_value_type quit_rty_t ) x)
- | About _ -> Obj.magic (to_value (to_value_type about_rty_t ) x)
- | Init _ -> Obj.magic (to_value (to_value_type init_rty_t ) x)
- | Interp _ -> Obj.magic (to_value (to_value_type interp_rty_t ) x)
- | StopWorker _ -> Obj.magic (to_value (to_value_type stop_worker_rty_t) x)
- | PrintAst _ -> Obj.magic (to_value (to_value_type print_ast_rty_t ) x)
- | Annotate _ -> Obj.magic (to_value (to_value_type annotate_rty_t ) x)
-
-let of_call (q : 'a call) : xml =
+let of_answer : type a. a call -> a value -> xml = function
+ | Add _ -> of_value (of_value_type add_rty_t )
+ | Edit_at _ -> of_value (of_value_type edit_at_rty_t )
+ | Query _ -> of_value (of_value_type query_rty_t )
+ | Goal _ -> of_value (of_value_type goals_rty_t )
+ | Evars _ -> of_value (of_value_type evars_rty_t )
+ | Hints _ -> of_value (of_value_type hints_rty_t )
+ | Status _ -> of_value (of_value_type status_rty_t )
+ | Search _ -> of_value (of_value_type search_rty_t )
+ | GetOptions _ -> of_value (of_value_type get_options_rty_t)
+ | SetOptions _ -> of_value (of_value_type set_options_rty_t)
+ | MkCases _ -> of_value (of_value_type mkcases_rty_t )
+ | Quit _ -> of_value (of_value_type quit_rty_t )
+ | About _ -> of_value (of_value_type about_rty_t )
+ | Init _ -> of_value (of_value_type init_rty_t )
+ | Interp _ -> of_value (of_value_type interp_rty_t )
+ | StopWorker _ -> of_value (of_value_type stop_worker_rty_t)
+ | PrintAst _ -> of_value (of_value_type print_ast_rty_t )
+ | Annotate _ -> of_value (of_value_type annotate_rty_t )
+
+let to_answer : type a. a call -> xml -> a value = function
+ | Add _ -> to_value (to_value_type add_rty_t )
+ | Edit_at _ -> to_value (to_value_type edit_at_rty_t )
+ | Query _ -> to_value (to_value_type query_rty_t )
+ | Goal _ -> to_value (to_value_type goals_rty_t )
+ | Evars _ -> to_value (to_value_type evars_rty_t )
+ | Hints _ -> to_value (to_value_type hints_rty_t )
+ | Status _ -> to_value (to_value_type status_rty_t )
+ | Search _ -> to_value (to_value_type search_rty_t )
+ | GetOptions _ -> to_value (to_value_type get_options_rty_t)
+ | SetOptions _ -> to_value (to_value_type set_options_rty_t)
+ | MkCases _ -> to_value (to_value_type mkcases_rty_t )
+ | Quit _ -> to_value (to_value_type quit_rty_t )
+ | About _ -> to_value (to_value_type about_rty_t )
+ | Init _ -> to_value (to_value_type init_rty_t )
+ | Interp _ -> to_value (to_value_type interp_rty_t )
+ | StopWorker _ -> to_value (to_value_type stop_worker_rty_t)
+ | PrintAst _ -> to_value (to_value_type print_ast_rty_t )
+ | Annotate _ -> to_value (to_value_type annotate_rty_t )
+
+let of_call : type a. a call -> xml = fun q ->
let mkCall x = constructor "call" (str_of_call q) [x] in
match q with
| Add x -> mkCall (of_value_type add_sty_t x)
@@ -648,59 +660,59 @@ let of_call (q : 'a call) : xml =
| PrintAst x -> mkCall (of_value_type print_ast_sty_t x)
| Annotate x -> mkCall (of_value_type annotate_sty_t x)
-let to_call : xml -> unknown call =
+let to_call : xml -> unknown_call =
do_match "call" (fun s a ->
let mkCallArg vt a = to_value_type vt (singleton a) in
match s with
- | "Add" -> Add (mkCallArg add_sty_t a)
- | "Edit_at" -> Edit_at (mkCallArg edit_at_sty_t a)
- | "Query" -> Query (mkCallArg query_sty_t a)
- | "Goal" -> Goal (mkCallArg goals_sty_t a)
- | "Evars" -> Evars (mkCallArg evars_sty_t a)
- | "Hints" -> Hints (mkCallArg hints_sty_t a)
- | "Status" -> Status (mkCallArg status_sty_t a)
- | "Search" -> Search (mkCallArg search_sty_t a)
- | "GetOptions" -> GetOptions (mkCallArg get_options_sty_t a)
- | "SetOptions" -> SetOptions (mkCallArg set_options_sty_t a)
- | "MkCases" -> MkCases (mkCallArg mkcases_sty_t a)
- | "Quit" -> Quit (mkCallArg quit_sty_t a)
- | "About" -> About (mkCallArg about_sty_t a)
- | "Init" -> Init (mkCallArg init_sty_t a)
- | "Interp" -> Interp (mkCallArg interp_sty_t a)
- | "StopWorker" -> StopWorker (mkCallArg stop_worker_sty_t a)
- | "PrintAst" -> PrintAst (mkCallArg print_ast_sty_t a)
- | "Annotate" -> Annotate (mkCallArg annotate_sty_t a)
+ | "Add" -> Unknown (Add (mkCallArg add_sty_t a))
+ | "Edit_at" -> Unknown (Edit_at (mkCallArg edit_at_sty_t a))
+ | "Query" -> Unknown (Query (mkCallArg query_sty_t a))
+ | "Goal" -> Unknown (Goal (mkCallArg goals_sty_t a))
+ | "Evars" -> Unknown (Evars (mkCallArg evars_sty_t a))
+ | "Hints" -> Unknown (Hints (mkCallArg hints_sty_t a))
+ | "Status" -> Unknown (Status (mkCallArg status_sty_t a))
+ | "Search" -> Unknown (Search (mkCallArg search_sty_t a))
+ | "GetOptions" -> Unknown (GetOptions (mkCallArg get_options_sty_t a))
+ | "SetOptions" -> Unknown (SetOptions (mkCallArg set_options_sty_t a))
+ | "MkCases" -> Unknown (MkCases (mkCallArg mkcases_sty_t a))
+ | "Quit" -> Unknown (Quit (mkCallArg quit_sty_t a))
+ | "About" -> Unknown (About (mkCallArg about_sty_t a))
+ | "Init" -> Unknown (Init (mkCallArg init_sty_t a))
+ | "Interp" -> Unknown (Interp (mkCallArg interp_sty_t a))
+ | "StopWorker" -> Unknown (StopWorker (mkCallArg stop_worker_sty_t a))
+ | "PrintAst" -> Unknown (PrintAst (mkCallArg print_ast_sty_t a))
+ | "Annotate" -> Unknown (Annotate (mkCallArg annotate_sty_t a))
| _ -> raise Marshal_error)
(** Debug printing *)
let pr_value_gen pr = function
| Good v -> "GOOD " ^ pr v
- | Fail (id,None,str) -> "FAIL "^Stateid.to_string id^" ["^str^"]"
+ | Fail (id,None,str) -> "FAIL "^Stateid.to_string id^" ["^Richpp.raw_print str^"]"
| Fail (id,Some(i,j),str) ->
"FAIL "^Stateid.to_string id^
- " ("^string_of_int i^","^string_of_int j^")["^str^"]"
+ " ("^string_of_int i^","^string_of_int j^")["^Richpp.raw_print str^"]"
let pr_value v = pr_value_gen (fun _ -> "FIXME") v
-let pr_full_value call value = match call with
- | Add _ -> pr_value_gen (print add_rty_t ) (Obj.magic value)
- | Edit_at _ -> pr_value_gen (print edit_at_rty_t ) (Obj.magic value)
- | Query _ -> pr_value_gen (print query_rty_t ) (Obj.magic value)
- | Goal _ -> pr_value_gen (print goals_rty_t ) (Obj.magic value)
- | Evars _ -> pr_value_gen (print evars_rty_t ) (Obj.magic value)
- | Hints _ -> pr_value_gen (print hints_rty_t ) (Obj.magic value)
- | Status _ -> pr_value_gen (print status_rty_t ) (Obj.magic value)
- | Search _ -> pr_value_gen (print search_rty_t ) (Obj.magic value)
- | GetOptions _ -> pr_value_gen (print get_options_rty_t) (Obj.magic value)
- | SetOptions _ -> pr_value_gen (print set_options_rty_t) (Obj.magic value)
- | MkCases _ -> pr_value_gen (print mkcases_rty_t ) (Obj.magic value)
- | Quit _ -> pr_value_gen (print quit_rty_t ) (Obj.magic value)
- | About _ -> pr_value_gen (print about_rty_t ) (Obj.magic value)
- | Init _ -> pr_value_gen (print init_rty_t ) (Obj.magic value)
- | Interp _ -> pr_value_gen (print interp_rty_t ) (Obj.magic value)
- | StopWorker _ -> pr_value_gen (print stop_worker_rty_t) (Obj.magic value)
- | PrintAst _ -> pr_value_gen (print print_ast_rty_t ) (Obj.magic value)
- | Annotate _ -> pr_value_gen (print annotate_rty_t ) (Obj.magic value)
-let pr_call call =
+let pr_full_value : type a. a call -> a value -> string = fun call value -> match call with
+ | Add _ -> pr_value_gen (print add_rty_t ) value
+ | Edit_at _ -> pr_value_gen (print edit_at_rty_t ) value
+ | Query _ -> pr_value_gen (print query_rty_t ) value
+ | Goal _ -> pr_value_gen (print goals_rty_t ) value
+ | Evars _ -> pr_value_gen (print evars_rty_t ) value
+ | Hints _ -> pr_value_gen (print hints_rty_t ) value
+ | Status _ -> pr_value_gen (print status_rty_t ) value
+ | Search _ -> pr_value_gen (print search_rty_t ) value
+ | GetOptions _ -> pr_value_gen (print get_options_rty_t) value
+ | SetOptions _ -> pr_value_gen (print set_options_rty_t) value
+ | MkCases _ -> pr_value_gen (print mkcases_rty_t ) value
+ | Quit _ -> pr_value_gen (print quit_rty_t ) value
+ | About _ -> pr_value_gen (print about_rty_t ) value
+ | Init _ -> pr_value_gen (print init_rty_t ) value
+ | Interp _ -> pr_value_gen (print interp_rty_t ) value
+ | StopWorker _ -> pr_value_gen (print stop_worker_rty_t) value
+ | PrintAst _ -> pr_value_gen (print print_ast_rty_t ) value
+ | Annotate _ -> pr_value_gen (print annotate_rty_t ) value
+let pr_call : type a. a call -> string = fun call ->
let return what x = str_of_call call ^ " " ^ print what x in
match call with
| Add x -> return add_sty_t x
@@ -735,7 +747,7 @@ let document to_string_fmt =
(to_string_fmt (of_value (fun _ -> PCData "b") (Good ())));
Printf.printf "or:\n\n%s\n\nwhere the attributes loc_s and loc_c are optional.\n"
(to_string_fmt (of_value (fun _ -> PCData "b")
- (Fail (Stateid.initial,Some (15,34),"error message"))));
+ (Fail (Stateid.initial,Some (15,34),Richpp.richpp_of_string "error message"))));
document_type_encoding to_string_fmt
(* vim: set foldmethod=marker: *)
diff --git a/ide/xmlprotocol.mli b/ide/xmlprotocol.mli
index 3f8514551..265a50c47 100644
--- a/ide/xmlprotocol.mli
+++ b/ide/xmlprotocol.mli
@@ -13,7 +13,7 @@ open Xml_datatype
type 'a call
-type unknown
+type unknown_call = Unknown : 'a call -> unknown_call
val add : add_sty -> add_rty call
val edit_at : edit_at_sty -> edit_at_rty call
@@ -43,7 +43,7 @@ val protocol_version : string
(** * XML data marshalling *)
val of_call : 'a call -> xml
-val to_call : xml -> unknown call
+val to_call : xml -> unknown_call
val of_answer : 'a call -> 'a value -> xml
val to_answer : 'a call -> xml -> 'a value
diff --git a/interp/constrarg.ml b/interp/constrarg.ml
index d9c60a18b..b093d92e7 100644
--- a/interp/constrarg.ml
+++ b/interp/constrarg.ml
@@ -19,10 +19,8 @@ let loc_of_or_by_notation f = function
| AN c -> f c
| ByNotation (loc,s,_) -> loc
-let unsafe_of_type (t : argument_type) : ('a, 'b, 'c) Genarg.genarg_type =
- Obj.magic t
-
-let wit_int_or_var = unsafe_of_type IntOrVarArgType
+let wit_int_or_var =
+ Genarg.make0 ~dyn:(val_tag (topwit Stdarg.wit_int)) None "int_or_var"
let wit_intro_pattern : (Constrexpr.constr_expr intro_pattern_expr located, glob_constr_and_expr intro_pattern_expr located, intro_pattern) genarg_type =
Genarg.make0 None "intropattern"
@@ -30,35 +28,37 @@ let wit_intro_pattern : (Constrexpr.constr_expr intro_pattern_expr located, glob
let wit_tactic : (raw_tactic_expr, glob_tactic_expr, glob_tactic_expr) genarg_type =
Genarg.make0 None "tactic"
-let wit_ident = unsafe_of_type IdentArgType
+let wit_ident =
+ Genarg.make0 None "ident"
-let wit_var = unsafe_of_type VarArgType
+let wit_var =
+ Genarg.make0 ~dyn:(val_tag (topwit wit_ident)) None "var"
let wit_ref = Genarg.make0 None "ref"
-let wit_quant_hyp = unsafe_of_type QuantHypArgType
-
-let wit_genarg = unsafe_of_type GenArgType
+let wit_quant_hyp = Genarg.make0 None "quant_hyp"
let wit_sort : (glob_sort, glob_sort, sorts) genarg_type =
Genarg.make0 None "sort"
-let wit_constr = unsafe_of_type ConstrArgType
+let wit_constr =
+ Genarg.make0 None "constr"
-let wit_constr_may_eval = unsafe_of_type ConstrMayEvalArgType
+let wit_constr_may_eval =
+ Genarg.make0 ~dyn:(val_tag (topwit wit_constr)) None "constr_may_eval"
let wit_uconstr = Genarg.make0 None "uconstr"
-let wit_open_constr = unsafe_of_type OpenConstrArgType
+let wit_open_constr = Genarg.make0 ~dyn:(val_tag (topwit wit_constr)) None "open_constr"
-let wit_constr_with_bindings = unsafe_of_type ConstrWithBindingsArgType
+let wit_constr_with_bindings = Genarg.make0 None "constr_with_bindings"
-let wit_bindings = unsafe_of_type BindingsArgType
+let wit_bindings = Genarg.make0 None "bindings"
let wit_hyp_location_flag : 'a Genarg.uniform_genarg_type =
Genarg.make0 None "hyp_location_flag"
-let wit_red_expr = unsafe_of_type RedExprArgType
+let wit_red_expr = Genarg.make0 None "redexpr"
let wit_clause_dft_concl =
Genarg.make0 None "clause_dft_concl"
@@ -66,9 +66,19 @@ let wit_clause_dft_concl =
(** Register location *)
let () =
+ register_name0 wit_int_or_var "Constrarg.wit_int_or_var";
register_name0 wit_ref "Constrarg.wit_ref";
+ register_name0 wit_ident "Constrarg.wit_ident";
+ register_name0 wit_var "Constrarg.wit_var";
register_name0 wit_intro_pattern "Constrarg.wit_intro_pattern";
register_name0 wit_tactic "Constrarg.wit_tactic";
register_name0 wit_sort "Constrarg.wit_sort";
+ register_name0 wit_constr "Constrarg.wit_constr";
register_name0 wit_uconstr "Constrarg.wit_uconstr";
+ register_name0 wit_open_constr "Constrarg.wit_open_constr";
+ register_name0 wit_constr_may_eval "Constrarg.wit_constr_may_eval";
+ register_name0 wit_red_expr "Constrarg.wit_red_expr";
register_name0 wit_clause_dft_concl "Constrarg.wit_clause_dft_concl";
+ register_name0 wit_quant_hyp "Constrarg.wit_quant_hyp";
+ register_name0 wit_bindings "Constrarg.wit_bindings";
+ register_name0 wit_constr_with_bindings "Constrarg.wit_constr_with_bindings";
diff --git a/interp/constrarg.mli b/interp/constrarg.mli
index ebef1ada5..e1a5f4d7c 100644
--- a/interp/constrarg.mli
+++ b/interp/constrarg.mli
@@ -26,7 +26,7 @@ val loc_of_or_by_notation : ('a -> Loc.t) -> 'a or_by_notation -> Loc.t
(** {5 Additional generic arguments} *)
-val wit_int_or_var : int or_var uniform_genarg_type
+val wit_int_or_var : (int or_var, int or_var, int) genarg_type
val wit_intro_pattern : (constr_expr intro_pattern_expr located, glob_constr_and_expr intro_pattern_expr located, intro_pattern) genarg_type
@@ -38,8 +38,6 @@ val wit_ref : (reference, global_reference located or_var, global_reference) gen
val wit_quant_hyp : quantified_hypothesis uniform_genarg_type
-val wit_genarg : (raw_generic_argument, glob_generic_argument, typed_generic_argument) genarg_type
-
val wit_sort : (glob_sort, glob_sort, sorts) genarg_type
val wit_constr : (constr_expr, glob_constr_and_expr, constr) genarg_type
@@ -52,17 +50,17 @@ val wit_constr_may_eval :
val wit_uconstr : (constr_expr , glob_constr_and_expr, Glob_term.closed_glob_constr) genarg_type
val wit_open_constr :
- (open_constr_expr, open_glob_constr, Evd.open_constr) genarg_type
+ (constr_expr, glob_constr_and_expr, constr) genarg_type
val wit_constr_with_bindings :
(constr_expr with_bindings,
glob_constr_and_expr with_bindings,
- constr with_bindings Evd.sigma) genarg_type
+ constr with_bindings delayed_open) genarg_type
val wit_bindings :
(constr_expr bindings,
glob_constr_and_expr bindings,
- constr bindings Evd.sigma) genarg_type
+ constr bindings delayed_open) genarg_type
val wit_hyp_location_flag : Locus.hyp_location_flag uniform_genarg_type
diff --git a/interp/constrexpr_ops.ml b/interp/constrexpr_ops.ml
index 164470026..9c577034e 100644
--- a/interp/constrexpr_ops.ml
+++ b/interp/constrexpr_ops.ml
@@ -125,11 +125,10 @@ let rec constr_expr_eq e1 e2 =
Option.equal Int.equal proj1 proj2 &&
constr_expr_eq e1 e2 &&
List.equal args_eq al1 al2
- | CRecord (_, e1, l1), CRecord (_, e2, l2) ->
+ | CRecord (_, l1), CRecord (_, l2) ->
let field_eq (r1, e1) (r2, e2) =
eq_reference r1 r2 && constr_expr_eq e1 e2
in
- Option.equal constr_expr_eq e1 e2 &&
List.equal field_eq l1 l2
| CCases(_,_,r1,a1,brl1), CCases(_,_,r2,a2,brl2) ->
(** Don't care about the case_style *)
@@ -178,7 +177,7 @@ and args_eq (a1,e1) (a2,e2) =
Option.equal (eq_located explicitation_eq) e1 e2 &&
constr_expr_eq a1 a2
-and case_expr_eq (e1, (n1, p1)) (e2, (n2, p2)) =
+and case_expr_eq (e1, n1, p1) (e2, n2, p2) =
constr_expr_eq e1 e2 &&
Option.equal (eq_located Name.equal) n1 n2 &&
Option.equal cases_pattern_expr_eq p1 p2
@@ -238,7 +237,7 @@ let constr_loc = function
| CLetIn (loc,_,_,_) -> loc
| CAppExpl (loc,_,_) -> loc
| CApp (loc,_,_) -> loc
- | CRecord (loc,_,_) -> loc
+ | CRecord (loc,_) -> loc
| CCases (loc,_,_,_,_) -> loc
| CLetTuple (loc,_,_,_,_) -> loc
| CIf (loc,_,_,_,_) -> loc
diff --git a/interp/constrextern.ml b/interp/constrextern.ml
index 9df8f9c23..70a35c613 100644
--- a/interp/constrextern.ml
+++ b/interp/constrextern.ml
@@ -462,15 +462,6 @@ let is_needed_for_correct_partial_application tail imp =
exception Expl
-let params_implicit n impl =
- let rec aux n impl =
- if n == 0 then true
- else match impl with
- | [] -> false
- | imp :: impl when is_status_implicit imp -> aux (pred n) impl
- | _ -> false
- in aux n impl
-
(* Implicit args indexes are in ascending order *)
(* inctx is useful only if there is a last argument to be deduced from ctxt *)
let explicitize loc inctx impl (cf,f) args =
@@ -689,7 +680,7 @@ let rec extern inctx scopes vars r =
| head :: tail -> ip q locs' tail
((extern_reference loc Id.Set.empty (ConstRef c), head) :: acc)
in
- CRecord (loc, None, List.rev (ip projs locals args []))
+ CRecord (loc, List.rev (ip projs locals args []))
with
| Not_found | No_match | Exit ->
extern_app loc inctx
@@ -721,26 +712,29 @@ let rec extern inctx scopes vars r =
(cases_predicate_names tml) vars in
let rtntypopt' = Option.map (extern_typ scopes vars') rtntypopt in
let tml = List.map (fun (tm,(na,x)) ->
- let na' = match na,tm with
- | Anonymous, GVar (_, id) ->
- begin match rtntypopt with
- | None -> None
- | Some ntn ->
- if occur_glob_constr id ntn then
- Some (Loc.ghost, Anonymous)
- else None
- end
- | Anonymous, _ -> None
- | Name id, GVar (_,id') when Id.equal id id' -> None
- | Name _, _ -> Some (Loc.ghost,na) in
- (sub_extern false scopes vars tm,
- (na',Option.map (fun (loc,ind,nal) ->
- let args = List.map (fun x -> PatVar (Loc.ghost, x)) nal in
- let fullargs =
- if !Flags.in_debugger then args else
- Notation_ops.add_patterns_for_params ind args in
- extern_ind_pattern_in_scope scopes vars ind fullargs
- ) x))) tml in
+ let na' = match na,tm with
+ | Anonymous, GVar (_, id) ->
+ begin match rtntypopt with
+ | None -> None
+ | Some ntn ->
+ if occur_glob_constr id ntn then
+ Some (Loc.ghost, Anonymous)
+ else None
+ end
+ | Anonymous, _ -> None
+ | Name id, GVar (_,id') when Id.equal id id' -> None
+ | Name _, _ -> Some (Loc.ghost,na) in
+ (sub_extern false scopes vars tm,
+ na',
+ Option.map (fun (loc,ind,nal) ->
+ let args = List.map (fun x -> PatVar (Loc.ghost, x)) nal in
+ let fullargs =
+ if !Flags.in_debugger then args else
+ Notation_ops.add_patterns_for_params ind args in
+ extern_ind_pattern_in_scope scopes vars ind fullargs
+ ) x))
+ tml
+ in
let eqns = List.map (extern_eqn inctx scopes vars) eqns in
CCases (loc,sty,rtntypopt',tml,eqns)
diff --git a/interp/constrextern.mli b/interp/constrextern.mli
index bf1f529c6..f617faa38 100644
--- a/interp/constrextern.mli
+++ b/interp/constrextern.mli
@@ -8,7 +8,6 @@
open Names
open Term
-open Context
open Termops
open Environ
open Libnames
@@ -42,7 +41,7 @@ val extern_reference : Loc.t -> Id.Set.t -> global_reference -> reference
val extern_type : bool -> env -> Evd.evar_map -> types -> constr_expr
val extern_sort : Evd.evar_map -> sorts -> glob_sort
val extern_rel_context : constr option -> env -> Evd.evar_map ->
- rel_context -> local_binder list
+ Context.Rel.t -> local_binder list
(** Printing options *)
val print_implicits : bool ref
diff --git a/interp/constrintern.ml b/interp/constrintern.ml
index a7b1bb412..964ed0514 100644
--- a/interp/constrintern.ml
+++ b/interp/constrintern.ml
@@ -101,7 +101,7 @@ let global_reference id =
let construct_reference ctx id =
try
- Term.mkVar (let _ = Context.lookup_named id ctx in id)
+ Term.mkVar (let _ = Context.Named.lookup id ctx in id)
with Not_found ->
global_reference id
@@ -685,7 +685,7 @@ let intern_var genv (ltacvars,ntnvars) namedctx loc id =
str "variable " ++ pr_id id ++ str " should be bound to a term.")
else
(* Is [id] a goal or section variable *)
- let _ = Context.lookup_named id namedctx in
+ let _ = Context.Named.lookup id namedctx in
try
(* [id] a section variable *)
(* Redundant: could be done in intern_qualid *)
@@ -698,19 +698,6 @@ let intern_var genv (ltacvars,ntnvars) namedctx loc id =
(* [id] a goal variable *)
GVar (loc,id), [], [], []
-let proj_impls r impls =
- let env = Global.env () in
- let f (x, l) = x, projection_implicits env r l in
- List.map f impls
-
-let proj_scopes n scopes =
- List.skipn_at_least n scopes
-
-let proj_impls_scopes p impls scopes =
- match p with
- | Some (r, n) -> proj_impls r impls, proj_scopes n scopes
- | None -> impls, scopes
-
let find_appl_head_data c =
match c with
| GRef (loc,ref,_) as x ->
@@ -1386,7 +1373,7 @@ let internalize globalenv env allow_patvar lvar c =
let (env',rbefore) =
List.fold_left intern_local_binder (env,[]) before in
let ro = f (intern env') in
- let n' = Option.map (fun _ -> List.length (List.filter (fun (_,(_,_,b,_)) -> (* remove let-ins *) b = None) rbefore)) n in
+ let n' = Option.map (fun _ -> List.count (fun (_,(_,_,b,_)) -> (* remove let-ins *) b = None) rbefore) n in
n', ro, List.fold_left intern_local_binder (env',rbefore) after
in
let n, ro, (env',rbl) =
@@ -1492,7 +1479,7 @@ let internalize globalenv env allow_patvar lvar c =
apply_impargs c env impargs args_scopes
(merge_impargs l args) loc
- | CRecord (loc, _, fs) ->
+ | CRecord (loc, fs) ->
let cargs =
sort_fields true loc fs
(fun k l -> CHole (loc, Some (Evar_kinds.QuestionMark (Evar_kinds.Define true)), Misctypes.IntroAnonymous, None) :: l)
@@ -1506,7 +1493,7 @@ let internalize globalenv env allow_patvar lvar c =
intern env app
end
| CCases (loc, sty, rtnpo, tms, eqns) ->
- let as_in_vars = List.fold_left (fun acc (_,(na,inb)) ->
+ let as_in_vars = List.fold_left (fun acc (_,na,inb) ->
Option.fold_left (fun x tt -> List.fold_right Id.Set.add (ids_of_cases_indtype tt) x)
(Option.fold_left (fun x (_,y) -> match y with | Name y' -> Id.Set.add y' x |_ -> x) acc na)
inb) Id.Set.empty tms in
@@ -1542,7 +1529,7 @@ let internalize globalenv env allow_patvar lvar c =
| CLetTuple (loc, nal, (na,po), b, c) ->
let env' = reset_tmp_scope env in
(* "in" is None so no match to add *)
- let ((b',(na',_)),_,_) = intern_case_item env' Id.Set.empty (b,(na,None)) in
+ let ((b',(na',_)),_,_) = intern_case_item env' Id.Set.empty (b,na,None) in
let p' = Option.map (fun u ->
let env'' = push_name_env lvar (Variable,[],[],[]) (reset_hidden_inductive_implicit_test env')
(Loc.ghost,na') in
@@ -1551,7 +1538,7 @@ let internalize globalenv env allow_patvar lvar c =
intern (List.fold_left (push_name_env lvar (Variable,[],[],[])) (reset_hidden_inductive_implicit_test env) nal) c)
| CIf (loc, c, (na,po), b1, b2) ->
let env' = reset_tmp_scope env in
- let ((c',(na',_)),_,_) = intern_case_item env' Id.Set.empty (c,(na,None)) in (* no "in" no match to ad too *)
+ let ((c',(na',_)),_,_) = intern_case_item env' Id.Set.empty (c,na,None) in (* no "in" no match to ad too *)
let p' = Option.map (fun p ->
let env'' = push_name_env lvar (Variable,[],[],[]) (reset_hidden_inductive_implicit_test env)
(Loc.ghost,na') in
@@ -1628,7 +1615,7 @@ let internalize globalenv env allow_patvar lvar c =
let rhs' = intern {env with ids = env_ids} rhs in
(loc,eqn_ids,pl,rhs')) pll
- and intern_case_item env forbidden_names_for_gen (tm,(na,t)) =
+ and intern_case_item env forbidden_names_for_gen (tm,na,t) =
(*the "match" part *)
let tm' = intern env tm in
(* the "as" part *)
diff --git a/interp/constrintern.mli b/interp/constrintern.mli
index 22cf910b2..73ecc437d 100644
--- a/interp/constrintern.mli
+++ b/interp/constrintern.mli
@@ -8,7 +8,6 @@
open Names
open Term
-open Context
open Evd
open Environ
open Libnames
@@ -161,7 +160,7 @@ val interp_binder_evars : env -> evar_map ref -> Name.t -> constr_expr -> types
val interp_context_evars :
?global_level:bool -> ?impl_env:internalization_env -> ?shift:int ->
env -> evar_map ref -> local_binder list ->
- internalization_env * ((env * rel_context) * Impargs.manual_implicits)
+ internalization_env * ((env * Context.Rel.t) * Impargs.manual_implicits)
(* val interp_context_gen : (env -> glob_constr -> unsafe_type_judgment Evd.in_evar_universe_context) -> *)
(* (env -> Evarutil.type_constraint -> glob_constr -> unsafe_judgment Evd.in_evar_universe_context) -> *)
@@ -178,7 +177,7 @@ val interp_context_evars :
val locate_reference : Libnames.qualid -> Globnames.global_reference
val is_global : Id.t -> bool
-val construct_reference : named_context -> Id.t -> constr
+val construct_reference : Context.Named.t -> Id.t -> constr
val global_reference : Id.t -> constr
val global_reference_in_absolute_module : DirPath.t -> Id.t -> constr
diff --git a/interp/coqlib.ml b/interp/coqlib.ml
index 9e5173815..23bcddaea 100644
--- a/interp/coqlib.ml
+++ b/interp/coqlib.ml
@@ -87,7 +87,7 @@ let check_required_library d =
*)
(* or failing ...*)
errorlabstrm "Coqlib.check_required_library"
- (str "Library " ++ str (DirPath.to_string dir) ++ str " has to be required first.")
+ (str "Library " ++ pr_dirpath dir ++ str " has to be required first.")
(************************************************************************)
(* Specific Coq objects *)
diff --git a/interp/genintern.ml b/interp/genintern.ml
index 47b717358..d6bfd347f 100644
--- a/interp/genintern.ml
+++ b/interp/genintern.ml
@@ -37,20 +37,16 @@ module Subst = Register (SubstObj)
let intern = Intern.obj
let register_intern0 = Intern.register0
-let generic_intern ist v =
- let unpacker wit v =
- let (ist, v) = intern wit ist (raw v) in
- (ist, in_gen (glbwit wit) v)
- in
- unpack { unpacker; } v
+let generic_intern ist (GenArg (Rawwit wit, v)) =
+ let (ist, v) = intern wit ist v in
+ (ist, in_gen (glbwit wit) v)
(** Substitution functions *)
let substitute = Subst.obj
let register_subst0 = Subst.register0
-let generic_substitute subs v =
- let unpacker wit v = in_gen (glbwit wit) (substitute wit subs (glb v)) in
- unpack { unpacker; } v
+let generic_substitute subs (GenArg (Glbwit wit, v)) =
+ in_gen (glbwit wit) (substitute wit subs v)
let () = Hook.set Detyping.subst_genarg_hook generic_substitute
diff --git a/interp/topconstr.ml b/interp/topconstr.ml
index cc8e697ea..8293f7f88 100644
--- a/interp/topconstr.ml
+++ b/interp/topconstr.ml
@@ -71,7 +71,7 @@ let ids_of_cases_indtype p =
let ids_of_cases_tomatch tms =
List.fold_right
- (fun (_,(ona,indnal)) l ->
+ (fun (_, ona, indnal) l ->
Option.fold_right (fun t ids -> cases_pattern_fold_names Id.Set.add ids t)
indnal
(Option.fold_right (Loc.down_located (name_fold Id.Set.add)) ona l))
@@ -111,11 +111,11 @@ let fold_constr_expr_with_binders g f n acc = function
| CDelimiters (loc,_,a) -> f n acc a
| CHole _ | CEvar _ | CPatVar _ | CSort _ | CPrim _ | CRef _ ->
acc
- | CRecord (loc,_,l) -> List.fold_left (fun acc (id, c) -> f n acc c) acc l
+ | CRecord (loc,l) -> List.fold_left (fun acc (id, c) -> f n acc c) acc l
| CCases (loc,sty,rtnpo,al,bl) ->
let ids = ids_of_cases_tomatch al in
let acc = Option.fold_left (f (Id.Set.fold g ids n)) acc rtnpo in
- let acc = List.fold_left (f n) acc (List.map fst al) in
+ let acc = List.fold_left (f n) acc (List.map (fun (fst,_,_) -> fst) al) in
List.fold_right (fun (loc,patl,rhs) acc ->
let ids = ids_of_pattern_list patl in
f (Id.Set.fold g ids n) acc rhs) bl acc
@@ -213,14 +213,14 @@ let map_constr_expr_with_binders g f e = function
| CDelimiters (loc,s,a) -> CDelimiters (loc,s,f e a)
| CHole _ | CEvar _ | CPatVar _ | CSort _
| CPrim _ | CRef _ as x -> x
- | CRecord (loc,p,l) -> CRecord (loc,p,List.map (fun (id, c) -> (id, f e c)) l)
+ | CRecord (loc,l) -> CRecord (loc,List.map (fun (id, c) -> (id, f e c)) l)
| CCases (loc,sty,rtnpo,a,bl) ->
let bl = List.map (fun (loc,patl,rhs) ->
let ids = ids_of_pattern_list patl in
(loc,patl,f (Id.Set.fold g ids e) rhs)) bl in
let ids = ids_of_cases_tomatch a in
let po = Option.map (f (Id.Set.fold g ids e)) rtnpo in
- CCases (loc, sty, po, List.map (fun (tm,x) -> (f e tm,x)) a,bl)
+ CCases (loc, sty, po, List.map (fun (tm,x,y) -> f e tm,x,y) a,bl)
| CLetTuple (loc,nal,(ona,po),b,c) ->
let e' = List.fold_right (Loc.down_located (name_fold g)) nal e in
let e'' = Option.fold_right (Loc.down_located (name_fold g)) ona e in
diff --git a/intf/constrexpr.mli b/intf/constrexpr.mli
index dcdbd47f6..1443a2cd6 100644
--- a/intf/constrexpr.mli
+++ b/intf/constrexpr.mli
@@ -32,7 +32,9 @@ type abstraction_kind = AbsLambda | AbsPi
type proj_flag = int option (** [Some n] = proj of the n-th visible argument *)
-type prim_token = Numeral of Bigint.bigint | String of string
+type prim_token =
+ | Numeral of Bigint.bigint (** representation of integer literals that appear in Coq scripts. *)
+ | String of string
type raw_cases_pattern_expr =
| RCPatAlias of Loc.t * raw_cases_pattern_expr * Id.t
@@ -73,9 +75,15 @@ type constr_expr =
| CAppExpl of Loc.t * (proj_flag * reference * instance_expr option) * constr_expr list
| CApp of Loc.t * (proj_flag * constr_expr) *
(constr_expr * explicitation located option) list
- | CRecord of Loc.t * constr_expr option * (reference * constr_expr) list
- | CCases of Loc.t * case_style * constr_expr option *
- case_expr list * branch_expr list
+ | CRecord of Loc.t * (reference * constr_expr) list
+
+ (* representation of the "let" and "match" constructs *)
+ | CCases of Loc.t (* position of the "match" keyword *)
+ * case_style (* determines whether this value represents "let" or "match" construct *)
+ * constr_expr option (* return-clause *)
+ * case_expr list
+ * branch_expr list (* branches *)
+
| CLetTuple of Loc.t * Name.t located list * (Name.t located option * constr_expr option) *
constr_expr * constr_expr
| CIf of Loc.t * constr_expr * (Name.t located option * constr_expr option)
@@ -90,8 +98,9 @@ type constr_expr =
| CPrim of Loc.t * prim_token
| CDelimiters of Loc.t * string * constr_expr
-and case_expr =
- constr_expr * (Name.t located option * cases_pattern_expr option)
+and case_expr = constr_expr (* expression that is being matched *)
+ * Name.t located option (* as-clause *)
+ * cases_pattern_expr option (* in-clause *)
and branch_expr =
Loc.t * cases_pattern_expr list located list * constr_expr
diff --git a/intf/extend.mli b/intf/extend.mli
index 033552380..57abdc38f 100644
--- a/intf/extend.mli
+++ b/intf/extend.mli
@@ -50,3 +50,49 @@ type constr_prod_entry_key =
type simple_constr_prod_entry_key =
(production_level,unit) constr_entry_key_gen
+
+(** {5 AST for user-provided entries} *)
+
+type user_symbol =
+| Ulist1 : user_symbol -> user_symbol
+| Ulist1sep : user_symbol * string -> user_symbol
+| Ulist0 : user_symbol -> user_symbol
+| Ulist0sep : user_symbol * string -> user_symbol
+| Uopt : user_symbol -> user_symbol
+| Umodifiers : user_symbol -> user_symbol
+| Uentry : string -> user_symbol
+| Uentryl : string * int -> user_symbol
+
+(** {5 Type-safe grammar extension} *)
+
+type ('self, 'a) symbol =
+| Atoken : Tok.t -> ('self, string) symbol
+| Alist1 : ('self, 'a) symbol -> ('self, 'a list) symbol
+| Alist1sep : ('self, 'a) symbol * string -> ('self, 'a list) symbol
+| Alist0 : ('self, 'a) symbol -> ('self, 'a list) symbol
+| Alist0sep : ('self, 'a) symbol * string -> ('self, 'a list) symbol
+| Aopt : ('self, 'a) symbol -> ('self, 'a option) symbol
+| Amodifiers : ('self, 'a) symbol -> ('self, 'a list) symbol
+| Aself : ('self, 'self) symbol
+| Anext : ('self, 'self) symbol
+| Aentry : 'a Entry.t -> ('self, 'a) symbol
+| Aentryl : 'a Entry.t * int -> ('self, 'a) symbol
+
+type ('self, _, 'r) rule =
+| Stop : ('self, 'r, 'r) rule
+| Next : ('self, 'a, 'r) rule * ('self, 'b) symbol -> ('self, 'b -> 'a, 'r) rule
+
+type 'a production_rule =
+| Rule : ('a, 'act, Loc.t -> 'a) rule * 'act -> 'a production_rule
+
+type 'a single_extend_statment =
+ string option *
+ (** Level *)
+ gram_assoc option *
+ (** Associativity *)
+ 'a production_rule list
+ (** Symbol list with the interpretation function *)
+
+type 'a extend_statment =
+ gram_position option *
+ 'a single_extend_statment list
diff --git a/intf/glob_term.mli b/intf/glob_term.mli
index 81d3e2222..b3159c860 100644
--- a/intf/glob_term.mli
+++ b/intf/glob_term.mli
@@ -29,9 +29,14 @@ type cases_pattern =
| PatCstr of Loc.t * constructor * cases_pattern list * Name.t
(** [PatCstr(p,C,l,x)] = "|'C' 'l' as 'x'" *)
+(** Representation of an internalized (or in other words globalized) term. *)
type glob_constr =
| GRef of (Loc.t * global_reference * glob_level list option)
+ (** An identifier that represents a reference to an object defined
+ either in the (global) environment or in the (local) context. *)
| GVar of (Loc.t * Id.t)
+ (** An identifier that cannot be regarded as "GRef".
+ Bound variables are typically represented this way. *)
| GEvar of Loc.t * existential_name * (Id.t * glob_constr) list
| GPatVar of Loc.t * (bool * patvar) (** Used for patterns only *)
| GApp of Loc.t * glob_constr * glob_constr list
@@ -39,8 +44,7 @@ type glob_constr =
| GProd of Loc.t * Name.t * binding_kind * glob_constr * glob_constr
| GLetIn of Loc.t * Name.t * glob_constr * glob_constr
| GCases of Loc.t * case_style * glob_constr option * tomatch_tuples * cases_clauses
- (** [GCases(l,style,r,tur,cc)] = "match 'tur' return 'r' with 'cc'" (in
- [MatchStyle]) *)
+ (** [GCases(l,style,r,tur,cc)] = "match 'tur' return 'r' with 'cc'" (in [MatchStyle]) *)
| GLetTuple of Loc.t * Name.t list * (Name.t * glob_constr option) *
glob_constr * glob_constr
| GIf of Loc.t * glob_constr * (Name.t * glob_constr option) * glob_constr * glob_constr
diff --git a/intf/misctypes.mli b/intf/misctypes.mli
index a20093bce..3c6d59ff0 100644
--- a/intf/misctypes.mli
+++ b/intf/misctypes.mli
@@ -16,6 +16,8 @@ type patvar = Id.t
(** Introduction patterns *)
+type tuple_flag = bool (* tells pattern list should be list of fixed length *)
+
type 'constr intro_pattern_expr =
| IntroForthcoming of bool
| IntroNaming of intro_pattern_naming_expr
@@ -31,7 +33,8 @@ and 'constr intro_pattern_action_expr =
| IntroApplyOn of 'constr * (Loc.t * 'constr intro_pattern_expr)
| IntroRewrite of bool
and 'constr or_and_intro_pattern_expr =
- (Loc.t * 'constr intro_pattern_expr) list list
+ | IntroOrPattern of (Loc.t * 'constr intro_pattern_expr) list list
+ | IntroAndPattern of (Loc.t * 'constr intro_pattern_expr) list
(** Move destination for hypothesis *)
@@ -43,7 +46,10 @@ type 'id move_location =
(** Sorts *)
-type 'a glob_sort_gen = GProp | GSet | GType of 'a
+type 'a glob_sort_gen =
+ | GProp (** representation of [Prop] literal *)
+ | GSet (** representation of [Set] literal *)
+ | GType of 'a (** representation of [Type] literal *)
type sort_info = string Loc.located list
type level_info = string Loc.located option
diff --git a/intf/tacexpr.mli b/intf/tacexpr.mli
index 6c5e44064..57c61874a 100644
--- a/intf/tacexpr.mli
+++ b/intf/tacexpr.mli
@@ -104,6 +104,11 @@ type ml_tactic_name = {
mltac_tactic : string;
}
+type ml_tactic_entry = {
+ mltac_name : ml_tactic_name;
+ mltac_index : int;
+}
+
(** Composite types *)
(** In globalize tactics, we need to keep the initial [constr_expr] to recompute
@@ -117,11 +122,12 @@ type open_glob_constr = unit * glob_constr_and_expr
type binding_bound_vars = Id.Set.t
type glob_constr_pattern_and_expr = glob_constr_and_expr * constr_pattern
-type delayed_open_constr_with_bindings =
- Environ.env -> Evd.evar_map -> Evd.evar_map * Term.constr with_bindings
+type 'a delayed_open =
+ { delayed : 'r. Environ.env -> 'r Sigma.t -> ('a, 'r) Sigma.sigma }
-type delayed_open_constr =
- Environ.env -> Evd.evar_map -> Evd.evar_map * Term.constr
+type delayed_open_constr_with_bindings = Term.constr with_bindings delayed_open
+
+type delayed_open_constr = Term.constr delayed_open
type intro_pattern = delayed_open_constr intro_pattern_expr located
type intro_patterns = delayed_open_constr intro_pattern_expr located list
@@ -156,10 +162,6 @@ type 'a gen_atomic_tactic_expr =
rec_flag * evars_flag * ('trm,'dtrm,'nam) induction_clause_list
| TacDoubleInduction of quantified_hypothesis * quantified_hypothesis
- (* Automation tactics *)
- | TacTrivial of debug * 'trm list * string list option
- | TacAuto of debug * int or_var option * 'trm list * string list option
-
(* Context management *)
| TacClear of bool * 'nam list
| TacClearBody of 'nam list
@@ -203,7 +205,6 @@ constraint 'a = <
(** Possible arguments of a tactic definition *)
and 'a gen_tactic_arg =
- | TacDynamic of Loc.t * Dyn.t
| TacGeneric of 'lev generic_argument
| MetaIdArg of Loc.t * bool * string
| ConstrMayEval of ('trm,'cst,'pat) may_eval
@@ -291,9 +292,9 @@ and 'a gen_tactic_expr =
| TacFun of 'a gen_tactic_fun_ast
| TacArg of 'a gen_tactic_arg located
(* For ML extensions *)
- | TacML of Loc.t * ml_tactic_name * 'l generic_argument list
+ | TacML of Loc.t * ml_tactic_entry * 'a gen_tactic_arg list
(* For syntax extensions *)
- | TacAlias of Loc.t * KerName.t * (Id.t * 'l generic_argument) list
+ | TacAlias of Loc.t * KerName.t * 'a gen_tactic_arg list
constraint 'a = <
term:'t;
@@ -387,8 +388,8 @@ type raw_tactic_arg =
type t_trm = Term.constr
type t_utrm = Glob_term.closed_glob_constr
-type t_pat = glob_constr_pattern_and_expr
-type t_cst = evaluable_global_reference and_short_name
+type t_pat = constr_pattern
+type t_cst = evaluable_global_reference
type t_ref = ltac_constant located
type t_nam = Id.t
diff --git a/intf/vernacexpr.mli b/intf/vernacexpr.mli
index 13dde16ec..7273b92b9 100644
--- a/intf/vernacexpr.mli
+++ b/intf/vernacexpr.mli
@@ -19,7 +19,6 @@ open Libnames
type lident = Id.t located
type lname = Name.t located
type lstring = string located
-type lreference = reference
type class_rawexpr = FunClass | SortClass | RefClass of reference or_by_notation
@@ -206,7 +205,7 @@ type proof_expr =
type grammar_tactic_prod_item_expr =
| TacTerm of string
- | TacNonTerm of Loc.t * string * (Names.Id.t * string) option
+ | TacNonTerm of Loc.t * string * (Names.Id.t * string)
type syntax_modifier =
| SetItemLevel of string list * Extend.production_level
@@ -287,8 +286,8 @@ type module_binder = bool option * lident list * module_ast_inl
type vernac_expr =
(* Control *)
| VernacLoad of verbose_flag * string
- | VernacTime of vernac_list
- | VernacRedirect of string * vernac_list
+ | VernacTime of vernac_expr located
+ | VernacRedirect of string * vernac_expr located
| VernacTimeout of int * vernac_expr
| VernacFail of vernac_expr
| VernacError of exn (* always fails *)
@@ -330,8 +329,8 @@ type vernac_expr =
| VernacBeginSection of lident
| VernacEndSegment of lident
| VernacRequire of
- lreference option * export_flag option * lreference list
- | VernacImport of export_flag * lreference list
+ reference option * export_flag option * reference list
+ | VernacImport of export_flag * reference list
| VernacCanonical of reference or_by_notation
| VernacCoercion of obsolete_locality * reference or_by_notation *
class_rawexpr * class_rawexpr
@@ -386,8 +385,7 @@ type vernac_expr =
| VernacBackTo of int
(* Commands *)
- | VernacDeclareTacticDefinition of
- (rec_flag * (reference * bool * raw_tactic_expr) list)
+ | VernacDeclareTacticDefinition of tacdef_body list
| VernacCreateHintDb of string * bool
| VernacRemoveHints of string list * reference list
| VernacHints of obsolete_locality * string list * hints_expr
@@ -421,7 +419,6 @@ type vernac_expr =
| VernacLocate of locatable
| VernacRegister of lident * register_kind
| VernacComments of comment list
- | VernacNop
(* Stm backdoor *)
| VernacStm of vernac_expr stm_vernac
@@ -455,9 +452,9 @@ type vernac_expr =
| VernacPolymorphic of bool * vernac_expr
| VernacLocal of bool * vernac_expr
-and vernac_list = located_vernac_expr list
-
-and located_vernac_expr = Loc.t * vernac_expr
+and tacdef_body =
+ | TacticDefinition of Id.t Loc.located * raw_tactic_expr (* indicates that user employed ':=' in Ltac body *)
+ | TacticRedefinition of reference * raw_tactic_expr (* indicates that user employed '::=' in Ltac body *)
(* A vernac classifier has to tell if a command:
vernac_when: has to be executed now (alters the parser) or later
diff --git a/kernel/cemitcodes.ml b/kernel/cemitcodes.ml
index 57e32684a..d779a81ff 100644
--- a/kernel/cemitcodes.ml
+++ b/kernel/cemitcodes.ml
@@ -29,11 +29,19 @@ let patch_char4 buff pos c1 c2 c3 c4 =
String.unsafe_set buff (pos + 2) c3;
String.unsafe_set buff (pos + 3) c4
-let patch_int buff pos n =
+let patch buff (pos, n) =
patch_char4 buff pos
(Char.unsafe_chr n) (Char.unsafe_chr (n asr 8)) (Char.unsafe_chr (n asr 16))
(Char.unsafe_chr (n asr 24))
+let patch_int buff patches =
+ (* copy code *before* patching because of nested evaluations:
+ the code we are patching might be called (and thus "concurrently" patched)
+ and results in wrong results. Side-effects... *)
+ let buff = String.copy buff in
+ let () = List.iter (fun p -> patch buff p) patches in
+ buff
+
(* Buffering of bytecode *)
let out_buffer = ref(String.create 1024)
@@ -298,8 +306,6 @@ let init () =
type emitcodes = string
-let copy = String.copy
-
let length = String.length
type to_patch = emitcodes * (patch list) * fv
@@ -324,8 +330,6 @@ let subst_patch s (ri,pos) =
let subst_to_patch s (code,pl,fv) =
code,List.rev_map (subst_patch s) pl,fv
-let subst_pconstant s (kn, u) = (fst (subst_con_kn s kn), u)
-
type body_code =
| BCdefined of to_patch
| BCalias of Names.constant
@@ -366,6 +370,8 @@ let to_memory (init_code, fun_code, fv) =
emit fun_code;
let code = String.create !out_position in
String.unsafe_blit !out_buffer 0 code 0 !out_position;
+ (** Later uses of this string are all purely functional *)
+ let code = CString.hcons code in
let reloc = List.rev !reloc_info in
Array.iter (fun lbl ->
(match lbl with
diff --git a/kernel/cemitcodes.mli b/kernel/cemitcodes.mli
index 10f3a6087..c80edd596 100644
--- a/kernel/cemitcodes.mli
+++ b/kernel/cemitcodes.mli
@@ -13,11 +13,9 @@ val subst_patch : Mod_subst.substitution -> patch -> patch
type emitcodes
-val copy : emitcodes -> emitcodes
-
val length : emitcodes -> int
-val patch_int : emitcodes -> (*pos*)int -> int -> unit
+val patch_int : emitcodes -> ((*pos*)int * int) list -> emitcodes
type to_patch = emitcodes * (patch list) * fv
diff --git a/kernel/closure.ml b/kernel/closure.ml
index 2ba80d836..9bc67b5ad 100644
--- a/kernel/closure.ml
+++ b/kernel/closure.ml
@@ -346,7 +346,6 @@ and fterm =
| FProj of projection * fconstr
| FFix of fixpoint * fconstr subs
| FCoFix of cofixpoint * fconstr subs
- | FCase of case_info * fconstr * fconstr * fconstr array
| FCaseT of case_info * constr * fconstr * constr array * fconstr subs (* predicate and branches are closures *)
| FLambda of int * (Name.t * constr) list * constr * fconstr subs
| FProd of Name.t * fconstr * fconstr
@@ -376,7 +375,6 @@ let update v1 no t =
type stack_member =
| Zapp of fconstr array
- | Zcase of case_info * fconstr * fconstr array
| ZcaseT of case_info * constr * constr array * fconstr subs
| Zproj of int * int * constant
| Zfix of fconstr * stack
@@ -569,10 +567,6 @@ let rec to_constr constr_fun lfts v =
| FFlex (ConstKey op) -> mkConstU op
| FInd op -> mkIndU op
| FConstruct op -> mkConstructU op
- | FCase (ci,p,c,ve) ->
- mkCase (ci, constr_fun lfts p,
- constr_fun lfts c,
- CArray.Fun1.map constr_fun lfts ve)
| FCaseT (ci,p,c,ve,env) ->
mkCase (ci, constr_fun lfts (mk_clos env p),
constr_fun lfts c,
@@ -646,9 +640,6 @@ let rec zip m stk =
match stk with
| [] -> m
| Zapp args :: s -> zip {norm=neutr m.norm; term=FApp(m, args)} s
- | Zcase(ci,p,br)::s ->
- let t = FCase(ci, p, m, br) in
- zip {norm=neutr m.norm; term=t} s
| ZcaseT(ci,p,br,e)::s ->
let t = FCaseT(ci, p, m, br, e) in
zip {norm=neutr m.norm; term=t} s
@@ -731,7 +722,7 @@ let rec get_args n tys f e stk =
(* Eta expansion: add a reference to implicit surrounding lambda at end of stack *)
let rec eta_expand_stack = function
- | (Zapp _ | Zfix _ | Zcase _ | ZcaseT _ | Zproj _
+ | (Zapp _ | Zfix _ | ZcaseT _ | Zproj _
| Zshift _ | Zupdate _ as e) :: s ->
e :: eta_expand_stack s
| [] ->
@@ -842,7 +833,6 @@ let rec knh info m stk =
| FCLOS(t,e) -> knht info e t (zupdate m stk)
| FLOCKED -> assert false
| FApp(a,b) -> knh info a (append_stack b (zupdate m stk))
- | FCase(ci,p,t,br) -> knh info t (Zcase(ci,p,br)::zupdate m stk)
| FCaseT(ci,p,t,br,e) -> knh info t (ZcaseT(ci,p,br,e)::zupdate m stk)
| FFix(((ri,n),(_,_,_)),_) ->
(match get_nth_arg m ri.(n) stk with
@@ -904,10 +894,6 @@ let rec knr info m stk =
| None -> (set_norm m; (m,stk)))
| FConstruct((ind,c),u) when red_set info.i_flags fIOTA ->
(match strip_update_shift_app m stk with
- (depth, args, Zcase(ci,_,br)::s) ->
- assert (ci.ci_npar>=0);
- let rargs = drop_parameters depth ci.ci_npar args in
- kni info br.(c-1) (rargs@s)
| (depth, args, ZcaseT(ci,_,br,e)::s) ->
assert (ci.ci_npar>=0);
let rargs = drop_parameters depth ci.ci_npar args in
@@ -924,7 +910,7 @@ let rec knr info m stk =
| (_,args,s) -> (m,args@s))
| FCoFix _ when red_set info.i_flags fIOTA ->
(match strip_update_shift_app m stk with
- (_, args, (((Zcase _|ZcaseT _|Zproj _)::_) as stk')) ->
+ (_, args, (((ZcaseT _|Zproj _)::_) as stk')) ->
let (fxe,fxbd) = contract_fix_vect m.term in
knit info fxe fxbd (args@stk')
| (_,args,s) -> (m,args@s))
@@ -953,9 +939,6 @@ let rec zip_term zfun m stk =
| [] -> m
| Zapp args :: s ->
zip_term zfun (mkApp(m, Array.map zfun args)) s
- | Zcase(ci,p,br)::s ->
- let t = mkCase(ci, zfun p, m, Array.map zfun br) in
- zip_term zfun t s
| ZcaseT(ci,p,br,e)::s ->
let t = mkCase(ci, zfun (mk_clos e p), m,
Array.map (fun b -> zfun (mk_clos e b)) br) in
diff --git a/kernel/closure.mli b/kernel/closure.mli
index 4b8f87227..07176cb7d 100644
--- a/kernel/closure.mli
+++ b/kernel/closure.mli
@@ -119,7 +119,6 @@ type fterm =
| FProj of projection * fconstr
| FFix of fixpoint * fconstr subs
| FCoFix of cofixpoint * fconstr subs
- | FCase of case_info * fconstr * fconstr * fconstr array
| FCaseT of case_info * constr * fconstr * constr array * fconstr subs (* predicate and branches are closures *)
| FLambda of int * (Name.t * constr) list * constr * fconstr subs
| FProd of Name.t * fconstr * fconstr
@@ -136,7 +135,6 @@ type fterm =
type stack_member =
| Zapp of fconstr array
- | Zcase of case_info * fconstr * fconstr array
| ZcaseT of case_info * constr * constr array * fconstr subs
| Zproj of int * int * constant
| Zfix of fconstr * stack
diff --git a/kernel/constr.ml b/kernel/constr.ml
index 7e103b1da..8e05e29eb 100644
--- a/kernel/constr.ml
+++ b/kernel/constr.ml
@@ -41,12 +41,24 @@ type case_printing =
{ ind_tags : bool list; (** tell whether letin or lambda in the arity of the inductive type *)
cstr_tags : bool list array; (* whether each pattern var of each constructor is a let-in (true) or not (false) *)
style : case_style }
+
+(* INVARIANT:
+ * - Array.length ci_cstr_ndecls = Array.length ci_cstr_nargs
+ * - forall (i : 0 .. pred (Array.length ci_cstr_ndecls)),
+ * ci_cstr_ndecls.(i) >= ci_cstr_nargs.(i)
+ *)
type case_info =
- { ci_ind : inductive;
- ci_npar : int;
- ci_cstr_ndecls : int array; (* number of pattern vars of each constructor (with let's)*)
- ci_cstr_nargs : int array; (* number of pattern vars of each constructor (w/o let's) *)
- ci_pp_info : case_printing (* not interpreted by the kernel *)
+ { ci_ind : inductive; (* inductive type to which belongs the value that is being matched *)
+ ci_npar : int; (* number of parameters of the above inductive type *)
+ ci_cstr_ndecls : int array; (* For each constructor, the corresponding integer determines
+ the number of values that can be bound in a match-construct.
+ NOTE: parameters of the inductive type are therefore excluded from the count *)
+ ci_cstr_nargs : int array; (* for each constructor, the corresponding integers determines
+ the number of values that can be applied to the constructor,
+ in addition to the parameters of the related inductive type
+ NOTE: "lets" are therefore excluded from the count
+ NOTE: parameters of the inductive type are also excluded from the count *)
+ ci_pp_info : case_printing (* not interpreted by the kernel *)
}
(********************************************************************)
@@ -545,8 +557,8 @@ let equal m n = eq_constr m n (* to avoid tracing a recursive fun *)
let eq_constr_univs univs m n =
if m == n then true
else
- let eq_universes _ = Univ.Instance.check_eq univs in
- let eq_sorts s1 s2 = s1 == s2 || Univ.check_eq univs (Sorts.univ_of_sort s1) (Sorts.univ_of_sort s2) in
+ let eq_universes _ = UGraph.check_eq_instances univs in
+ let eq_sorts s1 s2 = s1 == s2 || UGraph.check_eq univs (Sorts.univ_of_sort s1) (Sorts.univ_of_sort s2) in
let rec eq_constr' m n =
m == n || compare_head_gen eq_universes eq_sorts eq_constr' m n
in compare_head_gen eq_universes eq_sorts eq_constr' m n
@@ -554,11 +566,11 @@ let eq_constr_univs univs m n =
let leq_constr_univs univs m n =
if m == n then true
else
- let eq_universes _ = Univ.Instance.check_eq univs in
+ let eq_universes _ = UGraph.check_eq_instances univs in
let eq_sorts s1 s2 = s1 == s2 ||
- Univ.check_eq univs (Sorts.univ_of_sort s1) (Sorts.univ_of_sort s2) in
+ UGraph.check_eq univs (Sorts.univ_of_sort s1) (Sorts.univ_of_sort s2) in
let leq_sorts s1 s2 = s1 == s2 ||
- Univ.check_leq univs (Sorts.univ_of_sort s1) (Sorts.univ_of_sort s2) in
+ UGraph.check_leq univs (Sorts.univ_of_sort s1) (Sorts.univ_of_sort s2) in
let rec eq_constr' m n =
m == n || compare_head_gen eq_universes eq_sorts eq_constr' m n
in
@@ -571,12 +583,12 @@ let eq_constr_univs_infer univs m n =
if m == n then true, Constraint.empty
else
let cstrs = ref Constraint.empty in
- let eq_universes strict = Univ.Instance.check_eq univs in
+ let eq_universes strict = UGraph.check_eq_instances univs in
let eq_sorts s1 s2 =
if Sorts.equal s1 s2 then true
else
let u1 = Sorts.univ_of_sort s1 and u2 = Sorts.univ_of_sort s2 in
- if Univ.check_eq univs u1 u2 then true
+ if UGraph.check_eq univs u1 u2 then true
else
(cstrs := Univ.enforce_eq u1 u2 !cstrs;
true)
@@ -591,12 +603,12 @@ let leq_constr_univs_infer univs m n =
if m == n then true, Constraint.empty
else
let cstrs = ref Constraint.empty in
- let eq_universes strict l l' = Univ.Instance.check_eq univs l l' in
+ let eq_universes strict l l' = UGraph.check_eq_instances univs l l' in
let eq_sorts s1 s2 =
if Sorts.equal s1 s2 then true
else
let u1 = Sorts.univ_of_sort s1 and u2 = Sorts.univ_of_sort s2 in
- if Univ.check_eq univs u1 u2 then true
+ if UGraph.check_eq univs u1 u2 then true
else (cstrs := Univ.enforce_eq u1 u2 !cstrs;
true)
in
@@ -604,7 +616,7 @@ let leq_constr_univs_infer univs m n =
if Sorts.equal s1 s2 then true
else
let u1 = Sorts.univ_of_sort s1 and u2 = Sorts.univ_of_sort s2 in
- if Univ.check_leq univs u1 u2 then true
+ if UGraph.check_leq univs u1 u2 then true
else
(cstrs := Univ.enforce_leq u1 u2 !cstrs;
true)
diff --git a/kernel/constr.mli b/kernel/constr.mli
index c3118cdf7..f76b5ae4f 100644
--- a/kernel/constr.mli
+++ b/kernel/constr.mli
@@ -30,13 +30,23 @@ type case_printing =
cstr_tags : bool list array; (** tell whether letin or lambda in the signature of each constructor *)
style : case_style }
-(** the integer is the number of real args, needed for reduction *)
+(* INVARIANT:
+ * - Array.length ci_cstr_ndecls = Array.length ci_cstr_nargs
+ * - forall (i : 0 .. pred (Array.length ci_cstr_ndecls)),
+ * ci_cstr_ndecls.(i) >= ci_cstr_nargs.(i)
+ *)
type case_info =
- { ci_ind : inductive;
- ci_npar : int;
- ci_cstr_ndecls : int array; (* number of pattern vars of each constructor (with let's)*)
- ci_cstr_nargs : int array; (* number of pattern vars of each constructor (w/o let's) *)
- ci_pp_info : case_printing (** not interpreted by the kernel *)
+ { ci_ind : inductive; (* inductive type to which belongs the value that is being matched *)
+ ci_npar : int; (* number of parameters of the above inductive type *)
+ ci_cstr_ndecls : int array; (* For each constructor, the corresponding integer determines
+ the number of values that can be bound in a match-construct.
+ NOTE: parameters of the inductive type are therefore excluded from the count *)
+ ci_cstr_nargs : int array; (* for each constructor, the corresponding integers determines
+ the number of values that can be applied to the constructor,
+ in addition to the parameters of the related inductive type
+ NOTE: "lets" are therefore excluded from the count
+ NOTE: parameters of the inductive type are also excluded from the count *)
+ ci_pp_info : case_printing (* not interpreted by the kernel *)
}
(** {6 The type of constructions } *)
@@ -93,8 +103,9 @@ val mkLambda : Name.t * types * constr -> constr
(** Constructs the product [let x = t1 : t2 in t3] *)
val mkLetIn : Name.t * constr * types * constr -> constr
-(** [mkApp (f,[| t_1; ...; t_n |]] constructs the application
- {% $(f~t_1~\dots~t_n)$ %}. *)
+(** [mkApp (f, [|t1; ...; tN|]] constructs the application
+ {%html:(f t<sub>1</sub> ... t<sub>n</sub>)%}
+ {%latex:$(f~t_1\dots f_n)$%}. *)
val mkApp : constr * constr array -> constr
val map_puniverses : ('a -> 'b) -> 'a puniverses -> 'b puniverses
@@ -181,10 +192,13 @@ type ('constr, 'types) kind_of_term =
| Evar of 'constr pexistential
| Sort of Sorts.t
| Cast of 'constr * cast_kind * 'types
- | Prod of Name.t * 'types * 'types
- | Lambda of Name.t * 'types * 'constr
- | LetIn of Name.t * 'constr * 'types * 'constr
- | App of 'constr * 'constr array
+ | Prod of Name.t * 'types * 'types (** Concrete syntax ["forall A:B,C"] is represented as [Prod (A,B,C)]. *)
+ | Lambda of Name.t * 'types * 'constr (** Concrete syntax ["fun A:B => C"] is represented as [Lambda (A,B,C)]. *)
+ | LetIn of Name.t * 'constr * 'types * 'constr (** Concrete syntax ["let A:B := C in D"] is represented as [LetIn (A,B,C,D)]. *)
+ | App of 'constr * 'constr array (** Concrete syntax ["(F P1 P2 ... Pn)"] is represented as [App (F, [|P1; P2; ...; Pn|])].
+ The {!mkApp} constructor also enforces the following invariant:
+ - [F] itself is not {!App}
+ - and [[|P1;..;Pn|]] is not empty. *)
| Const of constant puniverses
| Ind of inductive puniverses
| Construct of constructor puniverses
@@ -205,19 +219,19 @@ val equal : constr -> constr -> bool
(** [eq_constr_univs u a b] is [true] if [a] equals [b] modulo alpha, casts,
application grouping and the universe equalities in [u]. *)
-val eq_constr_univs : constr Univ.check_function
+val eq_constr_univs : constr UGraph.check_function
(** [leq_constr_univs u a b] is [true] if [a] is convertible to [b] modulo
alpha, casts, application grouping and the universe inequalities in [u]. *)
-val leq_constr_univs : constr Univ.check_function
+val leq_constr_univs : constr UGraph.check_function
(** [eq_constr_univs u a b] is [true] if [a] equals [b] modulo alpha, casts,
application grouping and the universe equalities in [u]. *)
-val eq_constr_univs_infer : Univ.universes -> constr -> constr -> bool Univ.constrained
+val eq_constr_univs_infer : UGraph.t -> constr -> constr -> bool Univ.constrained
(** [leq_constr_univs u a b] is [true] if [a] is convertible to [b] modulo
alpha, casts, application grouping and the universe inequalities in [u]. *)
-val leq_constr_univs_infer : Univ.universes -> constr -> constr -> bool Univ.constrained
+val leq_constr_univs_infer : UGraph.t -> constr -> constr -> bool Univ.constrained
(** [eq_constr_univs a b] [true, c] if [a] equals [b] modulo alpha, casts,
application grouping and ignoring universe instances. *)
diff --git a/kernel/context.ml b/kernel/context.ml
index 454d4f252..3be1e8323 100644
--- a/kernel/context.ml
+++ b/kernel/context.ml
@@ -15,123 +15,233 @@
(* This file defines types and combinators regarding indexes-based and
names-based contexts *)
-open Util
-open Names
-
-(***************************************************************************)
-(* Type of assumptions *)
-(***************************************************************************)
-
-type named_declaration = Id.t * Constr.t option * Constr.t
-type named_list_declaration = Id.t list * Constr.t option * Constr.t
-type rel_declaration = Name.t * Constr.t option * Constr.t
-
-let map_named_declaration_skel f (id, (v : Constr.t option), ty) =
- (id, Option.map f v, f ty)
-let map_named_list_declaration = map_named_declaration_skel
-let map_named_declaration = map_named_declaration_skel
-
-let map_rel_declaration = map_named_declaration
-
-let fold_named_declaration f (_, v, ty) a = f ty (Option.fold_right f v a)
-let fold_rel_declaration = fold_named_declaration
-
-let exists_named_declaration f (_, v, ty) = Option.cata f false v || f ty
-let exists_rel_declaration f (_, v, ty) = Option.cata f false v || f ty
-
-let for_all_named_declaration f (_, v, ty) = Option.cata f true v && f ty
-let for_all_rel_declaration f (_, v, ty) = Option.cata f true v && f ty
-
-let eq_named_declaration (i1, c1, t1) (i2, c2, t2) =
- Id.equal i1 i2 && Option.equal Constr.equal c1 c2 && Constr.equal t1 t2
-
-let eq_rel_declaration (n1, c1, t1) (n2, c2, t2) =
- Name.equal n1 n2 && Option.equal Constr.equal c1 c2 && Constr.equal t1 t2
-
-(***************************************************************************)
-(* Type of local contexts (telescopes) *)
-(***************************************************************************)
-
-(*s Signatures of ordered optionally named variables, intended to be
- accessed by de Bruijn indices (to represent bound variables) *)
-
-type rel_context = rel_declaration list
-
-let empty_rel_context = []
-
-let add_rel_decl d ctxt = d::ctxt
+(** The modules defined below represent a {e local context}
+ as defined by Chapter 4 in the Reference Manual:
-let rec lookup_rel n sign =
- match n, sign with
- | 1, decl :: _ -> decl
- | n, _ :: sign -> lookup_rel (n-1) sign
- | _, [] -> raise Not_found
+ A {e local context} is an ordered list of of {e local declarations}
+ of names that we call {e variables}.
-let rel_context_length = List.length
+ A {e local declaration} of some variable can be either:
+ - a {e local assumption}, or
+ - a {e local definition}.
+*)
-let rel_context_nhyps hyps =
- let rec nhyps acc = function
- | [] -> acc
- | (_,None,_)::hyps -> nhyps (1+acc) hyps
- | (_,Some _,_)::hyps -> nhyps acc hyps in
- nhyps 0 hyps
-
-let rel_context_tags ctx =
- let rec aux l = function
- | [] -> l
- | (_,Some _,_)::ctx -> aux (true::l) ctx
- | (_,None,_)::ctx -> aux (false::l) ctx
- in aux [] ctx
-
-(*s Signatures of named hypotheses. Used for section variables and
- goal assumptions. *)
-
-type named_context = named_declaration list
-type named_list_context = named_list_declaration list
-
-let empty_named_context = []
-
-let add_named_decl d sign = d::sign
-
-let rec lookup_named id = function
- | (id',_,_ as decl) :: _ when Id.equal id id' -> decl
- | _ :: sign -> lookup_named id sign
- | [] -> raise Not_found
-
-let named_context_length = List.length
-let named_context_equal = List.equal eq_named_declaration
-
-let vars_of_named_context ctx =
- List.fold_left (fun accu (id, _, _) -> Id.Set.add id accu) Id.Set.empty ctx
-
-let instance_from_named_context sign =
- let filter = function
- | (id, None, _) -> Some (Constr.mkVar id)
- | (_, Some _, _) -> None
- in
- List.map_filter filter sign
-
-let fold_named_context f l ~init = List.fold_right f l init
-let fold_named_list_context f l ~init = List.fold_right f l init
-let fold_named_context_reverse f ~init l = List.fold_left f init l
-
-(*s Signatures of ordered section variables *)
-type section_context = named_context
-
-let fold_rel_context f l ~init:x = List.fold_right f l x
-let fold_rel_context_reverse f ~init:x l = List.fold_left f x l
-
-let map_context f l =
- let map_decl (n, body_o, typ as decl) =
- let body_o' = Option.smartmap f body_o in
- let typ' = f typ in
- if body_o' == body_o && typ' == typ then decl else
- (n, body_o', typ')
- in
- List.smartmap map_decl l
-
-let map_rel_context = map_context
-let map_named_context = map_context
+open Util
+open Names
-let iter_rel_context f = List.iter (fun (_,b,t) -> f t; Option.iter f b)
-let iter_named_context f = List.iter (fun (_,b,t) -> f t; Option.iter f b)
+(** Representation of contexts that can capture anonymous as well as non-anonymous variables.
+ Individual declarations are then designated by de Bruijn indexes. *)
+module Rel =
+ struct
+ (** Representation of {e local declarations}.
+
+ [(name, None, typ)] represents a {e local assumption}.
+ In the Reference Manual we denote them as [(name:typ)].
+
+ [(name, Some value, typ)] represents a {e local definition}.
+ In the Reference Manual we denote them as [(name := value : typ)].
+ *)
+ module Declaration =
+ struct
+ type t = Name.t * Constr.t option * Constr.t
+
+ (** Map all terms in a given declaration. *)
+ let map f (n, v, ty) = (n, Option.map f v, f ty)
+
+ (** Reduce all terms in a given declaration to a single value. *)
+ let fold f (_, v, ty) a = f ty (Option.fold_right f v a)
+
+ (** Check whether any term in a given declaration satisfies a given predicate. *)
+ let exists f (_, v, ty) = Option.cata f false v || f ty
+
+ (** Check whether all terms in a given declaration satisfy a given predicate. *)
+ let for_all f (_, v, ty) = Option.cata f true v && f ty
+
+ (** Check whether the two given declarations are equal. *)
+ let equal (n1, v1, ty1) (n2, v2, ty2) =
+ Name.equal n1 n2 && Option.equal Constr.equal v1 v2 && Constr.equal ty1 ty2
+ end
+
+ (** Rel-context is represented as a list of declarations.
+ Inner-most declarations are at the beginning of the list.
+ Outer-most declarations are at the end of the list. *)
+ type t = Declaration.t list
+
+ (** empty rel-context *)
+ let empty = []
+
+ (** Return a new rel-context enriched by with a given inner-most declaration. *)
+ let add d ctx = d :: ctx
+
+ (** Return a declaration designated by a given de Bruijn index.
+ @raise Not_found if the designated de Bruijn index is not present in the designated rel-context. *)
+ let rec lookup n ctx =
+ match n, ctx with
+ | 1, decl :: _ -> decl
+ | n, _ :: sign -> lookup (n-1) sign
+ | _, [] -> raise Not_found
+
+ (** Map all terms in a given rel-context. *)
+ let map f =
+ let map_decl (n, body_o, typ as decl) =
+ let body_o' = Option.smartmap f body_o in
+ let typ' = f typ in
+ if body_o' == body_o && typ' == typ then decl else
+ (n, body_o', typ')
+ in
+ List.smartmap map_decl
+
+ (** Reduce all terms in a given rel-context to a single value.
+ Innermost declarations are processed first. *)
+ let fold_inside f ~init = List.fold_left f init
+
+ (** Reduce all terms in a given rel-context to a single value.
+ Outermost declarations are processed first. *)
+ let fold_outside f l ~init = List.fold_right f l init
+
+ (** Perform a given action on every declaration in a given rel-context. *)
+ let iter f = List.iter (fun (_,b,t) -> f t; Option.iter f b)
+
+ (** Return the number of {e local declarations} in a given context. *)
+ let length = List.length
+
+ (** [extended_rel_list n Γ] builds an instance [args] such that [Γ,Δ ⊢ args:Γ]
+ with n = |Δ| and with the local definitions of [Γ] skipped in
+ [args]. Example: for [x:T,y:=c,z:U] and [n]=2, it gives [Rel 5, Rel 3]. *)
+ let nhyps =
+ let rec nhyps acc = function
+ | [] -> acc
+ | (_,None,_)::hyps -> nhyps (1+acc) hyps
+ | (_,Some _,_)::hyps -> nhyps acc hyps in
+ nhyps 0
+
+ (** Map a given rel-context to a list where each {e local assumption} is mapped to [true]
+ and each {e local definition} is mapped to [false]. *)
+ let to_tags =
+ let rec aux l = function
+ | [] -> l
+ | (_,Some _,_)::ctx -> aux (true::l) ctx
+ | (_,None,_)::ctx -> aux (false::l) ctx
+ in aux []
+
+ (** [extended_list n Γ] builds an instance [args] such that [Γ,Δ ⊢ args:Γ]
+ with n = |Δ| and with the {e local definitions} of [Γ] skipped in
+ [args]. Example: for [x:T, y:=c, z:U] and [n]=2, it gives [Rel 5, Rel 3]. *)
+ let to_extended_list n =
+ let rec reln l p = function
+ | (_, None, _) :: hyps -> reln (Constr.mkRel (n+p) :: l) (p+1) hyps
+ | (_, Some _, _) :: hyps -> reln l (p+1) hyps
+ | [] -> l
+ in
+ reln [] 1
+
+ (** [extended_vect n Γ] does the same, returning instead an array. *)
+ let to_extended_vect n hyps = Array.of_list (to_extended_list n hyps)
+ end
+
+(** This module represents contexts that can capture non-anonymous variables.
+ Individual declarations are then designated by the identifiers they bind. *)
+module Named =
+ struct
+ (** Representation of {e local declarations}.
+
+ [(id, None, typ)] represents a {e local assumption}.
+ In the Reference Manual we denote them as [(name:typ)].
+
+ [(id, Some value, typ)] represents a {e local definition}.
+ In the Reference Manual we denote them as [(name := value : typ)].
+ *)
+ module Declaration =
+ struct
+ (** Named-context is represented as a list of declarations.
+ Inner-most declarations are at the beginning of the list.
+ Outer-most declarations are at the end of the list. *)
+ type t = Id.t * Constr.t option * Constr.t
+
+ (** Map all terms in a given declaration. *)
+ let map = Rel.Declaration.map
+
+ (** Reduce all terms in a given declaration to a single value. *)
+ let fold f (_, v, ty) a = f ty (Option.fold_right f v a)
+
+ (** Check whether any term in a given declaration satisfies a given predicate. *)
+ let exists f (_, v, ty) = Option.cata f false v || f ty
+
+ (** Check whether all terms in a given declaration satisfy a given predicate. *)
+ let for_all f (_, v, ty) = Option.cata f true v && f ty
+
+ (** Check whether the two given declarations are equal. *)
+ let equal (i1, v1, ty1) (i2, v2, ty2) =
+ Id.equal i1 i2 && Option.equal Constr.equal v1 v2 && Constr.equal ty1 ty2
+ end
+
+ type t = Declaration.t list
+
+ (** empty named-context *)
+ let empty = []
+
+ (** empty named-context *)
+ let add d ctx = d :: ctx
+
+ (** Return a declaration designated by a given de Bruijn index.
+ @raise Not_found if the designated identifier is not present in the designated named-context. *)
+ let rec lookup id = function
+ | (id',_,_ as decl) :: _ when Id.equal id id' -> decl
+ | _ :: sign -> lookup id sign
+ | [] -> raise Not_found
+
+ (** Map all terms in a given named-context. *)
+ let map f =
+ let map_decl (n, body_o, typ as decl) =
+ let body_o' = Option.smartmap f body_o in
+ let typ' = f typ in
+ if body_o' == body_o && typ' == typ then decl else
+ (n, body_o', typ')
+ in
+ List.smartmap map_decl
+
+ (** Reduce all terms in a given named-context to a single value.
+ Innermost declarations are processed first. *)
+ let fold_inside f ~init = List.fold_left f init
+
+ (** Reduce all terms in a given named-context to a single value.
+ Outermost declarations are processed first. *)
+ let fold_outside f l ~init = List.fold_right f l init
+
+ (** Perform a given action on every declaration in a given named-context. *)
+ let iter f = List.iter (fun (_,b,t) -> f t; Option.iter f b)
+
+ (** Return the number of {e local declarations} in a given named-context. *)
+ let length = List.length
+
+ (** Check whether given two named-contexts are equal. *)
+ let equal = List.equal Declaration.equal
+
+ (** Return the set of all identifiers bound in a given named-context. *)
+ let to_vars =
+ List.fold_left (fun accu (id, _, _) -> Id.Set.add id accu) Id.Set.empty
+
+ (** [instance_from_named_context Ω] builds an instance [args] such
+ that [Ω ⊢ args:Ω] where [Ω] is a named context and with the local
+ definitions of [Ω] skipped. Example: for [id1:T,id2:=c,id3:U], it
+ gives [Var id1, Var id3]. All [idj] are supposed distinct. *)
+ let to_instance =
+ let filter = function
+ | (id, None, _) -> Some (Constr.mkVar id)
+ | (_, Some _, _) -> None
+ in
+ List.map_filter filter
+ end
+
+module NamedList =
+ struct
+ module Declaration =
+ struct
+ type t = Id.t list * Constr.t option * Constr.t
+ let map = Named.Declaration.map
+ end
+ type t = Declaration.t list
+ let fold f l ~init = List.fold_right f l init
+ end
+
+type section_context = Named.t
diff --git a/kernel/context.mli b/kernel/context.mli
index b78bbb03e..1976e46d3 100644
--- a/kernel/context.mli
+++ b/kernel/context.mli
@@ -6,117 +6,186 @@
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
+(** The modules defined below represent a {e local context}
+ as defined by Chapter 4 in the Reference Manual:
+
+ A {e local context} is an ordered list of of {e local declarations}
+ of names that we call {e variables}.
+
+ A {e local declaration} of some variable can be either:
+ - a {e local assumption}, or
+ - a {e local definition}.
+
+ {e Local assumptions} are denoted in the Reference Manual as [(name : typ)] and
+ {e local definitions} are there denoted as [(name := value : typ)].
+*)
+
open Names
-(** TODO: cleanup *)
+(** Representation of contexts that can capture anonymous as well as non-anonymous variables.
+ Individual declarations are then designated by de Bruijn indexes. *)
+module Rel :
+sig
+ (** Representation of {e local declarations}.
+
+ [(name, None, typ)] represents a {e local assumption}.
+
+ [(name, Some value, typ)] represents a {e local definition}.
+ *)
+ module Declaration :
+ sig
+ type t = Name.t * Constr.t option * Constr.t
+
+ (** Map all terms in a given declaration. *)
+ val map : (Constr.t -> Constr.t) -> t -> t
+
+ (** Reduce all terms in a given declaration to a single value. *)
+ val fold : (Constr.t -> 'a -> 'a) -> t -> 'a -> 'a
+
+ (** Check whether any term in a given declaration satisfies a given predicate. *)
+ val exists : (Constr.t -> bool) -> t -> bool
+
+ (** Check whether all terms in a given declaration satisfy a given predicate. *)
+ val for_all : (Constr.t -> bool) -> t -> bool
+
+ (** Check whether the two given declarations are equal. *)
+ val equal : t -> t -> bool
+ end
+
+ (** Rel-context is represented as a list of declarations.
+ Inner-most declarations are at the beginning of the list.
+ Outer-most declarations are at the end of the list. *)
+ type t = Declaration.t list
+
+ (** empty rel-context *)
+ val empty : t
+
+ (** Return a new rel-context enriched by with a given inner-most declaration. *)
+ val add : Declaration.t -> t -> t
+
+ (** Return a declaration designated by a given de Bruijn index.
+ @raise Not_found if the designated de Bruijn index outside the range. *)
+ val lookup : int -> t -> Declaration.t
+
+ (** Map all terms in a given rel-context. *)
+ val map : (Constr.t -> Constr.t) -> t -> t
+
+ (** Reduce all terms in a given rel-context to a single value.
+ Innermost declarations are processed first. *)
+ val fold_inside : ('a -> Declaration.t -> 'a) -> init:'a -> t -> 'a
+
+ (** Reduce all terms in a given rel-context to a single value.
+ Outermost declarations are processed first. *)
+ val fold_outside : (Declaration.t -> 'a -> 'a) -> t -> init:'a -> 'a
+
+ (** Perform a given action on every declaration in a given rel-context. *)
+ val iter : (Constr.t -> unit) -> t -> unit
+
+ (** Return the number of {e local declarations} in a given context. *)
+ val length : t -> int
-(** {6 Declarations} *)
-(** A {e declaration} has the form [(name,body,type)]. It is either an
- {e assumption} if [body=None] or a {e definition} if
- [body=Some actualbody]. It is referred by {e name} if [na] is an
- identifier or by {e relative index} if [na] is not an identifier
- (in the latter case, [na] is of type [name] but just for printing
- purpose) *)
+ (** Return the number of {e local assumptions} in a given rel-context. *)
+ val nhyps : t -> int
-type named_declaration = Id.t * Constr.t option * Constr.t
-type named_list_declaration = Id.t list * Constr.t option * Constr.t
-type rel_declaration = Name.t * Constr.t option * Constr.t
+ (** Map a given rel-context to a list where each {e local assumption} is mapped to [true]
+ and each {e local definition} is mapped to [false]. *)
+ val to_tags : t -> bool list
-val map_named_declaration :
- (Constr.t -> Constr.t) -> named_declaration -> named_declaration
-val map_named_list_declaration :
- (Constr.t -> Constr.t) -> named_list_declaration -> named_list_declaration
-val map_rel_declaration :
- (Constr.t -> Constr.t) -> rel_declaration -> rel_declaration
+ (** [extended_list n Γ] builds an instance [args] such that [Γ,Δ ⊢ args:Γ]
+ with n = |Δ| and with the {e local definitions} of [Γ] skipped in
+ [args]. Example: for [x:T, y:=c, z:U] and [n]=2, it gives [Rel 5, Rel 3]. *)
+ val to_extended_list : int -> t -> Constr.t list
-val fold_named_declaration :
- (Constr.t -> 'a -> 'a) -> named_declaration -> 'a -> 'a
-val fold_rel_declaration :
- (Constr.t -> 'a -> 'a) -> rel_declaration -> 'a -> 'a
+ (** [extended_vect n Γ] does the same, returning instead an array. *)
+ val to_extended_vect : int -> t -> Constr.t array
+end
-val exists_named_declaration :
- (Constr.t -> bool) -> named_declaration -> bool
-val exists_rel_declaration :
- (Constr.t -> bool) -> rel_declaration -> bool
+(** This module represents contexts that can capture non-anonymous variables.
+ Individual declarations are then designated by the identifiers they bind. *)
+module Named :
+sig
+ (** Representation of {e local declarations}.
-val for_all_named_declaration :
- (Constr.t -> bool) -> named_declaration -> bool
-val for_all_rel_declaration :
- (Constr.t -> bool) -> rel_declaration -> bool
+ [(id, None, typ)] represents a {e local assumption}.
-val eq_named_declaration :
- named_declaration -> named_declaration -> bool
+ [(id, Some value, typ)] represents a {e local definition}.
+ *)
+ module Declaration :
+ sig
+ type t = Id.t * Constr.t option * Constr.t
-val eq_rel_declaration :
- rel_declaration -> rel_declaration -> bool
+ (** Map all terms in a given declaration. *)
+ val map : (Constr.t -> Constr.t) -> t -> t
-(** {6 Signatures of ordered named declarations } *)
+ (** Reduce all terms in a given declaration to a single value. *)
+ val fold : (Constr.t -> 'a -> 'a) -> t -> 'a -> 'a
-type named_context = named_declaration list
-type section_context = named_context
-type named_list_context = named_list_declaration list
-type rel_context = rel_declaration list
-(** In [rel_context], more recent declaration is on top *)
+ (** Check whether any term in a given declaration satisfies a given predicate. *)
+ val exists : (Constr.t -> bool) -> t -> bool
-val empty_named_context : named_context
-val add_named_decl : named_declaration -> named_context -> named_context
-val vars_of_named_context : named_context -> Id.Set.t
+ (** Check whether all terms in a given declaration satisfy a given predicate. *)
+ val for_all : (Constr.t -> bool) -> t -> bool
-val lookup_named : Id.t -> named_context -> named_declaration
+ (** Check whether the two given declarations are equal. *)
+ val equal : t -> t -> bool
+ end
-(** number of declarations *)
-val named_context_length : named_context -> int
+ (** Rel-context is represented as a list of declarations.
+ Inner-most declarations are at the beginning of the list.
+ Outer-most declarations are at the end of the list. *)
+ type t = Declaration.t list
-(** named context equality *)
-val named_context_equal : named_context -> named_context -> bool
+ (** empty named-context *)
+ val empty : t
-(** {6 Recurrence on [named_context]: older declarations processed first } *)
-val fold_named_context :
- (named_declaration -> 'a -> 'a) -> named_context -> init:'a -> 'a
+ (** Return a new rel-context enriched by with a given inner-most declaration. *)
+ val add : Declaration.t -> t -> t
-val fold_named_list_context :
- (named_list_declaration -> 'a -> 'a) -> named_list_context -> init:'a -> 'a
+ (** Return a declaration designated by an identifier of the variable bound in that declaration.
+ @raise Not_found if the designated identifier is not bound in a given named-context. *)
+ val lookup : Id.t -> t -> Declaration.t
-(** newer declarations first *)
-val fold_named_context_reverse :
- ('a -> named_declaration -> 'a) -> init:'a -> named_context -> 'a
+ (** Map all terms in a given named-context. *)
+ val map : (Constr.t -> Constr.t) -> t -> t
-(** {6 Section-related auxiliary functions } *)
-val instance_from_named_context : named_context -> Constr.t list
+ (** Reduce all terms in a given named-context to a single value.
+ Innermost declarations are processed first. *)
+ val fold_inside : ('a -> Declaration.t -> 'a) -> init:'a -> t -> 'a
-(** {6 ... } *)
-(** Signatures of ordered optionally named variables, intended to be
- accessed by de Bruijn indices *)
+ (** Reduce all terms in a given named-context to a single value.
+ Outermost declarations are processed first. *)
+ val fold_outside : (Declaration.t -> 'a -> 'a) -> t -> init:'a -> 'a
-(** {6 Recurrence on [rel_context]: older declarations processed first } *)
-val fold_rel_context :
- (rel_declaration -> 'a -> 'a) -> rel_context -> init:'a -> 'a
+ (** Perform a given action on every declaration in a given named-context. *)
+ val iter : (Constr.t -> unit) -> t -> unit
-(** newer declarations first *)
-val fold_rel_context_reverse :
- ('a -> rel_declaration -> 'a) -> init:'a -> rel_context -> 'a
+ (** Return the number of {e local declarations} in a given named-context. *)
+ val length : t -> int
-(** {6 Map function of [rel_context] } *)
-val map_rel_context : (Constr.t -> Constr.t) -> rel_context -> rel_context
+ (** Check whether given two named-contexts are equal. *)
+ val equal : t -> t -> bool
-(** {6 Map function of [named_context] } *)
-val map_named_context : (Constr.t -> Constr.t) -> named_context -> named_context
+ (** Return the set of all identifiers bound in a given named-context. *)
+ val to_vars : t -> Id.Set.t
-(** {6 Map function of [rel_context] } *)
-val iter_rel_context : (Constr.t -> unit) -> rel_context -> unit
+ (** [instance_from_named_context Ω] builds an instance [args] such
+ that [Ω ⊢ args:Ω] where [Ω] is a named context and with the local
+ definitions of [Ω] skipped. Example: for [id1:T,id2:=c,id3:U], it
+ gives [Var id1, Var id3]. All [idj] are supposed distinct. *)
+ val to_instance : t -> Constr.t list
+end
-(** {6 Map function of [named_context] } *)
-val iter_named_context : (Constr.t -> unit) -> named_context -> unit
+module NamedList :
+sig
+ module Declaration :
+ sig
+ type t = Id.t list * Constr.t option * Constr.t
+ val map : (Constr.t -> Constr.t) -> t -> t
+ end
-(** {6 Contexts of declarations referred to by de Bruijn indices } *)
+ type t = Declaration.t list
-val empty_rel_context : rel_context
-val add_rel_decl : rel_declaration -> rel_context -> rel_context
+ val fold : (Declaration.t -> 'a -> 'a) -> t -> init:'a -> 'a
+end
-val lookup_rel : int -> rel_context -> rel_declaration
-(** Size of the [rel_context] including LetIns *)
-val rel_context_length : rel_context -> int
-(** Size of the [rel_context] without LetIns *)
-val rel_context_nhyps : rel_context -> int
-(** Indicates whether a LetIn or a Lambda, starting from oldest declaration *)
-val rel_context_tags : rel_context -> bool list
+type section_context = Named.t
diff --git a/kernel/cooking.ml b/kernel/cooking.ml
index f0e925582..3ab6983d8 100644
--- a/kernel/cooking.ml
+++ b/kernel/cooking.ml
@@ -173,7 +173,7 @@ let expmod_constr_subst cache modlist subst c =
let cook_constr { Opaqueproof.modlist ; abstract } c =
let cache = RefTable.create 13 in
let expmod = expmod_constr_subst cache modlist (pi2 abstract) in
- let hyps = Context.map_named_context expmod (pi1 abstract) in
+ let hyps = Context.Named.map expmod (pi1 abstract) in
abstract_constant_body (expmod c) hyps
let lift_univs cb subst =
@@ -195,13 +195,13 @@ let cook_constant env { from = cb; info } =
let abstract, usubst, abs_ctx = abstract in
let usubst, univs = lift_univs cb usubst in
let expmod = expmod_constr_subst cache modlist usubst in
- let hyps = Context.map_named_context expmod abstract in
+ let hyps = Context.Named.map expmod abstract in
let body = on_body modlist (hyps, usubst, abs_ctx)
(fun c -> abstract_constant_body (expmod c) hyps)
cb.const_body
in
let const_hyps =
- Context.fold_named_context (fun (h,_,_) hyps ->
+ Context.Named.fold_outside (fun (h,_,_) hyps ->
List.filter (fun (id,_,_) -> not (Id.equal id h)) hyps)
hyps ~init:cb.const_hyps in
let typ = match cb.const_type with
diff --git a/kernel/csymtable.ml b/kernel/csymtable.ml
index fc7e1b937..8f60216af 100644
--- a/kernel/csymtable.ml
+++ b/kernel/csymtable.ml
@@ -15,7 +15,6 @@
open Util
open Names
open Term
-open Context
open Vm
open Cemitcodes
open Cbytecodes
@@ -190,7 +189,7 @@ and slot_for_fv env fv =
let nv = Pre_env.lookup_named_val id env in
begin match force_lazy_val nv with
| None ->
- let _, b, _ = Context.lookup_named id env.env_named_context in
+ let _, b, _ = Context.Named.lookup id env.env_named_context in
fill_fv_cache nv id val_of_named idfun b
| Some (v, _) -> v
end
@@ -198,7 +197,7 @@ and slot_for_fv env fv =
let rv = Pre_env.lookup_rel_val i env in
begin match force_lazy_val rv with
| None ->
- let _, b, _ = lookup_rel i env.env_rel_context in
+ let _, b, _ = Context.Rel.lookup i env.env_rel_context in
fill_fv_cache rv i val_of_rel env_of_rel b
| Some (v, _) -> v
end
@@ -206,19 +205,13 @@ and slot_for_fv env fv =
assert false
and eval_to_patch env (buff,pl,fv) =
- (* copy code *before* patching because of nested evaluations:
- the code we are patching might be called (and thus "concurrently" patched)
- and results in wrong results. Side-effects... *)
- let buff = Cemitcodes.copy buff in
let patch = function
- | Reloc_annot a, pos -> patch_int buff pos (slot_for_annot a)
- | Reloc_const sc, pos -> patch_int buff pos (slot_for_str_cst sc)
- | Reloc_getglobal kn, pos ->
-(* Pp.msgnl (str"patching global: "++str(debug_string_of_con kn));*)
- patch_int buff pos (slot_for_getglobal env kn);
-(* Pp.msgnl (str"patch done: "++str(debug_string_of_con kn))*)
+ | Reloc_annot a, pos -> (pos, slot_for_annot a)
+ | Reloc_const sc, pos -> (pos, slot_for_str_cst sc)
+ | Reloc_getglobal kn, pos -> (pos, slot_for_getglobal env kn)
in
- List.iter patch pl;
+ let patches = List.map_left patch pl in
+ let buff = patch_int buff patches in
let vm_env = Array.map (slot_for_fv env) fv in
let tc = tcode_of_code buff (length buff) in
eval_tcode tc vm_env
diff --git a/kernel/declarations.mli b/kernel/declarations.mli
index de966daa0..1b77d5b7c 100644
--- a/kernel/declarations.mli
+++ b/kernel/declarations.mli
@@ -8,7 +8,6 @@
open Names
open Term
-open Context
(** This module defines the internal representation of global
declarations. This includes global constants/axioms, mutual
@@ -38,7 +37,7 @@ type ('a, 'b) declaration_arity =
| RegularArity of 'a
| TemplateArity of 'b
-type constant_type = (types, rel_context * template_arity) declaration_arity
+type constant_type = (types, Context.Rel.t * template_arity) declaration_arity
(** Inlining level of parameters at functor applications.
None means no inlining *)
@@ -117,7 +116,7 @@ type one_inductive_body = {
mind_typename : Id.t; (** Name of the type: [Ii] *)
- mind_arity_ctxt : rel_context; (** Arity context of [Ii] with parameters: [forall params, Ui] *)
+ mind_arity_ctxt : Context.Rel.t; (** Arity context of [Ii] with parameters: [forall params, Ui] *)
mind_arity : inductive_arity; (** Arity sort and original user arity *)
@@ -171,7 +170,7 @@ type mutual_inductive_body = {
mind_nparams_rec : int; (** Number of recursively uniform (i.e. ordinary) parameters *)
- mind_params_ctxt : rel_context; (** The context of parameters (includes let-in declaration) *)
+ mind_params_ctxt : Context.Rel.t; (** The context of parameters (includes let-in declaration) *)
mind_polymorphic : bool; (** Is it polymorphic or not *)
diff --git a/kernel/declareops.ml b/kernel/declareops.ml
index d9bd5c445..f73eea030 100644
--- a/kernel/declareops.ml
+++ b/kernel/declareops.ml
@@ -254,7 +254,7 @@ let subst_mind_body sub mib =
mind_nparams = mib.mind_nparams;
mind_nparams_rec = mib.mind_nparams_rec;
mind_params_ctxt =
- Context.map_rel_context (subst_mps sub) mib.mind_params_ctxt;
+ Context.Rel.map (subst_mps sub) mib.mind_params_ctxt;
mind_packets = Array.smartmap (subst_mind_packet sub) mib.mind_packets ;
mind_polymorphic = mib.mind_polymorphic;
mind_universes = mib.mind_universes;
@@ -308,3 +308,86 @@ let string_of_side_effect { Entries.eff } = match eff with
| Entries.SEsubproof (c,_,_) -> "P(" ^ Names.string_of_con c ^ ")"
| Entries.SEscheme (cl,_) ->
"S(" ^ String.concat ", " (List.map (fun (_,c,_,_) -> Names.string_of_con c) cl) ^ ")"
+
+(** Hashconsing of modules *)
+
+let hcons_functorize hty he hself f = match f with
+| NoFunctor e ->
+ let e' = he e in
+ if e == e' then f else NoFunctor e'
+| MoreFunctor (mid, ty, nf) ->
+ (** FIXME *)
+ let mid' = mid in
+ let ty' = hty ty in
+ let nf' = hself nf in
+ if mid == mid' && ty == ty' && nf == nf' then f
+ else MoreFunctor (mid, ty', nf')
+
+let hcons_module_alg_expr me = me
+
+let rec hcons_structure_field_body sb = match sb with
+| SFBconst cb ->
+ let cb' = hcons_const_body cb in
+ if cb == cb' then sb else SFBconst cb'
+| SFBmind mib ->
+ let mib' = hcons_mind mib in
+ if mib == mib' then sb else SFBmind mib'
+| SFBmodule mb ->
+ let mb' = hcons_module_body mb in
+ if mb == mb' then sb else SFBmodule mb'
+| SFBmodtype mb ->
+ let mb' = hcons_module_body mb in
+ if mb == mb' then sb else SFBmodtype mb'
+
+and hcons_structure_body sb =
+ (** FIXME *)
+ let map (l, sfb as fb) =
+ let l' = Names.Label.hcons l in
+ let sfb' = hcons_structure_field_body sfb in
+ if l == l' && sfb == sfb' then fb else (l', sfb')
+ in
+ List.smartmap map sb
+
+and hcons_module_signature ms =
+ hcons_functorize hcons_module_body hcons_structure_body hcons_module_signature ms
+
+and hcons_module_expression me =
+ hcons_functorize hcons_module_body hcons_module_alg_expr hcons_module_expression me
+
+and hcons_module_implementation mip = match mip with
+| Abstract -> Abstract
+| Algebraic me ->
+ let me' = hcons_module_expression me in
+ if me == me' then mip else Algebraic me'
+| Struct ms ->
+ let ms' = hcons_module_signature ms in
+ if ms == ms' then mip else Struct ms
+| FullStruct -> FullStruct
+
+and hcons_module_body mb =
+ let mp' = mb.mod_mp in
+ let expr' = hcons_module_implementation mb.mod_expr in
+ let type' = hcons_module_signature mb.mod_type in
+ let type_alg' = mb.mod_type_alg in
+ let constraints' = Univ.hcons_universe_context_set mb.mod_constraints in
+ let delta' = mb.mod_delta in
+ let retroknowledge' = mb.mod_retroknowledge in
+
+ if
+ mb.mod_mp == mp' &&
+ mb.mod_expr == expr' &&
+ mb.mod_type == type' &&
+ mb.mod_type_alg == type_alg' &&
+ mb.mod_constraints == constraints' &&
+ mb.mod_delta == delta' &&
+ mb.mod_retroknowledge == retroknowledge'
+ then mb
+ else {
+ mod_mp = mp';
+ mod_expr = expr';
+ mod_type = type';
+ mod_type_alg = type_alg';
+ mod_constraints = constraints';
+ mod_delta = delta';
+ mod_retroknowledge = retroknowledge';
+ }
diff --git a/kernel/declareops.mli b/kernel/declareops.mli
index 86ba29b8b..ad2b5d0a6 100644
--- a/kernel/declareops.mli
+++ b/kernel/declareops.mli
@@ -77,3 +77,4 @@ val inductive_context : mutual_inductive_body -> universe_context
val hcons_const_body : constant_body -> constant_body
val hcons_mind : mutual_inductive_body -> mutual_inductive_body
+val hcons_module_body : module_body -> module_body
diff --git a/kernel/environ.ml b/kernel/environ.ml
index cd376b69e..847e1d08f 100644
--- a/kernel/environ.ml
+++ b/kernel/environ.ml
@@ -24,7 +24,6 @@ open Errors
open Util
open Names
open Term
-open Context
open Vars
open Declarations
open Pre_env
@@ -70,7 +69,7 @@ let empty_context env =
(* Rel context *)
let lookup_rel n env =
- lookup_rel n env.env_rel_context
+ Context.Rel.lookup n env.env_rel_context
let evaluable_rel n env =
match lookup_rel n env with
@@ -81,7 +80,7 @@ let nb_rel env = env.env_nb_rel
let push_rel = push_rel
-let push_rel_context ctxt x = Context.fold_rel_context push_rel ctxt ~init:x
+let push_rel_context ctxt x = Context.Rel.fold_outside push_rel ctxt ~init:x
let push_rec_types (lna,typarray,_) env =
let ctxt = Array.map2_i (fun i na t -> (na, None, lift i t)) lna typarray in
@@ -120,7 +119,7 @@ let map_named_val f (ctxt,ctxtv) =
in
(map ctxt, ctxtv)
-let empty_named_context = empty_named_context
+let empty_named_context = Context.Named.empty
let push_named = push_named
let push_named_context = List.fold_right push_named
@@ -130,11 +129,11 @@ let val_of_named_context ctxt =
List.fold_right push_named_context_val ctxt empty_named_context_val
-let lookup_named id env = Context.lookup_named id env.env_named_context
-let lookup_named_val id (ctxt,_) = Context.lookup_named id ctxt
+let lookup_named id env = Context.Named.lookup id env.env_named_context
+let lookup_named_val id (ctxt,_) = Context.Named.lookup id ctxt
let eq_named_context_val c1 c2 =
- c1 == c2 || named_context_equal (named_context_of_val c1) (named_context_of_val c2)
+ c1 == c2 || Context.Named.equal (named_context_of_val c1) (named_context_of_val c2)
(* A local const is evaluable if it is defined *)
@@ -153,7 +152,7 @@ let reset_with_named_context (ctxt,ctxtv) env =
{ env with
env_named_context = ctxt;
env_named_vals = ctxtv;
- env_rel_context = empty_rel_context;
+ env_rel_context = Context.Rel.empty;
env_rel_val = [];
env_nb_rel = 0 }
@@ -176,7 +175,7 @@ let fold_named_context f env ~init =
in fold_right env
let fold_named_context_reverse f ~init env =
- Context.fold_named_context_reverse f ~init:init (named_context env)
+ Context.Named.fold_inside f ~init:init (named_context env)
(* Universe constraints *)
@@ -188,10 +187,10 @@ let map_universes f env =
let add_constraints c env =
if Univ.Constraint.is_empty c then env
- else map_universes (Univ.merge_constraints c) env
+ else map_universes (UGraph.merge_constraints c) env
let check_constraints c env =
- Univ.check_constraints c env.env_stratification.env_universes
+ UGraph.check_constraints c env.env_stratification.env_universes
let push_constraints_to_env (_,univs) env =
add_constraints univs env
@@ -199,19 +198,19 @@ let push_constraints_to_env (_,univs) env =
let add_universes strict ctx g =
let g = Array.fold_left
(* Be lenient, module typing reintroduces universes and constraints due to includes *)
- (fun g v -> try Univ.add_universe v strict g with Univ.AlreadyDeclared -> g)
+ (fun g v -> try UGraph.add_universe v strict g with UGraph.AlreadyDeclared -> g)
g (Univ.Instance.to_array (Univ.UContext.instance ctx))
in
- Univ.merge_constraints (Univ.UContext.constraints ctx) g
+ UGraph.merge_constraints (Univ.UContext.constraints ctx) g
let push_context ?(strict=false) ctx env =
map_universes (add_universes strict ctx) env
let add_universes_set strict ctx g =
let g = Univ.LSet.fold
- (fun v g -> try Univ.add_universe v strict g with Univ.AlreadyDeclared -> g)
+ (fun v g -> try UGraph.add_universe v strict g with UGraph.AlreadyDeclared -> g)
(Univ.ContextSet.levels ctx) g
- in Univ.merge_constraints (Univ.ContextSet.constraints ctx) g
+ in UGraph.merge_constraints (Univ.ContextSet.constraints ctx) g
let push_context_set ?(strict=false) ctx env =
map_universes (add_universes_set strict ctx) env
@@ -389,11 +388,11 @@ let add_mind kn mib env =
let lookup_constant_variables c env =
let cmap = lookup_constant c env in
- Context.vars_of_named_context cmap.const_hyps
+ Context.Named.to_vars cmap.const_hyps
let lookup_inductive_variables (kn,i) env =
let mis = lookup_mind kn env in
- Context.vars_of_named_context mis.mind_hyps
+ Context.Named.to_vars mis.mind_hyps
let lookup_constructor_variables (ind,_) env =
lookup_inductive_variables ind env
@@ -427,7 +426,7 @@ let global_vars_set env constr =
contained in the types of the needed variables. *)
let really_needed env needed =
- Context.fold_named_context_reverse
+ Context.Named.fold_inside
(fun need (id,copt,t) ->
if Id.Set.mem id need then
let globc =
@@ -443,9 +442,9 @@ let really_needed env needed =
let keep_hyps env needed =
let really_needed = really_needed env needed in
- Context.fold_named_context
+ Context.Named.fold_outside
(fun (id,_,_ as d) nsign ->
- if Id.Set.mem id really_needed then add_named_decl d nsign
+ if Id.Set.mem id really_needed then Context.Named.add d nsign
else nsign)
(named_context env)
~init:empty_named_context
@@ -602,7 +601,10 @@ let dispatch =
Array.init 31 (fun n -> mkConstruct
(digit_ind, nth_digit_plus_one i (30-n)))
in
- mkApp(mkConstruct(ind, 1), array_of_int tag)
+ (* We check that no bit above 31 is set to one. This assertion used to
+ fail in the VM, and led to conversion tests failing at Qed. *)
+ assert (Int.equal (tag lsr 31) 0);
+ mkApp(mkConstruct(ind, 1), array_of_int tag)
in
(* subfunction which dispatches the compiling information of an
diff --git a/kernel/environ.mli b/kernel/environ.mli
index c3354f551..520389954 100644
--- a/kernel/environ.mli
+++ b/kernel/environ.mli
@@ -8,7 +8,6 @@
open Names
open Term
-open Context
open Declarations
open Univ
@@ -41,9 +40,9 @@ val eq_named_context_val : named_context_val -> named_context_val -> bool
val empty_env : env
-val universes : env -> Univ.universes
-val rel_context : env -> rel_context
-val named_context : env -> named_context
+val universes : env -> UGraph.t
+val rel_context : env -> Context.Rel.t
+val named_context : env -> Context.Named.t
val named_context_val : env -> named_context_val
val opaque_tables : env -> Opaqueproof.opaquetab
@@ -60,25 +59,25 @@ val empty_context : env -> bool
(** {5 Context of de Bruijn variables ([rel_context]) } *)
val nb_rel : env -> int
-val push_rel : rel_declaration -> env -> env
-val push_rel_context : rel_context -> env -> env
+val push_rel : Context.Rel.Declaration.t -> env -> env
+val push_rel_context : Context.Rel.t -> env -> env
val push_rec_types : rec_declaration -> env -> env
(** Looks up in the context of local vars referred by indice ([rel_context])
raises [Not_found] if the index points out of the context *)
-val lookup_rel : int -> env -> rel_declaration
+val lookup_rel : int -> env -> Context.Rel.Declaration.t
val evaluable_rel : int -> env -> bool
(** {6 Recurrence on [rel_context] } *)
val fold_rel_context :
- (env -> rel_declaration -> 'a -> 'a) -> env -> init:'a -> 'a
+ (env -> Context.Rel.Declaration.t -> 'a -> 'a) -> env -> init:'a -> 'a
(** {5 Context of variables (section variables and goal assumptions) } *)
-val named_context_of_val : named_context_val -> named_context
+val named_context_of_val : named_context_val -> Context.Named.t
val named_vals_of_val : named_context_val -> Pre_env.named_vals
-val val_of_named_context : named_context -> named_context_val
+val val_of_named_context : Context.Named.t -> named_context_val
val empty_named_context_val : named_context_val
@@ -88,18 +87,18 @@ val empty_named_context_val : named_context_val
val map_named_val :
(constr -> constr) -> named_context_val -> named_context_val
-val push_named : named_declaration -> env -> env
-val push_named_context : named_context -> env -> env
+val push_named : Context.Named.Declaration.t -> env -> env
+val push_named_context : Context.Named.t -> env -> env
val push_named_context_val :
- named_declaration -> named_context_val -> named_context_val
+ Context.Named.Declaration.t -> named_context_val -> named_context_val
(** Looks up in the context of local vars referred by names ([named_context])
raises [Not_found] if the Id.t is not found *)
-val lookup_named : variable -> env -> named_declaration
-val lookup_named_val : variable -> named_context_val -> named_declaration
+val lookup_named : variable -> env -> Context.Named.Declaration.t
+val lookup_named_val : variable -> named_context_val -> Context.Named.Declaration.t
val evaluable_named : variable -> env -> bool
val named_type : variable -> env -> types
val named_body : variable -> env -> constr option
@@ -107,11 +106,11 @@ val named_body : variable -> env -> constr option
(** {6 Recurrence on [named_context]: older declarations processed first } *)
val fold_named_context :
- (env -> named_declaration -> 'a -> 'a) -> env -> init:'a -> 'a
+ (env -> Context.Named.Declaration.t -> 'a -> 'a) -> env -> init:'a -> 'a
(** Recurrence on [named_context] starting from younger decl *)
val fold_named_context_reverse :
- ('a -> named_declaration -> 'a) -> init:'a -> env -> 'a
+ ('a -> Context.Named.Declaration.t -> 'a) -> init:'a -> env -> 'a
(** This forgets named and rel contexts *)
val reset_context : env -> env
@@ -228,7 +227,7 @@ val vars_of_global : env -> constr -> Id.Set.t
val really_needed : env -> Id.Set.t -> Id.Set.t
(** like [really_needed] but computes a well ordered named context *)
-val keep_hyps : env -> Id.Set.t -> section_context
+val keep_hyps : env -> Id.Set.t -> Context.section_context
(** {5 Unsafe judgments. }
We introduce here the pre-type of judgments, which is
@@ -258,22 +257,22 @@ exception Hyp_not_found
return [tail::(f head (id,_,_) (rev tail))::head].
the value associated to id should not change *)
val apply_to_hyp : named_context_val -> variable ->
- (named_context -> named_declaration -> named_context -> named_declaration) ->
+ (Context.Named.t -> Context.Named.Declaration.t -> Context.Named.t -> Context.Named.Declaration.t) ->
named_context_val
(** [apply_to_hyp_and_dependent_on sign id f g] split [sign] into
[tail::(id,_,_)::head] and
return [(g tail)::(f (id,_,_))::head]. *)
val apply_to_hyp_and_dependent_on : named_context_val -> variable ->
- (named_declaration -> named_context_val -> named_declaration) ->
- (named_declaration -> named_context_val -> named_declaration) ->
+ (Context.Named.Declaration.t -> named_context_val -> Context.Named.Declaration.t) ->
+ (Context.Named.Declaration.t -> named_context_val -> Context.Named.Declaration.t) ->
named_context_val
val insert_after_hyp : named_context_val -> variable ->
- named_declaration ->
- (named_context -> unit) -> named_context_val
+ Context.Named.Declaration.t ->
+ (Context.Named.t -> unit) -> named_context_val
-val remove_hyps : Id.Set.t -> (named_declaration -> named_declaration) -> (Pre_env.lazy_val -> Pre_env.lazy_val) -> named_context_val -> named_context_val
+val remove_hyps : Id.Set.t -> (Context.Named.Declaration.t -> Context.Named.Declaration.t) -> (Pre_env.lazy_val -> Pre_env.lazy_val) -> named_context_val -> named_context_val
diff --git a/kernel/fast_typeops.ml b/kernel/fast_typeops.ml
index 2a6a55adf..ebc1853d9 100644
--- a/kernel/fast_typeops.ml
+++ b/kernel/fast_typeops.ml
@@ -90,7 +90,7 @@ let judge_of_variable env id =
variables of the current env *)
(* TODO: check order? *)
let check_hyps_inclusion env f c sign =
- Context.fold_named_context
+ Context.Named.fold_outside
(fun (id,_,ty1) () ->
try
let ty2 = named_type id env in
diff --git a/kernel/indtypes.ml b/kernel/indtypes.ml
index f9c2a7b0d..ac665bc25 100644
--- a/kernel/indtypes.ml
+++ b/kernel/indtypes.ml
@@ -12,7 +12,6 @@ open Names
open Univ
open Term
open Vars
-open Context
open Declarations
open Declareops
open Inductive
@@ -30,8 +29,13 @@ let indices_matter = ref false
let enforce_indices_matter () = indices_matter := true
let is_indices_matter () = !indices_matter
-(* Same as noccur_between but may perform reductions.
- Could be refined more... *)
+(* [weaker_noccur_between env n nvars t] (defined above), checks that
+ no de Bruijn indices between [n] and [n+nvars] occur in [t]. If
+ some such occurrences are found, then reduction is performed
+ (lazily for efficiency purposes) in order to determine whether
+ these occurrences are occurrences in the normal form. If the
+ occurrences are eliminated a witness reduct [Some t'] of [t] is
+ returned otherwise [None] is returned. *)
let weaker_noccur_between env x nvars t =
if noccur_between x nvars t then Some t
else
@@ -284,7 +288,7 @@ let typecheck_inductive env mie =
let full_polymorphic () =
let defu = Term.univ_of_sort def_level in
let is_natural =
- type_in_type env || (check_leq (universes env') infu defu)
+ type_in_type env || (UGraph.check_leq (universes env') infu defu)
in
let _ =
(** Impredicative sort, always allow *)
@@ -310,7 +314,7 @@ let typecheck_inductive env mie =
(* conclusions of the parameters *)
(* We enforce [u >= lev] in case [lev] has a strict upper *)
(* constraints over [u] *)
- let b = type_in_type env || check_leq (universes env') infu u in
+ let b = type_in_type env || UGraph.check_leq (universes env') infu u in
if not b then
anomaly ~label:"check_inductive"
(Pp.str"Incorrect universe " ++
@@ -336,7 +340,7 @@ let typecheck_inductive env mie =
type ill_formed_ind =
| LocalNonPos of int
| LocalNotEnoughArgs of int
- | LocalNotConstructor of rel_context * constr list
+ | LocalNotConstructor of Context.Rel.t * constr list
| LocalNonPar of int * int * int
exception IllFormedInd of ill_formed_ind
@@ -356,7 +360,7 @@ let explain_ind_err id ntyp env nbpar c err =
raise (InductiveError
(NotEnoughArgs (env,c',mkRel (kt+nbpar))))
| LocalNotConstructor (paramsctxt,args)->
- let nparams = rel_context_nhyps paramsctxt in
+ let nparams = Context.Rel.nhyps paramsctxt in
raise (InductiveError
(NotConstructor (env,id,c',mkRel (ntyp+nbpar),nparams,
List.length args - nparams)))
@@ -379,7 +383,7 @@ let failwith_non_pos_list n ntypes l =
(* Check the inductive type is called with the expected parameters *)
let check_correct_par (env,n,ntypes,_) hyps l largs =
- let nparams = rel_context_nhyps hyps in
+ let nparams = Context.Rel.nhyps hyps in
let largs = Array.of_list largs in
if Array.length largs < nparams then
raise (IllFormedInd (LocalNotEnoughArgs l));
@@ -451,17 +455,30 @@ let rec ienv_decompose_prod (env,_,_,_ as ienv) n c =
let array_min nmr a = if Int.equal nmr 0 then 0 else
Array.fold_left (fun k (nmri,_) -> min k nmri) nmr a
-(* The recursive function that checks positivity and builds the list
- of recursive arguments *)
+(** [check_positivity_one ienv hyps (mind,i) nargs lcnames indlc]
+ checks the positivity of the [i]-th member of the mutually
+ inductive definition [mind]. It returns an [Rtree.t] which
+ represents the position of the recursive calls of inductive in [i]
+ for use by the guard condition (terms at these positions are
+ considered sub-terms) as well as the number of of non-uniform
+ arguments (used to generate induction schemes, so a priori less
+ relevant to the kernel). *)
let check_positivity_one (env,_,ntypes,_ as ienv) hyps (_,i as ind) nargs lcnames indlc =
- let lparams = rel_context_length hyps in
- let nmr = rel_context_nhyps hyps in
- (* Checking the (strict) positivity of a constructor argument type [c] *)
+ let lparams = Context.Rel.length hyps in
+ let nmr = Context.Rel.nhyps hyps in
+ (** Positivity of one argument [c] of a constructor (i.e. the
+ constructor [cn] has a type of the shape [… -> c … -> P], where,
+ more generally, the arrows may be dependent). *)
let rec check_pos (env, n, ntypes, ra_env as ienv) nmr c =
let x,largs = decompose_app (whd_betadeltaiota env c) in
match kind_of_term x with
| Prod (na,b,d) ->
let () = assert (List.is_empty largs) in
+ (** If one of the inductives of the mutually inductive
+ block occurs in the left-hand side of a product, then
+ such an occurrence is a non-strictly-positive
+ recursive call. Occurrences in the right-hand side of
+ the product must be strictly positive.*)
(match weaker_noccur_between env n ntypes b with
None -> failwith_non_pos_list n ntypes [b]
| Some b ->
@@ -474,21 +491,35 @@ let check_positivity_one (env,_,ntypes,_ as ienv) hyps (_,i as ind) nargs lcname
Mrec _ -> compute_rec_par ienv hyps nmr largs
| _ -> nmr)
in
+ (** The case where one of the inductives of the mutually
+ inductive block occurs as an argument of another is not
+ known to be safe. So Coq rejects it. *)
if not (List.for_all (noccur_between n ntypes) largs)
then failwith_non_pos_list n ntypes largs
else (nmr1,rarg)
with Failure _ | Invalid_argument _ -> (nmr,mk_norec))
| Ind ind_kn ->
- (* If the inductive type being defined appears in a
- parameter, then we have a nested indtype *)
+ (** If one of the inductives of the mutually inductive
+ block being defined appears in a parameter, then we
+ have a nested inductive type. The positivity is then
+ discharged to the [check_positive_nested] function. *)
if List.for_all (noccur_between n ntypes) largs then (nmr,mk_norec)
else check_positive_nested ienv nmr (ind_kn, largs)
| err ->
+ (** If an inductive of the mutually inductive block
+ appears in any other way, then the positivy check gives
+ up. *)
if noccur_between n ntypes x &&
List.for_all (noccur_between n ntypes) largs
then (nmr,mk_norec)
else failwith_non_pos_list n ntypes (x::largs)
+ (** [check_positive_nested] handles the case of nested inductive
+ calls, that is, when an inductive types from the mutually
+ inductive block is called as an argument of an inductive types
+ (for the moment, this inductive type must be a previously
+ defined types, not one of the types of the mutually inductive
+ block being defined). *)
(* accesses to the environment are not factorised, but is it worth? *)
and check_positive_nested (env,n,ntypes,ra_env as ienv) nmr ((mi,u), largs) =
let (mib,mip) = lookup_mind_specif env mi in
@@ -497,12 +528,13 @@ let check_positivity_one (env,_,ntypes,_ as ienv) hyps (_,i as ind) nargs lcname
let (lpar,auxlargs) =
try List.chop auxnpar largs
with Failure _ -> raise (IllFormedInd (LocalNonPos n)) in
- (* If the inductive appears in the args (non params) then the
- definition is not positive. *)
+ (** Inductives of the inductive block being defined are only
+ allowed to appear nested in the parameters of another inductive
+ type. Not in the proper indices. *)
if not (List.for_all (noccur_between n ntypes) auxlargs) then
failwith_non_pos_list n ntypes auxlargs;
- (* We do not deal with imbricated mutual inductive types *)
+ (* Nested mutual inductive types are not supported *)
let auxntyp = mib.mind_ntypes in
if not (Int.equal auxntyp 1) then raise (IllFormedInd (LocalNonPos n));
(* The nested inductive type with parameters removed *)
@@ -513,8 +545,11 @@ let check_positivity_one (env,_,ntypes,_ as ienv) hyps (_,i as ind) nargs lcname
(* Parameters expressed in env' *)
let lpar' = List.map (lift auxntyp) lpar in
let irecargs_nmr =
- (* fails if the inductive type occurs non positively *)
- (* with recursive parameters substituted *)
+ (** Checks that the "nesting" inductive type is covariant in
+ the relevant parameters. In other words, that the
+ (nested) parameters which are instantiated with
+ inductives of the mutually inductive block occur
+ positively in the types of the nested constructors. *)
Array.map
(function c ->
let c' = hnf_prod_applist env' c lpar' in
@@ -528,10 +563,14 @@ let check_positivity_one (env,_,ntypes,_ as ienv) hyps (_,i as ind) nargs lcname
in
(nmr',(Rtree.mk_rec [|mk_paths (Imbr mi) irecargs|]).(0))
- (* check the inductive types occur positively in the products of C, if
- check_head=true, also check the head corresponds to a constructor of
- the ith type *)
-
+ (** [check_constructors ienv check_head nmr c] checks the positivity
+ condition in the type [c] of a constructor (i.e. that recursive
+ calls to the inductives of the mutually inductive definition
+ appear strictly positively in each of the arguments of the
+ constructor, see also [check_pos]). If [check_head] is [true],
+ then the type of the fully applied constructor (the "head" of
+ the type [c]) is checked to be the right (properly applied)
+ inductive type. *)
and check_constructors ienv check_head nmr c =
let rec check_constr_rec (env,n,ntypes,ra_env as ienv) nmr lrec c =
let x,largs = decompose_app (whd_betadeltaiota env c) in
@@ -571,17 +610,19 @@ let check_positivity_one (env,_,ntypes,_ as ienv) hyps (_,i as ind) nargs lcname
and nmr' = array_min nmr irecargs_nmr
in (nmr', mk_paths (Mrec ind) irecargs)
+(** [check_positivity kn env_ar params] checks that the mutually
+ inductive block [inds] is strictly positive. *)
let check_positivity kn env_ar params inds =
let ntypes = Array.length inds in
let rc = Array.mapi (fun j t -> (Mrec (kn,j),t)) (Rtree.mk_rec_calls ntypes) in
let lra_ind = Array.rev_to_list rc in
- let lparams = rel_context_length params in
- let nmr = rel_context_nhyps params in
+ let lparams = Context.Rel.length params in
+ let nmr = Context.Rel.nhyps params in
let check_one i (_,lcnames,lc,(sign,_)) =
let ra_env =
List.init lparams (fun _ -> (Norec,mk_norec)) @ lra_ind in
let ienv = (env_ar, 1+lparams, ntypes, ra_env) in
- let nargs = rel_context_nhyps sign - nmr in
+ let nargs = Context.Rel.nhyps sign - nmr in
check_positivity_one ienv params (kn,i) nargs lcnames lc
in
let irecargs_nmr = Array.mapi check_one inds in
@@ -639,6 +680,7 @@ let used_section_variables env inds =
keep_hyps env ids
let rel_vect n m = Array.init m (fun i -> mkRel(n+m-i))
+let rel_list n m = Array.to_list (rel_vect n m)
exception UndefinableExpansion
@@ -653,23 +695,21 @@ let compute_projections ((kn, _ as ind), u as indu) n x nparamargs params
that typechecking projections requires just a substitution and not
matching with a parameter context. *)
let indty, paramsletsubst =
- let _, _, subst, inst =
- List.fold_right
- (fun (na, b, t) (i, j, subst, inst) ->
- match b with
- | None -> (i-1, j-1, mkRel i :: subst, mkRel j :: inst)
- | Some b -> (i, j-1, substl subst b :: subst, inst))
- paramslet (nparamargs, List.length paramslet, [], [])
- in
+ (* [ty] = [Ind inst] is typed in context [params] *)
+ let inst = Context.Rel.to_extended_vect 0 paramslet in
+ let ty = mkApp (mkIndU indu, inst) in
+ (* [Ind inst] is typed in context [params-wo-let] *)
+ let inst' = rel_list 0 nparamargs in
+ (* {params-wo-let |- subst:params] *)
+ let subst = subst_of_rel_context_instance paramslet inst' in
+ (* {params-wo-let, x:Ind inst' |- subst':(params,x:Ind inst)] *)
let subst = (* For the record parameter: *)
- mkRel 1 :: List.map (lift 1) subst
- in
- let ty = mkApp (mkIndU indu, CArray.rev_of_list inst) in
+ mkRel 1 :: List.map (lift 1) subst in
ty, subst
in
let ci =
let print_info =
- { ind_tags = []; cstr_tags = [|rel_context_tags ctx|]; style = LetStyle } in
+ { ind_tags = []; cstr_tags = [|Context.Rel.to_tags ctx|]; style = LetStyle } in
{ ci_ind = ind;
ci_npar = nparamargs;
ci_cstr_ndecls = mind_consnrealdecls;
@@ -742,8 +782,8 @@ let build_inductive env p prv ctx env_ar params kn isrecord isfinite inds nmr re
let ntypes = Array.length inds in
(* Compute the set of used section variables *)
let hyps = used_section_variables env inds in
- let nparamargs = rel_context_nhyps params in
- let nparamdecls = rel_context_length params in
+ let nparamargs = Context.Rel.nhyps params in
+ let nparamdecls = Context.Rel.length params in
let subst, ctx = Univ.abstract_universes p ctx in
let params = Vars.subst_univs_level_context subst params in
let env_ar =
@@ -758,10 +798,10 @@ let build_inductive env p prv ctx env_ar params kn isrecord isfinite inds nmr re
let splayed_lc = Array.map (dest_prod_assum env_ar) lc in
let nf_lc = Array.map (fun (d,b) -> it_mkProd_or_LetIn b d) splayed_lc in
let consnrealdecls =
- Array.map (fun (d,_) -> rel_context_length d - rel_context_length params)
+ Array.map (fun (d,_) -> Context.Rel.length d - Context.Rel.length params)
splayed_lc in
let consnrealargs =
- Array.map (fun (d,_) -> rel_context_nhyps d - rel_context_nhyps params)
+ Array.map (fun (d,_) -> Context.Rel.nhyps d - Context.Rel.nhyps params)
splayed_lc in
(* Elimination sorts *)
let arkind,kelim =
@@ -794,8 +834,8 @@ let build_inductive env p prv ctx env_ar params kn isrecord isfinite inds nmr re
{ mind_typename = id;
mind_arity = arkind;
mind_arity_ctxt = Vars.subst_univs_level_context subst ar_sign;
- mind_nrealargs = rel_context_nhyps ar_sign - nparamargs;
- mind_nrealdecls = rel_context_length ar_sign - nparamdecls;
+ mind_nrealargs = Context.Rel.nhyps ar_sign - nparamargs;
+ mind_nrealdecls = Context.Rel.length ar_sign - nparamdecls;
mind_kelim = kelim;
mind_consnames = Array.of_list cnames;
mind_consnrealdecls = consnrealdecls;
diff --git a/kernel/indtypes.mli b/kernel/indtypes.mli
index a7bf8fabd..5b4615399 100644
--- a/kernel/indtypes.mli
+++ b/kernel/indtypes.mli
@@ -42,6 +42,6 @@ val enforce_indices_matter : unit -> unit
val is_indices_matter : unit -> bool
val compute_projections : pinductive -> Id.t -> Id.t ->
- int -> Context.rel_context -> int array -> int array ->
- Context.rel_context -> Context.rel_context ->
+ int -> Context.Rel.t -> int array -> int array ->
+ Context.Rel.t -> Context.Rel.t ->
(constant array * projection_body array)
diff --git a/kernel/inductive.ml b/kernel/inductive.ml
index 80dc69042..dd49c4a1b 100644
--- a/kernel/inductive.ml
+++ b/kernel/inductive.ml
@@ -12,7 +12,6 @@ open Names
open Univ
open Term
open Vars
-open Context
open Declarations
open Declareops
open Environ
@@ -77,7 +76,7 @@ let instantiate_params full t u args sign =
let fail () =
anomaly ~label:"instantiate_params" (Pp.str "type, ctxt and args mismatch") in
let (rem_args, subs, ty) =
- Context.fold_rel_context
+ Context.Rel.fold_outside
(fun (_,copt,_) (largs,subs,ty) ->
match (copt, largs, kind_of_term ty) with
| (None, a::args, Prod(_,_,t)) -> (args, a::subs, t)
@@ -151,7 +150,7 @@ let remember_subst u subst =
(* Bind expected levels of parameters to actual levels *)
(* Propagate the new levels in the signature *)
-let rec make_subst env =
+let make_subst env =
let rec make subst = function
| (_,Some _,_)::sign, exp, args ->
make subst (sign, exp, args)
@@ -270,18 +269,6 @@ let type_of_constructors (ind,u) (mib,mip) =
(* Type of case predicates *)
-let local_rels ctxt =
- let (rels,_) =
- Context.fold_rel_context_reverse
- (fun (rels,n) (_,copt,_) ->
- match copt with
- None -> (mkRel n :: rels, n+1)
- | Some _ -> (rels, n+1))
- ~init:([],1)
- ctxt
- in
- rels
-
(* Get type of inductive, with parameters instantiated *)
let inductive_sort_family mip =
@@ -304,20 +291,12 @@ let is_primitive_record (mib,_) =
| Some (Some _) -> true
| _ -> false
-let extended_rel_list n hyps =
- let rec reln l p = function
- | (_,None,_) :: hyps -> reln (mkRel (n+p) :: l) (p+1) hyps
- | (_,Some _,_) :: hyps -> reln l (p+1) hyps
- | [] -> l
- in
- reln [] 1 hyps
-
let build_dependent_inductive ind (_,mip) params =
let realargs,_ = List.chop mip.mind_nrealdecls mip.mind_arity_ctxt in
applist
(mkIndU ind,
List.map (lift mip.mind_nrealdecls) params
- @ extended_rel_list 0 realargs)
+ @ Context.Rel.to_extended_list 0 realargs)
(* This exception is local *)
exception LocalArity of (sorts_family * sorts_family * arity_error) option
@@ -369,22 +348,22 @@ let is_correct_arity env c pj ind specif params =
let build_branches_type (ind,u) (_,mip as specif) params p =
let build_one_branch i cty =
let typi = full_constructor_instantiate (ind,u,specif,params) cty in
- let (args,ccl) = decompose_prod_assum typi in
- let nargs = rel_context_length args in
+ let (cstrsign,ccl) = decompose_prod_assum typi in
+ let nargs = Context.Rel.length cstrsign in
let (_,allargs) = decompose_app ccl in
let (lparams,vargs) = List.chop (inductive_params specif) allargs in
let cargs =
let cstr = ith_constructor_of_inductive ind (i+1) in
- let dep_cstr = applist (mkConstructU (cstr,u),lparams@(local_rels args)) in
+ let dep_cstr = applist (mkConstructU (cstr,u),lparams@(Context.Rel.to_extended_list 0 cstrsign)) in
vargs @ [dep_cstr] in
- let base = betazeta_appvect mip.mind_nrealdecls (lift nargs p) (Array.of_list cargs) in
- it_mkProd_or_LetIn base args in
+ let base = lambda_appvect_assum (mip.mind_nrealdecls+1) (lift nargs p) (Array.of_list cargs) in
+ it_mkProd_or_LetIn base cstrsign in
Array.mapi build_one_branch mip.mind_nf_lc
(* [p] is the predicate, [c] is the match object, [realargs] is the
list of real args of the inductive type *)
let build_case_type env n p c realargs =
- whd_betaiota env (betazeta_appvect (n+1) p (Array.of_list (realargs@[c])))
+ whd_betaiota env (lambda_appvect_assum (n+1) p (Array.of_list (realargs@[c])))
let type_case_branches env (pind,largs) pj c =
let specif = lookup_mind_specif env (fst pind) in
@@ -519,7 +498,7 @@ let subterm_var p renv =
with Failure _ | Invalid_argument _ -> Not_subterm
let push_ctxt_renv renv ctxt =
- let n = rel_context_length ctxt in
+ let n = Context.Rel.length ctxt in
{ env = push_rel_context ctxt renv.env;
rel_min = renv.rel_min+n;
genv = iterate (fun ge -> lazy Not_subterm::ge) n renv.genv }
@@ -721,7 +700,7 @@ let restrict_spec env spec p =
else let absctx, ar = dest_lam_assum env p in
(* Optimization: if the predicate is not dependent, no restriction is needed
and we avoid building the recargs tree. *)
- if noccur_with_meta 1 (rel_context_length absctx) ar then spec
+ if noccur_with_meta 1 (Context.Rel.length absctx) ar then spec
else
let env = push_rel_context absctx env in
let arctx, s = dest_prod_assum env ar in
@@ -863,7 +842,7 @@ let filter_stack_domain env ci p stack =
let absctx, ar = dest_lam_assum env p in
(* Optimization: if the predicate is not dependent, no restriction is needed
and we avoid building the recargs tree. *)
- if noccur_with_meta 1 (rel_context_length absctx) ar then stack
+ if noccur_with_meta 1 (Context.Rel.length absctx) ar then stack
else let env = push_rel_context absctx env in
let rec filter_stack env ar stack =
let t = whd_betadeltaiota env ar in
diff --git a/kernel/inductive.mli b/kernel/inductive.mli
index b2f1e038b..c0d18bc6e 100644
--- a/kernel/inductive.mli
+++ b/kernel/inductive.mli
@@ -8,7 +8,6 @@
open Names
open Term
-open Context
open Univ
open Declarations
open Environ
@@ -35,7 +34,7 @@ val lookup_mind_specif : env -> inductive -> mind_specif
(** {6 Functions to build standard types related to inductive } *)
val ind_subst : mutual_inductive -> mutual_inductive_body -> universe_instance -> constr list
-val inductive_paramdecls : mutual_inductive_body puniverses -> rel_context
+val inductive_paramdecls : mutual_inductive_body puniverses -> Context.Rel.t
val instantiate_inductive_constraints :
mutual_inductive_body -> universe_instance -> constraints
@@ -86,7 +85,7 @@ val build_branches_type :
constr list -> constr -> types array
(** Return the arity of an inductive type *)
-val mind_arity : one_inductive_body -> rel_context * sorts_family
+val mind_arity : one_inductive_body -> Context.Rel.t * sorts_family
val inductive_sort_family : one_inductive_body -> sorts_family
@@ -111,8 +110,8 @@ exception SingletonInductiveBecomesProp of Id.t
val max_inductive_sort : sorts array -> universe
-val instantiate_universes : env -> rel_context ->
- template_arity -> constr Lazy.t array -> rel_context * sorts
+val instantiate_universes : env -> Context.Rel.t ->
+ template_arity -> constr Lazy.t array -> Context.Rel.t * sorts
(** {6 Debug} *)
diff --git a/kernel/kernel.mllib b/kernel/kernel.mllib
index 29fe887d7..f7220c94a 100644
--- a/kernel/kernel.mllib
+++ b/kernel/kernel.mllib
@@ -1,6 +1,7 @@
Names
Uint31
Univ
+UGraph
Esubst
Sorts
Evar
diff --git a/kernel/mod_typing.ml b/kernel/mod_typing.ml
index 4fc777c4f..ff44f0f54 100644
--- a/kernel/mod_typing.ml
+++ b/kernel/mod_typing.ml
@@ -104,7 +104,7 @@ let rec check_with_def env struc (idl,(c,ctx)) mp equiv =
let csti = Univ.enforce_eq_instances cus newus cst in
let csta = Univ.Constraint.union csti ccst in
let env' = Environ.push_context ~strict:false (Univ.UContext.make (inst, csta)) env in
- let () = if not (Univ.check_constraints cst (Environ.universes env')) then
+ let () = if not (UGraph.check_constraints cst (Environ.universes env')) then
error_incorrect_with_constraint lab
in
let cst = match cb.const_body with
diff --git a/kernel/names.ml b/kernel/names.ml
index f5d954e9c..02587bad9 100644
--- a/kernel/names.ml
+++ b/kernel/names.ml
@@ -23,6 +23,7 @@ open Util
(** {6 Identifiers } *)
+(** Representation and operations on identifiers. *)
module Id =
struct
type t = string
@@ -74,10 +75,12 @@ struct
end
-
+(** Representation and operations on identifiers that are allowed to be anonymous
+ (i.e. "_" in concrete syntax). *)
module Name =
struct
- type t = Name of Id.t | Anonymous
+ type t = Anonymous (** anonymous identifier *)
+ | Name of Id.t (** non-anonymous identifier *)
let compare n1 n2 = match n1, n2 with
| Anonymous, Anonymous -> 0
@@ -117,8 +120,8 @@ struct
end
-type name = Name.t = Name of Id.t | Anonymous
(** Alias, to import constructors. *)
+type name = Name.t = Anonymous | Name of Id.t
(** {6 Various types based on identifiers } *)
@@ -204,7 +207,7 @@ struct
DirPath.to_string p ^ "." ^ s
let debug_to_string (i, s, p) =
- "<"(*^string_of_dirpath p ^"#"^*) ^ s ^"#"^ string_of_int i^">"
+ "<"^DirPath.to_string p ^"#" ^ s ^"#"^ string_of_int i^">"
let compare (x : t) (y : t) =
if x == y then 0
@@ -282,6 +285,11 @@ module ModPath = struct
| MPbound uid -> MBId.to_string uid
| MPdot (mp,l) -> to_string mp ^ "." ^ Label.to_string l
+ let rec debug_to_string = function
+ | MPfile sl -> DirPath.to_string sl
+ | MPbound uid -> MBId.debug_to_string uid
+ | MPdot (mp,l) -> debug_to_string mp ^ "." ^ Label.to_string l
+
(** we compare labels first if both are MPdots *)
let rec compare mp1 mp2 =
if mp1 == mp2 then 0
@@ -375,12 +383,16 @@ module KerName = struct
let modpath kn = kn.modpath
let label kn = kn.knlabel
- let to_string kn =
+ let to_string_gen mp_to_string kn =
let dp =
if DirPath.is_empty kn.dirpath then "."
else "#" ^ DirPath.to_string kn.dirpath ^ "#"
in
- ModPath.to_string kn.modpath ^ dp ^ Label.to_string kn.knlabel
+ mp_to_string kn.modpath ^ dp ^ Label.to_string kn.knlabel
+
+ let to_string kn = to_string_gen ModPath.to_string kn
+
+ let debug_to_string kn = to_string_gen ModPath.debug_to_string kn
let print kn = str (to_string kn)
@@ -500,9 +512,9 @@ module KerPair = struct
let print kp = str (to_string kp)
let debug_to_string = function
- | Same kn -> "(" ^ KerName.to_string kn ^ ")"
+ | Same kn -> "(" ^ KerName.debug_to_string kn ^ ")"
| Dual (knu,knc) ->
- "(" ^ KerName.to_string knu ^ "," ^ KerName.to_string knc ^ ")"
+ "(" ^ KerName.debug_to_string knu ^ "," ^ KerName.debug_to_string knc ^ ")"
let debug_print kp = str (debug_to_string kp)
@@ -573,11 +585,16 @@ module Mindmap = HMap.Make(MutInd.CanOrd)
module Mindset = Mindmap.Set
module Mindmap_env = HMap.Make(MutInd.UserOrd)
-(** Beware: first inductive has index 0 *)
-(** Beware: first constructor has index 1 *)
+(** Designation of a (particular) inductive type. *)
+type inductive = MutInd.t (* the name of the inductive type *)
+ * int (* the position of this inductive type
+ within the block of mutually-recursive inductive types.
+ BEWARE: indexing starts from 0. *)
-type inductive = MutInd.t * int
-type constructor = inductive * int
+(** Designation of a (particular) constructor of a (particular) inductive type. *)
+type constructor = inductive (* designates the inductive type *)
+ * int (* the index of the constructor
+ BEWARE: indexing starts from 1. *)
let ind_modpath (mind,_) = MutInd.modpath mind
let constr_modpath (ind,_) = ind_modpath ind
diff --git a/kernel/names.mli b/kernel/names.mli
index 72dff03be..40f96813f 100644
--- a/kernel/names.mli
+++ b/kernel/names.mli
@@ -10,30 +10,33 @@ open Util
(** {6 Identifiers } *)
+(** Representation and operations on identifiers. *)
module Id :
sig
type t
- (** Type of identifiers *)
+ (** Values of this type represent (Coq) identifiers. *)
val equal : t -> t -> bool
- (** Equality over identifiers *)
+ (** Equality over identifiers. *)
val compare : t -> t -> int
- (** Comparison over identifiers *)
+ (** Comparison over identifiers. *)
val hash : t -> int
- (** Hash over identifiers *)
+ (** Hash over identifiers. *)
val is_valid : string -> bool
- (** Check that a string may be converted to an identifier. *)
+ (** Check that a string may be converted to an identifier.
+ @raise Unicode.Unsupported if the provided string contains unsupported UTF-8 characters. *)
val of_string : string -> t
- (** Converts a string into an identifier. May raise [UserError _] if the
- string is not valid, or echo a warning if it contains invalid identifier
- characters. *)
+ (** Converts a string into an identifier.
+ @raise UserError if the string is not valid, or echo a warning if it contains invalid identifier characters.
+ @raise Unicode.Unsupported if the provided string contains unsupported UTF-8 characters. *)
val of_string_soft : string -> t
- (** Same as {!of_string} except that no warning is ever issued. *)
+ (** Same as {!of_string} except that no warning is ever issued.
+ @raise Unicode.Unsupported if the provided string contains unsupported UTF-8 characters. *)
val to_string : t -> string
(** Converts a identifier into an string. *)
@@ -58,10 +61,12 @@ sig
end
+(** Representation and operations on identifiers that are allowed to be anonymous
+ (i.e. "_" in concrete syntax). *)
module Name :
sig
- type t = Name of Id.t | Anonymous
- (** A name is either undefined, either an identifier. *)
+ type t = Anonymous (** anonymous identifier *)
+ | Name of Id.t (** non-anonymous identifier *)
val compare : t -> t -> int
(** Comparison over names. *)
@@ -79,7 +84,7 @@ end
(** {6 Type aliases} *)
-type name = Name.t = Name of Id.t | Anonymous
+type name = Name.t = Anonymous | Name of Id.t
type variable = Id.t
type module_ident = Id.t
@@ -160,6 +165,8 @@ sig
module Set : Set.S with type elt = t
module Map : Map.ExtS with type key = t and module Set := Set
+ val hcons : t -> t
+
end
(** {6 Unique names for bound modules} *)
@@ -217,6 +224,9 @@ sig
val to_string : t -> string
+ val debug_to_string : t -> string
+ (** Same as [to_string], but outputs information related to debug. *)
+
val initial : t
(** Name of the toplevel structure ([= MPfile initial_dir]) *)
@@ -244,6 +254,10 @@ sig
(** Display *)
val to_string : t -> string
+
+ val debug_to_string : t -> string
+ (** Same as [to_string], but outputs information related to debug. *)
+
val print : t -> Pp.std_ppcmds
(** Comparisons *)
@@ -397,11 +411,16 @@ module Mindset : CSig.SetS with type elt = MutInd.t
module Mindmap : Map.ExtS with type key = MutInd.t and module Set := Mindset
module Mindmap_env : CSig.MapS with type key = MutInd.t
-(** Beware: first inductive has index 0 *)
-type inductive = MutInd.t * int
+(** Designation of a (particular) inductive type. *)
+type inductive = MutInd.t (* the name of the inductive type *)
+ * int (* the position of this inductive type
+ within the block of mutually-recursive inductive types.
+ BEWARE: indexing starts from 0. *)
-(** Beware: first constructor has index 1 *)
-type constructor = inductive * int
+(** Designation of a (particular) constructor of a (particular) inductive type. *)
+type constructor = inductive (* designates the inductive type *)
+ * int (* the index of the constructor
+ BEWARE: indexing starts from 1. *)
module Indmap : CSig.MapS with type key = inductive
module Constrmap : CSig.MapS with type key = constructor
diff --git a/kernel/nativecode.ml b/kernel/nativecode.ml
index 9d181b476..711096b2b 100644
--- a/kernel/nativecode.ml
+++ b/kernel/nativecode.ml
@@ -8,7 +8,6 @@
open Errors
open Names
open Term
-open Context
open Declarations
open Util
open Nativevalues
@@ -1826,15 +1825,15 @@ and apply_fv env sigma univ (fv_named,fv_rel) auxdefs ml =
in
let auxdefs = List.fold_right get_rel_val fv_rel auxdefs in
let auxdefs = List.fold_right get_named_val fv_named auxdefs in
- let lvl = rel_context_length env.env_rel_context in
+ let lvl = Context.Rel.length env.env_rel_context in
let fv_rel = List.map (fun (n,_) -> MLglobal (Grel (lvl-n))) fv_rel in
let fv_named = List.map (fun (id,_) -> MLglobal (Gnamed id)) fv_named in
let aux_name = fresh_lname Anonymous in
auxdefs, MLlet(aux_name, ml, mkMLapp (MLlocal aux_name) (Array.of_list (fv_rel@fv_named)))
and compile_rel env sigma univ auxdefs n =
- let (_,body,_) = lookup_rel n env.env_rel_context in
- let n = rel_context_length env.env_rel_context - n in
+ let (_,body,_) = Context.Rel.lookup n env.env_rel_context in
+ let n = Context.Rel.length env.env_rel_context - n in
match body with
| Some t ->
let code = lambda_of_constr env sigma t in
@@ -1844,7 +1843,7 @@ and compile_rel env sigma univ auxdefs n =
Glet(Grel n, MLprimitive (Mk_rel n))::auxdefs
and compile_named env sigma univ auxdefs id =
- let (_,body,_) = lookup_named id env.env_named_context in
+ let (_,body,_) = Context.Named.lookup id env.env_named_context in
match body with
| Some t ->
let code = lambda_of_constr env sigma t in
diff --git a/kernel/nativeconv.mli b/kernel/nativeconv.mli
index 6c0b310cb..63b1eb058 100644
--- a/kernel/nativeconv.mli
+++ b/kernel/nativeconv.mli
@@ -11,7 +11,7 @@ open Nativelambda
(** This module implements the conversion test by compiling to OCaml code *)
-val native_conv : conv_pb -> evars -> types conversion_function
+val native_conv : conv_pb -> evars -> types kernel_conversion_function
(** A conversion function parametrized by a universe comparator. Used outside of
the kernel. *)
diff --git a/kernel/nativelambda.ml b/kernel/nativelambda.ml
index f10db224f..01f59df15 100644
--- a/kernel/nativelambda.ml
+++ b/kernel/nativelambda.ml
@@ -485,7 +485,7 @@ module Renv =
let pop env = Vect.pop env.name_rel
let popn env n =
- for i = 1 to n do pop env done
+ for _i = 1 to n do pop env done
let get env n =
Lrel (Vect.get_last env.name_rel (n-1), n)
diff --git a/kernel/nativelib.ml b/kernel/nativelib.ml
index 948989fde..4296b73ab 100644
--- a/kernel/nativelib.ml
+++ b/kernel/nativelib.ml
@@ -30,10 +30,6 @@ let output_dir = ".coq-native"
(* Extension of genereted ml files, stored for debugging purposes *)
let source_ext = ".native"
-(* Global settings and utilies for interface with OCaml *)
-let compiler_name =
- if Dynlink.is_native then ocamlopt () else ocamlc ()
-
let ( / ) = Filename.concat
(* We have to delay evaluation of include_dirs because coqlib cannot be guessed
@@ -70,15 +66,16 @@ let call_compiler ml_filename =
remove link_filename;
remove (f ^ ".cmi");
let args =
- (if Dynlink.is_native then "-shared" else "-c")
+ (if Dynlink.is_native then "opt" else "ocamlc")
+ ::(if Dynlink.is_native then "-shared" else "-c")
::"-o"::link_filename
::"-rectypes"
::"-w"::"a"
::include_dirs
@ ["-impl"; ml_filename] in
- if !Flags.debug then Pp.msg_debug (Pp.str (compiler_name ^ " " ^ (String.concat " " args)));
+ if !Flags.debug then Pp.msg_debug (Pp.str (ocamlfind () ^ " " ^ (String.concat " " args)));
try
- let res = CUnix.sys_command compiler_name args in
+ let res = CUnix.sys_command (ocamlfind ()) args in
let res = match res with
| Unix.WEXITED 0 -> true
| Unix.WEXITED n ->
diff --git a/kernel/nativevalues.ml b/kernel/nativevalues.ml
index 5712c997d..d6fdfefa0 100644
--- a/kernel/nativevalues.ml
+++ b/kernel/nativevalues.ml
@@ -78,8 +78,6 @@ let accumulate_code (k:accumulator) (x:t) =
let rec accumulate (x:t) =
accumulate_code (Obj.magic accumulate) x
-let raccumulate = ref accumulate
-
let mk_accu_gen rcode (a:atom) =
(* Format.eprintf "size rcode =%i\n" (Obj.size (Obj.magic rcode)); *)
let r = Obj.new_block 0 3 in
@@ -160,31 +158,6 @@ let is_accu x =
let o = Obj.repr x in
Obj.is_block o && Int.equal (Obj.tag o) accumulate_tag
-(*let accumulate_fix_code (k:accumulator) (a:t) =
- match atom_of_accu k with
- | Afix(frec,_,rec_pos,_,_) ->
- let nargs = accu_nargs k in
- if nargs <> rec_pos || is_accu a then
- accumulate_code k a
- else
- let r = ref frec in
- for i = 0 to nargs - 1 do
- r := !r (arg_of_accu k i)
- done;
- !r a
- | _ -> assert false
-
-
-let rec accumulate_fix (x:t) =
- accumulate_fix_code (Obj.magic accumulate_fix) x
-
-let raccumulate_fix = ref accumulate_fix *)
-
-let is_atom_fix (a:atom) =
- match a with
- | Afix _ -> true
- | _ -> false
-
let mk_fix_accu rec_pos pos types bodies =
mk_accu_gen accumulate (Afix(types,bodies,rec_pos, pos))
diff --git a/kernel/opaqueproof.ml b/kernel/opaqueproof.ml
index 7d801902b..0c8772d8d 100644
--- a/kernel/opaqueproof.ml
+++ b/kernel/opaqueproof.ml
@@ -16,7 +16,7 @@ type work_list = (Instance.t * Id.t array) Cmap.t *
type cooking_info = {
modlist : work_list;
- abstract : Context.named_context * Univ.universe_level_subst * Univ.UContext.t }
+ abstract : Context.Named.t * Univ.universe_level_subst * Univ.UContext.t }
type proofterm = (constr * Univ.universe_context_set) Future.computation
type opaque =
| Indirect of substitution list * DirPath.t * int (* subst, lib, index *)
diff --git a/kernel/opaqueproof.mli b/kernel/opaqueproof.mli
index 9fd7172a5..5139cf051 100644
--- a/kernel/opaqueproof.mli
+++ b/kernel/opaqueproof.mli
@@ -48,7 +48,7 @@ type work_list = (Univ.Instance.t * Id.t array) Cmap.t *
type cooking_info = {
modlist : work_list;
- abstract : Context.named_context * Univ.universe_level_subst * Univ.UContext.t }
+ abstract : Context.Named.t * Univ.universe_level_subst * Univ.UContext.t }
(* The type has two caveats:
1) cook_constr is defined after
diff --git a/kernel/pre_env.ml b/kernel/pre_env.ml
index e1fe02595..4c1b2c5a6 100644
--- a/kernel/pre_env.ml
+++ b/kernel/pre_env.ml
@@ -15,7 +15,6 @@
open Util
open Names
-open Context
open Univ
open Term
open Declarations
@@ -45,7 +44,7 @@ type globals = {
env_modtypes : module_type_body MPmap.t}
type stratification = {
- env_universes : universes;
+ env_universes : UGraph.t;
env_engagement : engagement
}
@@ -66,9 +65,9 @@ type named_vals = (Id.t * lazy_val) list
type env = {
env_globals : globals;
- env_named_context : named_context;
+ env_named_context : Context.Named.t;
env_named_vals : named_vals;
- env_rel_context : rel_context;
+ env_rel_context : Context.Rel.t;
env_rel_val : lazy_val list;
env_nb_rel : int;
env_stratification : stratification;
@@ -77,7 +76,7 @@ type env = {
indirect_pterms : Opaqueproof.opaquetab;
}
-type named_context_val = named_context * named_vals
+type named_context_val = Context.Named.t * named_vals
let empty_named_context_val = [],[]
@@ -87,13 +86,13 @@ let empty_env = {
env_inductives = Mindmap_env.empty;
env_modules = MPmap.empty;
env_modtypes = MPmap.empty};
- env_named_context = empty_named_context;
+ env_named_context = Context.Named.empty;
env_named_vals = [];
- env_rel_context = empty_rel_context;
+ env_rel_context = Context.Rel.empty;
env_rel_val = [];
env_nb_rel = 0;
env_stratification = {
- env_universes = initial_universes;
+ env_universes = UGraph.initial_universes;
env_engagement = (PredicativeSet,StratifiedType) };
env_conv_oracle = Conv_oracle.empty;
retroknowledge = Retroknowledge.initial_retroknowledge;
@@ -107,7 +106,7 @@ let nb_rel env = env.env_nb_rel
let push_rel d env =
let rval = ref VKnone in
{ env with
- env_rel_context = add_rel_decl d env.env_rel_context;
+ env_rel_context = Context.Rel.add d env.env_rel_context;
env_rel_val = rval :: env.env_rel_val;
env_nb_rel = env.env_nb_rel + 1 }
@@ -127,7 +126,7 @@ let env_of_rel n env =
let push_named_context_val d (ctxt,vals) =
let id,_,_ = d in
let rval = ref VKnone in
- add_named_decl d ctxt, (id,rval)::vals
+ Context.Named.add d ctxt, (id,rval)::vals
let push_named d env =
(* if not (env.env_rel_context = []) then raise (ASSERT env.env_rel_context);
@@ -135,7 +134,7 @@ let push_named d env =
let id,body,_ = d in
let rval = ref VKnone in
{ env_globals = env.env_globals;
- env_named_context = Context.add_named_decl d env.env_named_context;
+ env_named_context = Context.Named.add d env.env_named_context;
env_named_vals = (id, rval) :: env.env_named_vals;
env_rel_context = env.env_rel_context;
env_rel_val = env.env_rel_val;
diff --git a/kernel/pre_env.mli b/kernel/pre_env.mli
index 23f9a3f41..f626aa0d3 100644
--- a/kernel/pre_env.mli
+++ b/kernel/pre_env.mli
@@ -8,9 +8,7 @@
open Names
open Term
-open Context
open Declarations
-open Univ
(** The type of environments. *)
@@ -32,7 +30,7 @@ type globals = {
env_modtypes : module_type_body MPmap.t}
type stratification = {
- env_universes : universes;
+ env_universes : UGraph.t;
env_engagement : engagement
}
@@ -46,9 +44,9 @@ type named_vals = (Id.t * lazy_val) list
type env = {
env_globals : globals;
- env_named_context : named_context;
+ env_named_context : Context.Named.t;
env_named_vals : named_vals;
- env_rel_context : rel_context;
+ env_rel_context : Context.Rel.t;
env_rel_val : lazy_val list;
env_nb_rel : int;
env_stratification : stratification;
@@ -57,7 +55,7 @@ type env = {
indirect_pterms : Opaqueproof.opaquetab;
}
-type named_context_val = named_context * named_vals
+type named_context_val = Context.Named.t * named_vals
val empty_named_context_val : named_context_val
@@ -66,15 +64,15 @@ val empty_env : env
(** Rel context *)
val nb_rel : env -> int
-val push_rel : rel_declaration -> env -> env
+val push_rel : Context.Rel.Declaration.t -> env -> env
val lookup_rel_val : int -> env -> lazy_val
val env_of_rel : int -> env -> env
(** Named context *)
val push_named_context_val :
- named_declaration -> named_context_val -> named_context_val
-val push_named : named_declaration -> env -> env
+ Context.Named.Declaration.t -> named_context_val -> named_context_val
+val push_named : Context.Named.Declaration.t -> env -> env
val lookup_named_val : Id.t -> env -> lazy_val
val env_of_named : Id.t -> env -> env
diff --git a/kernel/reduction.ml b/kernel/reduction.ml
index 97c3e1b34..40b80cc5e 100644
--- a/kernel/reduction.ml
+++ b/kernel/reduction.ml
@@ -20,7 +20,6 @@ open Util
open Names
open Term
open Vars
-open Context
open Univ
open Environ
open Closure
@@ -54,8 +53,7 @@ let compare_stack_shape stk1 stk2 =
| (_, Zapp l2::s2) -> compare_rec (bal-Array.length l2) stk1 s2
| (Zproj (n1,m1,p1)::s1, Zproj (n2,m2,p2)::s2) ->
Int.equal bal 0 && compare_rec 0 s1 s2
- | ((Zcase(c1,_,_)|ZcaseT(c1,_,_,_))::s1,
- (Zcase(c2,_,_)|ZcaseT(c2,_,_,_))::s2) ->
+ | (ZcaseT(c1,_,_,_)::s1, ZcaseT(c2,_,_,_)::s2) ->
Int.equal bal 0 (* && c1.ci_ind = c2.ci_ind *) && compare_rec 0 s1 s2
| (Zfix(_,a1)::s1, Zfix(_,a2)::s2) ->
Int.equal bal 0 && compare_rec 0 a1 a2 && compare_rec 0 s1 s2
@@ -89,9 +87,8 @@ let pure_stack lfts stk =
let (lfx,pa) = pure_rec l a in
(l, Zlfix((lfx,fx),pa)::pstk)
| (ZcaseT(ci,p,br,e),(l,pstk)) ->
- (l,Zlcase(ci,l,mk_clos e p,Array.map (mk_clos e) br)::pstk)
- | (Zcase(ci,p,br),(l,pstk)) ->
- (l,Zlcase(ci,l,p,br)::pstk)) in
+ (l,Zlcase(ci,l,mk_clos e p,Array.map (mk_clos e) br)::pstk))
+ in
snd (pure_rec lfts stk)
(****************************************************************************)
@@ -122,34 +119,20 @@ let whd_betadeltaiota_nolet env t =
Prod _|Lambda _|Fix _|CoFix _|LetIn _) -> t
| _ -> whd_val (create_clos_infos betadeltaiotanolet env) (inject t)
-(* Beta *)
-
-let beta_appvect c v =
- let rec stacklam env t stack =
- match kind_of_term t, stack with
- Lambda(_,_,c), arg::stacktl -> stacklam (arg::env) c stacktl
- | _ -> applist (substl env t, stack) in
- stacklam [] c (Array.to_list v)
-
-let betazeta_appvect n c v =
- let rec stacklam n env t stack =
- if Int.equal n 0 then applist (substl env t, stack) else
- match kind_of_term t, stack with
- Lambda(_,_,c), arg::stacktl -> stacklam (n-1) (arg::env) c stacktl
- | LetIn(_,b,_,c), _ -> stacklam (n-1) (substl env b::env) c stack
- | _ -> anomaly (Pp.str "Not enough lambda/let's") in
- stacklam n [] c (Array.to_list v)
-
(********************************************************************)
(* Conversion *)
(********************************************************************)
(* Conversion utility functions *)
-type 'a conversion_function = env -> 'a -> 'a -> unit
-type 'a trans_conversion_function = Names.transparent_state -> 'a conversion_function
-type 'a universe_conversion_function = env -> Univ.universes -> 'a -> 'a -> unit
-type 'a trans_universe_conversion_function =
- Names.transparent_state -> 'a universe_conversion_function
+
+(* functions of this type are called from the kernel *)
+type 'a kernel_conversion_function = env -> 'a -> 'a -> unit
+
+(* functions of this type can be called from outside the kernel *)
+type 'a extended_conversion_function =
+ ?l2r:bool -> ?reds:Names.transparent_state -> env ->
+ ?evars:((existential->constr option) * UGraph.t) ->
+ 'a -> 'a -> unit
exception NotConvertible
exception NotConvertibleVect of int
@@ -180,7 +163,7 @@ type 'a universe_state = 'a * 'a universe_compare
type ('a,'b) generic_conversion_function = env -> 'b universe_state -> 'a -> 'a -> 'b
-type 'a infer_conversion_function = env -> Univ.universes -> 'a -> 'a -> Univ.constraints
+type 'a infer_conversion_function = env -> UGraph.t -> 'a -> 'a -> Univ.constraints
let sort_cmp_universes env pb s0 s1 (u, check) =
(check.compare env pb s0 s1 u, check)
@@ -235,7 +218,6 @@ let rec no_arg_available = function
| Zshift _ :: stk -> no_arg_available stk
| Zapp v :: stk -> Int.equal (Array.length v) 0 && no_arg_available stk
| Zproj _ :: _ -> true
- | Zcase _ :: _ -> true
| ZcaseT _ :: _ -> true
| Zfix _ :: _ -> true
@@ -248,7 +230,6 @@ let rec no_nth_arg_available n = function
if n >= k then no_nth_arg_available (n-k) stk
else false
| Zproj _ :: _ -> true
- | Zcase _ :: _ -> true
| ZcaseT _ :: _ -> true
| Zfix _ :: _ -> true
@@ -258,13 +239,12 @@ let rec no_case_available = function
| Zshift _ :: stk -> no_case_available stk
| Zapp _ :: stk -> no_case_available stk
| Zproj (_,_,p) :: _ -> false
- | Zcase _ :: _ -> false
| ZcaseT _ :: _ -> false
| Zfix _ :: _ -> true
let in_whnf (t,stk) =
match fterm_of t with
- | (FLetIn _ | FCase _ | FCaseT _ | FApp _
+ | (FLetIn _ | FCaseT _ | FApp _
| FCLOS _ | FLIFT _ | FCast _) -> false
| FLambda _ -> no_arg_available stk
| FConstruct _ -> no_case_available stk
@@ -530,8 +510,8 @@ and eqappr cv_pb l2r infos (lft1,st1) (lft2,st2) cuniv =
else raise NotConvertible
(* Should not happen because both (hd1,v1) and (hd2,v2) are in whnf *)
- | ( (FLetIn _, _) | (FCase _,_) | (FCaseT _,_) | (FApp _,_) | (FCLOS _,_) | (FLIFT _,_)
- | (_, FLetIn _) | (_,FCase _) | (_,FCaseT _) | (_,FApp _) | (_,FCLOS _) | (_,FLIFT _)
+ | ( (FLetIn _, _) | (FCaseT _,_) | (FApp _,_) | (FCLOS _,_) | (FLIFT _,_)
+ | (_, FLetIn _) | (_,FCaseT _) | (_,FApp _) | (_,FCLOS _) | (_,FLIFT _)
| (FLOCKED,_) | (_,FLOCKED) ) -> assert false
(* In all other cases, terms are not convertible *)
@@ -556,17 +536,17 @@ and convert_vect l2r infos lft1 lft2 v1 v2 cuniv =
fold 0 cuniv
else raise NotConvertible
-let clos_fconv trans cv_pb l2r evars env univs t1 t2 =
+let clos_gen_conv trans cv_pb l2r evars env univs t1 t2 =
let reds = Closure.RedFlags.red_add_transparent betaiotazeta trans in
let infos = create_clos_infos ~evars reds env in
ccnv cv_pb l2r infos el_id el_id (inject t1) (inject t2) univs
let check_eq univs u u' =
- if not (check_eq univs u u') then raise NotConvertible
+ if not (UGraph.check_eq univs u u') then raise NotConvertible
let check_leq univs u u' =
- if not (check_leq univs u u') then raise NotConvertible
+ if not (UGraph.check_leq univs u u') then raise NotConvertible
let check_sort_cmp_universes env pb s0 s1 univs =
match (s0,s1) with
@@ -593,7 +573,7 @@ let checked_sort_cmp_universes env pb s0 s1 univs =
check_sort_cmp_universes env pb s0 s1 univs; univs
let check_convert_instances ~flex u u' univs =
- if Univ.Instance.check_eq univs u u' then univs
+ if UGraph.check_eq_instances univs u u' then univs
else raise NotConvertible
let checked_universes =
@@ -601,12 +581,12 @@ let checked_universes =
compare_instances = check_convert_instances }
let infer_eq (univs, cstrs as cuniv) u u' =
- if Univ.check_eq univs u u' then cuniv
+ if UGraph.check_eq univs u u' then cuniv
else
univs, (Univ.enforce_eq u u' cstrs)
let infer_leq (univs, cstrs as cuniv) u u' =
- if Univ.check_leq univs u u' then cuniv
+ if UGraph.check_leq univs u u' then cuniv
else
let cstrs' = Univ.enforce_leq u u' cstrs in
univs, cstrs'
@@ -635,57 +615,35 @@ let infer_cmp_universes env pb s0 s1 univs =
let infer_convert_instances ~flex u u' (univs,cstrs) =
(univs, Univ.enforce_eq_instances u u' cstrs)
-let inferred_universes : (Univ.universes * Univ.Constraint.t) universe_compare =
+let inferred_universes : (UGraph.t * Univ.Constraint.t) universe_compare =
{ compare = infer_cmp_universes;
compare_instances = infer_convert_instances }
-let trans_fconv_universes reds cv_pb l2r evars env univs t1 t2 =
+let gen_conv cv_pb l2r reds env evars univs t1 t2 =
let b =
if cv_pb = CUMUL then leq_constr_univs univs t1 t2
else eq_constr_univs univs t1 t2
in
if b then ()
else
- let _ = clos_fconv reds cv_pb l2r evars env (univs, checked_universes) t1 t2 in
+ let _ = clos_gen_conv reds cv_pb l2r evars env (univs, checked_universes) t1 t2 in
()
(* Profiling *)
-let trans_fconv_universes =
+let gen_conv cv_pb ?(l2r=false) ?(reds=full_transparent_state) env ?(evars=(fun _->None), universes env) =
+ let evars, univs = evars in
if Flags.profile then
- let trans_fconv_universes_key = Profile.declare_profile "trans_fconv_universes" in
- Profile.profile8 trans_fconv_universes_key trans_fconv_universes
- else trans_fconv_universes
-
-let trans_fconv reds cv_pb l2r evars env =
- trans_fconv_universes reds cv_pb l2r evars env (universes env)
-
-let trans_conv_cmp ?(l2r=false) conv reds = trans_fconv reds conv l2r (fun _->None)
-let trans_conv ?(l2r=false) ?(evars=fun _->None) reds = trans_fconv reds CONV l2r evars
-let trans_conv_leq ?(l2r=false) ?(evars=fun _->None) reds = trans_fconv reds CUMUL l2r evars
-
-let trans_conv_universes ?(l2r=false) ?(evars=fun _->None) reds =
- trans_fconv_universes reds CONV l2r evars
-let trans_conv_leq_universes ?(l2r=false) ?(evars=fun _->None) reds =
- trans_fconv_universes reds CUMUL l2r evars
+ let fconv_universes_key = Profile.declare_profile "trans_fconv_universes" in
+ Profile.profile8 fconv_universes_key gen_conv cv_pb l2r reds env evars univs
+ else gen_conv cv_pb l2r reds env evars univs
-let fconv = trans_fconv full_transparent_state
+let conv = gen_conv CONV
-let conv_cmp ?(l2r=false) cv_pb = fconv cv_pb l2r (fun _->None)
-let conv ?(l2r=false) ?(evars=fun _->None) = fconv CONV l2r evars
-let conv_leq ?(l2r=false) ?(evars=fun _->None) = fconv CUMUL l2r evars
-
-let conv_leq_vecti ?(l2r=false) ?(evars=fun _->None) env v1 v2 =
- Array.fold_left2_i
- (fun i _ t1 t2 ->
- try conv_leq ~l2r ~evars env t1 t2
- with NotConvertible -> raise (NotConvertibleVect i))
- ()
- v1
- v2
+let conv_leq = gen_conv CUMUL
let generic_conv cv_pb ~l2r evars reds env univs t1 t2 =
let (s, _) =
- clos_fconv reds cv_pb l2r evars env univs t1 t2
+ clos_gen_conv reds cv_pb l2r evars env univs t1 t2
in s
let infer_conv_universes cv_pb l2r evars reds env univs t1 t2 =
@@ -696,7 +654,7 @@ let infer_conv_universes cv_pb l2r evars reds env univs t1 t2 =
if b then cstrs
else
let univs = ((univs, Univ.Constraint.empty), inferred_universes) in
- let ((_,cstrs), _) = clos_fconv reds cv_pb l2r evars env univs t1 t2 in
+ let ((_,cstrs), _) = clos_gen_conv reds cv_pb l2r evars env univs t1 t2 in
cstrs
(* Profiling *)
@@ -715,18 +673,19 @@ let infer_conv_leq ?(l2r=false) ?(evars=fun _ -> None) ?(ts=full_transparent_sta
infer_conv_universes CUMUL l2r evars ts env univs t1 t2
(* This reference avoids always having to link C code with the kernel *)
-let vm_conv = ref (fun cv_pb -> fconv cv_pb false (fun _->None))
-let set_vm_conv f = vm_conv := f
+let vm_conv = ref (fun cv_pb env ->
+ gen_conv cv_pb env ~evars:((fun _->None), universes env))
+
+let set_vm_conv (f:conv_pb -> Term.types kernel_conversion_function) = vm_conv := f
let vm_conv cv_pb env t1 t2 =
try
!vm_conv cv_pb env t1 t2
with Not_found | Invalid_argument _ ->
- (Pp.msg_warning
- (Pp.str "Bytecode compilation failed, falling back to default conversion");
- fconv cv_pb false (fun _->None) env t1 t2)
+ Pp.msg_warning (Pp.str "Bytecode compilation failed, falling back to standard conversion");
+ gen_conv cv_pb env t1 t2
let default_conv cv_pb ?(l2r=false) env t1 t2 =
- fconv cv_pb false (fun _ -> None) env t1 t2
+ gen_conv cv_pb env t1 t2
let default_conv_leq = default_conv CUMUL
(*
@@ -739,12 +698,28 @@ let conv env t1 t2 =
Profile.profile4 convleqkey conv env t1 t2;;
*)
+(* Application with on-the-fly reduction *)
+
+let beta_applist c l =
+ let rec app subst c l =
+ match kind_of_term c, l with
+ | Lambda(_,_,c), arg::l -> app (arg::subst) c l
+ | _ -> applist (substl subst c, l) in
+ app [] c l
+
+let beta_appvect c v = beta_applist c (Array.to_list v)
+
+let beta_app c a = beta_applist c [a]
+
+(* Compatibility *)
+let betazeta_appvect = lambda_appvect_assum
+
(********************************************************************)
(* Special-Purpose Reduction *)
(********************************************************************)
(* pseudo-reduction rule:
- * [hnf_prod_app env s (Prod(_,B)) N --> B[N]
+ * [hnf_prod_app env (Prod(_,B)) N --> B[N]
* with an HNF on the first argument to produce a product.
* if this does not work, then we use the string S as part of our
* error message. *)
@@ -765,10 +740,10 @@ let dest_prod env =
match kind_of_term t with
| Prod (n,a,c0) ->
let d = (n,None,a) in
- decrec (push_rel d env) (add_rel_decl d m) c0
+ decrec (push_rel d env) (Context.Rel.add d m) c0
| _ -> m,t
in
- decrec env empty_rel_context
+ decrec env Context.Rel.empty
(* The same but preserving lets in the context, not internal ones. *)
let dest_prod_assum env =
@@ -777,17 +752,17 @@ let dest_prod_assum env =
match kind_of_term rty with
| Prod (x,t,c) ->
let d = (x,None,t) in
- prodec_rec (push_rel d env) (add_rel_decl d l) c
+ prodec_rec (push_rel d env) (Context.Rel.add d l) c
| LetIn (x,b,t,c) ->
let d = (x,Some b,t) in
- prodec_rec (push_rel d env) (add_rel_decl d l) c
+ prodec_rec (push_rel d env) (Context.Rel.add d l) c
| Cast (c,_,_) -> prodec_rec env l c
| _ ->
let rty' = whd_betadeltaiota env rty in
if Term.eq_constr rty' rty then l, rty
else prodec_rec env l rty'
in
- prodec_rec env empty_rel_context
+ prodec_rec env Context.Rel.empty
let dest_lam_assum env =
let rec lamec_rec env l ty =
@@ -795,14 +770,14 @@ let dest_lam_assum env =
match kind_of_term rty with
| Lambda (x,t,c) ->
let d = (x,None,t) in
- lamec_rec (push_rel d env) (add_rel_decl d l) c
+ lamec_rec (push_rel d env) (Context.Rel.add d l) c
| LetIn (x,b,t,c) ->
let d = (x,Some b,t) in
- lamec_rec (push_rel d env) (add_rel_decl d l) c
+ lamec_rec (push_rel d env) (Context.Rel.add d l) c
| Cast (c,_,_) -> lamec_rec env l c
| _ -> l,rty
in
- lamec_rec env empty_rel_context
+ lamec_rec env Context.Rel.empty
exception NotArity
diff --git a/kernel/reduction.mli b/kernel/reduction.mli
index 9a83ca709..1b5e5e32a 100644
--- a/kernel/reduction.mli
+++ b/kernel/reduction.mli
@@ -7,7 +7,6 @@
(************************************************************************)
open Term
-open Context
open Environ
(***********************************************************************
@@ -26,11 +25,11 @@ val nf_betaiota : env -> constr -> constr
exception NotConvertible
exception NotConvertibleVect of int
-type 'a conversion_function = env -> 'a -> 'a -> unit
-type 'a trans_conversion_function = Names.transparent_state -> 'a conversion_function
-type 'a universe_conversion_function = env -> Univ.universes -> 'a -> 'a -> unit
-type 'a trans_universe_conversion_function =
- Names.transparent_state -> 'a universe_conversion_function
+type 'a kernel_conversion_function = env -> 'a -> 'a -> unit
+type 'a extended_conversion_function =
+ ?l2r:bool -> ?reds:Names.transparent_state -> env ->
+ ?evars:((existential->constr option) * UGraph.t) ->
+ 'a -> 'a -> unit
type conv_pb = CONV | CUMUL
@@ -45,7 +44,7 @@ type 'a universe_state = 'a * 'a universe_compare
type ('a,'b) generic_conversion_function = env -> 'b universe_state -> 'a -> 'a -> 'b
-type 'a infer_conversion_function = env -> Univ.universes -> 'a -> 'a -> Univ.constraints
+type 'a infer_conversion_function = env -> UGraph.t -> 'a -> 'a -> Univ.constraints
val sort_cmp_universes : env -> conv_pb -> sorts -> sorts ->
'a * 'a universe_compare -> 'a * 'a universe_compare
@@ -55,27 +54,12 @@ constructors. *)
val convert_instances : flex:bool -> Univ.Instance.t -> Univ.Instance.t ->
'a * 'a universe_compare -> 'a * 'a universe_compare
-val checked_universes : Univ.universes universe_compare
-val inferred_universes : (Univ.universes * Univ.Constraint.t) universe_compare
+val checked_universes : UGraph.t universe_compare
+val inferred_universes : (UGraph.t * Univ.Constraint.t) universe_compare
-val trans_conv_cmp : ?l2r:bool -> conv_pb -> constr trans_conversion_function
-val trans_conv :
- ?l2r:bool -> ?evars:(existential->constr option) -> constr trans_conversion_function
-val trans_conv_leq :
- ?l2r:bool -> ?evars:(existential->constr option) -> types trans_conversion_function
+val conv : constr extended_conversion_function
-val trans_conv_universes :
- ?l2r:bool -> ?evars:(existential->constr option) -> constr trans_universe_conversion_function
-val trans_conv_leq_universes :
- ?l2r:bool -> ?evars:(existential->constr option) -> types trans_universe_conversion_function
-
-val conv_cmp : ?l2r:bool -> conv_pb -> constr conversion_function
-val conv :
- ?l2r:bool -> ?evars:(existential->constr option) -> constr conversion_function
-val conv_leq :
- ?l2r:bool -> ?evars:(existential->constr option) -> types conversion_function
-val conv_leq_vecti :
- ?l2r:bool -> ?evars:(existential->constr option) -> types array conversion_function
+val conv_leq : types extended_conversion_function
(** These conversion functions are used by module subtyping, which needs to infer
universe constraints inside the kernel *)
@@ -88,30 +72,35 @@ val generic_conv : conv_pb -> l2r:bool -> (existential->constr option) ->
Names.transparent_state -> (constr,'a) generic_conversion_function
(** option for conversion *)
-val set_vm_conv : (conv_pb -> types conversion_function) -> unit
-val vm_conv : conv_pb -> types conversion_function
+val set_vm_conv : (conv_pb -> types kernel_conversion_function) -> unit
+val vm_conv : conv_pb -> types kernel_conversion_function
-val default_conv : conv_pb -> ?l2r:bool -> types conversion_function
-val default_conv_leq : ?l2r:bool -> types conversion_function
+val default_conv : conv_pb -> ?l2r:bool -> types kernel_conversion_function
+val default_conv_leq : ?l2r:bool -> types kernel_conversion_function
(************************************************************************)
(** Builds an application node, reducing beta redexes it may produce. *)
+val beta_applist : constr -> constr list -> constr
+
+(** Builds an application node, reducing beta redexes it may produce. *)
val beta_appvect : constr -> constr array -> constr
-(** Builds an application node, reducing the [n] first beta-zeta redexes. *)
-val betazeta_appvect : int -> constr -> constr array -> constr
+(** Builds an application node, reducing beta redexe it may produce. *)
+val beta_app : constr -> constr -> constr
(** Pseudo-reduction rule Prod(x,A,B) a --> B[x\a] *)
val hnf_prod_applist : env -> types -> constr list -> types
+(** Compatibility alias for Term.lambda_appvect_assum *)
+val betazeta_appvect : int -> constr -> constr array -> constr
(***********************************************************************
s Recognizing products and arities modulo reduction *)
-val dest_prod : env -> types -> rel_context * types
-val dest_prod_assum : env -> types -> rel_context * types
-val dest_lam_assum : env -> types -> rel_context * types
+val dest_prod : env -> types -> Context.Rel.t * types
+val dest_prod_assum : env -> types -> Context.Rel.t * types
+val dest_lam_assum : env -> types -> Context.Rel.t * types
exception NotArity
diff --git a/kernel/safe_typing.ml b/kernel/safe_typing.ml
index 4c3264861..e56a6e099 100644
--- a/kernel/safe_typing.ml
+++ b/kernel/safe_typing.ml
@@ -222,13 +222,6 @@ let inline_private_constants_in_constr = Term_typing.inline_side_effects
let inline_private_constants_in_definition_entry = Term_typing.inline_entry_side_effects
let side_effects_of_private_constants x = Term_typing.uniq_seff (List.rev x)
-let constant_entry_of_private_constant = function
- | { Entries.eff = Entries.SEsubproof (kn, cb, eff_env) } ->
- [ kn, Term_typing.constant_entry_of_side_effect cb eff_env ]
- | { Entries.eff = Entries.SEscheme (l,_) } ->
- List.map (fun (_,kn,cb,eff_env) ->
- kn, Term_typing.constant_entry_of_side_effect cb eff_env) l
-
let private_con_of_con env c =
let cbo = Environ.lookup_constant c env.env in
{ Entries.from_env = Ephemeron.create env.revstruct;
@@ -561,6 +554,7 @@ let add_mind dir l mie senv =
let add_modtype l params_mte inl senv =
let mp = MPdot(senv.modpath, l) in
let mtb = Mod_typing.translate_modtype senv.env mp inl params_mte in
+ let mtb = Declareops.hcons_module_body mtb in
let senv' = add_field (l,SFBmodtype mtb) MT senv in
mp, senv'
@@ -581,6 +575,7 @@ let full_add_module_type mp mt senv =
let add_module l me inl senv =
let mp = MPdot(senv.modpath, l) in
let mb = Mod_typing.translate_module senv.env mp inl me in
+ let mb = Declareops.hcons_module_body mb in
let senv' = add_field (l,SFBmodule mb) M senv in
let senv'' =
if Modops.is_functor mb.mod_type then senv'
diff --git a/kernel/subtyping.ml b/kernel/subtyping.ml
index a422b18e0..5efc1078e 100644
--- a/kernel/subtyping.ml
+++ b/kernel/subtyping.ml
@@ -317,7 +317,7 @@ let check_constant cst env mp1 l info1 cb2 spec2 subst1 subst2 =
(* Check that the given definition does not add any constraint over
the expected ones, so that it can be used in place of
the original. *)
- if Univ.check_constraints ctx1 (Environ.universes env) then
+ if UGraph.check_constraints ctx1 (Environ.universes env) then
cstrs, env, inst2
else error (IncompatibleConstraints ctx1)
with Univ.UniverseInconsistency incon ->
diff --git a/kernel/term.ml b/kernel/term.ml
index ad8ae3be7..9ba45f540 100644
--- a/kernel/term.ml
+++ b/kernel/term.ml
@@ -10,7 +10,6 @@ open Util
open Pp
open Errors
open Names
-open Context
open Vars
(**********************************************************************)
@@ -471,26 +470,58 @@ let rec to_prod n lam =
| Cast (c,_,_) -> to_prod n c
| _ -> errorlabstrm "to_prod" (mt ())
-(* pseudo-reduction rule:
- * [prod_app s (Prod(_,B)) N --> B[N]
- * with an strip_outer_cast on the first argument to produce a product *)
+let it_mkProd_or_LetIn = List.fold_left (fun c d -> mkProd_or_LetIn d c)
+let it_mkLambda_or_LetIn = List.fold_left (fun c d -> mkLambda_or_LetIn d c)
-let prod_app t n =
- match kind_of_term (strip_outer_cast t) with
- | Prod (_,_,b) -> subst1 n b
- | _ ->
- errorlabstrm "prod_app"
- (str"Needed a product, but didn't find one" ++ fnl ())
+(* Application with expected on-the-fly reduction *)
+let lambda_applist c l =
+ let rec app subst c l =
+ match kind_of_term c, l with
+ | Lambda(_,_,c), arg::l -> app (arg::subst) c l
+ | _, [] -> substl subst c
+ | _ -> anomaly (Pp.str "Not enough lambda's") in
+ app [] c l
-(* prod_appvect T [| a1 ; ... ; an |] -> (T a1 ... an) *)
-let prod_appvect t nL = Array.fold_left prod_app t nL
+let lambda_appvect c v = lambda_applist c (Array.to_list v)
+
+let lambda_applist_assum n c l =
+ let rec app n subst t l =
+ if Int.equal n 0 then
+ if l == [] then substl subst t
+ else anomaly (Pp.str "Not enough arguments")
+ else match kind_of_term t, l with
+ | Lambda(_,_,c), arg::l -> app (n-1) (arg::subst) c l
+ | LetIn(_,b,_,c), _ -> app (n-1) (substl subst b::subst) c l
+ | _ -> anomaly (Pp.str "Not enough lambda/let's") in
+ app n [] c l
+
+let lambda_appvect_assum n c v = lambda_applist_assum n c (Array.to_list v)
(* prod_applist T [ a1 ; ... ; an ] -> (T a1 ... an) *)
-let prod_applist t nL = List.fold_left prod_app t nL
+let prod_applist c l =
+ let rec app subst c l =
+ match kind_of_term c, l with
+ | Prod(_,_,c), arg::l -> app (arg::subst) c l
+ | _, [] -> substl subst c
+ | _ -> anomaly (Pp.str "Not enough prod's") in
+ app [] c l
-let it_mkProd_or_LetIn = List.fold_left (fun c d -> mkProd_or_LetIn d c)
-let it_mkLambda_or_LetIn = List.fold_left (fun c d -> mkLambda_or_LetIn d c)
+(* prod_appvect T [| a1 ; ... ; an |] -> (T a1 ... an) *)
+let prod_appvect c v = prod_applist c (Array.to_list v)
+
+let prod_applist_assum n c l =
+ let rec app n subst t l =
+ if Int.equal n 0 then
+ if l == [] then substl subst t
+ else anomaly (Pp.str "Not enough arguments")
+ else match kind_of_term t, l with
+ | Prod(_,_,c), arg::l -> app (n-1) (arg::subst) c l
+ | LetIn(_,b,_,c), _ -> app (n-1) (substl subst b::subst) c l
+ | _ -> anomaly (Pp.str "Not enough prod/let's") in
+ app n [] c l
+
+let prod_appvect_assum n c v = prod_applist_assum n c (Array.to_list v)
(*********************************)
(* Other term destructors *)
@@ -547,24 +578,24 @@ let decompose_lam_n n =
let decompose_prod_assum =
let rec prodec_rec l c =
match kind_of_term c with
- | Prod (x,t,c) -> prodec_rec (add_rel_decl (x,None,t) l) c
- | LetIn (x,b,t,c) -> prodec_rec (add_rel_decl (x,Some b,t) l) c
+ | Prod (x,t,c) -> prodec_rec (Context.Rel.add (x,None,t) l) c
+ | LetIn (x,b,t,c) -> prodec_rec (Context.Rel.add (x,Some b,t) l) c
| Cast (c,_,_) -> prodec_rec l c
| _ -> l,c
in
- prodec_rec empty_rel_context
+ prodec_rec Context.Rel.empty
(* Transforms a lambda term [x1:T1]..[xn:Tn]T into the pair
([(xn,Tn);...;(x1,T1)],T), where T is not a lambda *)
let decompose_lam_assum =
let rec lamdec_rec l c =
match kind_of_term c with
- | Lambda (x,t,c) -> lamdec_rec (add_rel_decl (x,None,t) l) c
- | LetIn (x,b,t,c) -> lamdec_rec (add_rel_decl (x,Some b,t) l) c
+ | Lambda (x,t,c) -> lamdec_rec (Context.Rel.add (x,None,t) l) c
+ | LetIn (x,b,t,c) -> lamdec_rec (Context.Rel.add (x,Some b,t) l) c
| Cast (c,_,_) -> lamdec_rec l c
| _ -> l,c
in
- lamdec_rec empty_rel_context
+ lamdec_rec Context.Rel.empty
(* Given a positive integer n, decompose a product or let-in term
of the form [forall (x1:T1)..(xi:=ci:Ti)..(xn:Tn), T] into the pair
@@ -576,12 +607,12 @@ let decompose_prod_n_assum n =
let rec prodec_rec l n c =
if Int.equal n 0 then l,c
else match kind_of_term c with
- | Prod (x,t,c) -> prodec_rec (add_rel_decl (x,None,t) l) (n-1) c
- | LetIn (x,b,t,c) -> prodec_rec (add_rel_decl (x,Some b,t) l) (n-1) c
+ | Prod (x,t,c) -> prodec_rec (Context.Rel.add (x,None,t) l) (n-1) c
+ | LetIn (x,b,t,c) -> prodec_rec (Context.Rel.add (x,Some b,t) l) (n-1) c
| Cast (c,_,_) -> prodec_rec l n c
| c -> error "decompose_prod_n_assum: not enough assumptions"
in
- prodec_rec empty_rel_context n
+ prodec_rec Context.Rel.empty n
(* Given a positive integer n, decompose a lambda or let-in term [fun
(x1:T1)..(xi:=ci:Ti)..(xn:Tn) => T] into the pair of the abstracted
@@ -595,12 +626,12 @@ let decompose_lam_n_assum n =
let rec lamdec_rec l n c =
if Int.equal n 0 then l,c
else match kind_of_term c with
- | Lambda (x,t,c) -> lamdec_rec (add_rel_decl (x,None,t) l) (n-1) c
- | LetIn (x,b,t,c) -> lamdec_rec (add_rel_decl (x,Some b,t) l) n c
+ | Lambda (x,t,c) -> lamdec_rec (Context.Rel.add (x,None,t) l) (n-1) c
+ | LetIn (x,b,t,c) -> lamdec_rec (Context.Rel.add (x,Some b,t) l) n c
| Cast (c,_,_) -> lamdec_rec l n c
| c -> error "decompose_lam_n_assum: not enough abstractions"
in
- lamdec_rec empty_rel_context n
+ lamdec_rec Context.Rel.empty n
(* Same, counting let-in *)
let decompose_lam_n_decls n =
@@ -609,31 +640,12 @@ let decompose_lam_n_decls n =
let rec lamdec_rec l n c =
if Int.equal n 0 then l,c
else match kind_of_term c with
- | Lambda (x,t,c) -> lamdec_rec (add_rel_decl (x,None,t) l) (n-1) c
- | LetIn (x,b,t,c) -> lamdec_rec (add_rel_decl (x,Some b,t) l) (n-1) c
+ | Lambda (x,t,c) -> lamdec_rec (Context.Rel.add (x,None,t) l) (n-1) c
+ | LetIn (x,b,t,c) -> lamdec_rec (Context.Rel.add (x,Some b,t) l) (n-1) c
| Cast (c,_,_) -> lamdec_rec l n c
| c -> error "decompose_lam_n_decls: not enough abstractions"
in
- lamdec_rec empty_rel_context n
-
-(* (nb_lam [na1:T1]...[nan:Tan]c) where c is not an abstraction
- * gives n (casts are ignored) *)
-let nb_lam =
- let rec nbrec n c = match kind_of_term c with
- | Lambda (_,_,c) -> nbrec (n+1) c
- | Cast (c,_,_) -> nbrec n c
- | _ -> n
- in
- nbrec 0
-
-(* similar to nb_lam, but gives the number of products instead *)
-let nb_prod =
- let rec nbrec n c = match kind_of_term c with
- | Prod (_,_,c) -> nbrec (n+1) c
- | Cast (c,_,_) -> nbrec n c
- | _ -> n
- in
- nbrec 0
+ lamdec_rec Context.Rel.empty n
let prod_assum t = fst (decompose_prod_assum t)
let prod_n_assum n t = fst (decompose_prod_n_assum n t)
@@ -654,7 +666,7 @@ let strip_lam_n n t = snd (decompose_lam_n n t)
Such a term can canonically be seen as the pair of a context of types
and of a sort *)
-type arity = rel_context * sorts
+type arity = Context.Rel.t * sorts
let destArity =
let rec prodec_rec l c =
diff --git a/kernel/term.mli b/kernel/term.mli
index 14c20a205..7f79f6403 100644
--- a/kernel/term.mli
+++ b/kernel/term.mli
@@ -7,7 +7,6 @@
(************************************************************************)
open Names
-open Context
(** {5 Redeclaration of types from module Constr and Sorts}
@@ -213,14 +212,14 @@ val mkNamedLetIn : Id.t -> constr -> types -> constr -> constr
val mkNamedProd : Id.t -> types -> types -> types
(** Constructs either [(x:t)c] or [[x=b:t]c] *)
-val mkProd_or_LetIn : rel_declaration -> types -> types
-val mkProd_wo_LetIn : rel_declaration -> types -> types
-val mkNamedProd_or_LetIn : named_declaration -> types -> types
-val mkNamedProd_wo_LetIn : named_declaration -> types -> types
+val mkProd_or_LetIn : Context.Rel.Declaration.t -> types -> types
+val mkProd_wo_LetIn : Context.Rel.Declaration.t -> types -> types
+val mkNamedProd_or_LetIn : Context.Named.Declaration.t -> types -> types
+val mkNamedProd_wo_LetIn : Context.Named.Declaration.t -> types -> types
(** Constructs either [[x:t]c] or [[x=b:t]c] *)
-val mkLambda_or_LetIn : rel_declaration -> constr -> constr
-val mkNamedLambda_or_LetIn : named_declaration -> constr -> constr
+val mkLambda_or_LetIn : Context.Rel.Declaration.t -> constr -> constr
+val mkNamedLambda_or_LetIn : Context.Named.Declaration.t -> constr -> constr
(** {5 Other term constructors. } *)
@@ -262,14 +261,34 @@ val to_lambda : int -> constr -> constr
where [l] is [fun (x_1:T_1)...(x_n:T_n) => T] *)
val to_prod : int -> constr -> constr
+val it_mkLambda_or_LetIn : constr -> Context.Rel.t -> constr
+val it_mkProd_or_LetIn : types -> Context.Rel.t -> types
+
+(** In [lambda_applist c args], [c] is supposed to have the form
+ [λΓ.c] with [Γ] without let-in; it returns [c] with the variables
+ of [Γ] instantiated by [args]. *)
+val lambda_applist : constr -> constr list -> constr
+val lambda_appvect : constr -> constr array -> constr
+
+(** In [lambda_applist_assum n c args], [c] is supposed to have the
+ form [λΓ.c] with [Γ] of length [m] and possibly with let-ins; it
+ returns [c] with the assumptions of [Γ] instantiated by [args] and
+ the local definitions of [Γ] expanded. *)
+val lambda_applist_assum : int -> constr -> constr list -> constr
+val lambda_appvect_assum : int -> constr -> constr array -> constr
+
(** pseudo-reduction rule *)
(** [prod_appvect] [forall (x1:B1;...;xn:Bn), B] [a1...an] @return [B[a1...an]] *)
val prod_appvect : constr -> constr array -> constr
val prod_applist : constr -> constr list -> constr
-val it_mkLambda_or_LetIn : constr -> rel_context -> constr
-val it_mkProd_or_LetIn : types -> rel_context -> types
+(** In [prod_appvect_assum n c args], [c] is supposed to have the
+ form [∀Γ.c] with [Γ] of length [m] and possibly with let-ins; it
+ returns [c] with the assumptions of [Γ] instantiated by [args] and
+ the local definitions of [Γ] expanded. *)
+val prod_appvect_assum : int -> constr -> constr array -> constr
+val prod_applist_assum : int -> constr -> constr list -> constr
(** {5 Other term destructors. } *)
@@ -294,36 +313,29 @@ val decompose_lam_n : int -> constr -> (Name.t * constr) list * constr
(** Extract the premisses and the conclusion of a term of the form
"(xi:Ti) ... (xj:=cj:Tj) ..., T" where T is not a product nor a let *)
-val decompose_prod_assum : types -> rel_context * types
+val decompose_prod_assum : types -> Context.Rel.t * types
(** Idem with lambda's *)
-val decompose_lam_assum : constr -> rel_context * constr
+val decompose_lam_assum : constr -> Context.Rel.t * constr
(** Idem but extract the first [n] premisses, counting let-ins. *)
-val decompose_prod_n_assum : int -> types -> rel_context * types
+val decompose_prod_n_assum : int -> types -> Context.Rel.t * types
(** Idem for lambdas, _not_ counting let-ins *)
-val decompose_lam_n_assum : int -> constr -> rel_context * constr
+val decompose_lam_n_assum : int -> constr -> Context.Rel.t * constr
(** Idem, counting let-ins *)
-val decompose_lam_n_decls : int -> constr -> rel_context * constr
-
-(** [nb_lam] {% $ %}[x_1:T_1]...[x_n:T_n]c{% $ %} where {% $ %}c{% $ %} is not an abstraction
- gives {% $ %}n{% $ %} (casts are ignored) *)
-val nb_lam : constr -> int
-
-(** Similar to [nb_lam], but gives the number of products instead *)
-val nb_prod : constr -> int
+val decompose_lam_n_decls : int -> constr -> Context.Rel.t * constr
(** Return the premisses/parameters of a type/term (let-in included) *)
-val prod_assum : types -> rel_context
-val lam_assum : constr -> rel_context
+val prod_assum : types -> Context.Rel.t
+val lam_assum : constr -> Context.Rel.t
(** Return the first n-th premisses/parameters of a type (let included and counted) *)
-val prod_n_assum : int -> types -> rel_context
+val prod_n_assum : int -> types -> Context.Rel.t
(** Return the first n-th premisses/parameters of a term (let included but not counted) *)
-val lam_n_assum : int -> constr -> rel_context
+val lam_n_assum : int -> constr -> Context.Rel.t
(** Remove the premisses/parameters of a type/term *)
val strip_prod : types -> types
@@ -356,7 +368,7 @@ val under_outer_cast : (constr -> constr) -> constr -> constr
Such a term can canonically be seen as the pair of a context of types
and of a sort *)
-type arity = rel_context * sorts
+type arity = Context.Rel.t * sorts
(** Build an "arity" from its canonical form *)
val mkArity : arity -> types
@@ -436,11 +448,11 @@ val eq_constr : constr -> constr -> bool
(** [eq_constr_univs u a b] is [true] if [a] equals [b] modulo alpha, casts,
application grouping and the universe constraints in [u]. *)
-val eq_constr_univs : constr Univ.check_function
+val eq_constr_univs : constr UGraph.check_function
(** [leq_constr_univs u a b] is [true] if [a] is convertible to [b] modulo
alpha, casts, application grouping and the universe constraints in [u]. *)
-val leq_constr_univs : constr Univ.check_function
+val leq_constr_univs : constr UGraph.check_function
(** [eq_constr_univs a b] [true, c] if [a] equals [b] modulo alpha, casts,
application grouping and ignoring universe instances. *)
diff --git a/kernel/term_typing.ml b/kernel/term_typing.ml
index 510f43542..979165e49 100644
--- a/kernel/term_typing.ml
+++ b/kernel/term_typing.ml
@@ -16,7 +16,6 @@ open Errors
open Util
open Names
open Term
-open Context
open Declarations
open Environ
open Entries
@@ -246,8 +245,8 @@ let infer_declaration ~trust env kn dcl =
let global_vars_set_constant_type env = function
| RegularArity t -> global_vars_set env t
| TemplateArity (ctx,_) ->
- Context.fold_rel_context
- (fold_rel_declaration
+ Context.Rel.fold_outside
+ (Context.Rel.Declaration.fold
(fun t c -> Id.Set.union (global_vars_set env t) c))
ctx ~init:Id.Set.empty
diff --git a/kernel/typeops.ml b/kernel/typeops.ml
index f7f5e5074..f31cba0a8 100644
--- a/kernel/typeops.ml
+++ b/kernel/typeops.ml
@@ -12,7 +12,6 @@ open Names
open Univ
open Term
open Vars
-open Context
open Declarations
open Environ
open Entries
@@ -99,7 +98,7 @@ let judge_of_variable env id =
variables of the current env.
Order does not have to be checked assuming that all names are distinct *)
let check_hyps_inclusion env c sign =
- Context.fold_named_context
+ Context.Named.fold_outside
(fun (id,b1,ty1) () ->
try
let (_,b2,ty2) = lookup_named id env in
@@ -561,6 +560,6 @@ let infer_local_decls env decls =
| (id, d) :: l ->
let (env, l) = inferec env l in
let d = infer_local_decl env id d in
- (push_rel d env, add_rel_decl d l)
- | [] -> (env, empty_rel_context) in
+ (push_rel d env, Context.Rel.add d l)
+ | [] -> (env, Context.Rel.empty) in
inferec env decls
diff --git a/kernel/typeops.mli b/kernel/typeops.mli
index 2c6ca1fe2..2112284ea 100644
--- a/kernel/typeops.mli
+++ b/kernel/typeops.mli
@@ -9,7 +9,6 @@
open Names
open Univ
open Term
-open Context
open Environ
open Entries
open Declarations
@@ -28,7 +27,7 @@ val infer_v : env -> constr array -> unsafe_judgment array
val infer_type : env -> types -> unsafe_type_judgment
val infer_local_decls :
- env -> (Id.t * local_entry) list -> (env * rel_context)
+ env -> (Id.t * local_entry) list -> (env * Context.Rel.t)
(** {6 Basic operations of the typing machine. } *)
@@ -128,4 +127,4 @@ val make_polymorphic_if_constant_for_ind : env -> unsafe_judgment ->
constant_type
(** Check that hyps are included in env and fails with error otherwise *)
-val check_hyps_inclusion : env -> constr -> section_context -> unit
+val check_hyps_inclusion : env -> constr -> Context.section_context -> unit
diff --git a/kernel/uGraph.ml b/kernel/uGraph.ml
new file mode 100644
index 000000000..00883ddd8
--- /dev/null
+++ b/kernel/uGraph.ml
@@ -0,0 +1,906 @@
+(************************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2015 *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(************************************************************************)
+
+open Pp
+open Errors
+open Util
+open Univ
+
+(* Created in Caml by Gérard Huet for CoC 4.8 [Dec 1988] *)
+(* Functional code by Jean-Christophe Filliâtre for Coq V7.0 [1999] *)
+(* Extension with algebraic universes by HH for Coq V7.0 [Sep 2001] *)
+(* Additional support for sort-polymorphic inductive types by HH [Mar 2006] *)
+(* Support for universe polymorphism by MS [2014] *)
+
+(* Revisions by Bruno Barras, Hugo Herbelin, Pierre Letouzey, Matthieu
+ Sozeau, Pierre-Marie Pédrot, Jacques-Henri Jourdan *)
+
+let error_inconsistency o u v (p:explanation option) =
+ raise (UniverseInconsistency (o,Universe.make u,Universe.make v,p))
+
+(* Universes are stratified by a partial ordering $\le$.
+ Let $\~{}$ be the associated equivalence. We also have a strict ordering
+ $<$ between equivalence classes, and we maintain that $<$ is acyclic,
+ and contained in $\le$ in the sense that $[U]<[V]$ implies $U\le V$.
+
+ At every moment, we have a finite number of universes, and we
+ maintain the ordering in the presence of assertions $U<V$ and $U\le V$.
+
+ The equivalence $\~{}$ is represented by a tree structure, as in the
+ union-find algorithm. The assertions $<$ and $\le$ are represented by
+ adjacency lists.
+
+ We use the algorithm described in the paper:
+
+ Bender, M. A., Fineman, J. T., Gilbert, S., & Tarjan, R. E. (2011). A
+ new approach to incremental cycle detection and related
+ problems. arXiv preprint arXiv:1112.0784.
+
+ *)
+
+open Universe
+
+module UMap = LMap
+
+type status = NoMark | Visited | WeakVisited | ToMerge
+
+(* Comparison on this type is pointer equality *)
+type canonical_node =
+ { univ: Level.t;
+ ltle: bool UMap.t; (* true: strict (lt) constraint.
+ false: weak (le) constraint. *)
+ gtge: LSet.t;
+ rank : int;
+ klvl: int;
+ ilvl: int;
+ mutable status: status
+ }
+
+let big_rank = 1000000
+
+(* A Level.t is either an alias for another one, or a canonical one,
+ for which we know the universes that are above *)
+
+type univ_entry =
+ Canonical of canonical_node
+ | Equiv of Level.t
+
+type universes =
+ { entries : univ_entry UMap.t;
+ index : int;
+ n_nodes : int; n_edges : int }
+
+type t = universes
+
+(** Used to cleanup universes if a traversal function is interrupted before it
+ has the opportunity to do it itself. *)
+let unsafe_cleanup_universes g =
+ let iter _ n = match n with
+ | Equiv _ -> ()
+ | Canonical n -> n.status <- NoMark
+ in
+ UMap.iter iter g.entries
+
+let rec cleanup_universes g =
+ try unsafe_cleanup_universes g
+ with e ->
+ (** The only way unsafe_cleanup_universes may raise an exception is when
+ a serious error (stack overflow, out of memory) occurs, or a signal is
+ sent. In this unlikely event, we relaunch the cleanup until we finally
+ succeed. *)
+ cleanup_universes g; raise e
+
+(* Every Level.t has a unique canonical arc representative *)
+
+(* Low-level function : makes u an alias for v.
+ Does not removes edges from n_edges, but decrements n_nodes.
+ u should be entered as canonical before. *)
+let enter_equiv g u v =
+ { entries =
+ UMap.modify u (fun _ a ->
+ match a with
+ | Canonical n ->
+ n.status <- NoMark;
+ Equiv v
+ | _ -> assert false) g.entries;
+ index = g.index;
+ n_nodes = g.n_nodes - 1;
+ n_edges = g.n_edges }
+
+(* Low-level function : changes data associated with a canonical node.
+ Resets the mutable fields in the old record, in order to avoid breaking
+ invariants for other users of this record.
+ n.univ should already been inserted as a canonical node. *)
+let change_node g n =
+ { g with entries =
+ UMap.modify n.univ
+ (fun _ a ->
+ match a with
+ | Canonical n' ->
+ n'.status <- NoMark;
+ Canonical n
+ | _ -> assert false)
+ g.entries }
+
+(* repr : universes -> Level.t -> canonical_node *)
+(* canonical representative : we follow the Equiv links *)
+let rec repr g u =
+ let a =
+ try UMap.find u g.entries
+ with Not_found -> anomaly ~label:"Univ.repr"
+ (str"Universe " ++ Level.pr u ++ str" undefined")
+ in
+ match a with
+ | Equiv v -> repr g v
+ | Canonical arc -> arc
+
+let get_set_arc g = repr g Level.set
+let is_set_arc u = Level.is_set u.univ
+let is_prop_arc u = Level.is_prop u.univ
+
+exception AlreadyDeclared
+
+(* Reindexes the given universe, using the next available index. *)
+let use_index g u =
+ let u = repr g u in
+ let g = change_node g { u with ilvl = g.index } in
+ assert (g.index > min_int);
+ { g with index = g.index - 1 }
+
+(* [safe_repr] is like [repr] but if the graph doesn't contain the
+ searched universe, we add it. *)
+let safe_repr g u =
+ let rec safe_repr_rec entries u =
+ match UMap.find u entries with
+ | Equiv v -> safe_repr_rec entries v
+ | Canonical arc -> arc
+ in
+ try g, safe_repr_rec g.entries u
+ with Not_found ->
+ let can =
+ { univ = u;
+ ltle = UMap.empty; gtge = LSet.empty;
+ rank = if Level.is_small u then big_rank else 0;
+ klvl = 0; ilvl = 0;
+ status = NoMark }
+ in
+ let g = { g with
+ entries = UMap.add u (Canonical can) g.entries;
+ n_nodes = g.n_nodes + 1 }
+ in
+ let g = use_index g u in
+ g, repr g u
+
+(* Returns 1 if u is higher than v in topological order.
+ -1 lower
+ 0 if u = v *)
+let topo_compare u v =
+ if u.klvl > v.klvl then 1
+ else if u.klvl < v.klvl then -1
+ else if u.ilvl > v.ilvl then 1
+ else if u.ilvl < v.ilvl then -1
+ else (assert (u==v); 0)
+
+(* Checks most of the invariants of the graph. For debugging purposes. *)
+let check_universes_invariants g =
+ let n_edges = ref 0 in
+ let n_nodes = ref 0 in
+ UMap.iter (fun l u ->
+ match u with
+ | Canonical u ->
+ UMap.iter (fun v strict ->
+ incr n_edges;
+ let v = repr g v in
+ assert (topo_compare u v = -1);
+ if u.klvl = v.klvl then
+ assert (LSet.mem u.univ v.gtge ||
+ LSet.exists (fun l -> u == repr g l) v.gtge))
+ u.ltle;
+ LSet.iter (fun v ->
+ let v = repr g v in
+ assert (v.klvl = u.klvl &&
+ (UMap.mem u.univ v.ltle ||
+ UMap.exists (fun l _ -> u == repr g l) v.ltle))
+ ) u.gtge;
+ assert (u.status = NoMark);
+ assert (Level.equal l u.univ);
+ assert (u.ilvl > g.index);
+ assert (not (UMap.mem u.univ u.ltle));
+ incr n_nodes
+ | Equiv _ -> assert (not (Level.is_small l)))
+ g.entries;
+ assert (!n_edges = g.n_edges);
+ assert (!n_nodes = g.n_nodes)
+
+let clean_ltle g ltle =
+ UMap.fold (fun u strict acc ->
+ let uu = (repr g u).univ in
+ if Level.equal uu u then acc
+ else (
+ let acc = UMap.remove u (fst acc) in
+ if not strict && UMap.mem uu acc then (acc, true)
+ else (UMap.add uu strict acc, true)))
+ ltle (ltle, false)
+
+let clean_gtge g gtge =
+ LSet.fold (fun u acc ->
+ let uu = (repr g u).univ in
+ if Level.equal uu u then acc
+ else LSet.add uu (LSet.remove u (fst acc)), true)
+ gtge (gtge, false)
+
+(* [get_ltle] and [get_gtge] return ltle and gtge arcs.
+ Moreover, if one of these lists is dirty (e.g. points to a
+ non-canonical node), these functions clean this node in the
+ graph by removing some duplicate edges *)
+let get_ltle g u =
+ let ltle, chgt_ltle = clean_ltle g u.ltle in
+ if not chgt_ltle then u.ltle, u, g
+ else
+ let sz = UMap.cardinal u.ltle in
+ let sz2 = UMap.cardinal ltle in
+ let u = { u with ltle } in
+ let g = change_node g u in
+ let g = { g with n_edges = g.n_edges + sz2 - sz } in
+ u.ltle, u, g
+
+let get_gtge g u =
+ let gtge, chgt_gtge = clean_gtge g u.gtge in
+ if not chgt_gtge then u.gtge, u, g
+ else
+ let u = { u with gtge } in
+ let g = change_node g u in
+ u.gtge, u, g
+
+(* [revert_graph] rollbacks the changes made to mutable fields in
+ nodes in the graph.
+ [to_revert] contains the touched nodes. *)
+let revert_graph to_revert g =
+ List.iter (fun t ->
+ match UMap.find t g.entries with
+ | Equiv _ -> ()
+ | Canonical t ->
+ t.status <- NoMark) to_revert
+
+exception AbortBackward of universes
+exception CycleDetected
+
+(* Implementation of the algorithm described in § 5.1 of the following paper:
+
+ Bender, M. A., Fineman, J. T., Gilbert, S., & Tarjan, R. E. (2011). A
+ new approach to incremental cycle detection and related
+ problems. arXiv preprint arXiv:1112.0784.
+
+ The "STEP X" comments contained in this file refers to the
+ corresponding step numbers of the algorithm described in Section
+ 5.1 of this paper. *)
+
+(* [delta] is the timeout for backward search. It might be
+ useful to tune a multiplicative constant. *)
+let get_delta g =
+ int_of_float
+ (min (float_of_int g.n_edges ** 0.5)
+ (float_of_int g.n_nodes ** (2./.3.)))
+
+let rec backward_traverse to_revert b_traversed count g x =
+ let x = repr g x in
+ let count = count - 1 in
+ if count < 0 then begin
+ revert_graph to_revert g;
+ raise (AbortBackward g)
+ end;
+ if x.status = NoMark then begin
+ x.status <- Visited;
+ let to_revert = x.univ::to_revert in
+ let gtge, x, g = get_gtge g x in
+ let to_revert, b_traversed, count, g =
+ LSet.fold (fun y (to_revert, b_traversed, count, g) ->
+ backward_traverse to_revert b_traversed count g y)
+ gtge (to_revert, b_traversed, count, g)
+ in
+ to_revert, x.univ::b_traversed, count, g
+ end
+ else to_revert, b_traversed, count, g
+
+let rec forward_traverse f_traversed g v_klvl x y =
+ let y = repr g y in
+ if y.klvl < v_klvl then begin
+ let y = { y with klvl = v_klvl;
+ gtge = if x == y then LSet.empty
+ else LSet.singleton x.univ }
+ in
+ let g = change_node g y in
+ let ltle, y, g = get_ltle g y in
+ let f_traversed, g =
+ UMap.fold (fun z _ (f_traversed, g) ->
+ forward_traverse f_traversed g v_klvl y z)
+ ltle (f_traversed, g)
+ in
+ y.univ::f_traversed, g
+ end else if y.klvl = v_klvl && x != y then
+ let g = change_node g
+ { y with gtge = LSet.add x.univ y.gtge } in
+ f_traversed, g
+ else f_traversed, g
+
+let rec find_to_merge to_revert g x v =
+ let x = repr g x in
+ match x.status with
+ | Visited -> false, to_revert | ToMerge -> true, to_revert
+ | NoMark ->
+ let to_revert = x::to_revert in
+ if Level.equal x.univ v then
+ begin x.status <- ToMerge; true, to_revert end
+ else
+ begin
+ let merge, to_revert = LSet.fold
+ (fun y (merge, to_revert) ->
+ let merge', to_revert = find_to_merge to_revert g y v in
+ merge' || merge, to_revert) x.gtge (false, to_revert)
+ in
+ x.status <- if merge then ToMerge else Visited;
+ merge, to_revert
+ end
+ | _ -> assert false
+
+let get_new_edges g to_merge =
+ (* Computing edge sets. *)
+ let to_merge_lvl =
+ List.fold_left (fun acc u -> UMap.add u.univ u acc)
+ UMap.empty to_merge
+ in
+ let ltle =
+ UMap.fold (fun _ n acc ->
+ UMap.merge (fun _ strict1 strict2 ->
+ match strict1, strict2 with
+ | Some true, _ | _, Some true -> Some true
+ | _, _ -> Some false)
+ acc n.ltle)
+ to_merge_lvl UMap.empty
+ in
+ let ltle, _ = clean_ltle g ltle in
+ let ltle =
+ UMap.merge (fun _ a strict ->
+ match a, strict with
+ | Some _, Some true ->
+ (* There is a lt edge inside the new component. This is a
+ "bad cycle". *)
+ raise CycleDetected
+ | Some _, Some false -> None
+ | _, _ -> strict
+ ) to_merge_lvl ltle
+ in
+ let gtge =
+ UMap.fold (fun _ n acc -> LSet.union acc n.gtge)
+ to_merge_lvl LSet.empty
+ in
+ let gtge, _ = clean_gtge g gtge in
+ let gtge = LSet.diff gtge (UMap.domain to_merge_lvl) in
+ (ltle, gtge)
+
+
+let reorder g u v =
+ (* STEP 2: backward search in the k-level of u. *)
+ let delta = get_delta g in
+
+ (* [v_klvl] is the chosen future level for u, v and all
+ traversed nodes. *)
+ let b_traversed, v_klvl, g =
+ try
+ let to_revert, b_traversed, _, g = backward_traverse [] [] delta g u in
+ revert_graph to_revert g;
+ let v_klvl = (repr g u).klvl in
+ b_traversed, v_klvl, g
+ with AbortBackward g ->
+ (* Backward search was too long, use the next k-level. *)
+ let v_klvl = (repr g u).klvl + 1 in
+ [], v_klvl, g
+ in
+ let f_traversed, g =
+ (* STEP 3: forward search. Contrary to what is described in
+ the paper, we do not test whether v_klvl = u.klvl nor we assign
+ v_klvl to v.klvl. Indeed, the first call to forward_traverse
+ will do all that. *)
+ forward_traverse [] g v_klvl (repr g v) v
+ in
+
+ (* STEP 4: merge nodes if needed. *)
+ let to_merge, b_reindex, f_reindex =
+ if (repr g u).klvl = v_klvl then
+ begin
+ let merge, to_revert = find_to_merge [] g u v in
+ let r =
+ if merge then
+ List.filter (fun u -> u.status = ToMerge) to_revert,
+ List.filter (fun u -> (repr g u).status <> ToMerge) b_traversed,
+ List.filter (fun u -> (repr g u).status <> ToMerge) f_traversed
+ else [], b_traversed, f_traversed
+ in
+ List.iter (fun u -> u.status <- NoMark) to_revert;
+ r
+ end
+ else [], b_traversed, f_traversed
+ in
+ let to_reindex, g =
+ match to_merge with
+ | [] -> List.rev_append f_reindex b_reindex, g
+ | n0::q0 ->
+ (* Computing new root. *)
+ let root, rank_rest =
+ List.fold_left (fun ((best, rank_rest) as acc) n ->
+ if n.rank >= best.rank then n, best.rank else acc)
+ (n0, min_int) q0
+ in
+ let ltle, gtge = get_new_edges g to_merge in
+ (* Inserting the new root. *)
+ let g = change_node g
+ { root with ltle; gtge;
+ rank = max root.rank (rank_rest + 1); }
+ in
+
+ (* Inserting shortcuts for old nodes. *)
+ let g = List.fold_left (fun g n ->
+ if Level.equal n.univ root.univ then g else enter_equiv g n.univ root.univ)
+ g to_merge
+ in
+
+ (* Updating g.n_edges *)
+ let oldsz =
+ List.fold_left (fun sz u -> sz+UMap.cardinal u.ltle)
+ 0 to_merge
+ in
+ let sz = UMap.cardinal ltle in
+ let g = { g with n_edges = g.n_edges + sz - oldsz } in
+
+ (* Not clear in the paper: we have to put the newly
+ created component just between B and F. *)
+ List.rev_append f_reindex (root.univ::b_reindex), g
+
+ in
+
+ (* STEP 5: reindex traversed nodes. *)
+ List.fold_left use_index g to_reindex
+
+(* Assumes [u] and [v] are already in the graph. *)
+(* Does NOT assume that ucan != vcan. *)
+let insert_edge strict ucan vcan g =
+ try
+ let u = ucan.univ and v = vcan.univ in
+ (* STEP 1: do we need to reorder nodes ? *)
+ let g = if topo_compare ucan vcan <= 0 then g else reorder g u v in
+
+ (* STEP 6: insert the new edge in the graph. *)
+ let u = repr g u in
+ let v = repr g v in
+ if u == v then
+ if strict then raise CycleDetected else g
+ else
+ let g =
+ try let oldstrict = UMap.find v.univ u.ltle in
+ if strict && not oldstrict then
+ change_node g { u with ltle = UMap.add v.univ true u.ltle }
+ else g
+ with Not_found ->
+ { (change_node g { u with ltle = UMap.add v.univ strict u.ltle })
+ with n_edges = g.n_edges + 1 }
+ in
+ if u.klvl <> v.klvl || LSet.mem u.univ v.gtge then g
+ else
+ let v = { v with gtge = LSet.add u.univ v.gtge } in
+ change_node g v
+ with
+ | CycleDetected as e -> raise e
+ | e ->
+ (** Unlikely event: fatal error or signal *)
+ let () = cleanup_universes g in
+ raise e
+
+let add_universe vlev strict g =
+ try
+ let _arcv = UMap.find vlev g.entries in
+ raise AlreadyDeclared
+ with Not_found ->
+ assert (g.index > min_int);
+ let v = {
+ univ = vlev;
+ ltle = LMap.empty;
+ gtge = LSet.empty;
+ rank = 0;
+ klvl = 0;
+ ilvl = g.index;
+ status = NoMark;
+ }
+ in
+ let entries = UMap.add vlev (Canonical v) g.entries in
+ let g = { entries; index = g.index - 1; n_nodes = g.n_nodes + 1; n_edges = g.n_edges } in
+ insert_edge strict (get_set_arc g) v g
+
+exception Found_explanation of explanation
+
+let get_explanation strict u v g =
+ let v = repr g v in
+ let visited_strict = ref UMap.empty in
+ let rec traverse strict u =
+ if u == v then
+ if strict then None else Some []
+ else if topo_compare u v = 1 then None
+ else
+ let visited =
+ try not (UMap.find u.univ !visited_strict) || strict
+ with Not_found -> false
+ in
+ if visited then None
+ else begin
+ visited_strict := UMap.add u.univ strict !visited_strict;
+ try
+ UMap.iter (fun u' strictu' ->
+ match traverse (strict && not strictu') (repr g u') with
+ | None -> ()
+ | Some exp ->
+ let typ = if strictu' then Lt else Le in
+ raise (Found_explanation ((typ, make u') :: exp)))
+ u.ltle;
+ None
+ with Found_explanation exp -> Some exp
+ end
+ in
+ let u = repr g u in
+ if u == v then [(Eq, make v.univ)]
+ else match traverse strict u with Some exp -> exp | None -> assert false
+
+let get_explanation strict u v g =
+ if !Flags.univ_print then Some (get_explanation strict u v g)
+ else None
+
+(* To compare two nodes, we simply do a forward search.
+ We implement two improvements:
+ - we ignore nodes that are higher than the destination;
+ - we do a BFS rather than a DFS because we expect to have a short
+ path (typically, the shortest path has length 1)
+*)
+exception Found of canonical_node list
+let search_path strict u v g =
+ let rec loop to_revert todo next_todo =
+ match todo, next_todo with
+ | [], [] -> to_revert (* No path found *)
+ | [], _ -> loop to_revert next_todo []
+ | (u, strict)::todo, _ ->
+ if u.status = Visited || (u.status = WeakVisited && strict)
+ then loop to_revert todo next_todo
+ else
+ let to_revert =
+ if u.status = NoMark then u::to_revert else to_revert
+ in
+ u.status <- if strict then WeakVisited else Visited;
+ if try UMap.find v.univ u.ltle || not strict
+ with Not_found -> false
+ then raise (Found to_revert)
+ else
+ begin
+ let next_todo =
+ UMap.fold (fun u strictu next_todo ->
+ let strict = not strictu && strict in
+ let u = repr g u in
+ if u == v && not strict then raise (Found to_revert)
+ else if topo_compare u v = 1 then next_todo
+ else (u, strict)::next_todo)
+ u.ltle next_todo
+ in
+ loop to_revert todo next_todo
+ end
+ in
+ if u == v then not strict
+ else
+ try
+ let res, to_revert =
+ try false, loop [] [u, strict] []
+ with Found to_revert -> true, to_revert
+ in
+ List.iter (fun u -> u.status <- NoMark) to_revert;
+ res
+ with e ->
+ (** Unlikely event: fatal error or signal *)
+ let () = cleanup_universes g in
+ raise e
+
+(** Uncomment to debug the cycle detection algorithm. *)
+(*let insert_edge strict ucan vcan g =
+ check_universes_invariants g;
+ let g = insert_edge strict ucan vcan g in
+ check_universes_invariants g;
+ let ucan = repr g ucan.univ in
+ let vcan = repr g vcan.univ in
+ assert (search_path strict ucan vcan g);
+ g*)
+
+(** First, checks on universe levels *)
+
+let check_equal g u v =
+ let arcu = repr g u and arcv = repr g v in
+ arcu == arcv
+
+let check_eq_level g u v = u == v || check_equal g u v
+
+let check_smaller g strict u v =
+ let arcu = repr g u and arcv = repr g v in
+ if strict then
+ search_path true arcu arcv g
+ else
+ is_prop_arc arcu
+ || (is_set_arc arcu && not (is_prop_arc arcv))
+ || search_path false arcu arcv g
+
+(** Then, checks on universes *)
+
+type 'a check_function = universes -> 'a -> 'a -> bool
+
+let check_equal_expr g x y =
+ x == y || (let (u, n) = x and (v, m) = y in
+ Int.equal n m && check_equal g u v)
+
+let check_eq_univs g l1 l2 =
+ let f x1 x2 = check_equal_expr g x1 x2 in
+ let exists x1 l = Universe.exists (fun x2 -> f x1 x2) l in
+ Universe.for_all (fun x1 -> exists x1 l2) l1
+ && Universe.for_all (fun x2 -> exists x2 l1) l2
+
+let check_eq g u v =
+ Universe.equal u v || check_eq_univs g u v
+
+let check_smaller_expr g (u,n) (v,m) =
+ let diff = n - m in
+ match diff with
+ | 0 -> check_smaller g false u v
+ | 1 -> check_smaller g true u v
+ | x when x < 0 -> check_smaller g false u v
+ | _ -> false
+
+let exists_bigger g ul l =
+ Universe.exists (fun ul' ->
+ check_smaller_expr g ul ul') l
+
+let real_check_leq g u v =
+ Universe.for_all (fun ul -> exists_bigger g ul v) u
+
+let check_leq g u v =
+ Universe.equal u v ||
+ is_type0m_univ u ||
+ check_eq_univs g u v || real_check_leq g u v
+
+(* enforce_univ_eq g u v will force u=v if possible, will fail otherwise *)
+
+let rec enforce_univ_eq u v g =
+ let ucan = repr g u in
+ let vcan = repr g v in
+ if topo_compare ucan vcan = 1 then enforce_univ_eq v u g
+ else
+ let g = insert_edge false ucan vcan g in (* Cannot fail *)
+ try insert_edge false vcan ucan g
+ with CycleDetected ->
+ error_inconsistency Eq v u (get_explanation true u v g)
+
+(* enforce_univ_leq g u v will force u<=v if possible, will fail otherwise *)
+let enforce_univ_leq u v g =
+ let ucan = repr g u in
+ let vcan = repr g v in
+ try insert_edge false ucan vcan g
+ with CycleDetected ->
+ error_inconsistency Le u v (get_explanation true v u g)
+
+(* enforce_univ_lt u v will force u<v if possible, will fail otherwise *)
+let enforce_univ_lt u v g =
+ let ucan = repr g u in
+ let vcan = repr g v in
+ try insert_edge true ucan vcan g
+ with CycleDetected ->
+ error_inconsistency Lt u v (get_explanation false v u g)
+
+let empty_universes =
+ let set_arc = Canonical {
+ univ = Level.set;
+ ltle = LMap.empty;
+ gtge = LSet.empty;
+ rank = big_rank;
+ klvl = 0;
+ ilvl = (-1);
+ status = NoMark;
+ } in
+ let prop_arc = Canonical {
+ univ = Level.prop;
+ ltle = LMap.empty;
+ gtge = LSet.empty;
+ rank = big_rank;
+ klvl = 0;
+ ilvl = 0;
+ status = NoMark;
+ } in
+ let entries = UMap.add Level.set set_arc (UMap.singleton Level.prop prop_arc) in
+ let empty = { entries; index = (-2); n_nodes = 2; n_edges = 0 } in
+ enforce_univ_lt Level.prop Level.set empty
+
+(* Prop = Set is forbidden here. *)
+let initial_universes = empty_universes
+
+let is_initial_universes g = UMap.equal (==) g.entries initial_universes.entries
+
+let enforce_constraint cst g =
+ match cst with
+ | (u,Lt,v) -> enforce_univ_lt u v g
+ | (u,Le,v) -> enforce_univ_leq u v g
+ | (u,Eq,v) -> enforce_univ_eq u v g
+
+let merge_constraints c g =
+ Constraint.fold enforce_constraint c g
+
+let check_constraint g (l,d,r) =
+ match d with
+ | Eq -> check_equal g l r
+ | Le -> check_smaller g false l r
+ | Lt -> check_smaller g true l r
+
+let check_constraints c g =
+ Constraint.for_all (check_constraint g) c
+
+(* Normalization *)
+
+(** [normalize_universes g] returns a graph where all edges point
+ directly to the canonical representent of their target. The output
+ graph should be equivalent to the input graph from a logical point
+ of view, but optimized. We maintain the invariant that the key of
+ a [Canonical] element is its own name, by keeping [Equiv] edges. *)
+let normalize_universes g =
+ let g =
+ { g with
+ entries = UMap.map (fun entry ->
+ match entry with
+ | Equiv u -> Equiv ((repr g u).univ)
+ | Canonical ucan -> Canonical { ucan with rank = 1 })
+ g.entries }
+ in
+ UMap.fold (fun _ u g ->
+ match u with
+ | Equiv u -> g
+ | Canonical u ->
+ let _, u, g = get_ltle g u in
+ let _, _, g = get_gtge g u in
+ g)
+ g.entries g
+
+let constraints_of_universes g =
+ let constraints_of u v acc =
+ match v with
+ | Canonical {univ=u; ltle} ->
+ UMap.fold (fun v strict acc->
+ let typ = if strict then Lt else Le in
+ Constraint.add (u,typ,v) acc) ltle acc
+ | Equiv v -> Constraint.add (u,Eq,v) acc
+ in
+ UMap.fold constraints_of g.entries Constraint.empty
+
+let constraints_of_universes g =
+ constraints_of_universes (normalize_universes g)
+
+(** [sort_universes g] builds a totally ordered universe graph. The
+ output graph should imply the input graph (and the implication
+ will be strict most of the time), but is not necessarily minimal.
+ Moreover, it adds levels [Type.n] to identify universes at level
+ n. An artificial constraint Set < Type.2 is added to ensure that
+ Type.n and small universes are not merged. Note: the result is
+ unspecified if the input graph already contains [Type.n] nodes
+ (calling a module Type is probably a bad idea anyway). *)
+let sort_universes g =
+ let cans =
+ UMap.fold (fun _ u l ->
+ match u with
+ | Equiv _ -> l
+ | Canonical can -> can :: l
+ ) g.entries []
+ in
+ let cans = List.sort topo_compare cans in
+ let lowest_levels =
+ UMap.mapi (fun u _ -> if Level.is_small u then 0 else 2)
+ (UMap.filter
+ (fun _ u -> match u with Equiv _ -> false | Canonical _ -> true)
+ g.entries)
+ in
+ let lowest_levels =
+ List.fold_left (fun lowest_levels can ->
+ let lvl = UMap.find can.univ lowest_levels in
+ UMap.fold (fun u' strict lowest_levels ->
+ let cost = if strict then 1 else 0 in
+ let u' = (repr g u').univ in
+ UMap.modify u' (fun _ lvl0 -> max lvl0 (lvl+cost)) lowest_levels)
+ can.ltle lowest_levels)
+ lowest_levels cans
+ in
+ let max_lvl = UMap.fold (fun _ a b -> max a b) lowest_levels 0 in
+ let mp = Names.DirPath.make [Names.Id.of_string "Type"] in
+ let types = Array.init (max_lvl + 1) (function
+ | 0 -> Level.prop
+ | 1 -> Level.set
+ | n -> Level.make mp (n-2))
+ in
+ let g = Array.fold_left (fun g u ->
+ let g, u = safe_repr g u in
+ change_node g { u with rank = big_rank }) g types
+ in
+ let g = if max_lvl >= 2 then enforce_univ_lt Level.set types.(2) g else g in
+ let g =
+ UMap.fold (fun u lvl g -> enforce_univ_eq u (types.(lvl)) g)
+ lowest_levels g
+ in
+ normalize_universes g
+
+(** Instances *)
+
+let check_eq_instances g t1 t2 =
+ let t1 = Instance.to_array t1 in
+ let t2 = Instance.to_array t2 in
+ t1 == t2 ||
+ (Int.equal (Array.length t1) (Array.length t2) &&
+ let rec aux i =
+ (Int.equal i (Array.length t1)) || (check_eq_level g t1.(i) t2.(i) && aux (i + 1))
+ in aux 0)
+
+(** Pretty-printing *)
+
+let pr_arc prl = function
+ | _, Canonical {univ=u; ltle} ->
+ if UMap.is_empty ltle then mt ()
+ else
+ prl u ++ str " " ++
+ v 0
+ (pr_sequence (fun (v, strict) ->
+ (if strict then str "< " else str "<= ") ++ prl v)
+ (UMap.bindings ltle)) ++
+ fnl ()
+ | u, Equiv v ->
+ prl u ++ str " = " ++ prl v ++ fnl ()
+
+let pr_universes prl g =
+ let graph = UMap.fold (fun u a l -> (u,a)::l) g.entries [] in
+ prlist (pr_arc prl) graph
+
+(* Dumping constraints to a file *)
+
+let dump_universes output g =
+ let dump_arc u = function
+ | Canonical {univ=u; ltle} ->
+ let u_str = Level.to_string u in
+ UMap.iter (fun v strict ->
+ let typ = if strict then Lt else Le in
+ output typ u_str (Level.to_string v)) ltle;
+ | Equiv v ->
+ output Eq (Level.to_string u) (Level.to_string v)
+ in
+ UMap.iter dump_arc g.entries
+
+(** Profiling *)
+
+let merge_constraints =
+ if Flags.profile then
+ let key = Profile.declare_profile "merge_constraints" in
+ Profile.profile2 key merge_constraints
+ else merge_constraints
+let check_constraints =
+ if Flags.profile then
+ let key = Profile.declare_profile "check_constraints" in
+ Profile.profile2 key check_constraints
+ else check_constraints
+
+let check_eq =
+ if Flags.profile then
+ let check_eq_key = Profile.declare_profile "check_eq" in
+ Profile.profile3 check_eq_key check_eq
+ else check_eq
+
+let check_leq =
+ if Flags.profile then
+ let check_leq_key = Profile.declare_profile "check_leq" in
+ Profile.profile3 check_leq_key check_leq
+ else check_leq
diff --git a/kernel/uGraph.mli b/kernel/uGraph.mli
new file mode 100644
index 000000000..e95cf4d1c
--- /dev/null
+++ b/kernel/uGraph.mli
@@ -0,0 +1,63 @@
+(************************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2015 *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(************************************************************************)
+
+open Univ
+
+(** {6 Graphs of universes. } *)
+
+type t
+
+type universes = t
+
+type 'a check_function = universes -> 'a -> 'a -> bool
+val check_leq : universe check_function
+val check_eq : universe check_function
+
+(** The empty graph of universes *)
+val empty_universes : universes
+
+(** The initial graph of universes: Prop < Set *)
+val initial_universes : universes
+
+val is_initial_universes : universes -> bool
+
+val sort_universes : universes -> universes
+
+(** Adds a universe to the graph, ensuring it is >= or > Set.
+ @raises AlreadyDeclared if the level is already declared in the graph. *)
+
+exception AlreadyDeclared
+
+val add_universe : universe_level -> bool -> universes -> universes
+
+(** {6 ... } *)
+(** Merge of constraints in a universes graph.
+ The function [merge_constraints] merges a set of constraints in a given
+ universes graph. It raises the exception [UniverseInconsistency] if the
+ constraints are not satisfiable. *)
+
+val enforce_constraint : univ_constraint -> universes -> universes
+val merge_constraints : constraints -> universes -> universes
+
+val constraints_of_universes : universes -> constraints
+
+val check_constraint : universes -> univ_constraint -> bool
+val check_constraints : constraints -> universes -> bool
+
+val check_eq_instances : Instance.t check_function
+(** Check equality of instances w.r.t. a universe graph *)
+
+(** {6 Pretty-printing of universes. } *)
+
+val pr_universes : (Level.t -> Pp.std_ppcmds) -> universes -> Pp.std_ppcmds
+
+(** {6 Dumping to a file } *)
+
+val dump_universes :
+ (constraint_type -> string -> string -> unit) ->
+ universes -> unit
diff --git a/kernel/univ.ml b/kernel/univ.ml
index 21ffafedb..9d62c9af5 100644
--- a/kernel/univ.ml
+++ b/kernel/univ.ml
@@ -12,8 +12,8 @@
(* Additional support for sort-polymorphic inductive types by HH [Mar 2006] *)
(* Support for universe polymorphism by MS [2014] *)
-(* Revisions by Bruno Barras, Hugo Herbelin, Pierre Letouzey, Matthieu Sozeau,
- Pierre-Marie Pédrot *)
+(* Revisions by Bruno Barras, Hugo Herbelin, Pierre Letouzey, Matthieu
+ Sozeau, Pierre-Marie Pédrot *)
open Pp
open Errors
@@ -653,170 +653,6 @@ open Universe
let universe_level = Universe.level
-type status = Unset | SetLe | SetLt
-
-(* Comparison on this type is pointer equality *)
-type canonical_arc =
- { univ: Level.t;
- lt: Level.t list;
- le: Level.t list;
- rank : int;
- mutable status : status;
- (** Guaranteed to be unset out of the [compare_neq] functions. It is used
- to do an imperative traversal of the graph, ensuring a O(1) check that
- a node has already been visited. Quite performance critical indeed. *)
- }
-
-let arc_is_le arc = match arc.status with
-| Unset -> false
-| SetLe | SetLt -> true
-
-let arc_is_lt arc = match arc.status with
-| Unset | SetLe -> false
-| SetLt -> true
-
-let terminal u = {univ=u; lt=[]; le=[]; rank=0; status = Unset}
-
-module UMap :
-sig
- type key = Level.t
- type +'a t
- val empty : 'a t
- val add : key -> 'a -> 'a t -> 'a t
- val find : key -> 'a t -> 'a
- val equal : ('a -> 'a -> bool) -> 'a t -> 'a t -> bool
- val fold : (key -> 'a -> 'b -> 'b) -> 'a t -> 'b -> 'b
- val iter : (key -> 'a -> unit) -> 'a t -> unit
- val mapi : (key -> 'a -> 'b) -> 'a t -> 'b t
-end = HMap.Make(Level)
-
-(* A Level.t is either an alias for another one, or a canonical one,
- for which we know the universes that are above *)
-
-type univ_entry =
- Canonical of canonical_arc
- | Equiv of Level.t
-
-type universes = univ_entry UMap.t
-
-(** Used to cleanup universes if a traversal function is interrupted before it
- has the opportunity to do it itself. *)
-let unsafe_cleanup_universes g =
- let iter _ arc = match arc with
- | Equiv _ -> ()
- | Canonical arc -> arc.status <- Unset
- in
- UMap.iter iter g
-
-let rec cleanup_universes g =
- try unsafe_cleanup_universes g
- with e ->
- (** The only way unsafe_cleanup_universes may raise an exception is when
- a serious error (stack overflow, out of memory) occurs, or a signal is
- sent. In this unlikely event, we relaunch the cleanup until we finally
- succeed. *)
- cleanup_universes g; raise e
-
-let enter_equiv_arc u v g =
- UMap.add u (Equiv v) g
-
-let enter_arc ca g =
- UMap.add ca.univ (Canonical ca) g
-
-(* Every Level.t has a unique canonical arc representative *)
-
-(** The graph always contains nodes for Prop and Set. *)
-
-let terminal_lt u v =
- {(terminal u) with lt=[v]}
-
-let empty_universes =
- let g = enter_arc (terminal Level.set) UMap.empty in
- let g = enter_arc (terminal_lt Level.prop Level.set) g in
- g
-
-(* repr : universes -> Level.t -> canonical_arc *)
-(* canonical representative : we follow the Equiv links *)
-
-let rec repr g u =
- let a =
- try UMap.find u g
- with Not_found -> anomaly ~label:"Univ.repr"
- (str"Universe " ++ Level.pr u ++ str" undefined")
- in
- match a with
- | Equiv v -> repr g v
- | Canonical arc -> arc
-
-let get_prop_arc g = repr g Level.prop
-let get_set_arc g = repr g Level.set
-let is_set_arc u = Level.is_set u.univ
-let is_prop_arc u = Level.is_prop u.univ
-
-exception AlreadyDeclared
-
-let add_universe vlev strict g =
- try
- let _arcv = UMap.find vlev g in
- raise AlreadyDeclared
- with Not_found ->
- let v = terminal vlev in
- let arc =
- let arc = get_set_arc g in
- if strict then
- { arc with lt=vlev::arc.lt}
- else
- { arc with le=vlev::arc.le}
- in
- let g = enter_arc arc g in
- enter_arc v g
-
-(* reprleq : canonical_arc -> canonical_arc list *)
-(* All canonical arcv such that arcu<=arcv with arcv#arcu *)
-let reprleq g arcu =
- let rec searchrec w = function
- | [] -> w
- | v :: vl ->
- let arcv = repr g v in
- if List.memq arcv w || arcu==arcv then
- searchrec w vl
- else
- searchrec (arcv :: w) vl
- in
- searchrec [] arcu.le
-
-
-(* between : Level.t -> canonical_arc -> canonical_arc list *)
-(* between u v = { w | u<=w<=v, w canonical } *)
-(* between is the most costly operation *)
-
-let between g arcu arcv =
- (* good are all w | u <= w <= v *)
- (* bad are all w | u <= w ~<= v *)
- (* find good and bad nodes in {w | u <= w} *)
- (* explore b u = (b or "u is good") *)
- let rec explore ((good, bad, b) as input) arcu =
- if List.memq arcu good then
- (good, bad, true) (* b or true *)
- else if List.memq arcu bad then
- input (* (good, bad, b or false) *)
- else
- let leq = reprleq g arcu in
- (* is some universe >= u good ? *)
- let good, bad, b_leq =
- List.fold_left explore (good, bad, false) leq
- in
- if b_leq then
- arcu::good, bad, true (* b or true *)
- else
- good, arcu::bad, b (* b or false *)
- in
- let good,_,_ = explore ([arcv],[],false) arcu in
- good
-(* We assume compare(u,v) = LE with v canonical (see compare below).
- In this case List.hd(between g u v) = repr u
- Otherwise, between g u v = []
- *)
type constraint_type = Lt | Le | Eq
@@ -831,343 +667,6 @@ let constraint_type_ord c1 c2 = match c1, c2 with
| Eq, Eq -> 0
| Eq, _ -> 1
-(** [fast_compare_neq] : is [arcv] in the transitive upward closure of [arcu] ?
-
- In [strict] mode, we fully distinguish between LE and LT, while in
- non-strict mode, we simply answer LE for both situations.
-
- If [arcv] is encountered in a LT part, we could directly answer
- without visiting unneeded parts of this transitive closure.
- In [strict] mode, if [arcv] is encountered in a LE part, we could only
- change the default answer (1st arg [c]) from NLE to LE, since a strict
- constraint may appear later. During the recursive traversal,
- [lt_done] and [le_done] are universes we have already visited,
- they do not contain [arcv]. The 4rd arg is [(lt_todo,le_todo)],
- two lists of universes not yet considered, known to be above [arcu],
- strictly or not.
-
- We use depth-first search, but the presence of [arcv] in [new_lt]
- is checked as soon as possible : this seems to be slightly faster
- on a test.
-
- We do the traversal imperatively, setting the [status] flag on visited nodes.
- This ensures O(1) check, but it also requires unsetting the flag when leaving
- the function. Some special care has to be taken in order to ensure we do not
- recover a messed up graph at the end. This occurs in particular when the
- traversal raises an exception. Even though the code below is exception-free,
- OCaml may still raise random exceptions, essentially fatal exceptions or
- signal handlers. Therefore we ensure the cleanup by a catch-all clause. Note
- also that the use of an imperative solution does make this function
- thread-unsafe. For now we do not check universes in different threads, but if
- ever this is to be done, we would need some lock somewhere.
-
-*)
-
-let get_explanation strict g arcu arcv =
- (* [c] characterizes whether (and how) arcv has already been related
- to arcu among the lt_done,le_done universe *)
- let rec cmp c to_revert lt_todo le_todo = match lt_todo, le_todo with
- | [],[] -> (to_revert, c)
- | (arc,p)::lt_todo, le_todo ->
- if arc_is_lt arc then
- cmp c to_revert lt_todo le_todo
- else
- let rec find lt_todo lt le = match le with
- | [] ->
- begin match lt with
- | [] ->
- let () = arc.status <- SetLt in
- cmp c (arc :: to_revert) lt_todo le_todo
- | u :: lt ->
- let arc = repr g u in
- let p = (Lt, make u) :: p in
- if arc == arcv then
- if strict then (to_revert, p) else (to_revert, p)
- else find ((arc, p) :: lt_todo) lt le
- end
- | u :: le ->
- let arc = repr g u in
- let p = (Le, make u) :: p in
- if arc == arcv then
- if strict then (to_revert, p) else (to_revert, p)
- else find ((arc, p) :: lt_todo) lt le
- in
- find lt_todo arc.lt arc.le
- | [], (arc,p)::le_todo ->
- if arc == arcv then
- (* No need to continue inspecting universes above arc:
- if arcv is strictly above arc, then we would have a cycle.
- But we cannot answer LE yet, a stronger constraint may
- come later from [le_todo]. *)
- if strict then cmp p to_revert [] le_todo else (to_revert, p)
- else
- if arc_is_le arc then
- cmp c to_revert [] le_todo
- else
- let rec find lt_todo lt = match lt with
- | [] ->
- let fold accu u =
- let p = (Le, make u) :: p in
- let node = (repr g u, p) in
- node :: accu
- in
- let le_new = List.fold_left fold le_todo arc.le in
- let () = arc.status <- SetLe in
- cmp c (arc :: to_revert) lt_todo le_new
- | u :: lt ->
- let arc = repr g u in
- let p = (Lt, make u) :: p in
- if arc == arcv then
- if strict then (to_revert, p) else (to_revert, p)
- else find ((arc, p) :: lt_todo) lt
- in
- find [] arc.lt
- in
- let start = (* if is_prop_arc arcu then [Le, make arcv.univ] else *) [] in
- try
- let (to_revert, c) = cmp start [] [] [(arcu, [])] in
- (** Reset all the touched arcs. *)
- let () = List.iter (fun arc -> arc.status <- Unset) to_revert in
- List.rev c
- with e ->
- (** Unlikely event: fatal error or signal *)
- let () = cleanup_universes g in
- raise e
-
-let get_explanation strict g arcu arcv =
- if !Flags.univ_print then Some (get_explanation strict g arcu arcv)
- else None
-
-type fast_order = FastEQ | FastLT | FastLE | FastNLE
-
-let fast_compare_neq strict g arcu arcv =
- (* [c] characterizes whether arcv has already been related
- to arcu among the lt_done,le_done universe *)
- let rec cmp c to_revert lt_todo le_todo = match lt_todo, le_todo with
- | [],[] -> (to_revert, c)
- | arc::lt_todo, le_todo ->
- if arc_is_lt arc then
- cmp c to_revert lt_todo le_todo
- else
- let () = arc.status <- SetLt in
- process_lt c (arc :: to_revert) lt_todo le_todo arc.lt arc.le
- | [], arc::le_todo ->
- if arc == arcv then
- (* No need to continue inspecting universes above arc:
- if arcv is strictly above arc, then we would have a cycle.
- But we cannot answer LE yet, a stronger constraint may
- come later from [le_todo]. *)
- if strict then cmp FastLE to_revert [] le_todo else (to_revert, FastLE)
- else
- if arc_is_le arc then
- cmp c to_revert [] le_todo
- else
- let () = arc.status <- SetLe in
- process_le c (arc :: to_revert) [] le_todo arc.lt arc.le
-
- and process_lt c to_revert lt_todo le_todo lt le = match le with
- | [] ->
- begin match lt with
- | [] -> cmp c to_revert lt_todo le_todo
- | u :: lt ->
- let arc = repr g u in
- if arc == arcv then
- if strict then (to_revert, FastLT) else (to_revert, FastLE)
- else process_lt c to_revert (arc :: lt_todo) le_todo lt le
- end
- | u :: le ->
- let arc = repr g u in
- if arc == arcv then
- if strict then (to_revert, FastLT) else (to_revert, FastLE)
- else process_lt c to_revert (arc :: lt_todo) le_todo lt le
-
- and process_le c to_revert lt_todo le_todo lt le = match lt with
- | [] ->
- let fold accu u =
- let node = repr g u in
- node :: accu
- in
- let le_new = List.fold_left fold le_todo le in
- cmp c to_revert lt_todo le_new
- | u :: lt ->
- let arc = repr g u in
- if arc == arcv then
- if strict then (to_revert, FastLT) else (to_revert, FastLE)
- else process_le c to_revert (arc :: lt_todo) le_todo lt le
-
- in
- try
- let (to_revert, c) = cmp FastNLE [] [] [arcu] in
- (** Reset all the touched arcs. *)
- let () = List.iter (fun arc -> arc.status <- Unset) to_revert in
- c
- with e ->
- (** Unlikely event: fatal error or signal *)
- let () = cleanup_universes g in
- raise e
-
-let get_explanation_strict g arcu arcv = get_explanation true g arcu arcv
-
-let fast_compare g arcu arcv =
- if arcu == arcv then FastEQ else fast_compare_neq true g arcu arcv
-
-let is_leq g arcu arcv =
- arcu == arcv ||
- (match fast_compare_neq false g arcu arcv with
- | FastNLE -> false
- | (FastEQ|FastLE|FastLT) -> true)
-
-let is_lt g arcu arcv =
- if arcu == arcv then false
- else
- match fast_compare_neq true g arcu arcv with
- | FastLT -> true
- | (FastEQ|FastLE|FastNLE) -> false
-
-(* Invariants : compare(u,v) = EQ <=> compare(v,u) = EQ
- compare(u,v) = LT or LE => compare(v,u) = NLE
- compare(u,v) = NLE => compare(v,u) = NLE or LE or LT
-
- Adding u>=v is consistent iff compare(v,u) # LT
- and then it is redundant iff compare(u,v) # NLE
- Adding u>v is consistent iff compare(v,u) = NLE
- and then it is redundant iff compare(u,v) = LT *)
-
-(** * Universe checks [check_eq] and [check_leq], used in coqchk *)
-
-(** First, checks on universe levels *)
-
-let check_equal g u v =
- let arcu = repr g u and arcv = repr g v in
- arcu == arcv
-
-let check_eq_level g u v = u == v || check_equal g u v
-
-let check_smaller g strict u v =
- let arcu = repr g u and arcv = repr g v in
- if strict then
- is_lt g arcu arcv
- else
- is_prop_arc arcu
- || (is_set_arc arcu && not (is_prop_arc arcv))
- || is_leq g arcu arcv
-
-(** Then, checks on universes *)
-
-type 'a check_function = universes -> 'a -> 'a -> bool
-
-let check_equal_expr g x y =
- x == y || (let (u, n) = x and (v, m) = y in
- Int.equal n m && check_equal g u v)
-
-let check_eq_univs g l1 l2 =
- let f x1 x2 = check_equal_expr g x1 x2 in
- let exists x1 l = Huniv.exists (fun x2 -> f x1 x2) l in
- Huniv.for_all (fun x1 -> exists x1 l2) l1
- && Huniv.for_all (fun x2 -> exists x2 l1) l2
-
-let check_eq g u v =
- Universe.equal u v || check_eq_univs g u v
-
-let check_smaller_expr g (u,n) (v,m) =
- let diff = n - m in
- match diff with
- | 0 -> check_smaller g false u v
- | 1 -> check_smaller g true u v
- | x when x < 0 -> check_smaller g false u v
- | _ -> false
-
-let exists_bigger g ul l =
- Huniv.exists (fun ul' ->
- check_smaller_expr g ul ul') l
-
-let real_check_leq g u v =
- Huniv.for_all (fun ul -> exists_bigger g ul v) u
-
-let check_leq g u v =
- Universe.equal u v ||
- Universe.is_type0m u ||
- check_eq_univs g u v || real_check_leq g u v
-
-(** Enforcing new constraints : [setlt], [setleq], [merge], [merge_disc] *)
-
-(* setlt : Level.t -> Level.t -> reason -> unit *)
-(* forces u > v *)
-(* this is normally an update of u in g rather than a creation. *)
-let setlt g arcu arcv =
- let arcu' = {arcu with lt=arcv.univ::arcu.lt} in
- enter_arc arcu' g, arcu'
-
-(* checks that non-redundant *)
-let setlt_if (g,arcu) v =
- let arcv = repr g v in
- if is_lt g arcu arcv then g, arcu
- else setlt g arcu arcv
-
-(* setleq : Level.t -> Level.t -> unit *)
-(* forces u >= v *)
-(* this is normally an update of u in g rather than a creation. *)
-let setleq g arcu arcv =
- let arcu' = {arcu with le=arcv.univ::arcu.le} in
- enter_arc arcu' g, arcu'
-
-(* checks that non-redundant *)
-let setleq_if (g,arcu) v =
- let arcv = repr g v in
- if is_leq g arcu arcv then g, arcu
- else setleq g arcu arcv
-
-(* merge : Level.t -> Level.t -> unit *)
-(* we assume compare(u,v) = LE *)
-(* merge u v forces u ~ v with repr u as canonical repr *)
-let merge g arcu arcv =
- (* we find the arc with the biggest rank, and we redirect all others to it *)
- let arcu, g, v =
- let best_ranked (max_rank, old_max_rank, best_arc, rest) arc =
- if Level.is_small arc.univ ||
- (arc.rank >= max_rank && not (Level.is_small best_arc.univ))
- then (arc.rank, max_rank, arc, best_arc::rest)
- else (max_rank, old_max_rank, best_arc, arc::rest)
- in
- match between g arcu arcv with
- | [] -> anomaly (str "Univ.between")
- | arc::rest ->
- let (max_rank, old_max_rank, best_arc, rest) =
- List.fold_left best_ranked (arc.rank, min_int, arc, []) rest in
- if max_rank > old_max_rank then best_arc, g, rest
- else begin
- (* one redirected node also has max_rank *)
- let arcu = {best_arc with rank = max_rank + 1} in
- arcu, enter_arc arcu g, rest
- end
- in
- let redirect (g,w,w') arcv =
- let g' = enter_equiv_arc arcv.univ arcu.univ g in
- (g',List.unionq arcv.lt w,arcv.le@w')
- in
- let (g',w,w') = List.fold_left redirect (g,[],[]) v in
- let g_arcu = (g',arcu) in
- let g_arcu = List.fold_left setlt_if g_arcu w in
- let g_arcu = List.fold_left setleq_if g_arcu w' in
- fst g_arcu
-
-(* merge_disc : Level.t -> Level.t -> unit *)
-(* we assume compare(u,v) = compare(v,u) = NLE *)
-(* merge_disc u v forces u ~ v with repr u as canonical repr *)
-let merge_disc g arc1 arc2 =
- let arcu, arcv = if Level.is_small arc2.univ || arc1.rank < arc2.rank then arc2, arc1 else arc1, arc2 in
- let arcu, g =
- if not (Int.equal arc1.rank arc2.rank) then arcu, g
- else
- let arcu = {arcu with rank = succ arcu.rank} in
- arcu, enter_arc arcu g
- in
- let g' = enter_equiv_arc arcv.univ arcu.univ g in
- let g_arcu = (g',arcu) in
- let g_arcu = List.fold_left setlt_if g_arcu arcv.lt in
- let g_arcu = List.fold_left setleq_if g_arcu arcv.le in
- fst g_arcu
-
(* Universe inconsistency: error raised when trying to enforce a relation
that would create a cycle in the graph of universes. *)
@@ -1178,70 +677,10 @@ exception UniverseInconsistency of univ_inconsistency
let error_inconsistency o u v (p:explanation option) =
raise (UniverseInconsistency (o,make u,make v,p))
-(* enforce_univ_eq : Level.t -> Level.t -> unit *)
-(* enforce_univ_eq u v will force u=v if possible, will fail otherwise *)
-
-let enforce_univ_eq u v g =
- let arcu = repr g u and arcv = repr g v in
- match fast_compare g arcu arcv with
- | FastEQ -> g
- | FastLT ->
- let p = get_explanation_strict g arcu arcv in
- error_inconsistency Eq v u p
- | FastLE -> merge g arcu arcv
- | FastNLE ->
- (match fast_compare g arcv arcu with
- | FastLT ->
- let p = get_explanation_strict g arcv arcu in
- error_inconsistency Eq u v p
- | FastLE -> merge g arcv arcu
- | FastNLE -> merge_disc g arcu arcv
- | FastEQ -> anomaly (Pp.str "Univ.compare"))
-
-(* enforce_univ_leq : Level.t -> Level.t -> unit *)
-(* enforce_univ_leq u v will force u<=v if possible, will fail otherwise *)
-let enforce_univ_leq u v g =
- let arcu = repr g u and arcv = repr g v in
- if is_leq g arcu arcv then g
- else
- match fast_compare g arcv arcu with
- | FastLT ->
- let p = get_explanation_strict g arcv arcu in
- error_inconsistency Le u v p
- | FastLE -> merge g arcv arcu
- | FastNLE -> fst (setleq g arcu arcv)
- | FastEQ -> anomaly (Pp.str "Univ.compare")
-
-(* enforce_univ_lt u v will force u<v if possible, will fail otherwise *)
-let enforce_univ_lt u v g =
- let arcu = repr g u and arcv = repr g v in
- match fast_compare g arcu arcv with
- | FastLT -> g
- | FastLE -> fst (setlt g arcu arcv)
- | FastEQ -> error_inconsistency Lt u v (Some [(Eq,make v)])
- | FastNLE ->
- match fast_compare_neq false g arcv arcu with
- FastNLE -> fst (setlt g arcu arcv)
- | FastEQ -> anomaly (Pp.str "Univ.compare")
- | (FastLE|FastLT) ->
- let p = get_explanation false g arcv arcu in
- error_inconsistency Lt u v p
-
-(* Prop = Set is forbidden here. *)
-let initial_universes = empty_universes
-
-let is_initial_universes g = UMap.equal (==) g initial_universes
-
(* Constraints and sets of constraints. *)
type univ_constraint = Level.t * constraint_type * Level.t
-let enforce_constraint cst g =
- match cst with
- | (u,Lt,v) -> enforce_univ_lt u v g
- | (u,Le,v) -> enforce_univ_leq u v g
- | (u,Eq,v) -> enforce_univ_eq u v g
-
let pr_constraint_type op =
let op_str = match op with
| Lt -> " < "
@@ -1276,8 +715,6 @@ end
let empty_constraint = Constraint.empty
let union_constraint = Constraint.union
let eq_constraint = Constraint.equal
-let merge_constraints c g =
- Constraint.fold enforce_constraint c g
type constraints = Constraint.t
@@ -1378,218 +815,12 @@ let enforce_leq u v c =
let enforce_leq_level u v c =
if Level.equal u v then c else Constraint.add (u,Le,v) c
-let check_constraint g (l,d,r) =
- match d with
- | Eq -> check_equal g l r
- | Le -> check_smaller g false l r
- | Lt -> check_smaller g true l r
-
-let check_constraints c g =
- Constraint.for_all (check_constraint g) c
-
let enforce_univ_constraint (u,d,v) =
match d with
| Eq -> enforce_eq u v
| Le -> enforce_leq u v
| Lt -> enforce_leq (super u) v
-(* Normalization *)
-
-let lookup_level u g =
- try Some (UMap.find u g) with Not_found -> None
-
-(** [normalize_universes g] returns a graph where all edges point
- directly to the canonical representent of their target. The output
- graph should be equivalent to the input graph from a logical point
- of view, but optimized. We maintain the invariant that the key of
- a [Canonical] element is its own name, by keeping [Equiv] edges
- (see the assertion)... I (Stéphane Glondu) am not sure if this
- plays a role in the rest of the module. *)
-let normalize_universes g =
- let rec visit u arc cache = match lookup_level u cache with
- | Some x -> x, cache
- | None -> match Lazy.force arc with
- | None ->
- u, UMap.add u u cache
- | Some (Canonical {univ=v; lt=_; le=_}) ->
- v, UMap.add u v cache
- | Some (Equiv v) ->
- let v, cache = visit v (lazy (lookup_level v g)) cache in
- v, UMap.add u v cache
- in
- let cache = UMap.fold
- (fun u arc cache -> snd (visit u (Lazy.lazy_from_val (Some arc)) cache))
- g UMap.empty
- in
- let repr x = UMap.find x cache in
- let lrepr us = List.fold_left
- (fun e x -> LSet.add (repr x) e) LSet.empty us
- in
- let canonicalize u = function
- | Equiv _ -> Equiv (repr u)
- | Canonical {univ=v; lt=lt; le=le; rank=rank} ->
- assert (u == v);
- (* avoid duplicates and self-loops *)
- let lt = lrepr lt and le = lrepr le in
- let le = LSet.filter
- (fun x -> x != u && not (LSet.mem x lt)) le
- in
- LSet.iter (fun x -> assert (x != u)) lt;
- Canonical {
- univ = v;
- lt = LSet.elements lt;
- le = LSet.elements le;
- rank = rank;
- status = Unset;
- }
- in
- UMap.mapi canonicalize g
-
-let constraints_of_universes g =
- let constraints_of u v acc =
- match v with
- | Canonical {univ=u; lt=lt; le=le} ->
- let acc = List.fold_left (fun acc v -> Constraint.add (u,Lt,v) acc) acc lt in
- let acc = List.fold_left (fun acc v -> Constraint.add (u,Le,v) acc) acc le in
- acc
- | Equiv v -> Constraint.add (u,Eq,v) acc
- in
- UMap.fold constraints_of g Constraint.empty
-
-let constraints_of_universes g =
- constraints_of_universes (normalize_universes g)
-
-(** Longest path algorithm. This is used to compute the minimal number of
- universes required if the only strict edge would be the Lt one. This
- algorithm assumes that the given universes constraints are a almost DAG, in
- the sense that there may be {Eq, Le}-cycles. This is OK for consistent
- universes, which is the only case where we use this algorithm. *)
-
-(** Adjacency graph *)
-type graph = constraint_type LMap.t LMap.t
-
-exception Connected
-
-(** Check connectedness *)
-let connected x y (g : graph) =
- let rec connected x target seen g =
- if Level.equal x target then raise Connected
- else if not (LSet.mem x seen) then
- let seen = LSet.add x seen in
- let fold z _ seen = connected z target seen g in
- let neighbours = try LMap.find x g with Not_found -> LMap.empty in
- LMap.fold fold neighbours seen
- else seen
- in
- try ignore(connected x y LSet.empty g); false with Connected -> true
-
-let add_edge x y v (g : graph) =
- try
- let neighbours = LMap.find x g in
- let neighbours = LMap.add y v neighbours in
- LMap.add x neighbours g
- with Not_found ->
- LMap.add x (LMap.singleton y v) g
-
-(** We want to keep the graph DAG. If adding an edge would cause a cycle, that
- would necessarily be an {Eq, Le}-cycle, otherwise there would have been a
- universe inconsistency. Therefore we may omit adding such a cycling edge
- without changing the compacted graph. *)
-let add_eq_edge x y v g = if connected y x g then g else add_edge x y v g
-
-(** Construct the DAG and its inverse at the same time. *)
-let make_graph g : (graph * graph) =
- let fold u arc accu = match arc with
- | Equiv v ->
- let (dir, rev) = accu in
- (add_eq_edge u v Eq dir, add_eq_edge v u Eq rev)
- | Canonical { univ; lt; le; } ->
- let () = assert (u == univ) in
- let fold_lt (dir, rev) v = (add_edge u v Lt dir, add_edge v u Lt rev) in
- let fold_le (dir, rev) v = (add_eq_edge u v Le dir, add_eq_edge v u Le rev) in
- (** Order is important : lt after le, because of the possible redundancy
- between [le] and [lt] in a canonical arc. This way, the [lt] constraint
- is the last one set, which is correct because it implies [le]. *)
- let accu = List.fold_left fold_le accu le in
- let accu = List.fold_left fold_lt accu lt in
- accu
- in
- UMap.fold fold g (LMap.empty, LMap.empty)
-
-(** Construct a topological order out of a DAG. *)
-let rec topological_fold u g rem seen accu =
- let is_seen =
- try
- let status = LMap.find u seen in
- assert status; (** If false, not a DAG! *)
- true
- with Not_found -> false
- in
- if not is_seen then
- let rem = LMap.remove u rem in
- let seen = LMap.add u false seen in
- let neighbours = try LMap.find u g with Not_found -> LMap.empty in
- let fold v _ (rem, seen, accu) = topological_fold v g rem seen accu in
- let (rem, seen, accu) = LMap.fold fold neighbours (rem, seen, accu) in
- (rem, LMap.add u true seen, u :: accu)
- else (rem, seen, accu)
-
-let rec topological g rem seen accu =
- let node = try Some (LMap.choose rem) with Not_found -> None in
- match node with
- | None -> accu
- | Some (u, _) ->
- let rem, seen, accu = topological_fold u g rem seen accu in
- topological g rem seen accu
-
-(** Compute the longest path from any vertex. *)
-let constraint_cost = function
-| Eq | Le -> 0
-| Lt -> 1
-
-(** This algorithm browses the graph in topological order, computing for each
- encountered node the length of the longest path leading to it. Should be
- O(|V|) or so (modulo map representation). *)
-let rec flatten_graph rem (rev : graph) map mx = match rem with
-| [] -> map, mx
-| u :: rem ->
- let prev = try LMap.find u rev with Not_found -> LMap.empty in
- let fold v cstr accu =
- let v_cost = LMap.find v map in
- max (v_cost + constraint_cost cstr) accu
- in
- let u_cost = LMap.fold fold prev 0 in
- let map = LMap.add u u_cost map in
- flatten_graph rem rev map (max mx u_cost)
-
-(** [sort_universes g] builds a map from universes in [g] to natural
- numbers. It outputs a graph containing equivalence edges from each
- level appearing in [g] to [Type.n], and [lt] edges between the
- [Type.n]s. The output graph should imply the input graph (and the
- [Type.n]s. The output graph should imply the input graph (and the
- implication will be strict most of the time), but is not
- necessarily minimal. Note: the result is unspecified if the input
- graph already contains [Type.n] nodes (calling a module Type is
- probably a bad idea anyway). *)
-let sort_universes orig =
- let (dir, rev) = make_graph orig in
- let order = topological dir dir LMap.empty [] in
- let compact, max = flatten_graph order rev LMap.empty 0 in
- let mp = Names.DirPath.make [Names.Id.of_string "Type"] in
- let types = Array.init (max + 1) (fun n -> Level.make mp n) in
- (** Old universes are made equal to [Type.n] *)
- let fold u level accu = UMap.add u (Equiv types.(level)) accu in
- let sorted = LMap.fold fold compact UMap.empty in
- (** Add all [Type.n] nodes *)
- let fold i accu u =
- if i < max then
- let pred = types.(i + 1) in
- let arc = {univ = u; lt = [pred]; le = []; rank = 0; status = Unset; } in
- UMap.add u (Canonical arc) accu
- else accu
- in
- Array.fold_left_i fold sorted types
-
(* Miscellaneous functions to remove or test local univ assumed to
occur in a universe *)
@@ -1645,7 +876,6 @@ module Instance : sig
val pr : (Level.t -> Pp.std_ppcmds) -> t -> Pp.std_ppcmds
val levels : t -> LSet.t
- val check_eq : t check_function
end =
struct
type t = Level.t array
@@ -1731,13 +961,6 @@ struct
(* Necessary as universe instances might come from different modules and
unmarshalling doesn't preserve sharing *))
- let check_eq g t1 t2 =
- t1 == t2 ||
- (Int.equal (Array.length t1) (Array.length t2) &&
- let rec aux i =
- (Int.equal i (Array.length t1)) || (check_eq_level g t1.(i) t2.(i) && aux (i + 1))
- in aux 0)
-
end
let enforce_eq_instances x y =
@@ -1993,27 +1216,6 @@ let abstract_universes poly ctx =
(** Pretty-printing *)
-let pr_arc prl = function
- | _, Canonical {univ=u; lt=[]; le=[]} ->
- mt ()
- | _, Canonical {univ=u; lt=lt; le=le} ->
- let opt_sep = match lt, le with
- | [], _ | _, [] -> mt ()
- | _ -> spc ()
- in
- prl u ++ str " " ++
- v 0
- (pr_sequence (fun v -> str "< " ++ prl v) lt ++
- opt_sep ++
- pr_sequence (fun v -> str "<= " ++ prl v) le) ++
- fnl ()
- | u, Equiv v ->
- prl u ++ str " = " ++ prl v ++ fnl ()
-
-let pr_universes prl g =
- let graph = UMap.fold (fun u a l -> (u,a)::l) g [] in
- prlist (pr_arc prl) graph
-
let pr_constraints prl = Constraint.pr prl
let pr_universe_context = UContext.pr
@@ -2026,19 +1228,6 @@ let pr_universe_subst =
let pr_universe_level_subst =
LMap.pr (fun u -> str" := " ++ Level.pr u ++ spc ())
-(* Dumping constraints to a file *)
-
-let dump_universes output g =
- let dump_arc u = function
- | Canonical {univ=u; lt=lt; le=le} ->
- let u_str = Level.to_string u in
- List.iter (fun v -> output Lt u_str (Level.to_string v)) lt;
- List.iter (fun v -> output Le u_str (Level.to_string v)) le
- | Equiv v ->
- output Eq (Level.to_string u) (Level.to_string v)
- in
- UMap.iter dump_arc g
-
module Huniverse_set =
Hashcons.Make(
struct
@@ -2086,26 +1275,3 @@ let subst_instance_constraints =
let key = Profile.declare_profile "subst_instance_constraints" in
Profile.profile2 key subst_instance_constraints
else subst_instance_constraints
-
-let merge_constraints =
- if Flags.profile then
- let key = Profile.declare_profile "merge_constraints" in
- Profile.profile2 key merge_constraints
- else merge_constraints
-let check_constraints =
- if Flags.profile then
- let key = Profile.declare_profile "check_constraints" in
- Profile.profile2 key check_constraints
- else check_constraints
-
-let check_eq =
- if Flags.profile then
- let check_eq_key = Profile.declare_profile "check_eq" in
- Profile.profile3 check_eq_key check_eq
- else check_eq
-
-let check_leq =
- if Flags.profile then
- let check_leq_key = Profile.declare_profile "check_leq" in
- Profile.profile3 check_leq_key check_leq
- else check_leq
diff --git a/kernel/univ.mli b/kernel/univ.mli
index 9788f129b..1ccdebd50 100644
--- a/kernel/univ.mli
+++ b/kernel/univ.mli
@@ -40,6 +40,9 @@ sig
val pr : t -> Pp.std_ppcmds
(** Pretty-printing *)
+ val to_string : t -> string
+ (** Debug printing *)
+
val var : int -> t
val var_index : t -> int option
@@ -115,6 +118,9 @@ sig
val type1 : t
(** the universe of the type of Prop/Set *)
+
+ val exists : (Level.t * int -> bool) -> t -> bool
+ val for_all : (Level.t * int -> bool) -> t -> bool
end
type universe = Universe.t
@@ -148,31 +154,6 @@ val univ_level_mem : universe_level -> universe -> bool
val univ_level_rem : universe_level -> universe -> universe -> universe
-(** {6 Graphs of universes. } *)
-
-type universes
-
-type 'a check_function = universes -> 'a -> 'a -> bool
-val check_leq : universe check_function
-val check_eq : universe check_function
-
-(** The empty graph of universes *)
-val empty_universes : universes
-
-(** The initial graph of universes: Prop < Set *)
-val initial_universes : universes
-
-val is_initial_universes : universes -> bool
-
-val sort_universes : universes -> universes
-
-(** Adds a universe to the graph, ensuring it is >= or > Set.
- @raises AlreadyDeclared if the level is already declared in the graph. *)
-
-exception AlreadyDeclared
-
-val add_universe : universe_level -> bool -> universes -> universes
-
(** {6 Constraints. } *)
type constraint_type = Lt | Le | Eq
@@ -203,12 +184,6 @@ val enforce_leq : universe constraint_function
val enforce_eq_level : universe_level constraint_function
val enforce_leq_level : universe_level constraint_function
-(** {6 ... } *)
-(** Merge of constraints in a universes graph.
- The function [merge_constraints] merges a set of constraints in a given
- universes graph. It raises the exception [UniverseInconsistency] if the
- constraints are not satisfiable. *)
-
(** Type explanation is used to decorate error messages to provide
useful explanation why a given constraint is rejected. It is composed
of a path of universes and relation kinds [(r1,u1);..;(rn,un)] means
@@ -226,14 +201,6 @@ type univ_inconsistency = constraint_type * universe * universe * explanation op
exception UniverseInconsistency of univ_inconsistency
-val enforce_constraint : univ_constraint -> universes -> universes
-val merge_constraints : constraints -> universes -> universes
-
-val constraints_of_universes : universes -> constraints
-
-val check_constraint : universes -> univ_constraint -> bool
-val check_constraints : constraints -> universes -> bool
-
(** {6 Support for universe polymorphism } *)
(** Polymorphic maps from universe levels to 'a *)
@@ -309,8 +276,6 @@ sig
val levels : t -> LSet.t
(** The set of levels in the instance *)
- val check_eq : t check_function
- (** Check equality of instances w.r.t. a universe graph *)
end
type universe_instance = Instance.t
@@ -428,7 +393,6 @@ val instantiate_univ_constraints : universe_instance -> universe_context -> cons
(** {6 Pretty-printing of universes. } *)
-val pr_universes : (Level.t -> Pp.std_ppcmds) -> universes -> Pp.std_ppcmds
val pr_constraint_type : constraint_type -> Pp.std_ppcmds
val pr_constraints : (Level.t -> Pp.std_ppcmds) -> constraints -> Pp.std_ppcmds
val pr_universe_context : (Level.t -> Pp.std_ppcmds) -> universe_context -> Pp.std_ppcmds
@@ -439,12 +403,6 @@ val explain_universe_inconsistency : (Level.t -> Pp.std_ppcmds) ->
val pr_universe_level_subst : universe_level_subst -> Pp.std_ppcmds
val pr_universe_subst : universe_subst -> Pp.std_ppcmds
-(** {6 Dumping to a file } *)
-
-val dump_universes :
- (constraint_type -> string -> string -> unit) ->
- universes -> unit
-
(** {6 Hash-consing } *)
val hcons_univ : universe -> universe
diff --git a/kernel/vars.ml b/kernel/vars.ml
index 6bdae992d..4554c6be1 100644
--- a/kernel/vars.ml
+++ b/kernel/vars.ml
@@ -8,7 +8,6 @@
open Names
open Esubst
-open Context
(*********************)
(* Occurring *)
@@ -151,20 +150,33 @@ let make_subst = function
done;
subst
+(* The type of substitutions, with term substituting most recent
+ binder at the head *)
+
+type substl = Constr.t list
+
let substnl laml n c = substn_many (make_subst laml) n c
let substl laml c = substn_many (make_subst laml) 0 c
let subst1 lam c = substn_many [|make_substituend lam|] 0 c
-let substnl_decl laml k r = map_rel_declaration (fun c -> substnl laml k c) r
-let substl_decl laml r = map_rel_declaration (fun c -> substnl laml 0 c) r
-let subst1_decl lam r = map_rel_declaration (fun c -> subst1 lam c) r
+let substnl_decl laml k r = Context.Rel.Declaration.map (fun c -> substnl laml k c) r
+let substl_decl laml r = Context.Rel.Declaration.map (fun c -> substnl laml 0 c) r
+let subst1_decl lam r = Context.Rel.Declaration.map (fun c -> subst1 lam c) r
+
+(* Build a substitution from an instance, inserting missing let-ins *)
+
+let subst_of_rel_context_instance sign l =
+ let rec aux subst sign l =
+ match sign, l with
+ | (_,None,_)::sign', a::args' -> aux (a::subst) sign' args'
+ | (_,Some c,_)::sign', args' ->
+ aux (substl subst c :: subst) sign' args'
+ | [], [] -> subst
+ | _ -> Errors.anomaly (Pp.str "Instance and signature do not match")
+ in aux [] (List.rev sign) l
-let substnl_named_decl laml k d =
- map_named_declaration (fun c -> substnl laml k c) d
-let substl_named_decl laml d =
- map_named_declaration (fun c -> substnl laml 0 c) d
-let subst1_named_decl lam d =
- map_named_declaration (fun c -> subst1 lam c) d
+let adjust_subst_to_rel_context sign l =
+ List.rev (subst_of_rel_context_instance sign l)
(* (thin_val sigma) removes identity substitutions from sigma *)
@@ -197,15 +209,10 @@ let replace_vars var_alist x =
in
substrec 0 x
-(*
-let repvarkey = Profile.declare_profile "replace_vars";;
-let replace_vars vl c = Profile.profile2 repvarkey replace_vars vl c ;;
-*)
-
-(* (subst_var str t) substitute (VAR str) by (Rel 1) in t *)
+(* (subst_var str t) substitute (Var str) by (Rel 1) in t *)
let subst_var str t = replace_vars [(str, Constr.mkRel 1)] t
-(* (subst_vars [id1;...;idn] t) substitute (VAR idj) by (Rel j) in t *)
+(* (subst_vars [id1;...;idn] t) substitute (Var idj) by (Rel j) in t *)
let substn_vars p vars c =
let _,subst =
List.fold_left (fun (n,l) var -> ((n+1),(var,Constr.mkRel n)::l)) (p,[]) vars
@@ -294,7 +301,7 @@ let subst_univs_level_constr subst c =
if !changed then c' else c
let subst_univs_level_context s =
- map_rel_context (subst_univs_level_constr s)
+ Context.Rel.map (subst_univs_level_constr s)
let subst_instance_constr subst c =
if Univ.Instance.is_empty subst then c
@@ -335,7 +342,7 @@ let subst_instance_constr subst c =
let subst_instance_context s ctx =
if Univ.Instance.is_empty s then ctx
- else map_rel_context (fun x -> subst_instance_constr s x) ctx
+ else Context.Rel.map (fun x -> subst_instance_constr s x) ctx
type id_key = constant tableKey
let eq_id_key x y = Names.eq_table_key Constant.equal x y
diff --git a/kernel/vars.mli b/kernel/vars.mli
index 501a5b859..574d50ecc 100644
--- a/kernel/vars.mli
+++ b/kernel/vars.mli
@@ -8,7 +8,6 @@
open Names
open Constr
-open Context
(** {6 Occur checks } *)
@@ -42,32 +41,85 @@ val liftn : int -> int -> constr -> constr
(** [lift n c] lifts by [n] the positive indexes in [c] *)
val lift : int -> constr -> constr
-(** [substnl [a1;...;an] k c] substitutes in parallel [a1],...,[an]
+(** The type [substl] is the type of substitutions [u₁..un] of type
+ some context Δ and defined in some environment Γ. Typing of
+ substitutions is defined by:
+ - Γ ⊢ ∅ : ∅,
+ - Γ ⊢ u₁..u{_n-1} : Δ and Γ ⊢ u{_n} : An\[u₁..u{_n-1}\] implies
+ Γ ⊢ u₁..u{_n} : Δ,x{_n}:A{_n}
+ - Γ ⊢ u₁..u{_n-1} : Δ and Γ ⊢ un : A{_n}\[u₁..u{_n-1}\] implies
+ Γ ⊢ u₁..u{_n} : Δ,x{_n}:=c{_n}:A{_n} when Γ ⊢ u{_n} ≡ c{_n}\[u₁..u{_n-1}\]
+
+ Note that [u₁..un] is represented as a list with [un] at the head of
+ the list, i.e. as [[un;...;u₁]]. *)
+
+type substl = constr list
+
+(** Let [Γ] be a context interleaving declarations [x₁:T₁..xn:Tn]
+ and definitions [y₁:=c₁..yp:=cp] in some context [Γ₀]. Let
+ [u₁..un] be an {e instance} of [Γ], i.e. an instance in [Γ₀]
+ of the [xi]. Then, [subst_of_rel_context_instance Γ u₁..un]
+ returns the corresponding {e substitution} of [Γ], i.e. the
+ appropriate interleaving [σ] of the [u₁..un] with the [c₁..cp],
+ all of them in [Γ₀], so that a derivation [Γ₀, Γ, Γ₁|- t:T]
+ can be instantiated into a derivation [Γ₀, Γ₁ |- t[σ]:T[σ]] using
+ [substnl σ |Γ₁| t].
+ Note that the instance [u₁..un] is represented starting with [u₁],
+ as if usable in [applist] while the substitution is
+ represented the other way round, i.e. ending with either [u₁] or
+ [c₁], as if usable for [substl]. *)
+val subst_of_rel_context_instance : Context.Rel.t -> constr list -> substl
+
+(** For compatibility: returns the substitution reversed *)
+val adjust_subst_to_rel_context : Context.Rel.t -> constr list -> constr list
+
+(** [substnl [a₁;...;an] k c] substitutes in parallel [a₁],...,[an]
for respectively [Rel(k+1)],...,[Rel(k+n)] in [c]; it relocates
- accordingly indexes in [a1],...,[an] and [c] *)
-val substnl : constr list -> int -> constr -> constr
-val substl : constr list -> constr -> constr
+ accordingly indexes in [an],...,[a1] and [c]. In terms of typing, if
+ Γ ⊢ a{_n}..a₁ : Δ and Γ, Δ, Γ' ⊢ c : T with |Γ'|=k, then
+ Γ, Γ' ⊢ [substnl [a₁;...;an] k c] : [substnl [a₁;...;an] k T]. *)
+val substnl : substl -> int -> constr -> constr
+
+(** [substl σ c] is a short-hand for [substnl σ 0 c] *)
+val substl : substl -> constr -> constr
+
+(** [substl a c] is a short-hand for [substnl [a] 0 c] *)
val subst1 : constr -> constr -> constr
-val substnl_decl : constr list -> int -> rel_declaration -> rel_declaration
-val substl_decl : constr list -> rel_declaration -> rel_declaration
-val subst1_decl : constr -> rel_declaration -> rel_declaration
+(** [substnl_decl [a₁;...;an] k Ω] substitutes in parallel [a₁], ..., [an]
+ for respectively [Rel(k+1)], ..., [Rel(k+n)] in [Ω]; it relocates
+ accordingly indexes in [a₁],...,[an] and [c]. In terms of typing, if
+ Γ ⊢ a{_n}..a₁ : Δ and Γ, Δ, Γ', Ω ⊢ with |Γ'|=[k], then
+ Γ, Γ', [substnl_decl [a₁;...;an]] k Ω ⊢. *)
+val substnl_decl : substl -> int -> Context.Rel.Declaration.t -> Context.Rel.Declaration.t
-val substnl_named_decl : constr list -> int -> named_declaration -> named_declaration
-val subst1_named_decl : constr -> named_declaration -> named_declaration
-val substl_named_decl : constr list -> named_declaration -> named_declaration
+(** [substl_decl σ Ω] is a short-hand for [substnl_decl σ 0 Ω] *)
+val substl_decl : substl -> Context.Rel.Declaration.t -> Context.Rel.Declaration.t
+(** [subst1_decl a Ω] is a short-hand for [substnl_decl [a] 0 Ω] *)
+val subst1_decl : constr -> Context.Rel.Declaration.t -> Context.Rel.Declaration.t
+
+(** [replace_vars k [(id₁,c₁);...;(idn,cn)] t] substitutes [Var idj] by
+ [cj] in [t]. *)
val replace_vars : (Id.t * constr) list -> constr -> constr
-(** (subst_var str t) substitute (VAR str) by (Rel 1) in t *)
-val subst_var : Id.t -> constr -> constr
-(** [subst_vars [id1;...;idn] t] substitute [VAR idj] by [Rel j] in [t]
- if two names are identical, the one of least indice is kept *)
+(** [substn_vars k [id₁;...;idn] t] substitutes [Var idj] by [Rel j+k-1] in [t].
+ If two names are identical, the one of least index is kept. In terms of
+ typing, if Γ,x{_n}:U{_n},...,x₁:U₁,Γ' ⊢ t:T, together with id{_j}:T{_j} and
+ Γ,x{_n}:U{_n},...,x₁:U₁,Γ' ⊢ T{_j}\[id{_j+1}..id{_n}:=x{_j+1}..x{_n}\] ≡ Uj,
+ then Γ\\{id₁,...,id{_n}\},x{_n}:U{_n},...,x₁:U₁,Γ' ⊢ [substn_vars
+ (|Γ'|+1) [id₁;...;idn] t] : [substn_vars (|Γ'|+1) [id₁;...;idn]
+ T]. *)
+val substn_vars : int -> Id.t list -> constr -> constr
+
+(** [subst_vars [id1;...;idn] t] is a short-hand for [substn_vars
+ [id1;...;idn] 1 t]: it substitutes [Var idj] by [Rel j] in [t]. If
+ two names are identical, the one of least index is kept. *)
val subst_vars : Id.t list -> constr -> constr
-(** [substn_vars n [id1;...;idk] t] substitute [VAR idj] by [Rel j+n-1] in [t]
- if two names are identical, the one of least indice is kept *)
-val substn_vars : int -> Id.t list -> constr -> constr
+(** [subst_var id t] is a short-hand for [substn_vars [id] 1 t]: it
+ substitutes [Var id] by [Rel 1] in [t]. *)
+val subst_var : Id.t -> constr -> constr
(** {3 Substitution of universes} *)
@@ -82,11 +134,11 @@ val subst_univs_constr : universe_subst -> constr -> constr
(** Level substitutions for polymorphism. *)
val subst_univs_level_constr : universe_level_subst -> constr -> constr
-val subst_univs_level_context : Univ.universe_level_subst -> rel_context -> rel_context
+val subst_univs_level_context : Univ.universe_level_subst -> Context.Rel.t -> Context.Rel.t
(** Instance substitution for polymorphism. *)
val subst_instance_constr : universe_instance -> constr -> constr
-val subst_instance_context : universe_instance -> rel_context -> rel_context
+val subst_instance_context : universe_instance -> Context.Rel.t -> Context.Rel.t
type id_key = constant tableKey
val eq_id_key : id_key -> id_key -> bool
diff --git a/kernel/vconv.mli b/kernel/vconv.mli
index 7e5397c06..ff01735c0 100644
--- a/kernel/vconv.mli
+++ b/kernel/vconv.mli
@@ -12,7 +12,7 @@ open Reduction
(**********************************************************************
s conversion functions *)
-val vm_conv : conv_pb -> types conversion_function
+val vm_conv : conv_pb -> types kernel_conversion_function
(** A conversion function parametrized by a universe comparator. Used outside of
the kernel. *)
diff --git a/lib/cList.ml b/lib/cList.ml
index 0ac372d8d..ba592d13f 100644
--- a/lib/cList.ml
+++ b/lib/cList.ml
@@ -48,6 +48,8 @@ sig
val filteri :
(int -> 'a -> bool) -> 'a list -> 'a list
val smartfilter : ('a -> bool) -> 'a list -> 'a list
+ val extend : bool list -> 'a -> 'a list -> 'a list
+ val count : ('a -> bool) -> 'a list -> int
val index : 'a eq -> 'a -> 'a list -> int
val index0 : 'a eq -> 'a -> 'a list -> int
val iteri : (int -> 'a -> unit) -> 'a list -> unit
@@ -375,6 +377,18 @@ let rec smartfilter f l = match l with
else h :: tl'
else tl'
+let rec extend l a l' = match l,l' with
+ | true::l, b::l' -> b :: extend l a l'
+ | false::l, l' -> a :: extend l a l'
+ | [], [] -> []
+ | _ -> invalid_arg "extend"
+
+let count f l =
+ let rec aux acc = function
+ | [] -> acc
+ | h :: t -> if f h then aux (acc + 1) t else aux acc t in
+ aux 0 l
+
let rec index_f f x l n = match l with
| [] -> raise Not_found
| y :: l -> if f x y then n else index_f f x l (succ n)
@@ -638,12 +652,13 @@ let rec split3 = function
let (rx, ry, rz) = split3 l in (x::rx, y::ry, z::rz)
let firstn n l =
- let rec aux acc = function
- | (0, l) -> List.rev acc
- | (n, (h::t)) -> aux (h::acc) (pred n, t)
+ let rec aux acc n l =
+ match n, l with
+ | 0, _ -> List.rev acc
+ | n, h::t -> aux (h::acc) (pred n) t
| _ -> failwith "firstn"
in
- aux [] (n,l)
+ aux [] n l
let rec last = function
| [] -> failwith "List.last"
diff --git a/lib/cList.mli b/lib/cList.mli
index 19eeb2509..9c7b815c1 100644
--- a/lib/cList.mli
+++ b/lib/cList.mli
@@ -94,6 +94,11 @@ sig
(** [smartfilter f [a1...an] = List.filter f [a1...an]] but if for all i
[f ai = true], then [smartfilter f l == l] *)
+ val extend : bool list -> 'a -> 'a list -> 'a list
+(** [extend l a [a1..an]] assumes that the number of [true] in [l] is [n];
+ it extends [a1..an] by inserting [a] at the position of [false] in [l] *)
+ val count : ('a -> bool) -> 'a list -> int
+
val index : 'a eq -> 'a -> 'a list -> int
(** [index] returns the 1st index of an element in a list (counting from 1). *)
diff --git a/lib/cMap.ml b/lib/cMap.ml
index 665e1a216..d1a32b7aa 100644
--- a/lib/cMap.ml
+++ b/lib/cMap.ml
@@ -12,6 +12,13 @@ sig
val compare : t -> t -> int
end
+module type MonadS =
+sig
+ type +'a t
+ val return : 'a -> 'a t
+ val (>>=) : 'a t -> ('a -> 'b t) -> 'b t
+end
+
module type S = Map.S
module type ExtS =
@@ -30,6 +37,12 @@ sig
sig
val map : (key -> 'a -> key * 'b) -> 'a t -> 'b t
end
+ module Monad(M : MonadS) :
+ sig
+ val fold : (key -> 'a -> 'b -> 'b M.t) -> 'a t -> 'b -> 'b M.t
+ val fold_left : (key -> 'a -> 'b -> 'b M.t) -> 'a t -> 'b -> 'b M.t
+ val fold_right : (key -> 'a -> 'b -> 'b M.t) -> 'a t -> 'b -> 'b M.t
+ end
end
module MapExt (M : Map.OrderedType) :
@@ -47,6 +60,12 @@ sig
sig
val map : (M.t -> 'a -> M.t * 'b) -> 'a map -> 'b map
end
+ module Monad(MS : MonadS) :
+ sig
+ val fold : (M.t -> 'a -> 'b -> 'b MS.t) -> 'a map -> 'b -> 'b MS.t
+ val fold_left : (M.t -> 'a -> 'b -> 'b MS.t) -> 'a map -> 'b -> 'b MS.t
+ val fold_right : (M.t -> 'a -> 'b -> 'b MS.t) -> 'a map -> 'b -> 'b MS.t
+ end
end =
struct
(** This unsafe module is a way to access to the actual implementations of
@@ -159,6 +178,29 @@ struct
end
+ module Monad(M : MonadS) =
+ struct
+
+ open M
+
+ let rec fold_left f s accu = match map_prj s with
+ | MEmpty -> return accu
+ | MNode (l, k, v, r, h) ->
+ fold_left f l accu >>= fun accu ->
+ f k v accu >>= fun accu ->
+ fold_left f r accu
+
+ let rec fold_right f s accu = match map_prj s with
+ | MEmpty -> return accu
+ | MNode (l, k, v, r, h) ->
+ fold_right f r accu >>= fun accu ->
+ f k v accu >>= fun accu ->
+ fold_right f l accu
+
+ let fold = fold_left
+
+ end
+
end
module Make(M : Map.OrderedType) =
diff --git a/lib/cMap.mli b/lib/cMap.mli
index 2f243da83..464dc503b 100644
--- a/lib/cMap.mli
+++ b/lib/cMap.mli
@@ -14,6 +14,13 @@ sig
val compare : t -> t -> int
end
+module type MonadS =
+sig
+ type +'a t
+ val return : 'a -> 'a t
+ val (>>=) : 'a t -> ('a -> 'b t) -> 'b t
+end
+
module type S = Map.S
module type ExtS =
@@ -59,6 +66,14 @@ sig
i.e.: for all (k : key) (x : 'a), compare (fst (f k x)) k = 0. *)
end
+ module Monad(M : MonadS) :
+ sig
+ val fold : (key -> 'a -> 'b -> 'b M.t) -> 'a t -> 'b -> 'b M.t
+ val fold_left : (key -> 'a -> 'b -> 'b M.t) -> 'a t -> 'b -> 'b M.t
+ val fold_right : (key -> 'a -> 'b -> 'b M.t) -> 'a t -> 'b -> 'b M.t
+ end
+ (** Fold operators parameterized by any monad. *)
+
end
module Make(M : Map.OrderedType) : ExtS with
diff --git a/lib/cSig.mli b/lib/cSig.mli
index e095c82cb..151cfbdca 100644
--- a/lib/cSig.mli
+++ b/lib/cSig.mli
@@ -14,6 +14,8 @@ type ('a, 'b) union = Inl of 'a | Inr of 'b
type 'a until = Stop of 'a | Cont of 'a
(** Used for browsable-until structures. *)
+type (_, _) eq = Refl : ('a, 'a) eq
+
module type SetS =
sig
type elt
@@ -46,6 +48,8 @@ end
(** Redeclaration of OCaml set signature, to preserve compatibility. See OCaml
documentation for more information. *)
+module type EmptyS = sig end
+
module type MapS =
sig
type key
diff --git a/lib/clib.mllib b/lib/clib.mllib
index 9c9607abd..3c1c5da33 100644
--- a/lib/clib.mllib
+++ b/lib/clib.mllib
@@ -8,6 +8,7 @@ Hashcons
CSet
CMap
Int
+Dyn
HMap
Option
Store
diff --git a/lib/dyn.ml b/lib/dyn.ml
index 04b32870a..676467e46 100644
--- a/lib/dyn.ml
+++ b/lib/dyn.ml
@@ -6,12 +6,55 @@
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
-open Errors
-open Pp
+module type TParam =
+sig
+ type 'a t
+end
+module type S =
+sig
+type 'a tag
+type t = Dyn : 'a tag * 'a -> t
+
+val create : string -> 'a tag
+val eq : 'a tag -> 'b tag -> ('a, 'b) CSig.eq option
+val repr : 'a tag -> string
+
+type any = Any : 'a tag -> any
+
+val name : string -> any option
+
+module Map(M : TParam) :
+sig
+ type t
+ val empty : t
+ val add : 'a tag -> 'a M.t -> t -> t
+ val remove : 'a tag -> t -> t
+ val find : 'a tag -> t -> 'a M.t
+ val mem : 'a tag -> t -> bool
+
+ type any = Any : 'a tag * 'a M.t -> any
+
+ type map = { map : 'a. 'a tag -> 'a M.t -> 'a M.t }
+ val map : map -> t -> t
+
+ val iter : (any -> unit) -> t -> unit
+ val fold : (any -> 'r -> 'r) -> t -> 'r -> 'r
+
+end
+
+val dump : unit -> (int * string) list
+end
+
+module Make(M : CSig.EmptyS) =
+struct
(* Dynamics, programmed with DANGER !!! *)
-type t = int * Obj.t
+type 'a tag = int
+
+type t = Dyn : 'a tag * 'a -> t
+
+type any = Any : 'a tag -> any
let dyntab = ref (Int.Map.empty : string Int.Map.t)
(** Instead of working with tags as strings, which are costly, we use their
@@ -24,27 +67,44 @@ let create (s : string) =
let () =
if Int.Map.mem hash !dyntab then
let old = Int.Map.find hash !dyntab in
- let msg = str "Dynamic tag collision: " ++ str s ++ str " vs. " ++ str old in
- anomaly ~label:"Dyn.create" msg
+ let () = Printf.eprintf "Dynamic tag collision: %s vs. %s\n%!" s old in
+ assert false
in
let () = dyntab := Int.Map.add hash s !dyntab in
- let infun v = (hash, Obj.repr v) in
- let outfun (nh, rv) =
- if Int.equal hash nh then Obj.magic rv
- else
- anomaly (str "dyn_out: expected " ++ str s)
- in
- (infun, outfun)
+ hash
-let has_tag (s, _) tag =
- let hash = Hashtbl.hash (tag : string) in
- Int.equal s hash
+let eq : 'a 'b. 'a tag -> 'b tag -> ('a, 'b) CSig.eq option =
+ fun h1 h2 -> if Int.equal h1 h2 then Some (Obj.magic CSig.Refl) else None
-let tag (s,_) =
+let repr s =
try Int.Map.find s !dyntab
with Not_found ->
- anomaly (str "Unknown dynamic tag " ++ int s)
+ let () = Printf.eprintf "Unknown dynamic tag %i\n%!" s in
+ assert false
-let pointer_equal (t1,o1) (t2,o2) = t1 = t2 && o1 == o2
+let name s =
+ let hash = Hashtbl.hash s in
+ if Int.Map.mem hash !dyntab then Some (Any hash) else None
let dump () = Int.Map.bindings !dyntab
+
+module Map(M : TParam) =
+struct
+type t = Obj.t M.t Int.Map.t
+let cast : 'a M.t -> 'b M.t = Obj.magic
+let empty = Int.Map.empty
+let add tag v m = Int.Map.add tag (cast v) m
+let remove tag m = Int.Map.remove tag m
+let find tag m = cast (Int.Map.find tag m)
+let mem = Int.Map.mem
+
+type any = Any : 'a tag * 'a M.t -> any
+
+type map = { map : 'a. 'a tag -> 'a M.t -> 'a M.t }
+let map f m = Int.Map.mapi f.map m
+
+let iter f m = Int.Map.iter (fun k v -> f (Any (k, v))) m
+let fold f m accu = Int.Map.fold (fun k v accu -> f (Any (k, v)) accu) m accu
+end
+
+end
diff --git a/lib/dyn.mli b/lib/dyn.mli
index c040d8b0b..c94fa764b 100644
--- a/lib/dyn.mli
+++ b/lib/dyn.mli
@@ -7,11 +7,46 @@
(************************************************************************)
(** Dynamics. Use with extreme care. Not for kids. *)
+module type TParam =
+sig
+ type 'a t
+end
-type t
+module type S =
+sig
+type 'a tag
+type t = Dyn : 'a tag * 'a -> t
+
+val create : string -> 'a tag
+val eq : 'a tag -> 'b tag -> ('a, 'b) CSig.eq option
+val repr : 'a tag -> string
+
+type any = Any : 'a tag -> any
+
+val name : string -> any option
+
+module Map(M : TParam) :
+sig
+ type t
+ val empty : t
+ val add : 'a tag -> 'a M.t -> t -> t
+ val remove : 'a tag -> t -> t
+ val find : 'a tag -> t -> 'a M.t
+ val mem : 'a tag -> t -> bool
+
+ type any = Any : 'a tag * 'a M.t -> any
+
+ type map = { map : 'a. 'a tag -> 'a M.t -> 'a M.t }
+ val map : map -> t -> t
+
+ val iter : (any -> unit) -> t -> unit
+ val fold : (any -> 'r -> 'r) -> t -> 'r -> 'r
+
+end
-val create : string -> ('a -> t) * (t -> 'a)
-val tag : t -> string
-val has_tag : t -> string -> bool
-val pointer_equal : t -> t -> bool
val dump : unit -> (int * string) list
+
+end
+
+(** FIXME: use OCaml 4.02 generative functors when available *)
+module Make(M : CSig.EmptyS) : S
diff --git a/lib/envars.ml b/lib/envars.ml
index 679e3fdfe..89ce52831 100644
--- a/lib/envars.ml
+++ b/lib/envars.ml
@@ -146,23 +146,12 @@ let coqpath =
let exe s = s ^ Coq_config.exec_extension
-let guess_camlbin () = which (user_path ()) (exe "ocamlc")
+let guess_ocamlfind () = which (user_path ()) (exe "ocamlfind")
-let camlbin () =
- if !Flags.camlbin_spec then !Flags.camlbin else
- if !Flags.boot then Coq_config.camlbin else
- try guess_camlbin () with Not_found -> Coq_config.camlbin
-
-let ocamlc () = camlbin () / Coq_config.ocamlc
-
-let ocamlopt () = camlbin () / Coq_config.ocamlopt
-
-let camllib () =
- if !Flags.boot then
- Coq_config.camllib
- else
- let _, res = CUnix.run_command (ocamlc () ^ " -where") in
- String.strip res
+let ocamlfind () =
+ if !Flags.ocamlfind_spec then !Flags.ocamlfind else
+ if !Flags.boot then Coq_config.ocamlfind else
+ try guess_ocamlfind () / "ocamlfind" with Not_found -> Coq_config.ocamlfind
(** {2 Camlp4 paths} *)
@@ -173,9 +162,7 @@ let camlp4bin () =
if !Flags.boot then Coq_config.camlp4bin else
try guess_camlp4bin ()
with Not_found ->
- let cb = camlbin () in
- if Sys.file_exists (cb / exe Coq_config.camlp4) then cb
- else Coq_config.camlp4bin
+ Coq_config.camlp4bin
let camlp4 () = camlp4bin () / exe Coq_config.camlp4
@@ -183,7 +170,7 @@ let camlp4lib () =
if !Flags.boot then
Coq_config.camlp4lib
else
- let ex, res = CUnix.run_command (camlp4 () ^ " -where") in
+ let ex, res = CUnix.run_command (ocamlfind () ^ " query " ^ Coq_config.camlp4) in
match ex with
| Unix.WEXITED 0 -> String.strip res
| _ -> "/dev/null"
diff --git a/lib/envars.mli b/lib/envars.mli
index d95b6f099..90a42859b 100644
--- a/lib/envars.mli
+++ b/lib/envars.mli
@@ -47,17 +47,8 @@ val coqroot : string
the order it gets added to the search path. *)
val coqpath : string list
-(** [camlbin ()] is the path to the ocaml binaries. *)
-val camlbin : unit -> string
-
-(** [camllib ()] is the path to the ocaml standard library. *)
-val camllib : unit -> string
-
-(** [ocamlc ()] is the ocaml bytecode compiler that compiled this Coq. *)
-val ocamlc : unit -> string
-
-(** [ocamlc ()] is the ocaml native compiler that compiled this Coq. *)
-val ocamlopt : unit -> string
+(** [camlbin ()] is the path to the ocamlfind binary. *)
+val ocamlfind : unit -> string
(** [camlp4bin ()] is the path to the camlp4 binary. *)
val camlp4bin : unit -> string
diff --git a/lib/feedback.ml b/lib/feedback.ml
index cce0c6bc6..1a90685de 100644
--- a/lib/feedback.ml
+++ b/lib/feedback.ml
@@ -18,7 +18,7 @@ type message_level =
type message = {
message_level : message_level;
- message_content : string;
+ message_content : xml;
}
let of_message_level = function
@@ -39,12 +39,12 @@ let to_message_level =
let of_message msg =
let lvl = of_message_level msg.message_level in
- let content = Serialize.of_string msg.message_content in
+ let content = Serialize.of_xml msg.message_content in
Xml_datatype.Element ("message", [], [lvl; content])
let to_message xml = match xml with
| Xml_datatype.Element ("message", [], [lvl; content]) -> {
message_level = to_message_level lvl;
- message_content = Serialize.to_string content }
+ message_content = Serialize.to_xml content }
| _ -> raise Serialize.Marshal_error
let is_message = function
diff --git a/lib/feedback.mli b/lib/feedback.mli
index 162867626..0d8e20230 100644
--- a/lib/feedback.mli
+++ b/lib/feedback.mli
@@ -18,7 +18,7 @@ type message_level =
type message = {
message_level : message_level;
- message_content : string;
+ message_content : xml;
}
val of_message : message -> xml
diff --git a/lib/flags.ml b/lib/flags.ml
index 2c23ec984..c1ec9738c 100644
--- a/lib/flags.ml
+++ b/lib/flags.ml
@@ -103,18 +103,20 @@ let we_are_parsing = ref false
(* Current means no particular compatibility consideration.
For correct comparisons, this constructor should remain the last one. *)
-type compat_version = V8_2 | V8_3 | V8_4 | Current
+type compat_version = V8_2 | V8_3 | V8_4 | V8_5 | Current
let compat_version = ref Current
let version_strictly_greater v = match !compat_version, v with
-| V8_2, (V8_2 | V8_3 | V8_4 | Current) -> false
-| V8_3, (V8_3 | V8_4 | Current) -> false
-| V8_4, (V8_4 | Current) -> false
+| V8_2, (V8_2 | V8_3 | V8_4 | V8_5 | Current) -> false
+| V8_3, (V8_3 | V8_4 | V8_5 | Current) -> false
+| V8_4, (V8_4 | V8_5 | Current) -> false
+| V8_5, (V8_5 | Current) -> false
| Current, Current -> false
| V8_3, V8_2 -> true
| V8_4, (V8_2 | V8_3) -> true
-| Current, (V8_2 | V8_3 | V8_4) -> true
+| V8_5, (V8_2 | V8_3 | V8_4) -> true
+| Current, (V8_2 | V8_3 | V8_4 | V8_5) -> true
let version_less_or_equal v = not (version_strictly_greater v)
@@ -122,6 +124,7 @@ let pr_version = function
| V8_2 -> "8.2"
| V8_3 -> "8.3"
| V8_4 -> "8.4"
+ | V8_5 -> "8.5"
| Current -> "current"
(* Translate *)
@@ -195,9 +198,9 @@ let is_standard_doc_url url =
let coqlib_spec = ref false
let coqlib = ref "(not initialized yet)"
-(* Options for changing camlbin (used by coqmktop) *)
-let camlbin_spec = ref false
-let camlbin = ref Coq_config.camlbin
+(* Options for changing ocamlfind (used by coqmktop) *)
+let ocamlfind_spec = ref false
+let ocamlfind = ref Coq_config.camlbin
(* Options for changing camlp4bin (used by coqmktop) *)
let camlp4bin_spec = ref false
diff --git a/lib/flags.mli b/lib/flags.mli
index ab06eda30..62fa3b016 100644
--- a/lib/flags.mli
+++ b/lib/flags.mli
@@ -57,7 +57,7 @@ val raw_print : bool ref
val record_print : bool ref
val univ_print : bool ref
-type compat_version = V8_2 | V8_3 | V8_4 | Current
+type compat_version = V8_2 | V8_3 | V8_4 | V8_5 | Current
val compat_version : compat_version ref
val version_strictly_greater : compat_version -> bool
val version_less_or_equal : compat_version -> bool
@@ -122,8 +122,8 @@ val coqlib_spec : bool ref
val coqlib : string ref
(** Options for specifying where OCaml binaries reside *)
-val camlbin_spec : bool ref
-val camlbin : string ref
+val ocamlfind_spec : bool ref
+val ocamlfind : string ref
val camlp4bin_spec : bool ref
val camlp4bin : string ref
diff --git a/lib/future.ml b/lib/future.ml
index 5cd2beba9..ff16286c4 100644
--- a/lib/future.ml
+++ b/lib/future.ml
@@ -7,8 +7,9 @@
(************************************************************************)
(* To deal with side effects we have to save/restore the system state *)
-let freeze = ref (fun () -> assert false : unit -> Dyn.t)
-let unfreeze = ref (fun _ -> () : Dyn.t -> unit)
+type freeze
+let freeze = ref (fun () -> assert false : unit -> freeze)
+let unfreeze = ref (fun _ -> () : freeze -> unit)
let set_freeze f g = freeze := f; unfreeze := g
let not_ready_msg = ref (fun name ->
@@ -58,7 +59,7 @@ type 'a assignement = [ `Val of 'a | `Exn of Exninfo.iexn | `Comp of 'a computat
and 'a comp =
| Delegated of (unit -> unit)
| Closure of (unit -> 'a)
- | Val of 'a * Dyn.t option
+ | Val of 'a * freeze option
| Exn of Exninfo.iexn (* Invariant: this exception is always "fixed" as in fix_exn *)
and 'a comput =
diff --git a/lib/future.mli b/lib/future.mli
index 58f0a71ad..114c59176 100644
--- a/lib/future.mli
+++ b/lib/future.mli
@@ -157,10 +157,11 @@ val transactify : ('a -> 'b) -> 'a -> 'b
(** Debug: print a computation given an inner printing function. *)
val print : ('a -> Pp.std_ppcmds) -> 'a computation -> Pp.std_ppcmds
+type freeze
(* These functions are needed to get rid of side effects.
Thy are set for the outermos layer of the system, since they have to
deal with the whole system state. *)
-val set_freeze : (unit -> Dyn.t) -> (Dyn.t -> unit) -> unit
+val set_freeze : (unit -> freeze) -> (freeze -> unit) -> unit
val customize_not_ready_msg : (string -> Pp.std_ppcmds) -> unit
val customize_not_here_msg : (string -> Pp.std_ppcmds) -> unit
diff --git a/lib/genarg.ml b/lib/genarg.ml
index cba54c114..c7273ac93 100644
--- a/lib/genarg.ml
+++ b/lib/genarg.ml
@@ -9,37 +9,61 @@
open Pp
open Util
+module ValT = Dyn.Make(struct end)
+module ArgT = Dyn.Make(struct end)
+
+module Val =
+struct
+
+ type 'a typ = 'a ValT.tag
+
+ type _ tag =
+ | Base : 'a typ -> 'a tag
+ | List : 'a tag -> 'a list tag
+ | Opt : 'a tag -> 'a option tag
+ | Pair : 'a tag * 'b tag -> ('a * 'b) tag
+
+ type t = Dyn : 'a tag * 'a -> t
+
+ let rec eq : type a b. a tag -> b tag -> (a, b) CSig.eq option =
+ fun t1 t2 -> match t1, t2 with
+ | Base t1, Base t2 -> ValT.eq t1 t2
+ | List t1, List t2 ->
+ begin match eq t1 t2 with
+ | None -> None
+ | Some Refl -> Some Refl
+ end
+ | Opt t1, Opt t2 ->
+ begin match eq t1 t2 with
+ | None -> None
+ | Some Refl -> Some Refl
+ end
+ | Pair (t1, u1), Pair (t2, u2) ->
+ begin match eq t1 t2 with
+ | None -> None
+ | Some Refl ->
+ match eq u1 u2 with
+ | None -> None
+ | Some Refl -> Some Refl
+ end
+ | _ -> None
+
+ let rec repr : type a. a tag -> std_ppcmds = function
+ | Base t -> str (ValT.repr t)
+ | List t -> repr t ++ spc () ++ str "list"
+ | Opt t -> repr t ++ spc () ++ str "option"
+ | Pair (t1, t2) -> str "(" ++ repr t1 ++ str " * " ++ repr t2 ++ str ")"
+
+end
+
type argument_type =
- (* Basic types *)
- | IntOrVarArgType
- | IdentArgType
- | VarArgType
(* Specific types *)
- | GenArgType
- | ConstrArgType
- | ConstrMayEvalArgType
- | QuantHypArgType
- | OpenConstrArgType
- | ConstrWithBindingsArgType
- | BindingsArgType
- | RedExprArgType
| ListArgType of argument_type
| OptArgType of argument_type
| PairArgType of argument_type * argument_type
| ExtraArgType of string
let rec argument_type_eq arg1 arg2 = match arg1, arg2 with
-| IntOrVarArgType, IntOrVarArgType -> true
-| IdentArgType, IdentArgType -> true
-| VarArgType, VarArgType -> true
-| GenArgType, GenArgType -> true
-| ConstrArgType, ConstrArgType -> true
-| ConstrMayEvalArgType, ConstrMayEvalArgType -> true
-| QuantHypArgType, QuantHypArgType -> true
-| OpenConstrArgType, OpenConstrArgType -> true
-| ConstrWithBindingsArgType, ConstrWithBindingsArgType -> true
-| BindingsArgType, BindingsArgType -> true
-| RedExprArgType, RedExprArgType -> true
| ListArgType arg1, ListArgType arg2 -> argument_type_eq arg1 arg2
| OptArgType arg1, OptArgType arg2 -> argument_type_eq arg1 arg2
| PairArgType (arg1l, arg1r), PairArgType (arg2l, arg2r) ->
@@ -48,17 +72,6 @@ let rec argument_type_eq arg1 arg2 = match arg1, arg2 with
| _ -> false
let rec pr_argument_type = function
-| IntOrVarArgType -> str "int_or_var"
-| IdentArgType -> str "ident"
-| VarArgType -> str "var"
-| GenArgType -> str "genarg"
-| ConstrArgType -> str "constr"
-| ConstrMayEvalArgType -> str "constr_may_eval"
-| QuantHypArgType -> str "qhyp"
-| OpenConstrArgType -> str "open_constr"
-| ConstrWithBindingsArgType -> str "constr_with_bindings"
-| BindingsArgType -> str "bindings"
-| RedExprArgType -> str "redexp"
| ListArgType t -> pr_argument_type t ++ spc () ++ str "list"
| OptArgType t -> pr_argument_type t ++ spc () ++ str "opt"
| PairArgType (t1, t2) ->
@@ -66,55 +79,129 @@ let rec pr_argument_type = function
str "*" ++ spc () ++ pr_argument_type t2 ++ str ")"
| ExtraArgType s -> str s
-type ('raw, 'glob, 'top) genarg_type = argument_type
+type (_, _, _) genarg_type =
+| ExtraArg : ('a * 'b * 'c) ArgT.tag -> ('a, 'b, 'c) genarg_type
+| ListArg : ('a, 'b, 'c) genarg_type -> ('a list, 'b list, 'c list) genarg_type
+| OptArg : ('a, 'b, 'c) genarg_type -> ('a option, 'b option, 'c option) genarg_type
+| PairArg : ('a1, 'b1, 'c1) genarg_type * ('a2, 'b2, 'c2) genarg_type ->
+ ('a1 * 'a2, 'b1 * 'b2, 'c1 * 'c2) genarg_type
+
+let rec genarg_type_eq : type a1 a2 b1 b2 c1 c2.
+ (a1, b1, c1) genarg_type -> (a2, b2, c2) genarg_type ->
+ (a1 * b1 * c1, a2 * b2 * c2) CSig.eq option =
+fun t1 t2 -> match t1, t2 with
+| ExtraArg t1, ExtraArg t2 -> ArgT.eq t1 t2
+| ListArg t1, ListArg t2 ->
+ begin match genarg_type_eq t1 t2 with
+ | None -> None
+ | Some Refl -> Some Refl
+ end
+| OptArg t1, OptArg t2 ->
+ begin match genarg_type_eq t1 t2 with
+ | None -> None
+ | Some Refl -> Some Refl
+ end
+| PairArg (t1, u1), PairArg (t2, u2) ->
+ begin match genarg_type_eq t1 t2 with
+ | None -> None
+ | Some Refl ->
+ match genarg_type_eq u1 u2 with
+ | None -> None
+ | Some Refl -> Some Refl
+ end
+| _ -> None
type 'a uniform_genarg_type = ('a, 'a, 'a) genarg_type
(** Alias for concision *)
(* Dynamics but tagged by a type expression *)
-type rlevel
-type glevel
-type tlevel
-
-type 'a generic_argument = argument_type * Obj.t
-type raw_generic_argument = rlevel generic_argument
-type glob_generic_argument = glevel generic_argument
-type typed_generic_argument = tlevel generic_argument
-
-let rawwit t = t
-let glbwit t = t
-let topwit t = t
+type rlevel = [ `rlevel ]
+type glevel = [ `glevel ]
+type tlevel = [ `tlevel ]
-let wit_list t = ListArgType t
+type _ level =
+| Rlevel : rlevel level
+| Glevel : glevel level
+| Tlevel : tlevel level
-let wit_opt t = OptArgType t
+type (_, _) abstract_argument_type =
+| Rawwit : ('a, 'b, 'c) genarg_type -> ('a, rlevel) abstract_argument_type
+| Glbwit : ('a, 'b, 'c) genarg_type -> ('b, glevel) abstract_argument_type
+| Topwit : ('a, 'b, 'c) genarg_type -> ('c, tlevel) abstract_argument_type
-let wit_pair t1 t2 = PairArgType (t1,t2)
+type 'l generic_argument = GenArg : ('a, 'l) abstract_argument_type * 'a -> 'l generic_argument
-let in_gen t o = (t,Obj.repr o)
-let out_gen t (t',o) = if argument_type_eq t t' then Obj.magic o else failwith "out_gen"
-let genarg_tag (s,_) = s
-
-let has_type (t, v) u = argument_type_eq t u
+type raw_generic_argument = rlevel generic_argument
+type glob_generic_argument = glevel generic_argument
+type typed_generic_argument = tlevel generic_argument
-let unquote x = x
+let rawwit t = Rawwit t
+let glbwit t = Glbwit t
+let topwit t = Topwit t
+
+let wit_list t = ListArg t
+
+let wit_opt t = OptArg t
+
+let wit_pair t1 t2 = PairArg (t1, t2)
+
+let in_gen t o = GenArg (t, o)
+
+let abstract_argument_type_eq :
+ type a b l. (a, l) abstract_argument_type -> (b, l) abstract_argument_type -> (a, b) CSig.eq option =
+ fun t1 t2 -> match t1, t2 with
+ | Rawwit t1, Rawwit t2 ->
+ begin match genarg_type_eq t1 t2 with
+ | None -> None
+ | Some Refl -> Some Refl
+ end
+ | Glbwit t1, Glbwit t2 ->
+ begin match genarg_type_eq t1 t2 with
+ | None -> None
+ | Some Refl -> Some Refl
+ end
+ | Topwit t1, Topwit t2 ->
+ begin match genarg_type_eq t1 t2 with
+ | None -> None
+ | Some Refl -> Some Refl
+ end
+
+let out_gen (type a) (type l) (t : (a, l) abstract_argument_type) (o : l generic_argument) : a =
+ let GenArg (t', v) = o in
+ match abstract_argument_type_eq t t' with
+ | None -> failwith "out_gen"
+ | Some Refl -> v
+
+let has_type (GenArg (t, v)) u = match abstract_argument_type_eq t u with
+| None -> false
+| Some _ -> true
+
+let rec untype : type a b c. (a, b, c) genarg_type -> argument_type = function
+| ExtraArg t -> ExtraArgType (ArgT.repr t)
+| ListArg t -> ListArgType (untype t)
+| OptArg t -> OptArgType (untype t)
+| PairArg (t1, t2) -> PairArgType (untype t1, untype t2)
+
+let unquote : type l. (_, l) abstract_argument_type -> _ = function
+| Rawwit t -> untype t
+| Glbwit t -> untype t
+| Topwit t -> untype t
+
+let genarg_tag (GenArg (t, _)) = unquote t
-type ('a,'b) abstract_argument_type = argument_type
type 'a raw_abstract_argument_type = ('a,rlevel) abstract_argument_type
type 'a glob_abstract_argument_type = ('a,glevel) abstract_argument_type
type 'a typed_abstract_argument_type = ('a,tlevel) abstract_argument_type
-type ('a, 'b, 'c, 'l) cast = Obj.t
-
-let raw = Obj.obj
-let glb = Obj.obj
-let top = Obj.obj
-
-type ('r, 'l) unpacker =
- { unpacker : 'a 'b 'c. ('a, 'b, 'c) genarg_type -> ('a, 'b, 'c, 'l) cast -> 'r }
+type ('a, 'b, 'c, 'l) cast =
+| Rcast : 'a -> ('a, 'b, 'c, rlevel) cast
+| Gcast : 'b -> ('a, 'b, 'c, glevel) cast
+| Tcast : 'c -> ('a, 'b, 'c, tlevel) cast
-let unpack pack (t, obj) = pack.unpacker t (Obj.obj obj)
+let raw : ('a, 'b, 'c, rlevel) cast -> _ = function Rcast x -> x
+let glb : ('a, 'b, 'c, glevel) cast -> _ = function Gcast x -> x
+let top : ('a, 'b, 'c, tlevel) cast -> _ = function Tcast x -> x
(** Type transformers *)
@@ -122,16 +209,20 @@ type ('r, 'l) list_unpacker =
{ list_unpacker : 'a 'b 'c. ('a, 'b, 'c) genarg_type ->
('a list, 'b list, 'c list, 'l) cast -> 'r }
-let list_unpack pack (t, obj) = match t with
-| ListArgType t -> pack.list_unpacker t (Obj.obj obj)
+let list_unpack (type l) (pack : (_, l) list_unpacker) (GenArg (t, obj) : l generic_argument) = match t with
+| Rawwit (ListArg t) -> pack.list_unpacker t (Rcast obj)
+| Glbwit (ListArg t) -> pack.list_unpacker t (Gcast obj)
+| Topwit (ListArg t) -> pack.list_unpacker t (Tcast obj)
| _ -> failwith "out_gen"
type ('r, 'l) opt_unpacker =
{ opt_unpacker : 'a 'b 'c. ('a, 'b, 'c) genarg_type ->
('a option, 'b option, 'c option, 'l) cast -> 'r }
-let opt_unpack pack (t, obj) = match t with
-| OptArgType t -> pack.opt_unpacker t (Obj.obj obj)
+let opt_unpack (type l) (pack : (_, l) opt_unpacker) (GenArg (t, obj) : l generic_argument) = match t with
+| Rawwit (OptArg t) -> pack.opt_unpacker t (Rcast obj)
+| Glbwit (OptArg t) -> pack.opt_unpacker t (Gcast obj)
+| Topwit (OptArg t) -> pack.opt_unpacker t (Tcast obj)
| _ -> failwith "out_gen"
type ('r, 'l) pair_unpacker =
@@ -139,37 +230,62 @@ type ('r, 'l) pair_unpacker =
('a1, 'b1, 'c1) genarg_type -> ('a2, 'b2, 'c2) genarg_type ->
(('a1 * 'a2), ('b1 * 'b2), ('c1 * 'c2), 'l) cast -> 'r }
-let pair_unpack pack (t, obj) = match t with
-| PairArgType (t1, t2) -> pack.pair_unpacker t1 t2 (Obj.obj obj)
+let pair_unpack (type l) (pack : (_, l) pair_unpacker) (GenArg (t, obj) : l generic_argument) = match t with
+| Rawwit (PairArg (t1, t2)) -> pack.pair_unpacker t1 t2 (Rcast obj)
+| Glbwit (PairArg (t1, t2)) -> pack.pair_unpacker t1 t2 (Gcast obj)
+| Topwit (PairArg (t1, t2)) -> pack.pair_unpacker t1 t2 (Tcast obj)
| _ -> failwith "out_gen"
(** Creating args *)
-let (arg0_map : Obj.t option String.Map.t ref) = ref String.Map.empty
+module type Param = sig type ('raw, 'glb, 'top) t end
+module ArgMap(M : Param) =
+struct
+ type _ pack = Pack : ('raw, 'glb, 'top) M.t -> ('raw * 'glb * 'top) pack
+ include ArgT.Map(struct type 'a t = 'a pack end)
+end
+
+type ('raw, 'glb, 'top) load = {
+ nil : 'raw option;
+ dyn : 'top Val.tag;
+}
+
+module LoadMap = ArgMap(struct type ('r, 'g, 't) t = ('r, 'g, 't) load end)
-let create_arg opt name =
- if String.Map.mem name !arg0_map then
+let arg0_map = ref LoadMap.empty
+
+let create_arg opt ?dyn name =
+ match ArgT.name name with
+ | Some _ ->
Errors.anomaly (str "generic argument already declared: " ++ str name)
- else
- let () = arg0_map := String.Map.add name (Obj.magic opt) !arg0_map in
- ExtraArgType name
+ | None ->
+ let dyn = match dyn with None -> Val.Base (ValT.create name) | Some dyn -> dyn in
+ let obj = LoadMap.Pack { nil = opt; dyn; } in
+ let name = ArgT.create name in
+ let () = arg0_map := LoadMap.add name obj !arg0_map in
+ ExtraArg name
let make0 = create_arg
-let default_empty_value t =
- let rec aux = function
- | ListArgType _ -> Some (Obj.repr [])
- | OptArgType _ -> Some (Obj.repr None)
- | PairArgType(t1, t2) ->
- (match aux t1, aux t2 with
- | Some v1, Some v2 -> Some (Obj.repr (v1, v2))
- | _ -> None)
- | ExtraArgType s ->
- String.Map.find s !arg0_map
- | _ -> None in
- match aux t with
- | Some v -> Some (Obj.obj v)
- | None -> None
+let rec default_empty_value : type a b c. (a, b, c) genarg_type -> a option = function
+| ListArg _ -> Some []
+| OptArg _ -> Some None
+| PairArg (t1, t2) ->
+ begin match default_empty_value t1, default_empty_value t2 with
+ | Some v1, Some v2 -> Some (v1, v2)
+ | _ -> None
+ end
+| ExtraArg s ->
+ match LoadMap.find s !arg0_map with LoadMap.Pack obj -> obj.nil
+
+let rec val_tag : type a b c. (a, b, c) genarg_type -> c Val.tag = function
+| ListArg t -> Val.List (val_tag t)
+| OptArg t -> Val.Opt (val_tag t)
+| PairArg (t1, t2) -> Val.Pair (val_tag t1, val_tag t2)
+| ExtraArg s ->
+ match LoadMap.find s !arg0_map with LoadMap.Pack obj -> obj.dyn
+
+let val_tag = function Topwit t -> val_tag t
(** Registering genarg-manipulating functions *)
@@ -182,30 +298,31 @@ end
module Register (M : GenObj) =
struct
- let arg0_map =
- ref (String.Map.empty : (Obj.t, Obj.t, Obj.t) M.obj String.Map.t)
+ module GenMap = ArgMap(struct type ('r, 'g, 't) t = ('r, 'g, 't) M.obj end)
+ let arg0_map = ref GenMap.empty
let register0 arg f = match arg with
- | ExtraArgType s ->
- if String.Map.mem s !arg0_map then
- let msg = str M.name ++ str " function already registered: " ++ str s in
+ | ExtraArg s ->
+ if GenMap.mem s !arg0_map then
+ let msg = str M.name ++ str " function already registered: " ++ str (ArgT.repr s) in
Errors.anomaly msg
else
- arg0_map := String.Map.add s (Obj.magic f) !arg0_map
+ arg0_map := GenMap.add s (GenMap.Pack f) !arg0_map
| _ -> assert false
let get_obj0 name =
- try String.Map.find name !arg0_map
+ try
+ let GenMap.Pack obj = GenMap.find name !arg0_map in obj
with Not_found ->
- match M.default (ExtraArgType name) with
+ match M.default (ExtraArg name) with
| None ->
- Errors.anomaly (str M.name ++ str " function not found: " ++ str name)
+ Errors.anomaly (str M.name ++ str " function not found: " ++ str (ArgT.repr name))
| Some obj -> obj
(** For now, the following function is quite dummy and should only be applied
to an extra argument type, otherwise, it will badly fail. *)
let obj t = match t with
- | ExtraArgType s -> Obj.magic (get_obj0 s)
+ | ExtraArg s -> get_obj0 s
| _ -> assert false
end
@@ -213,23 +330,13 @@ end
(** Hackish part *)
let arg0_names = ref (String.Map.empty : string String.Map.t)
-(** We use this table to associate a name to a given witness, to use it with
- the extension mechanism. This is REALLY ad-hoc, but I do not know how to
- do so nicely either. *)
-
+
let register_name0 t name = match t with
-| ExtraArgType s ->
+| ExtraArg s ->
+ let s = ArgT.repr s in
let () = assert (not (String.Map.mem s !arg0_names)) in
arg0_names := String.Map.add s name !arg0_names
| _ -> failwith "register_name0"
let get_name0 name =
String.Map.find name !arg0_names
-
-module Unsafe =
-struct
-
-let inj tpe x = (tpe, x)
-let prj (_, x) = x
-
-end
diff --git a/lib/genarg.mli b/lib/genarg.mli
index 671d96b7b..ce0536cf4 100644
--- a/lib/genarg.mli
+++ b/lib/genarg.mli
@@ -68,18 +68,53 @@ ExtraArgType of string '_a '_b
(** {5 Generic types} *)
-type ('raw, 'glob, 'top) genarg_type
+module ArgT :
+sig
+ type 'a tag
+ val eq : 'a tag -> 'b tag -> ('a, 'b) CSig.eq option
+ val repr : 'a tag -> string
+ type any = Any : 'a tag -> any
+ val name : string -> any option
+end
+
+type (_, _, _) genarg_type =
+| ExtraArg : ('a * 'b * 'c) ArgT.tag -> ('a, 'b, 'c) genarg_type
+| ListArg : ('a, 'b, 'c) genarg_type -> ('a list, 'b list, 'c list) genarg_type
+| OptArg : ('a, 'b, 'c) genarg_type -> ('a option, 'b option, 'c option) genarg_type
+| PairArg : ('a1, 'b1, 'c1) genarg_type * ('a2, 'b2, 'c2) genarg_type ->
+ ('a1 * 'a2, 'b1 * 'b2, 'c1 * 'c2) genarg_type
(** Generic types. ['raw] is the OCaml lowest level, ['glob] is the globalized
one, and ['top] the internalized one. *)
+module Val :
+sig
+ type 'a typ
+
+ type _ tag =
+ | Base : 'a typ -> 'a tag
+ | List : 'a tag -> 'a list tag
+ | Opt : 'a tag -> 'a option tag
+ | Pair : 'a tag * 'b tag -> ('a * 'b) tag
+
+ type t = Dyn : 'a tag * 'a -> t
+
+ val eq : 'a tag -> 'b tag -> ('a, 'b) CSig.eq option
+ val repr: 'a tag -> Pp.std_ppcmds
+
+end
+(** Dynamic types for toplevel values. While the generic types permit to relate
+ objects at various levels of interpretation, toplevel values are wearing
+ their own type regardless of where they came from. This allows to use the
+ same runtime representation for several generic types. *)
+
type 'a uniform_genarg_type = ('a, 'a, 'a) genarg_type
(** Alias for concision when the three types agree. *)
-val make0 : 'raw option -> string -> ('raw, 'glob, 'top) genarg_type
+val make0 : 'raw option -> ?dyn:'top Val.tag -> string -> ('raw, 'glob, 'top) genarg_type
(** Create a new generic type of argument: force to associate
unique ML types at each of the three levels. *)
-val create_arg : 'raw option -> string -> ('raw, 'glob, 'top) genarg_type
+val create_arg : 'raw option -> ?dyn:'top Val.tag -> string -> ('raw, 'glob, 'top) genarg_type
(** Alias for [make0]. *)
(** {5 Specialized types} *)
@@ -91,11 +126,14 @@ val create_arg : 'raw option -> string -> ('raw, 'glob, 'top) genarg_type
out_gen is monomorphic over 'a, hence type-safe
*)
-type rlevel
-type glevel
-type tlevel
+type rlevel = [ `rlevel ]
+type glevel = [ `glevel ]
+type tlevel = [ `tlevel ]
-type ('a, 'co) abstract_argument_type
+type (_, _) abstract_argument_type =
+| Rawwit : ('a, 'b, 'c) genarg_type -> ('a, rlevel) abstract_argument_type
+| Glbwit : ('a, 'b, 'c) genarg_type -> ('b, glevel) abstract_argument_type
+| Topwit : ('a, 'b, 'c) genarg_type -> ('c, tlevel) abstract_argument_type
(** Type at level ['co] represented by an OCaml value of type ['a]. *)
type 'a raw_abstract_argument_type = ('a, rlevel) abstract_argument_type
@@ -120,7 +158,7 @@ val topwit : ('a, 'b, 'c) genarg_type -> ('c, tlevel) abstract_argument_type
(** {5 Generic arguments} *)
-type 'a generic_argument
+type 'l generic_argument = GenArg : ('a, 'l) abstract_argument_type * 'a -> 'l generic_argument
(** A inhabitant of ['level generic_argument] is a inhabitant of some type at
level ['level], together with the representation of this type. *)
@@ -141,66 +179,31 @@ val has_type : 'co generic_argument -> ('a, 'co) abstract_argument_type -> bool
(** [has_type v t] tells whether [v] has type [t]. If true, it ensures that
[out_gen t v] will not raise a dynamic type exception. *)
-(** {6 Destructors} *)
-
-type ('a, 'b, 'c, 'l) cast
-
-val raw : ('a, 'b, 'c, rlevel) cast -> 'a
-val glb : ('a, 'b, 'c, glevel) cast -> 'b
-val top : ('a, 'b, 'c, tlevel) cast -> 'c
-
-type ('r, 'l) unpacker =
- { unpacker : 'a 'b 'c. ('a, 'b, 'c) genarg_type -> ('a, 'b, 'c, 'l) cast -> 'r }
-
-val unpack : ('r, 'l) unpacker -> 'l generic_argument -> 'r
-(** Existential-type destructors. *)
-
-(** {6 Manipulation of generic arguments}
+(** {6 Dynamic toplevel values} *)
-Those functions fail if they are applied to an argument which has not the right
-dynamic type. *)
-
-type ('r, 'l) list_unpacker =
- { list_unpacker : 'a 'b 'c. ('a, 'b, 'c) genarg_type ->
- ('a list, 'b list, 'c list, 'l) cast -> 'r }
-
-val list_unpack : ('r, 'l) list_unpacker -> 'l generic_argument -> 'r
-
-type ('r, 'l) opt_unpacker =
- { opt_unpacker : 'a 'b 'c. ('a, 'b, 'c) genarg_type ->
- ('a option, 'b option, 'c option, 'l) cast -> 'r }
-
-val opt_unpack : ('r, 'l) opt_unpacker -> 'l generic_argument -> 'r
-
-type ('r, 'l) pair_unpacker =
- { pair_unpacker : 'a1 'a2 'b1 'b2 'c1 'c2.
- ('a1, 'b1, 'c1) genarg_type -> ('a2, 'b2, 'c2) genarg_type ->
- (('a1 * 'a2), ('b1 * 'b2), ('c1 * 'c2), 'l) cast -> 'r }
-
-val pair_unpack : ('r, 'l) pair_unpacker -> 'l generic_argument -> 'r
+val val_tag : 'a typed_abstract_argument_type -> 'a Val.tag
+(** Retrieve the dynamic type associated to a toplevel genarg. Only works for
+ ground generic arguments. *)
(** {6 Type reification} *)
type argument_type =
- (** Basic types *)
- | IntOrVarArgType
- | IdentArgType
- | VarArgType
(** Specific types *)
- | GenArgType
- | ConstrArgType
- | ConstrMayEvalArgType
- | QuantHypArgType
- | OpenConstrArgType
- | ConstrWithBindingsArgType
- | BindingsArgType
- | RedExprArgType
| ListArgType of argument_type
| OptArgType of argument_type
| PairArgType of argument_type * argument_type
| ExtraArgType of string
+(** {6 Equalities} *)
+
val argument_type_eq : argument_type -> argument_type -> bool
+val genarg_type_eq :
+ ('a1, 'b1, 'c1) genarg_type ->
+ ('a2, 'b2, 'c2) genarg_type ->
+ ('a1 * 'b1 * 'c1, 'a2 * 'b2 * 'c2) CSig.eq option
+val abstract_argument_type_eq :
+ ('a, 'l) abstract_argument_type -> ('b, 'l) abstract_argument_type ->
+ ('a, 'b) CSig.eq option
val pr_argument_type : argument_type -> Pp.std_ppcmds
(** Print a human-readable representation for a given type. *)
@@ -256,23 +259,3 @@ val register_name0 : ('a, 'b, 'c) genarg_type -> string -> unit
val get_name0 : string -> string
(** Return the absolute path of a given witness. *)
-
-(** {5 Unsafe loophole} *)
-
-module Unsafe :
-sig
-
-(** Unsafe magic functions. Not for kids. This is provided here as a loophole to
- escape this module. Do NOT use outside of the dedicated areas. NOT. EVER. *)
-
-val inj : argument_type -> Obj.t -> 'lev generic_argument
-(** Injects an object as generic argument. !!!BEWARE!!! only do this as
- [inj tpe x] where:
-
- 1. [tpe] is the reification of a [('a, 'b, 'c) genarg_type];
- 2. [x] has type ['a], ['b] or ['c] according to the return level ['lev]. *)
-
-val prj : 'lev generic_argument -> Obj.t
-(** Recover the contents of a generic argument. *)
-
-end
diff --git a/lib/hMap.ml b/lib/hMap.ml
index ba6aad913..220adc28f 100644
--- a/lib/hMap.ml
+++ b/lib/hMap.ml
@@ -329,4 +329,17 @@ struct
Int.Map.map fs s
end
+ module Monad(M : CMap.MonadS) =
+ struct
+ module IntM = Int.Map.Monad(M)
+ module ExtM = Map.Monad(M)
+
+ let fold f s accu =
+ let ff _ m accu = ExtM.fold f m accu in
+ IntM.fold ff s accu
+
+ let fold_left _ _ _ = assert false
+ let fold_right _ _ _ = assert false
+ end
+
end
diff --git a/lib/hashcons.ml b/lib/hashcons.ml
index 144d95130..b5192dbb8 100644
--- a/lib/hashcons.ml
+++ b/lib/hashcons.ml
@@ -72,7 +72,7 @@ module Make (X : HashconsedType) : (S with type t = X.t and type u = X.u) =
end
-(* A few usefull wrappers:
+(* A few useful wrappers:
* takes as argument the function [generate] above and build a function of type
* u -> t -> t that creates a fresh table each time it is applied to the
* sub-hcons functions. *)
@@ -96,20 +96,6 @@ let recursive_hcons h f u =
let () = loop := hrec in
hrec
-(* A set of global hashcons functions *)
-let hashcons_resets = ref []
-let init() = List.iter (fun f -> f()) !hashcons_resets
-
-(* [register_hcons h u] registers the hcons function h, result of the above
- * wrappers. It returns another hcons function that always uses the same
- * table, which can be reinitialized by init()
- *)
-let register_hcons h u =
- let hf = ref (h u) in
- let reset() = hf := h u in
- hashcons_resets := reset :: !hashcons_resets;
- (fun x -> !hf x)
-
(* Basic hashcons modules for string and obj. Integers do not need be
hashconsed. *)
@@ -194,18 +180,3 @@ module Hobj = Make(
let equal = comp_obj
let hash = Hashtbl.hash
end)
-
-(* Hashconsing functions for string and obj. Always use the same
- * global tables. The latter can be reinitialized with init()
- *)
-(* string : string -> string *)
-(* obj : Obj.t -> Obj.t *)
-let string = register_hcons (simple_hcons Hstring.generate Hstring.hcons) ()
-let obj = register_hcons (recursive_hcons Hobj.generate Hobj.hcons) ()
-
-(* The unsafe polymorphic hashconsing function *)
-let magic_hash (c : 'a) =
- init();
- let r = obj (Obj.repr c) in
- init();
- (Obj.magic r : 'a)
diff --git a/lib/hashset.ml b/lib/hashset.ml
index 6fb78f9a4..b2795c6b1 100644
--- a/lib/hashset.ml
+++ b/lib/hashset.ml
@@ -162,7 +162,7 @@ module Make (E : EqType) =
t.hashes.(index) <- newhashes;
if sz <= t.limit && newsz > t.limit then begin
t.oversize <- t.oversize + 1;
- for i = 0 to over_limit do test_shrink_bucket t done;
+ for _i = 0 to over_limit do test_shrink_bucket t done;
end;
if t.oversize > Array.length t.table / over_limit then resize t
end else if Weak.check bucket i then begin
diff --git a/lib/heap.ml b/lib/heap.ml
index 187189fca..97ccadeba 100644
--- a/lib/heap.ml
+++ b/lib/heap.ml
@@ -62,8 +62,6 @@ module Functional(X : Ordered) = struct
let empty = Leaf
- let is_empty t = t = Leaf
-
let rec add x = function
| Leaf ->
Node (Leaf, x, Leaf)
diff --git a/lib/lib.mllib b/lib/lib.mllib
index f3f6ad8fc..a9181c51c 100644
--- a/lib/lib.mllib
+++ b/lib/lib.mllib
@@ -1,6 +1,5 @@
Errors
Bigint
-Dyn
Segmenttree
Unicodetable
Unicode
diff --git a/lib/option.ml b/lib/option.ml
index 4ea613e4f..fbb883d30 100644
--- a/lib/option.ml
+++ b/lib/option.ml
@@ -41,8 +41,8 @@ let hash f = function
exception IsNone
-(** [get x] returns [y] where [x] is [Some y]. It raises IsNone
- if [x] equals [None]. *)
+(** [get x] returns [y] where [x] is [Some y].
+ @raise [IsNone] if [x] equals [None]. *)
let get = function
| Some y -> y
| _ -> raise IsNone
diff --git a/lib/option.mli b/lib/option.mli
index 409dff9d3..5e085620e 100644
--- a/lib/option.mli
+++ b/lib/option.mli
@@ -34,8 +34,8 @@ val compare : ('a -> 'a -> int) -> 'a option -> 'a option -> int
(** Lift a hash to option types. *)
val hash : ('a -> int) -> 'a option -> int
-(** [get x] returns [y] where [x] is [Some y]. It raises IsNone
- if [x] equals [None]. *)
+(** [get x] returns [y] where [x] is [Some y].
+ @raise IsNone if [x] equals [None]. *)
val get : 'a option -> 'a
(** [make x] returns [Some x]. *)
@@ -54,7 +54,7 @@ val flatten : 'a option option -> 'a option
val append : 'a option -> 'a option -> 'a option
-(** {6 "Iterators"} ***)
+(** {6 "Iterators"} *)
(** [iter f x] executes [f y] if [x] equals [Some y]. It does nothing
otherwise. *)
@@ -63,8 +63,8 @@ val iter : ('a -> unit) -> 'a option -> unit
exception Heterogeneous
(** [iter2 f x y] executes [f z w] if [x] equals [Some z] and [y] equals
- [Some w]. It does nothing if both [x] and [y] are [None]. And raises
- [Heterogeneous] otherwise. *)
+ [Some w]. It does nothing if both [x] and [y] are [None].
+ @raise Heterogeneous otherwise. *)
val iter2 : ('a -> 'b -> unit) -> 'a option -> 'b option -> unit
(** [map f x] is [None] if [x] is [None] and [Some (f y)] if [x] is [Some y]. *)
@@ -78,8 +78,8 @@ val smartmap : ('a -> 'a) -> 'a option -> 'a option
val fold_left : ('b -> 'a -> 'b) -> 'b -> 'a option -> 'b
(** [fold_left2 f a x y] is [f z w] if [x] is [Some z] and [y] is [Some w].
- It is [a] if both [x] and [y] are [None]. Otherwise it raises
- [Heterogeneous]. *)
+ It is [a] if both [x] and [y] are [None].
+ @raise Heterogeneous otherwise. *)
val fold_left2 : ('a -> 'b -> 'c -> 'a) -> 'a -> 'b option -> 'c option -> 'a
(** [fold_right f x a] is [f y a] if [x] is [Some y], and [a] otherwise. *)
@@ -91,7 +91,7 @@ val fold_map : ('a -> 'b -> 'a * 'c) -> 'a -> 'b option -> 'a * 'c option
(** [cata f e x] is [e] if [x] is [None] and [f a] if [x] is [Some a] *)
val cata : ('a -> 'b) -> 'b -> 'a option -> 'b
-(** {6 More Specific Operations} ***)
+(** {6 More Specific Operations} *)
(** [default a x] is [y] if [x] is [Some y] and [a] otherwise. *)
val default : 'a -> 'a option -> 'a
diff --git a/lib/pp.ml b/lib/pp.ml
index 4f50e3e19..0260f98fa 100644
--- a/lib/pp.ml
+++ b/lib/pp.ml
@@ -51,25 +51,18 @@ sig
val prj : t -> 'a key -> 'a option
end =
struct
- (** See module {Dyn} for more details. *)
- type t = int * Obj.t
+module Dyn = Dyn.Make(struct end)
- type 'a key = int
-
- let dyntab = ref (Int.Map.empty : string Int.Map.t)
-
- let create (s : string) =
- let hash = Hashtbl.hash s in
- let () = assert (not (Int.Map.mem hash !dyntab)) in
- let () = dyntab := Int.Map.add hash s !dyntab in
- hash
-
- let inj x h = (h, Obj.repr x)
-
- let prj (nh, rv) h =
- if Int.equal h nh then Some (Obj.magic rv)
- else None
+type t = Dyn.t
+type 'a key = 'a Dyn.tag
+let create = Dyn.create
+let inj x k = Dyn.Dyn (k, x)
+let prj : type a. t -> a key -> a option = fun dyn k ->
+ let Dyn.Dyn (k', x) = dyn in
+ match Dyn.eq k k' with
+ | None -> None
+ | Some CSig.Refl -> Some x
end
@@ -412,7 +405,7 @@ type message_level = Feedback.message_level =
type message = Feedback.message = {
message_level : message_level;
- message_content : string;
+ message_content : Xml_datatype.xml;
}
let of_message = Feedback.of_message
@@ -511,11 +504,11 @@ let string_of_ppcmds c =
msg_with Format.str_formatter c;
Format.flush_str_formatter ()
-let log_via_feedback () = logger := (fun ~id lvl msg ->
+let log_via_feedback printer = logger := (fun ~id lvl msg ->
!feeder {
Feedback.contents = Feedback.Message {
message_level = lvl;
- message_content = string_of_ppcmds msg };
+ message_content = printer msg };
Feedback.route = !feedback_route;
Feedback.id = id })
diff --git a/lib/pp.mli b/lib/pp.mli
index 2508779e8..015151bc9 100644
--- a/lib/pp.mli
+++ b/lib/pp.mli
@@ -116,7 +116,7 @@ type message_level = Feedback.message_level =
type message = Feedback.message = {
message_level : message_level;
- message_content : string;
+ message_content : Xml_datatype.xml;
}
type logger = message_level -> std_ppcmds -> unit
@@ -154,7 +154,7 @@ val std_logger : logger
val set_logger : logger -> unit
-val log_via_feedback : unit -> unit
+val log_via_feedback : (std_ppcmds -> Xml_datatype.xml) -> unit
val of_message : message -> Xml_datatype.xml
val to_message : Xml_datatype.xml -> message
diff --git a/lib/richpp.ml b/lib/richpp.ml
index 453df43de..fe3edd99c 100644
--- a/lib/richpp.ml
+++ b/lib/richpp.ml
@@ -163,4 +163,38 @@ let xml_of_rich_pp tag_of_annotation attributes_of_annotation xml =
in
node xml
+type richpp = xml
+let repr xml = xml
+let richpp_of_xml xml = xml
+let richpp_of_string s = PCData s
+
+let richpp_of_pp pp =
+ let annotate t = match Pp.Tag.prj t Ppstyle.tag with
+ | None -> None
+ | Some key -> Some (Ppstyle.repr key)
+ in
+ let rec drop = function
+ | PCData s -> [PCData s]
+ | Element (_, annotation, cs) ->
+ let cs = List.concat (List.map drop cs) in
+ match annotation.annotation with
+ | None -> cs
+ | Some s -> [Element (String.concat "." s, [], cs)]
+ in
+ let xml = rich_pp annotate pp in
+ Element ("_", [], drop xml)
+
+let raw_print xml =
+ let buf = Buffer.create 1024 in
+ let rec print = function
+ | PCData s -> Buffer.add_string buf s
+ | Element (_, _, cs) -> List.iter print cs
+ in
+ let () = print xml in
+ Buffer.contents buf
+
+let of_richpp x = Element ("richpp", [], [x])
+let to_richpp xml = match xml with
+| Element ("richpp", [], [x]) -> x
+| _ -> raise Serialize.Marshal_error
diff --git a/lib/richpp.mli b/lib/richpp.mli
index 05c16621b..807d52aba 100644
--- a/lib/richpp.mli
+++ b/lib/richpp.mli
@@ -39,3 +39,29 @@ val xml_of_rich_pp :
('annotation -> (string * string) list) ->
'annotation located Xml_datatype.gxml ->
Xml_datatype.xml
+
+(** {5 Enriched text} *)
+
+type richpp
+(** Type of text with style annotations *)
+
+val richpp_of_pp : Pp.std_ppcmds -> richpp
+(** Extract style information from formatted text *)
+
+val richpp_of_xml : Xml_datatype.xml -> richpp
+(** Do not use outside of dedicated areas *)
+
+val richpp_of_string : string -> richpp
+(** Make a styled text out of a normal string *)
+
+val repr : richpp -> Xml_datatype.xml
+(** Observe the styled text as XML *)
+
+(** {5 Serialization} *)
+
+val of_richpp : richpp -> Xml_datatype.xml
+val to_richpp : Xml_datatype.xml -> richpp
+
+(** Represent the semi-structured document as a string, dropping any additional
+ information. *)
+val raw_print : richpp -> string
diff --git a/lib/serialize.ml b/lib/serialize.ml
index 79a79dd4e..685ec6049 100644
--- a/lib/serialize.ml
+++ b/lib/serialize.ml
@@ -114,3 +114,7 @@ let to_loc xml =
with Not_found | Invalid_argument _ -> raise Marshal_error)
| _ -> raise Marshal_error
+let of_xml x = Element ("xml", [], [x])
+let to_xml xml = match xml with
+| Element ("xml", [], [x]) -> x
+| _ -> raise Marshal_error
diff --git a/lib/serialize.mli b/lib/serialize.mli
index 2a8e53163..d7c14e7e7 100644
--- a/lib/serialize.mli
+++ b/lib/serialize.mli
@@ -35,3 +35,5 @@ val of_edit_id: int -> xml
val to_edit_id: xml -> int
val of_loc : Loc.t -> xml
val to_loc : xml -> Loc.t
+val of_xml : xml -> xml
+val to_xml : xml -> xml
diff --git a/lib/system.ml b/lib/system.ml
index 9bdcecef1..779e30816 100644
--- a/lib/system.ml
+++ b/lib/system.ml
@@ -12,35 +12,83 @@ open Pp
open Errors
open Util
-(* All subdirectories, recursively *)
+(** Dealing with directories *)
-let exists_dir dir =
- try Sys.is_directory dir with Sys_error _ -> false
+type unix_path = string (* path in unix-style, with '/' separator *)
+
+type file_kind =
+ | FileDir of unix_path * (* basename of path: *) string
+ | FileRegular of string (* basename of file *)
+
+(* Copy of Filename.concat but assuming paths to always be POSIX *)
+
+let (//) dirname filename =
+ let l = String.length dirname in
+ if l = 0 || dirname.[l-1] = '/'
+ then dirname ^ filename
+ else dirname ^ "/" ^ filename
+
+(* Excluding directories; We avoid directories starting with . as well
+ as CVS and _darcs and any subdirs given via -exclude-dir *)
let skipped_dirnames = ref ["CVS"; "_darcs"]
-let exclude_search_in_dirname f = skipped_dirnames := f :: !skipped_dirnames
+let exclude_directory f = skipped_dirnames := f :: !skipped_dirnames
let ok_dirname f =
- not (String.is_empty f) && f.[0] != '.' &&
- not (String.List.mem f !skipped_dirnames) &&
- (match Unicode.ident_refutation f with None -> true | _ -> false)
+ not (f = "") && f.[0] != '.' &&
+ not (List.mem f !skipped_dirnames) (*&&
+ (match Unicode.ident_refutation f with None -> true | _ -> false)*)
+
+(* Check directory can be opened *)
+
+let exists_dir dir =
+ try Sys.is_directory dir with Sys_error _ -> false
+
+let check_unix_dir warn dir =
+ if (Sys.os_type = "Win32" || Sys.os_type = "Cygwin") &&
+ (String.length dir > 2 && dir.[1] = ':' ||
+ String.contains dir '\\' ||
+ String.contains dir ';')
+ then warn ("assuming " ^ dir ^
+ " to be a Unix path even if looking like a Win32 path.")
+
+let apply_subdir f path name =
+ (* we avoid all files and subdirs starting by '.' (e.g. .svn) *)
+ (* as well as skipped files like CVS, ... *)
+ if ok_dirname name then
+ let path = if path = "." then name else path//name in
+ match try (Unix.stat path).Unix.st_kind with Unix.Unix_error _ -> Unix.S_BLK with
+ | Unix.S_DIR -> f (FileDir (path,name))
+ | Unix.S_REG -> f (FileRegular name)
+ | _ -> ()
+
+let process_directory f path =
+ Array.iter (apply_subdir f path) (Sys.readdir path)
+
+let process_subdirectories f path =
+ let f = function FileDir (path,base) -> f path base | FileRegular _ -> () in
+ process_directory f path
+
+(** Returns the list of all recursive subdirectories of [root] in
+ depth-first search, with sons ordered as on the file system;
+ warns if [root] does not exist *)
let all_subdirs ~unix_path:root =
let l = ref [] in
let add f rel = l := (f, rel) :: !l in
- let rec traverse dir rel =
- Array.iter (fun f ->
- if ok_dirname f then
- let file = Filename.concat dir f in
- if Sys.is_directory file then begin
- let newrel = rel @ [f] in
- add file newrel;
- traverse file newrel
- end)
- (Sys.readdir dir)
+ let rec traverse path rel =
+ let f = function
+ | FileDir (path,f) ->
+ let newrel = rel @ [f] in
+ add path newrel;
+ traverse path newrel
+ | _ -> ()
+ in process_directory f path
in
- if exists_dir root then traverse root [];
+ check_unix_dir (fun s -> msg_warning (str s)) root;
+ if exists_dir root then traverse root []
+ else msg_warning (str ("Cannot open " ^ root));
List.rev !l
(* Caching directory contents for efficient syntactic equality of file
@@ -61,20 +109,22 @@ let make_dir_table dir =
Array.fold_left filter_dotfiles StrSet.empty (Sys.readdir dir)
let exists_in_dir_respecting_case dir bf =
- let contents, cached =
- try StrMap.find dir !dirmap, true with Not_found ->
+ let cache_dir dir =
let contents = make_dir_table dir in
dirmap := StrMap.add dir contents !dirmap;
- contents, false in
+ contents in
+ let contents, fresh =
+ try
+ (* in batch mode, assume the directory content is still fresh *)
+ StrMap.find dir !dirmap, !Flags.batch_mode
+ with Not_found ->
+ (* in batch mode, we are not yet sure the directory exists *)
+ if !Flags.batch_mode && not (exists_dir dir) then StrSet.empty, true
+ else cache_dir dir, true in
StrSet.mem bf contents ||
- if cached then begin
+ not fresh &&
(* rescan, there is a new file we don't know about *)
- let contents = make_dir_table dir in
- dirmap := StrMap.add dir contents !dirmap;
- StrSet.mem bf contents
- end
- else
- false
+ StrSet.mem bf (cache_dir dir)
let file_exists_respecting_case path f =
(* This function ensures that a file with expected lowercase/uppercase
@@ -84,7 +134,7 @@ let file_exists_respecting_case path f =
let df = Filename.dirname f in
(String.equal df "." || aux df)
&& exists_in_dir_respecting_case (Filename.concat path df) bf
- in Sys.file_exists (Filename.concat path f) && aux f
+ in (!Flags.batch_mode || Sys.file_exists (Filename.concat path f)) && aux f
let rec search paths test =
match paths with
diff --git a/lib/system.mli b/lib/system.mli
index 062c8ea85..e1190dfb5 100644
--- a/lib/system.mli
+++ b/lib/system.mli
@@ -8,14 +8,46 @@
(** {5 Coqtop specific system utilities} *)
+(** {6 Directories} *)
+
+type unix_path = string (* path in unix-style, with '/' separator *)
+
+type file_kind =
+ | FileDir of unix_path * (* basename of path: *) string
+ | FileRegular of string (* basename of file *)
+
+val (//) : unix_path -> string -> unix_path
+
+val exists_dir : unix_path -> bool
+
+(** [check_unix_dir warn path] calls [warn] with an appropriate
+ message if [path] looks does not look like a Unix path on Windows *)
+
+val check_unix_dir : (string -> unit) -> unix_path -> unit
+
+(** [exclude_search_in_dirname path] excludes [path] when processing
+ directories *)
+
+val exclude_directory : unix_path -> unit
+
+(** [process_directory f path] applies [f] on contents of directory
+ [path]; fails with Unix_error if the latter does not exists; skips
+ all files or dirs starting with "." *)
+
+val process_directory : (file_kind -> unit) -> unix_path -> unit
+
+(** [process_subdirectories f path] applies [f path/file file] on each
+ [file] of the directory [path]; fails with Unix_error if the
+ latter does not exists; kips all files or dirs starting with "." *)
+
+val process_subdirectories : (unix_path -> string -> unit) -> unix_path -> unit
+
(** {6 Files and load paths} *)
(** Load path entries remember the original root
given by the user. For efficiency, we keep the full path (field
[directory]), the root path and the path relative to the root. *)
-val exclude_search_in_dirname : string -> unit
-
val all_subdirs : unix_path:string -> (CUnix.physical_path * string list) list
val is_in_path : CUnix.load_path -> string -> bool
val is_in_system_path : string -> bool
@@ -24,8 +56,6 @@ val where_in_path :
val where_in_path_rex :
CUnix.load_path -> Str.regexp -> (CUnix.physical_path * string) list
-val exists_dir : string -> bool
-
val find_file_in_path :
?warn:bool -> CUnix.load_path -> string -> CUnix.physical_path * string
diff --git a/lib/unicode.ml b/lib/unicode.ml
index 1765e93dc..05998bb80 100644
--- a/lib/unicode.ml
+++ b/lib/unicode.ml
@@ -18,7 +18,7 @@ exception Unsupported
to simplify the masking process. (This choice seems to be a good
trade-off between speed and space after some benchmarks.) *)
-(* A 256ko table, initially filled with zeros. *)
+(* A 256 KiB table, initially filled with zeros. *)
let table = Array.make (1 lsl 17) 0
(* Associate a 2-bit pattern to each status at position [i].
@@ -147,6 +147,11 @@ let utf8_of_unicode n =
s
end
+(* If [s] is some UTF-8 encoded string
+ and [i] is a position of some UTF-8 character within [s]
+ then [next_utf8 s i] returns [(j,n)] where:
+ - [j] indicates the position of the next UTF-8 character
+ - [n] represents the UTF-8 character at index [i] *)
let next_utf8 s i =
let err () = invalid_arg "utf8" in
let l = String.length s - i in
diff --git a/lib/unicode.mli b/lib/unicode.mli
index 520203d43..72d1f2950 100644
--- a/lib/unicode.mli
+++ b/lib/unicode.mli
@@ -10,19 +10,29 @@
type status = Letter | IdentPart | Symbol
+(** This exception is raised when UTF-8 the input string contains unsupported UTF-8 characters. *)
exception Unsupported
-(** Classify a unicode char into 3 classes, or raise [Unsupported] *)
+(** Classify a unicode char into 3 classes.
+ @raise Unsupported if the input string contains unsupported UTF-8 characters. *)
val classify : int -> status
-(** Check whether a given string be used as a legal identifier.
- - [None] means yes
- - [Some (b,s)] means no, with explanation [s] and severity [b] *)
+(** Return [None] if a given string can be used as a (Coq) identifier.
+ Return [Some (b,s)] otherwise, where [s] is an explanation and [b] is severity.
+ @raise Unsupported if the input string contains unsupported UTF-8 characters. *)
val ident_refutation : string -> (bool * string) option
-(** First char of a string, converted to lowercase *)
+(** First char of a string, converted to lowercase
+ @raise Unsupported if the input string contains unsupported UTF-8 characters.
+ @raise Assert_failure if the input string is empty. *)
val lowercase_first_char : string -> string
-(** For extraction, turn a unicode string into an ascii-only one *)
+(** Return [true] if all UTF-8 characters in the input string are just plain ASCII characters.
+ Returns [false] otherwise. *)
val is_basic_ascii : string -> bool
+
+(** [ascii_of_ident s] maps UTF-8 string to a string composed solely from ASCII characters.
+ Those UTF-8 characters which do not have their ASCII counterparts are
+ translated to ["__Uxxxx_"] where {i xxxx} are four hexadecimal digits.
+ @raise Unsupported if the input string contains unsupported UTF-8 characters. *)
val ascii_of_ident : string -> string
diff --git a/lib/util.ml b/lib/util.ml
index a20dba0fc..b67539918 100644
--- a/lib/util.ml
+++ b/lib/util.ml
@@ -124,6 +124,7 @@ let delayed_force f = f ()
type ('a, 'b) union = ('a, 'b) CSig.union = Inl of 'a | Inr of 'b
type 'a until = 'a CSig.until = Stop of 'a | Cont of 'a
+type ('a, 'b) eq = ('a, 'b) CSig.eq = Refl : ('a, 'a) eq
let map_union f g = function
| Inl a -> Inl (f a)
diff --git a/lib/util.mli b/lib/util.mli
index 4156af672..7923c65a3 100644
--- a/lib/util.mli
+++ b/lib/util.mli
@@ -111,5 +111,7 @@ val map_union : ('a -> 'c) -> ('b -> 'd) -> ('a, 'b) union -> ('c, 'd) union
type 'a until = 'a CSig.until = Stop of 'a | Cont of 'a
(** Used for browsable-until structures. *)
+type ('a, 'b) eq = ('a, 'b) CSig.eq = Refl : ('a, 'a) eq
+
val open_utf8_file_in : string -> in_channel
(** Open an utf-8 encoded file and skip the byte-order mark if any. *)
diff --git a/library/declare.ml b/library/declare.ml
index 5f6f0fe45..817870a7c 100644
--- a/library/declare.ml
+++ b/library/declare.ml
@@ -426,13 +426,13 @@ let definition_message id =
Flags.if_verbose msg_info (pr_id id ++ str " is defined")
let assumption_message id =
- Flags.if_verbose msg_info (pr_id id ++ str " is assumed")
+ (* Changing "assumed" to "declared", "assuming" referring more to
+ the type of the object than to the name of the object (see
+ discussion on coqdev: "Chapter 4 of the Reference Manual", 8/10/2015) *)
+ Flags.if_verbose msg_info (pr_id id ++ str " is declared")
(** Global universe names, in a different summary *)
-type universe_names =
- (Univ.universe_level Idmap.t * Id.t Univ.LMap.t)
-
(* Discharged or not *)
type universe_decl = polymorphic * (Id.t * Univ.universe_level) list
diff --git a/library/declaremods.ml b/library/declaremods.ml
index 043484151..4c9c40a73 100644
--- a/library/declaremods.ml
+++ b/library/declaremods.ml
@@ -371,7 +371,7 @@ let rec replace_module_object idl mp0 objs0 mp1 objs1 =
match idl, objs0 with
| _,[] -> []
| id::idl,(id',obj)::tail when Id.equal id id' ->
- assert (object_has_tag obj "MODULE");
+ assert (String.equal (object_tag obj) "MODULE");
let mp_id = MPdot(mp0, Label.of_id id) in
let objs = match idl with
| [] -> Lib.subst_objects (map_mp mp1 mp_id empty_delta_resolver) objs1
diff --git a/library/decls.ml b/library/decls.ml
index 0cd4ccb25..cafdcd0ab 100644
--- a/library/decls.ml
+++ b/library/decls.ml
@@ -11,7 +11,6 @@
open Util
open Names
-open Context
open Decl_kinds
open Libnames
@@ -55,7 +54,7 @@ let initialize_named_context_for_proof () =
Environ.push_named_context_val d signv) sign Environ.empty_named_context_val
let last_section_hyps dir =
- fold_named_context
+ Context.Named.fold_outside
(fun (id,_,_) sec_ids ->
try if DirPath.equal dir (variable_path id) then id::sec_ids else sec_ids
with Not_found -> sec_ids)
diff --git a/library/global.mli b/library/global.mli
index 9db30c8ff..bf653307c 100644
--- a/library/global.mli
+++ b/library/global.mli
@@ -19,9 +19,9 @@ val env : unit -> Environ.env
val env_is_initial : unit -> bool
-val universes : unit -> Univ.universes
+val universes : unit -> UGraph.t
val named_context_val : unit -> Environ.named_context_val
-val named_context : unit -> Context.named_context
+val named_context : unit -> Context.Named.t
(** {6 Enriching the global environment } *)
@@ -73,7 +73,7 @@ val add_module_parameter :
(** {6 Queries in the global environment } *)
-val lookup_named : variable -> Context.named_declaration
+val lookup_named : variable -> Context.Named.Declaration.t
val lookup_constant : constant -> Declarations.constant_body
val lookup_inductive : inductive ->
Declarations.mutual_inductive_body * Declarations.one_inductive_body
diff --git a/library/globnames.ml b/library/globnames.ml
index 3ae44b2cc..cf0e37174 100644
--- a/library/globnames.ml
+++ b/library/globnames.ml
@@ -14,10 +14,10 @@ open Libnames
(*s Global reference is a kernel side type for all references together *)
type global_reference =
- | VarRef of variable
- | ConstRef of constant
- | IndRef of inductive
- | ConstructRef of constructor
+ | VarRef of variable (** A reference to the section-context. *)
+ | ConstRef of constant (** A reference to the environment. *)
+ | IndRef of inductive (** A reference to an inductive type. *)
+ | ConstructRef of constructor (** A reference to a constructor of an inductive type. *)
let isVarRef = function VarRef _ -> true | _ -> false
let isConstRef = function ConstRef _ -> true | _ -> false
diff --git a/library/globnames.mli b/library/globnames.mli
index f94f6216f..f4956e3df 100644
--- a/library/globnames.mli
+++ b/library/globnames.mli
@@ -13,10 +13,10 @@ open Mod_subst
(** {6 Global reference is a kernel side type for all references together } *)
type global_reference =
- | VarRef of variable
- | ConstRef of constant
- | IndRef of inductive
- | ConstructRef of constructor
+ | VarRef of variable (** A reference to the section-context. *)
+ | ConstRef of constant (** A reference to the environment. *)
+ | IndRef of inductive (** A reference to an inductive type. *)
+ | ConstructRef of constructor (** A reference to a constructor of an inductive type. *)
val isVarRef : global_reference -> bool
val isConstRef : global_reference -> bool
diff --git a/library/keys.ml b/library/keys.ml
index 0c167494e..057dc3b65 100644
--- a/library/keys.ml
+++ b/library/keys.ml
@@ -12,35 +12,31 @@ open Globnames
open Term
open Libobject
-type key =
+type key =
| KGlob of global_reference
- | KLam
+ | KLam
| KLet
| KProd
| KSort
- | KEvar
- | KCase
- | KFix
+ | KCase
+ | KFix
| KCoFix
- | KRel
- | KMeta
+ | KRel
module KeyOrdered = struct
type t = key
let hash gr =
match gr with
- | KGlob gr -> 10 + RefOrdered.hash gr
+ | KGlob gr -> 8 + RefOrdered.hash gr
| KLam -> 0
| KLet -> 1
| KProd -> 2
| KSort -> 3
- | KEvar -> 4
- | KCase -> 5
- | KFix -> 6
- | KCoFix -> 7
- | KRel -> 8
- | KMeta -> 9
+ | KCase -> 4
+ | KFix -> 5
+ | KCoFix -> 6
+ | KRel -> 7
let compare gr1 gr2 =
match gr1, gr2 with
@@ -62,8 +58,6 @@ module Keyset = Keymap.Set
(* Mapping structure for references to be considered equivalent *)
-type keys = Keyset.t Keymap.t
-
let keys = Summary.ref Keymap.empty ~name:"Keys_decl"
let add_kv k v m =
@@ -153,12 +147,10 @@ let pr_key pr_global = function
| KLet -> str"Let"
| KProd -> str"Product"
| KSort -> str"Sort"
- | KEvar -> str"Evar"
| KCase -> str"Case"
| KFix -> str"Fix"
| KCoFix -> str"CoFix"
| KRel -> str"Rel"
- | KMeta -> str"Meta"
let pr_keyset pr_global v =
prlist_with_sep spc (pr_key pr_global) (Keyset.elements v)
diff --git a/library/lib.mli b/library/lib.mli
index 29fc7cd24..53e98e760 100644
--- a/library/lib.mli
+++ b/library/lib.mli
@@ -168,7 +168,7 @@ type variable_context = variable_info list
type abstr_info = variable_context * Univ.universe_level_subst * Univ.UContext.t
val instance_from_variable_context : variable_context -> Names.Id.t array
-val named_of_variable_context : variable_context -> Context.named_context
+val named_of_variable_context : variable_context -> Context.Named.t
val section_segment_of_constant : Names.constant -> abstr_info
val section_segment_of_mutual_inductive: Names.mutual_inductive -> abstr_info
@@ -179,8 +179,8 @@ val is_in_section : Globnames.global_reference -> bool
val add_section_variable : Names.Id.t -> Decl_kinds.binding_kind -> Decl_kinds.polymorphic -> Univ.universe_context_set -> unit
val add_section_context : Univ.universe_context_set -> unit
val add_section_constant : bool (* is_projection *) ->
- Names.constant -> Context.named_context -> unit
-val add_section_kn : Names.mutual_inductive -> Context.named_context -> unit
+ Names.constant -> Context.Named.t -> unit
+val add_section_kn : Names.mutual_inductive -> Context.Named.t -> unit
val replacement_context : unit -> Opaqueproof.work_list
(** {6 Discharge: decrease the section level if in the current section } *)
@@ -193,6 +193,6 @@ val discharge_inductive : Names.inductive -> Names.inductive
(* discharging a constant in one go *)
val full_replacement_context : unit -> Opaqueproof.work_list list
val full_section_segment_of_constant :
- Names.constant -> (Context.named_context -> Context.named_context) list
+ Names.constant -> (Context.Named.t -> Context.Named.t) list
diff --git a/library/libnames.ml b/library/libnames.ml
index a2f22b2ef..99ff2f2fb 100644
--- a/library/libnames.ml
+++ b/library/libnames.ml
@@ -13,7 +13,7 @@ open Names
(**********************************************)
-let pr_dirpath sl = (str (DirPath.to_string sl))
+let pr_dirpath sl = str (DirPath.to_string sl)
(*s Operations on dirpaths *)
@@ -197,7 +197,7 @@ let string_of_reference = function
let pr_reference = function
| Qualid (_,qid) -> pr_qualid qid
- | Ident (_,id) -> str (Id.to_string id)
+ | Ident (_,id) -> Id.print id
let loc_of_reference = function
| Qualid (loc,qid) -> loc
diff --git a/library/libobject.ml b/library/libobject.ml
index 706e39915..bbbb134df 100644
--- a/library/libobject.ml
+++ b/library/libobject.ml
@@ -8,6 +8,9 @@
open Libnames
open Pp
+open Util
+
+module Dyn = Dyn.Make(struct end)
(* The relax flag is used to make it possible to load files while ignoring
failures to incorporate some objects. This can be useful when one
@@ -70,15 +73,25 @@ type dynamic_object_declaration = {
dyn_discharge_function : object_name * obj -> obj option;
dyn_rebuild_function : obj -> obj }
-let object_tag = Dyn.tag
-let object_has_tag = Dyn.has_tag
+let object_tag (Dyn.Dyn (t, _)) = Dyn.repr t
let cache_tab =
(Hashtbl.create 17 : (string,dynamic_object_declaration) Hashtbl.t)
+let make_dyn (type a) (tag : a Dyn.tag) =
+ let infun x = Dyn.Dyn (tag, x) in
+ let outfun : (Dyn.t -> a) = fun dyn ->
+ let Dyn.Dyn (t, x) = dyn in
+ match Dyn.eq t tag with
+ | None -> assert false
+ | Some Refl -> x
+ in
+ (infun, outfun)
+
let declare_object_full odecl =
let na = odecl.object_name in
- let (infun,outfun) = Dyn.create na in
+ let tag = Dyn.create na in
+ let (infun, outfun) = make_dyn tag in
let cacher (oname,lobj) = odecl.cache_function (oname,outfun lobj)
and loader i (oname,lobj) = odecl.load_function i (oname,outfun lobj)
and opener i (oname,lobj) = odecl.open_function i (oname,outfun lobj)
@@ -158,3 +171,5 @@ let discharge_object ((_,lobj) as node) =
let rebuild_object lobj =
apply_dyn_fun lobj (fun d -> d.dyn_rebuild_function lobj) lobj
+
+let dump = Dyn.dump
diff --git a/library/libobject.mli b/library/libobject.mli
index f3880a437..dbe0de8f8 100644
--- a/library/libobject.mli
+++ b/library/libobject.mli
@@ -99,7 +99,6 @@ val declare_object :
'a object_declaration -> ('a -> obj)
val object_tag : obj -> string
-val object_has_tag : obj -> string -> bool
val cache_object : object_name * obj -> unit
val load_object : int -> object_name * obj -> unit
@@ -109,3 +108,7 @@ val classify_object : obj -> obj substitutivity
val discharge_object : object_name * obj -> obj option
val rebuild_object : obj -> obj
val relax : bool -> unit
+
+(** {6 Debug} *)
+
+val dump : unit -> (int * string) list
diff --git a/library/library.ml b/library/library.ml
index 79e5792c0..c41e10608 100644
--- a/library/library.ml
+++ b/library/library.ml
@@ -132,7 +132,7 @@ let try_find_library dir =
try find_library dir
with Not_found ->
errorlabstrm "Library.find_library"
- (str "Unknown library " ++ str (DirPath.to_string dir))
+ (str "Unknown library " ++ pr_dirpath dir)
let register_library_filename dir f =
(* Not synchronized: overwrite the previous binding if one existed *)
@@ -286,28 +286,18 @@ let locate_absolute_library dir =
with Not_found -> [] in
match find ".vo" @ find ".vio" with
| [] -> raise LibNotFound
- | [file] -> dir, file
+ | [file] -> file
| [vo;vi] when Unix.((stat vo).st_mtime < (stat vi).st_mtime) ->
msg_warning (str"Loading " ++ str vi ++ str " instead of " ++
str vo ++ str " because it is more recent");
- dir, vi
- | [vo;vi] -> dir, vo
+ vi
+ | [vo;vi] -> vo
| _ -> assert false
let locate_qualified_library ?root ?(warn = true) qid =
(* Search library in loadpath *)
let dir, base = repr_qualid qid in
- let loadpath = match root with
- | None -> Loadpath.expand_path dir
- | Some root ->
- let filter path =
- if is_dirpath_prefix_of root path then
- let path = drop_dirpath_prefix root path in
- is_dirpath_suffix_of dir path
- else false
- in
- Loadpath.filter_path filter
- in
+ let loadpath = Loadpath.expand_path ?root dir in
let () = match loadpath with [] -> raise LibUnmappedDir | _ -> () in
let find ext =
try
@@ -459,7 +449,7 @@ let intern_from_file f =
module DPMap = Map.Make(DirPath)
let rec intern_library (needed, contents) (dir, f) from =
- Pp.feedback(Feedback.FileDependency (from, f));
+ Pp.feedback(Feedback.FileDependency (from, DirPath.to_string dir));
(* Look if in the current logical environment *)
try (find_library dir).libsum_digests, (needed, contents)
with Not_found ->
@@ -467,6 +457,7 @@ let rec intern_library (needed, contents) (dir, f) from =
try (DPMap.find dir contents).library_digests, (needed, contents)
with Not_found ->
(* [dir] is an absolute name which matches [f] which must be in loadpath *)
+ let f = match f with Some f -> f | None -> try_locate_absolute_library dir in
let m = intern_from_file f in
if not (DirPath.equal dir m.library_name) then
errorlabstrm "load_physical_library"
@@ -481,13 +472,13 @@ and intern_library_deps libs dir m from =
(dir :: needed, DPMap.add dir m contents )
and intern_mandatory_library caller from libs (dir,d) =
- let digest, libs = intern_library libs (try_locate_absolute_library dir) from in
+ let digest, libs = intern_library libs (dir, None) from in
if not (Safe_typing.digest_match ~actual:digest ~required:d) then
- errorlabstrm "" (str "Compiled library " ++ str (DirPath.to_string caller) ++ str ".vo makes inconsistent assumptions over library " ++ str (DirPath.to_string dir));
+ errorlabstrm "" (str "Compiled library " ++ pr_dirpath caller ++ str ".vo makes inconsistent assumptions over library " ++ pr_dirpath dir);
libs
-let rec_intern_library libs mref =
- let _, libs = intern_library libs mref None in
+let rec_intern_library libs (dir, f) =
+ let _, libs = intern_library libs (dir, Some f) None in
libs
let native_name_from_filename f =
@@ -579,7 +570,7 @@ let safe_locate_module (loc,qid) =
try Nametab.locate_module qid
with Not_found ->
user_err_loc
- (loc,"import_library", str (string_of_qualid qid) ++ str " is not a module")
+ (loc,"import_library", pr_qualid qid ++ str " is not a module")
let import_module export modl =
(* Optimization: libraries in a raw in the list are imported
@@ -604,7 +595,7 @@ let import_module export modl =
try Declaremods.import_module export mp; aux [] l
with Not_found ->
user_err_loc (loc,"import_library",
- str (string_of_qualid dir) ++ str " is not a module"))
+ pr_qualid dir ++ str " is not a module"))
| [] -> flush acc
in aux [] modl
@@ -614,9 +605,9 @@ let import_module export modl =
let check_coq_overwriting p id =
let l = DirPath.repr p in
let is_empty = match l with [] -> true | _ -> false in
- if not !Flags.boot && not is_empty && String.equal (Id.to_string (List.last l)) "Coq" then
+ if not !Flags.boot && not is_empty && Id.equal (List.last l) coq_root then
errorlabstrm ""
- (str "Cannot build module " ++ str (DirPath.to_string p) ++ str "." ++ pr_id id ++ str "." ++ spc () ++
+ (str "Cannot build module " ++ pr_dirpath p ++ str "." ++ pr_id id ++ str "." ++ spc () ++
str "it starts with prefix \"Coq\" which is reserved for the Coq library.")
(* Verifies that a string starts by a letter and do not contain
@@ -781,13 +772,6 @@ let save_library_raw f sum lib univs proofs =
System.marshal_out_segment f' ch (proofs : seg_proofs);
close_out ch
-(************************************************************************)
-(*s Display the memory use of a library. *)
-
-open Printf
-
-let mem s = Pp.mt ()
-
module StringOrd = struct type t = string let compare = String.compare end
module StringSet = Set.Make(StringOrd)
diff --git a/library/library.mli b/library/library.mli
index 25c9604ce..8f5b775d8 100644
--- a/library/library.mli
+++ b/library/library.mli
@@ -85,8 +85,5 @@ val locate_qualified_library :
*)
-(** {6 Statistics: display the memory use of a library. } *)
-val mem : DirPath.t -> Pp.std_ppcmds
-
(** {6 Native compiler. } *)
val native_name_from_filename : string -> string
diff --git a/library/loadpath.ml b/library/loadpath.ml
index 78f8dd25f..f8169576d 100644
--- a/library/loadpath.ml
+++ b/library/loadpath.ml
@@ -84,10 +84,6 @@ let add_load_path phys_path coq_path ~implicit =
end
| _ -> anomaly_too_many_paths phys_path
-let extend_path_with_dirpath p dir =
- List.fold_left Filename.concat p
- (List.rev_map Id.to_string (DirPath.repr dir))
-
let filter_path f =
let rec aux = function
| [] -> []
@@ -97,18 +93,19 @@ let filter_path f =
in
aux !load_paths
-let expand_path dir =
+let expand_path ?root dir =
let rec aux = function
| [] -> []
- | { path_physical = ph; path_logical = lg; path_implicit = implicit } :: l ->
- match implicit with
- | true ->
- (** The path is implicit, so that we only want match the logical suffix *)
- if is_dirpath_suffix_of dir lg then (ph, lg) :: aux l else aux l
- | false ->
- (** Otherwise we must match exactly *)
- if DirPath.equal dir lg then (ph, lg) :: aux l else aux l
- in
+ | { path_physical = ph; path_logical = lg; path_implicit = implicit } :: l ->
+ let success =
+ match root with
+ | None ->
+ if implicit then is_dirpath_suffix_of dir lg
+ else DirPath.equal dir lg
+ | Some root ->
+ is_dirpath_prefix_of root lg &&
+ is_dirpath_suffix_of dir (drop_dirpath_prefix root lg) in
+ if success then (ph, lg) :: aux l else aux l in
aux !load_paths
let locate_file fname =
diff --git a/library/loadpath.mli b/library/loadpath.mli
index 49ffc1148..4e79edbdc 100644
--- a/library/loadpath.mli
+++ b/library/loadpath.mli
@@ -42,7 +42,7 @@ val find_load_path : CUnix.physical_path -> t
val is_in_load_paths : CUnix.physical_path -> bool
(** Whether a physical path is currently bound. *)
-val expand_path : DirPath.t -> (CUnix.physical_path * DirPath.t) list
+val expand_path : ?root:DirPath.t -> DirPath.t -> (CUnix.physical_path * DirPath.t) list
(** Given a relative logical path, associate the list of absolute physical and
logical paths which are possible matches of it. *)
diff --git a/library/nameops.ml b/library/nameops.ml
index 98b417c2a..71405d024 100644
--- a/library/nameops.ml
+++ b/library/nameops.ml
@@ -12,7 +12,7 @@ open Names
(* Identifiers *)
-let pr_id id = str (Id.to_string id)
+let pr_id id = Id.print id
let pr_name = function
| Anonymous -> str "_"
@@ -141,7 +141,7 @@ let name_max na1 na2 =
| Name _ -> na1
| Anonymous -> na2
-let pr_lab l = str (Label.to_string l)
+let pr_lab l = Label.print l
let default_library = Names.DirPath.initial (* = ["Top"] *)
diff --git a/library/nametab.ml b/library/nametab.ml
index 40acb3ae2..bbae98fc0 100644
--- a/library/nametab.ml
+++ b/library/nametab.ml
@@ -523,7 +523,7 @@ let shortest_qualid_of_tactic kn =
KnTab.shortest_qualid Id.Set.empty sp !the_tactictab
let pr_global_env env ref =
- try str (string_of_qualid (shortest_qualid_of_global env ref))
+ try pr_qualid (shortest_qualid_of_global env ref)
with Not_found as e ->
if !Flags.debug then Pp.msg_debug (Pp.str "pr_global_env not found"); raise e
diff --git a/library/summary.ml b/library/summary.ml
index 46c52acc4..19e7e5fd9 100644
--- a/library/summary.ml
+++ b/library/summary.ml
@@ -10,6 +10,8 @@ open Pp
open Errors
open Util
+module Dyn = Dyn.Make(struct end)
+
type marshallable = [ `Yes | `No | `Shallow ]
type 'a summary_declaration = {
freeze_function : marshallable -> 'a;
@@ -20,8 +22,19 @@ let summaries = ref Int.Map.empty
let mangle id = id ^ "-SUMMARY"
+let make_dyn (type a) (tag : a Dyn.tag) =
+ let infun x = Dyn.Dyn (tag, x) in
+ let outfun : (Dyn.t -> a) = fun dyn ->
+ let Dyn.Dyn (t, x) = dyn in
+ match Dyn.eq t tag with
+ | None -> assert false
+ | Some Refl -> x
+ in
+ (infun, outfun)
+
let internal_declare_summary hash sumname sdecl =
- let (infun, outfun) = Dyn.create (mangle sumname) in
+ let tag = Dyn.create (mangle sumname) in
+ let (infun, outfun) = make_dyn tag in
let dyn_freeze b = infun (sdecl.freeze_function b)
and dyn_unfreeze sum = sdecl.unfreeze_function (outfun sum)
and dyn_init = sdecl.init_function in
@@ -164,8 +177,15 @@ let project_summary { summaries; ml_module } ?(complement=false) ids =
List.filter (fun (id, _) -> List.mem id ids) summaries
let pointer_equal l1 l2 =
+ let ptr_equal d1 d2 =
+ let Dyn.Dyn (t1, x1) = d1 in
+ let Dyn.Dyn (t2, x2) = d2 in
+ match Dyn.eq t1 t2 with
+ | None -> false
+ | Some Refl -> x1 == x2
+ in
CList.for_all2eq
- (fun (id1,v1) (id2,v2) -> id1 = id2 && Dyn.pointer_equal v1 v2) l1 l2
+ (fun (id1,v1) (id2,v2) -> id1 = id2 && ptr_equal v1 v2) l1 l2
(** All-in-one reference declaration + registration *)
@@ -176,3 +196,5 @@ let ref ?(freeze=fun _ r -> r) ~name x =
unfreeze_function = ((:=) r);
init_function = (fun () -> r := x) };
r
+
+let dump = Dyn.dump
diff --git a/library/summary.mli b/library/summary.mli
index c24a0b4b8..27889cab2 100644
--- a/library/summary.mli
+++ b/library/summary.mli
@@ -71,3 +71,7 @@ val unfreeze_summary : frozen_bits -> unit
val surgery_summary : frozen -> frozen_bits -> frozen
val project_summary : frozen -> ?complement:bool -> string list -> frozen_bits
val pointer_equal : frozen_bits -> frozen_bits -> bool
+
+(** {6 Debug} *)
+
+val dump : unit -> (int * string) list
diff --git a/library/universes.ml b/library/universes.ml
index 7972c478a..68e422e00 100644
--- a/library/universes.ml
+++ b/library/universes.ml
@@ -102,6 +102,7 @@ module Constraints = struct
end
type universe_constraints = Constraints.t
+type 'a constraint_accumulator = universe_constraints -> 'a -> 'a option
type 'a universe_constrained = 'a * universe_constraints
type 'a universe_constraint_function = 'a -> 'a -> universe_constraints -> universe_constraints
@@ -135,82 +136,76 @@ let to_constraints g s =
| _, ULe, Some l' -> enforce_leq x y acc
| _, ULub, _ -> acc
| _, d, _ ->
- let f = if d == ULe then check_leq else check_eq in
+ let f = if d == ULe then UGraph.check_leq else UGraph.check_eq in
if f g x y then acc else
raise (Invalid_argument
"to_constraints: non-trivial algebraic constraint between universes")
in Constraints.fold tr s Constraint.empty
-let eq_constr_univs_infer univs m n =
- if m == n then true, Constraints.empty
+let eq_constr_univs_infer univs fold m n accu =
+ if m == n then Some accu
else
- let cstrs = ref Constraints.empty in
- let eq_universes strict = Univ.Instance.check_eq univs in
+ let cstrs = ref accu in
+ let eq_universes strict = UGraph.check_eq_instances univs in
let eq_sorts s1 s2 =
if Sorts.equal s1 s2 then true
else
let u1 = Sorts.univ_of_sort s1 and u2 = Sorts.univ_of_sort s2 in
- if Univ.check_eq univs u1 u2 then true
- else
- (cstrs := Constraints.add (u1, UEq, u2) !cstrs;
- true)
+ match fold (Constraints.singleton (u1, UEq, u2)) !cstrs with
+ | None -> false
+ | Some accu -> cstrs := accu; true
in
let rec eq_constr' m n =
m == n || Constr.compare_head_gen eq_universes eq_sorts eq_constr' m n
in
let res = Constr.compare_head_gen eq_universes eq_sorts eq_constr' m n in
- res, !cstrs
+ if res then Some !cstrs else None
(** Variant of [eq_constr_univs_infer] taking kind-of-term functions,
to expose subterms of [m] and [n], arguments. *)
-let eq_constr_univs_infer_with kind1 kind2 univs m n =
+let eq_constr_univs_infer_with kind1 kind2 univs fold m n accu =
(* spiwack: duplicates the code of [eq_constr_univs_infer] because I
haven't find a way to factor the code without destroying
pointer-equality optimisations in [eq_constr_univs_infer].
Pointer equality is not sufficient to ensure equality up to
[kind1,kind2], because [kind1] and [kind2] may be different,
typically evaluating [m] and [n] in different evar maps. *)
- let cstrs = ref Constraints.empty in
- let eq_universes strict = Univ.Instance.check_eq univs in
+ let cstrs = ref accu in
+ let eq_universes strict = UGraph.check_eq_instances univs in
let eq_sorts s1 s2 =
if Sorts.equal s1 s2 then true
else
let u1 = Sorts.univ_of_sort s1 and u2 = Sorts.univ_of_sort s2 in
- if Univ.check_eq univs u1 u2 then true
- else
- (cstrs := Constraints.add (u1, UEq, u2) !cstrs;
- true)
+ match fold (Constraints.singleton (u1, UEq, u2)) !cstrs with
+ | None -> false
+ | Some accu -> cstrs := accu; true
in
let rec eq_constr' m n =
Constr.compare_head_gen_with kind1 kind2 eq_universes eq_sorts eq_constr' m n
in
let res = Constr.compare_head_gen_with kind1 kind2 eq_universes eq_sorts eq_constr' m n in
- res, !cstrs
+ if res then Some !cstrs else None
-let leq_constr_univs_infer univs m n =
- if m == n then true, Constraints.empty
+let leq_constr_univs_infer univs fold m n accu =
+ if m == n then Some accu
else
- let cstrs = ref Constraints.empty in
- let eq_universes strict l l' = Univ.Instance.check_eq univs l l' in
+ let cstrs = ref accu in
+ let eq_universes strict l l' = UGraph.check_eq_instances univs l l' in
let eq_sorts s1 s2 =
if Sorts.equal s1 s2 then true
else
let u1 = Sorts.univ_of_sort s1 and u2 = Sorts.univ_of_sort s2 in
- if Univ.check_eq univs u1 u2 then true
- else (cstrs := Constraints.add (u1, UEq, u2) !cstrs;
- true)
+ match fold (Constraints.singleton (u1, UEq, u2)) !cstrs with
+ | None -> false
+ | Some accu -> cstrs := accu; true
in
let leq_sorts s1 s2 =
if Sorts.equal s1 s2 then true
else
let u1 = Sorts.univ_of_sort s1 and u2 = Sorts.univ_of_sort s2 in
- if Univ.check_leq univs u1 u2 then
- ((if Univ.is_type0_univ u1 then
- cstrs := Constraints.add (u1, ULe, u2) !cstrs);
- true)
- else
- (cstrs := Constraints.add (u1, ULe, u2) !cstrs;
- true)
+ match fold (Constraints.singleton (u1, ULe, u2)) !cstrs with
+ | None -> false
+ | Some accu -> cstrs := accu; true
in
let rec eq_constr' m n =
m == n || Constr.compare_head_gen eq_universes eq_sorts eq_constr' m n
@@ -220,7 +215,7 @@ let leq_constr_univs_infer univs m n =
eq_constr' leq_constr' m n
and leq_constr' m n = m == n || compare_leq m n in
let res = compare_leq m n in
- res, !cstrs
+ if res then Some !cstrs else None
let eq_constr_universes m n =
if m == n then true, Constraints.empty
@@ -650,14 +645,14 @@ let normalize_univ_variable_opt_subst ectx =
in
let update l b =
assert (match Universe.level b with Some l' -> not (Level.equal l l') | None -> true);
- ectx := Univ.LMap.add l (Some b) !ectx; b
+ try ectx := Univ.LMap.add l (Some b) !ectx; b with Not_found -> assert false
in normalize_univ_variable ~find ~update
let normalize_univ_variable_subst subst =
let find l = Univ.LMap.find l !subst in
let update l b =
assert (match Universe.level b with Some l' -> not (Level.equal l l') | None -> true);
- subst := Univ.LMap.add l b !subst; b in
+ try subst := Univ.LMap.update l b !subst; b with Not_found -> assert false in
normalize_univ_variable ~find ~update
let normalize_universe_opt_subst subst =
@@ -869,27 +864,27 @@ let normalize_context_set ctx us algs =
let csts =
(* We first put constraints in a normal-form: all self-loops are collapsed
to equalities. *)
- let g = Univ.LSet.fold (fun v g -> Univ.add_universe v false g)
- ctx Univ.empty_universes
+ let g = Univ.LSet.fold (fun v g -> UGraph.add_universe v false g)
+ ctx UGraph.empty_universes
in
let g =
Univ.Constraint.fold
(fun (l, d, r) g ->
let g =
if not (Level.is_small l || LSet.mem l ctx) then
- try Univ.add_universe l false g
- with Univ.AlreadyDeclared -> g
+ try UGraph.add_universe l false g
+ with UGraph.AlreadyDeclared -> g
else g
in
let g =
if not (Level.is_small r || LSet.mem r ctx) then
- try Univ.add_universe r false g
- with Univ.AlreadyDeclared -> g
+ try UGraph.add_universe r false g
+ with UGraph.AlreadyDeclared -> g
else g
in g) csts g
in
- let g = Univ.Constraint.fold Univ.enforce_constraint csts g in
- Univ.constraints_of_universes g
+ let g = Univ.Constraint.fold UGraph.enforce_constraint csts g in
+ UGraph.constraints_of_universes g
in
let noneqs =
Constraint.fold (fun (l,d,r as cstr) noneqs ->
@@ -1027,7 +1022,7 @@ let refresh_constraints univs (ctx, cstrs) =
Univ.Constraint.fold (fun c (cstrs', univs as acc) ->
let c = translate_cstr c in
if is_trivial_leq c then acc
- else (Univ.Constraint.add c cstrs', Univ.enforce_constraint c univs))
+ else (Univ.Constraint.add c cstrs', UGraph.enforce_constraint c univs))
cstrs (Univ.Constraint.empty, univs)
in ((ctx, cstrs'), univs')
diff --git a/library/universes.mli b/library/universes.mli
index edb06dfc5..53cf5f384 100644
--- a/library/universes.mli
+++ b/library/universes.mli
@@ -63,6 +63,7 @@ module Constraints : sig
end
type universe_constraints = Constraints.t
+type 'a constraint_accumulator = universe_constraints -> 'a -> 'a option
type 'a universe_constrained = 'a * universe_constraints
type 'a universe_constraint_function = 'a -> 'a -> universe_constraints -> universe_constraints
@@ -71,11 +72,12 @@ val subst_univs_universe_constraints : universe_subst_fn ->
val enforce_eq_instances_univs : bool -> universe_instance universe_constraint_function
-val to_constraints : universes -> universe_constraints -> constraints
+val to_constraints : UGraph.t -> universe_constraints -> constraints
(** [eq_constr_univs_infer u a b] is [true, c] if [a] equals [b] modulo alpha, casts,
application grouping, the universe constraints in [u] and additional constraints [c]. *)
-val eq_constr_univs_infer : Univ.universes -> constr -> constr -> bool universe_constrained
+val eq_constr_univs_infer : UGraph.t -> 'a constraint_accumulator ->
+ constr -> constr -> 'a -> 'a option
(** [eq_constr_univs_infer_With kind1 kind2 univs m n] is a variant of
{!eq_constr_univs_infer} taking kind-of-term functions, to expose
@@ -83,12 +85,13 @@ val eq_constr_univs_infer : Univ.universes -> constr -> constr -> bool universe_
val eq_constr_univs_infer_with :
(constr -> (constr,types) kind_of_term) ->
(constr -> (constr,types) kind_of_term) ->
- Univ.universes -> constr -> constr -> bool universe_constrained
+ UGraph.t -> 'a constraint_accumulator -> constr -> constr -> 'a -> 'a option
(** [leq_constr_univs u a b] is [true, c] if [a] is convertible to [b]
modulo alpha, casts, application grouping, the universe constraints
in [u] and additional constraints [c]. *)
-val leq_constr_univs_infer : Univ.universes -> constr -> constr -> bool universe_constrained
+val leq_constr_univs_infer : UGraph.t -> 'a constraint_accumulator ->
+ constr -> constr -> 'a -> 'a option
(** [eq_constr_universes a b] [true, c] if [a] equals [b] modulo alpha, casts,
application grouping and the universe constraints in [c]. *)
@@ -223,7 +226,7 @@ val restrict_universe_context : universe_context_set -> universe_set -> universe
val simplify_universe_context : universe_context_set ->
universe_context_set * universe_level_subst
-val refresh_constraints : universes -> universe_context_set -> universe_context_set * universes
+val refresh_constraints : UGraph.t -> universe_context_set -> universe_context_set * UGraph.t
(** Pretty-printing *)
diff --git a/myocamlbuild.ml b/myocamlbuild.ml
index 097a10425..73ef7e1ed 100644
--- a/myocamlbuild.ml
+++ b/myocamlbuild.ml
@@ -104,7 +104,7 @@ let _build = Options.build_dir
let core_libs =
["lib/clib"; "lib/lib"; "kernel/kernel"; "library/library";
- "pretyping/pretyping"; "interp/interp"; "proofs/proofs";
+ "engine/engine"; "pretyping/pretyping"; "interp/interp"; "proofs/proofs";
"parsing/parsing"; "printing/printing"; "tactics/tactics";
"stm/stm"; "toplevel/toplevel"; "parsing/highparsing";
"tactics/hightactics"]
diff --git a/parsing/compat.ml4 b/parsing/compat.ml4
index d1d55c81f..3405d2429 100644
--- a/parsing/compat.ml4
+++ b/parsing/compat.ml4
@@ -238,6 +238,70 @@ end
END
+(** Some definitions are grammar-specific in Camlp4, so we use a functor to
+ depend on it while taking a dummy argument in Camlp5. *)
+
+module GramextMake (G : GrammarSig) :
+sig
+ val stoken : Tok.t -> G.symbol
+ val sself : G.symbol
+ val snext : G.symbol
+ val slist0 : G.symbol -> G.symbol
+ val slist0sep : G.symbol * G.symbol -> G.symbol
+ val slist1 : G.symbol -> G.symbol
+ val slist1sep : G.symbol * G.symbol -> G.symbol
+ val sopt : G.symbol -> G.symbol
+ val snterml : G.internal_entry * string -> G.symbol
+ val snterm : G.internal_entry -> G.symbol
+ val snterml_level : G.symbol -> string
+end =
+struct
+
+IFDEF CAMLP5 THEN
+ let stoken tok =
+ let pattern = match tok with
+ | Tok.KEYWORD s -> "", s
+ | Tok.IDENT s -> "IDENT", s
+ | Tok.METAIDENT s -> "METAIDENT", s
+ | Tok.PATTERNIDENT s -> "PATTERNIDENT", s
+ | Tok.FIELD s -> "FIELD", s
+ | Tok.INT s -> "INT", s
+ | Tok.INDEX s -> "INDEX", s
+ | Tok.STRING s -> "STRING", s
+ | Tok.LEFTQMARK -> "LEFTQMARK", ""
+ | Tok.BULLET s -> "BULLET", s
+ | Tok.EOI -> "EOI", ""
+ in
+ Gramext.Stoken pattern
+ELSE
+ module Gramext = G
+ let stoken tok = match tok with
+ | Tok.KEYWORD s -> Gramext.Skeyword s
+ | tok -> Gramext.Stoken ((=) tok, G.Token.to_string tok)
+END
+
+IFDEF CAMLP5_6_00 THEN
+ let slist0sep (x, y) = Gramext.Slist0sep (x, y, false)
+ let slist1sep (x, y) = Gramext.Slist1sep (x, y, false)
+ELSE
+ let slist0sep (x, y) = Gramext.Slist0sep (x, y)
+ let slist1sep (x, y) = Gramext.Slist1sep (x, y)
+END
+
+ let snterml (x, y) = Gramext.Snterml (x, y)
+ let snterm x = Gramext.Snterm x
+ let sself = Gramext.Sself
+ let snext = Gramext.Snext
+ let slist0 x = Gramext.Slist0 x
+ let slist1 x = Gramext.Slist1 x
+ let sopt x = Gramext.Sopt x
+
+ let snterml_level = function
+ | Gramext.Snterml (_, l) -> l
+ | _ -> failwith "snterml_level"
+
+end
+
(** Misc functional adjustments *)
@@ -323,3 +387,11 @@ let qualified_name loc path name =
let path = List.fold_right fold path (Ast.IdLid (loc, name)) in
Ast.ExId (loc, path)
END
+
+IFDEF CAMLP5 THEN
+let warning_verbose = Gramext.warning_verbose
+ELSE
+(* TODO: this is a workaround, since there isn't such
+ [warning_verbose] in new camlp4. *)
+let warning_verbose = ref true
+END
diff --git a/parsing/egramcoq.ml b/parsing/egramcoq.ml
index b0bbdd813..e9c3a7073 100644
--- a/parsing/egramcoq.ml
+++ b/parsing/egramcoq.ml
@@ -167,10 +167,9 @@ let rec make_constr_prod_item assoc from forpat = function
[]
let prepare_empty_levels forpat (pos,p4assoc,name,reinit) =
- let entry =
- if forpat then weaken_entry Constr.pattern
- else weaken_entry Constr.operconstr in
- grammar_extend entry reinit (pos,[(name, p4assoc, [])])
+ let empty = (pos, [(name, p4assoc, [])]) in
+ if forpat then grammar_extend Constr.pattern reinit empty
+ else grammar_extend Constr.operconstr reinit empty
let pure_sublevels level symbs =
let filter s =
@@ -189,13 +188,10 @@ let extend_constr (entry,level) (n,assoc) mkact forpat rules =
let symbs = make_constr_prod_item assoc n forpat pt in
let pure_sublevels = pure_sublevels level symbs in
let needed_levels = register_empty_levels forpat pure_sublevels in
- let map_level (pos, ass1, name, ass2) =
- (Option.map of_coq_position pos, Option.map of_coq_assoc ass1, name, ass2) in
- let needed_levels = List.map map_level needed_levels in
let pos,p4assoc,name,reinit = find_position forpat assoc level in
let nb_decls = List.length needed_levels + 1 in
List.iter (prepare_empty_levels forpat) needed_levels;
- grammar_extend entry reinit (Option.map of_coq_position pos,
+ unsafe_grammar_extend entry reinit (Option.map of_coq_position pos,
[(name, Option.map of_coq_assoc p4assoc, [symbs, mkact pt])]);
nb_decls) 0 rules
@@ -233,11 +229,11 @@ let extend_constr_notation ng =
let get_tactic_entry n =
if Int.equal n 0 then
- weaken_entry Tactic.simple_tactic, None
+ Tactic.simple_tactic, None
else if Int.equal n 5 then
- weaken_entry Tactic.binder_tactic, None
+ Tactic.binder_tactic, None
else if 1<=n && n<5 then
- weaken_entry Tactic.tactic_expr, Some (Extend.Level (string_of_int n))
+ Tactic.tactic_expr, Some (Extend.Level (string_of_int n))
else
error ("Invalid Tactic Notation level: "^(string_of_int n)^".")
@@ -246,22 +242,27 @@ let get_tactic_entry n =
type tactic_grammar = {
tacgram_level : int;
- tacgram_prods : grammar_prod_item list;
+ tacgram_prods : Tacexpr.raw_tactic_expr grammar_prod_item list;
}
type all_grammar_command =
| Notation of Notation.level * notation_grammar
| TacticGrammar of KerName.t * tactic_grammar
- | MLTacticGrammar of ml_tactic_name * grammar_prod_item list list
+ | MLTacticGrammar of ml_tactic_name * Tacexpr.raw_tactic_expr grammar_prod_item list list
(** ML Tactic grammar extensions *)
let add_ml_tactic_entry name prods =
- let entry = weaken_entry Tactic.simple_tactic in
- let mkact loc l : raw_tactic_expr = Tacexpr.TacML (loc, name, List.map snd l) in
- let rules = List.map (make_rule mkact) prods in
+ let entry = Tactic.simple_tactic in
+ let mkact i loc l : raw_tactic_expr =
+ let open Tacexpr in
+ let entry = { mltac_name = name; mltac_index = i } in
+ let map arg = TacGeneric arg in
+ TacML (loc, entry, List.map map l)
+ in
+ let rules = List.map_i (fun i p -> make_rule (mkact i) p) 0 prods in
synchronize_level_positions ();
- grammar_extend entry None (None ,[(None, None, List.rev rules)]);
+ grammar_extend entry None (None, [(None, None, List.rev rules)]);
1
(* Declaration of the tactic grammar rule *)
@@ -274,14 +275,30 @@ let head_is_ident tg = match tg.tacgram_prods with
let add_tactic_entry kn tg =
let entry, pos = get_tactic_entry tg.tacgram_level in
- let mkact loc l = (TacAlias (loc,kn,l):raw_tactic_expr) in
+ let mkact loc l =
+ let filter = function
+ | GramTerminal _ -> None
+ | GramNonTerminal (_, t, _) -> Some (Genarg.unquote t)
+ in
+ let types = List.map_filter filter tg.tacgram_prods in
+ let map arg t =
+ (** HACK to handle especially the tactic(...) entry *)
+ let wit = Genarg.rawwit Constrarg.wit_tactic in
+ if Genarg.argument_type_eq t (Genarg.unquote wit) then
+ Tacexp (Genarg.out_gen wit arg)
+ else
+ TacGeneric arg
+ in
+ let l = List.map2 map l types in
+ (TacAlias (loc,kn,l):raw_tactic_expr)
+ in
let () =
if Int.equal tg.tacgram_level 0 && not (head_is_ident tg) then
error "Notation for simple tactic must start with an identifier."
in
let rules = make_rule mkact tg.tacgram_prods in
synchronize_level_positions ();
- grammar_extend entry None (Option.map of_coq_position pos,[(None, None, List.rev [rules])]);
+ grammar_extend entry None (pos, [(None, None, List.rev [rules])]);
1
let (grammar_state : (int * all_grammar_command) list ref) = ref []
@@ -374,7 +391,7 @@ let create_ltac_quotation name cast wit e =
let rule = [
gram_token_of_string name;
gram_token_of_string ":";
- symbol_of_prod_entry_key (Agram (Gram.Entry.name e));
+ symbol_of_prod_entry_key (Aentry (name_of_entry e));
] in
let action v _ _ loc =
let loc = !@loc in
diff --git a/parsing/egramcoq.mli b/parsing/egramcoq.mli
index 964bd5419..17524971f 100644
--- a/parsing/egramcoq.mli
+++ b/parsing/egramcoq.mli
@@ -38,7 +38,7 @@ type notation_grammar = {
type tactic_grammar = {
tacgram_level : int;
- tacgram_prods : grammar_prod_item list;
+ tacgram_prods : Tacexpr.raw_tactic_expr grammar_prod_item list;
}
(** {5 Adding notations} *)
@@ -50,7 +50,7 @@ val extend_tactic_grammar : KerName.t -> tactic_grammar -> unit
(** Add a tactic notation rule to the parsing system. This produces a TacAlias
tactic with the provided kernel name. *)
-val extend_ml_tactic_grammar : Tacexpr.ml_tactic_name -> grammar_prod_item list list -> unit
+val extend_ml_tactic_grammar : Tacexpr.ml_tactic_name -> Tacexpr.raw_tactic_expr grammar_prod_item list list -> unit
(** Add a ML tactic notation rule to the parsing system. This produces a
TacML tactic with the provided string as name. *)
diff --git a/parsing/egramml.ml b/parsing/egramml.ml
index 3896970c6..77252e742 100644
--- a/parsing/egramml.ml
+++ b/parsing/egramml.ml
@@ -13,35 +13,55 @@ open Pcoq
open Genarg
open Vernacexpr
-(** Making generic actions in type generic_argument *)
-
-let make_generic_action
- (f:Loc.t -> ('b * raw_generic_argument) list -> 'a) pil =
- let rec make env = function
- | [] ->
- Gram.action (fun loc -> f (to_coqloc loc) env)
- | None :: tl -> (* parse a non-binding item *)
- Gram.action (fun _ -> make env tl)
- | Some (p, t) :: tl -> (* non-terminal *)
- Gram.action (fun v -> make ((p, Unsafe.inj t v) :: env) tl) in
- make [] (List.rev pil)
-
(** Grammar extensions declared at ML level *)
-type grammar_prod_item =
+type 's grammar_prod_item =
| GramTerminal of string
- | GramNonTerminal of
- Loc.t * argument_type * prod_entry_key * Id.t option
+ | GramNonTerminal :
+ Loc.t * 'a raw_abstract_argument_type * ('s, 'a) entry_key -> 's grammar_prod_item
+
+type 'a ty_arg = ('a -> raw_generic_argument)
+
+type ('self, _, 'r) ty_rule =
+| TyStop : ('self, 'r, 'r) ty_rule
+| TyNext : ('self, 'a, 'r) ty_rule * ('self, 'b) Extend.symbol * 'b ty_arg option ->
+ ('self, 'b -> 'a, 'r) ty_rule
+
+type ('self, 'r) any_ty_rule =
+| AnyTyRule : ('self, 'act, Loc.t -> 'r) ty_rule -> ('self, 'r) any_ty_rule
+
+let rec ty_rule_of_gram = function
+| [] -> AnyTyRule TyStop
+| GramTerminal s :: rem ->
+ let AnyTyRule rem = ty_rule_of_gram rem in
+ let tok = Atoken (Lexer.terminal s) in
+ let r = TyNext (rem, tok, None) in
+ AnyTyRule r
+| GramNonTerminal (_, t, tok) :: rem ->
+ let AnyTyRule rem = ty_rule_of_gram rem in
+ let inj = Some (fun obj -> Genarg.in_gen t obj) in
+ let r = TyNext (rem, tok, inj) in
+ AnyTyRule r
+
+let rec ty_erase : type s a r. (s, a, r) ty_rule -> (s, a, r) Extend.rule = function
+| TyStop -> Extend.Stop
+| TyNext (rem, tok, _) -> Extend.Next (ty_erase rem, tok)
+
+type 'r gen_eval = Loc.t -> raw_generic_argument list -> 'r
-let make_prod_item = function
- | GramTerminal s -> (gram_token_of_string s, None)
- | GramNonTerminal (_,t,e,po) ->
- (symbol_of_prod_entry_key e, Option.map (fun p -> (p,t)) po)
+let rec ty_eval : type s a. (s, a, Loc.t -> s) ty_rule -> s gen_eval -> a = function
+| TyStop -> fun f loc -> f loc []
+| TyNext (rem, tok, None) -> fun f _ -> ty_eval rem f
+| TyNext (rem, tok, Some inj) -> fun f x ->
+ let f loc args = f loc (inj x :: args) in
+ ty_eval rem f
-let make_rule mkact pt =
- let (symbs,ntl) = List.split (List.map make_prod_item pt) in
- let act = make_generic_action mkact ntl in
- (symbs, act)
+let make_rule f prod =
+ let AnyTyRule ty_rule = ty_rule_of_gram (List.rev prod) in
+ let symb = ty_erase ty_rule in
+ let f loc l = f loc (List.rev l) in
+ let act = ty_eval ty_rule f in
+ Extend.Rule (symb, act)
(** Vernac grammar extensions *)
@@ -58,6 +78,6 @@ let get_extend_vernac_rule (s, i) =
let extend_vernac_command_grammar s nt gl =
let nt = Option.default Vernac_.command nt in
vernac_exts := (s,gl) :: !vernac_exts;
- let mkact loc l = VernacExtend (s,List.map snd l) in
+ let mkact loc l = VernacExtend (s, l) in
let rules = [make_rule mkact gl] in
- maybe_uncurry (Gram.extend nt) (None,[(None, None, List.rev rules)])
+ grammar_extend nt None (None, [None, None, rules])
diff --git a/parsing/egramml.mli b/parsing/egramml.mli
index f71c368a4..edf971574 100644
--- a/parsing/egramml.mli
+++ b/parsing/egramml.mli
@@ -6,24 +6,26 @@
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
+open Vernacexpr
+
(** Mapping of grammar productions to camlp4 actions. *)
(** This is the part specific to vernac extensions.
For the Coq-level Notation and Tactic Notation, see Egramcoq. *)
-type grammar_prod_item =
+type 's grammar_prod_item =
| GramTerminal of string
- | GramNonTerminal of Loc.t * Genarg.argument_type *
- Pcoq.prod_entry_key * Names.Id.t option
+ | GramNonTerminal : Loc.t * 'a Genarg.raw_abstract_argument_type *
+ ('s, 'a) Pcoq.entry_key -> 's grammar_prod_item
val extend_vernac_command_grammar :
- Vernacexpr.extend_name -> Vernacexpr.vernac_expr Pcoq.Gram.entry option ->
- grammar_prod_item list -> unit
+ Vernacexpr.extend_name -> vernac_expr Pcoq.Gram.entry option ->
+ vernac_expr grammar_prod_item list -> unit
-val get_extend_vernac_rule : Vernacexpr.extend_name -> grammar_prod_item list
+val get_extend_vernac_rule : Vernacexpr.extend_name -> vernac_expr grammar_prod_item list
(** Utility function reused in Egramcoq : *)
val make_rule :
- (Loc.t -> (Names.Id.t * Genarg.raw_generic_argument) list -> 'b) ->
- grammar_prod_item list -> Pcoq.Gram.symbol list * Pcoq.Gram.action
+ (Loc.t -> Genarg.raw_generic_argument list -> 'a) ->
+ 'a grammar_prod_item list -> 'a Extend.production_rule
diff --git a/parsing/entry.ml b/parsing/entry.ml
new file mode 100644
index 000000000..0519903d3
--- /dev/null
+++ b/parsing/entry.ml
@@ -0,0 +1,59 @@
+(************************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2015 *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(************************************************************************)
+
+open Errors
+open Util
+
+type 'a t = string * string
+
+type repr = string * string
+
+type universe = string
+
+(* The univ_tab is not part of the state. It contains all the grammars that
+ exist or have existed before in the session. *)
+
+let univ_tab = (Hashtbl.create 7 : (string, unit) Hashtbl.t)
+
+let create_univ s =
+ Hashtbl.add univ_tab s (); s
+
+let univ_name s = s
+
+let uprim = create_univ "prim"
+let uconstr = create_univ "constr"
+let utactic = create_univ "tactic"
+let uvernac = create_univ "vernac"
+
+let get_univ s =
+ try
+ Hashtbl.find univ_tab s; s
+ with Not_found ->
+ anomaly (Pp.str ("Unknown grammar universe: "^s))
+
+(** Entries are registered with a unique name *)
+
+let entries = ref String.Set.empty
+
+let create u name =
+ let uname = u ^ ":" ^ name in
+ let () =
+ if String.Set.mem uname !entries then
+ anomaly (Pp.str ("Entry " ^ uname ^ " already defined"))
+ in
+ let () = entries := String.Set.add uname !entries in
+ (u, name)
+
+let dynamic name = ("", name)
+
+let unsafe_of_name (u, s) =
+ let uname = u ^ ":" ^ s in
+ assert (String.Set.mem uname !entries);
+ (u, s)
+
+let repr (u, s) = (u, s)
diff --git a/parsing/entry.mli b/parsing/entry.mli
new file mode 100644
index 000000000..97cd5b110
--- /dev/null
+++ b/parsing/entry.mli
@@ -0,0 +1,44 @@
+(************************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2015 *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(************************************************************************)
+
+(** Typed grammar entries *)
+
+type 'a t
+(** Typed grammar entries. We need to defined them here so that they are
+ marshallable and defined before the Pcoq.Gram module. They are basically
+ unique names made of a universe and an entry name. They should be kept
+ synchronized with the {!Pcoq} entries though. *)
+
+type repr = string * string
+(** Representation of entries. *)
+
+(** Table of Coq statically defined grammar entries *)
+
+type universe
+
+(** There are four predefined universes: "prim", "constr", "tactic", "vernac" *)
+
+val get_univ : string -> universe
+val univ_name : universe -> string
+
+val uprim : universe
+val uconstr : universe
+val utactic : universe
+val uvernac : universe
+
+(** {5 Uniquely defined entries} *)
+
+val create : universe -> string -> 'a t
+(** Create an entry. They should be synchronized with the entries defined in
+ {!Pcoq}. *)
+
+(** {5 Meta-programming} *)
+
+val repr : 'a t -> repr
+
+val unsafe_of_name : (string * string) -> 'a t
diff --git a/parsing/g_constr.ml4 b/parsing/g_constr.ml4
index 5edb7b808..1ac260ebe 100644
--- a/parsing/g_constr.ml4
+++ b/parsing/g_constr.ml4
@@ -224,10 +224,7 @@ GEXTEND Gram
] ]
;
record_declaration:
- [ [ fs = record_fields -> CRecord (!@loc, None, fs)
-(* | c = lconstr; "with"; fs = LIST1 record_field_declaration SEP ";" -> *)
-(* CRecord (!@loc, Some c, fs) *)
- ] ]
+ [ [ fs = record_fields -> CRecord (!@loc, fs) ] ]
;
record_fields:
@@ -267,14 +264,14 @@ GEXTEND Gram
CLetTuple (!@loc,lb,po,c1,c2)
| "let"; "'"; p=pattern; ":="; c1 = operconstr LEVEL "200";
"in"; c2 = operconstr LEVEL "200" ->
- CCases (!@loc, LetPatternStyle, None, [(c1,(None,None))], [(!@loc, [(!@loc,[p])], c2)])
+ CCases (!@loc, LetPatternStyle, None, [c1, None, None], [(!@loc, [(!@loc,[p])], c2)])
| "let"; "'"; p=pattern; ":="; c1 = operconstr LEVEL "200";
rt = case_type; "in"; c2 = operconstr LEVEL "200" ->
- CCases (!@loc, LetPatternStyle, Some rt, [(c1, (aliasvar p, None))], [(!@loc, [(!@loc, [p])], c2)])
+ CCases (!@loc, LetPatternStyle, Some rt, [c1, aliasvar p, None], [(!@loc, [(!@loc, [p])], c2)])
| "let"; "'"; p=pattern; "in"; t = pattern LEVEL "200";
":="; c1 = operconstr LEVEL "200"; rt = case_type;
"in"; c2 = operconstr LEVEL "200" ->
- CCases (!@loc, LetPatternStyle, Some rt, [(c1, (aliasvar p, Some t))], [(!@loc, [(!@loc, [p])], c2)])
+ CCases (!@loc, LetPatternStyle, Some rt, [c1, aliasvar p, Some t], [(!@loc, [(!@loc, [p])], c2)])
| "if"; c=operconstr LEVEL "200"; po = return_type;
"then"; b1=operconstr LEVEL "200";
"else"; b2=operconstr LEVEL "200" ->
@@ -338,11 +335,10 @@ GEXTEND Gram
br=branches; "end" -> CCases(!@loc,RegularStyle,ty,ci,br) ] ]
;
case_item:
- [ [ c=operconstr LEVEL "100"; p=pred_pattern -> (c,p) ] ]
- ;
- pred_pattern:
- [ [ ona = OPT ["as"; id=name -> id];
- ty = OPT ["in"; t=pattern -> t] -> (ona,ty) ] ]
+ [ [ c=operconstr LEVEL "100";
+ ona = OPT ["as"; id=name -> id];
+ ty = OPT ["in"; t=pattern -> t] ->
+ (c,ona,ty) ] ]
;
case_type:
[ [ "return"; ty = operconstr LEVEL "100" -> ty ] ]
diff --git a/parsing/g_ltac.ml4 b/parsing/g_ltac.ml4
index 959b0e89f..12d53030d 100644
--- a/parsing/g_ltac.ml4
+++ b/parsing/g_ltac.ml4
@@ -29,6 +29,12 @@ let genarg_of_unit () = in_gen (rawwit Stdarg.wit_unit) ()
let genarg_of_int n = in_gen (rawwit Stdarg.wit_int) n
let genarg_of_ipattern pat = in_gen (rawwit Constrarg.wit_intro_pattern) pat
+let reference_to_id = function
+ | Libnames.Ident (loc, id) -> (loc, id)
+ | Libnames.Qualid (loc,_) ->
+ Errors.user_err_loc (loc, "",
+ str "This expression should be a simple identifier.")
+
(* Tactics grammar rules *)
GEXTEND Gram
@@ -250,9 +256,16 @@ GEXTEND Gram
(* Definitions for tactics *)
tacdef_body:
[ [ name = Constr.global; it=LIST1 input_fun; redef = ltac_def_kind; body = tactic_expr ->
- (name, redef, TacFun (it, body))
+ if redef then Vernacexpr.TacticRedefinition (name, TacFun (it, body))
+ else
+ let id = reference_to_id name in
+ Vernacexpr.TacticDefinition (id, TacFun (it, body))
| name = Constr.global; redef = ltac_def_kind; body = tactic_expr ->
- (name, redef, body) ] ]
+ if redef then Vernacexpr.TacticRedefinition (name, body)
+ else
+ let id = reference_to_id name in
+ Vernacexpr.TacticDefinition (id, body)
+ ] ]
;
tactic:
[ [ tac = tactic_expr -> tac ] ]
diff --git a/parsing/g_prim.ml4 b/parsing/g_prim.ml4
index 5297c163b..5e67e9957 100644
--- a/parsing/g_prim.ml4
+++ b/parsing/g_prim.ml4
@@ -32,7 +32,7 @@ let my_int_of_string loc s =
GEXTEND Gram
GLOBAL:
- bigint natural integer identref name ident var preident
+ bigint natural index integer identref name ident var preident
fullyqualid qualid reference dirpath ne_lstring
ne_string string pattern_ident pattern_identref by_notation smart_global;
preident:
@@ -113,6 +113,9 @@ GEXTEND Gram
natural:
[ [ i = INT -> my_int_of_string (!@loc) i ] ]
;
+ index:
+ [ [ i = INDEX -> my_int_of_string (!@loc) i ] ]
+ ;
bigint: (* Negative numbers are dealt with specially *)
[ [ i = INT -> (Bigint.of_string i) ] ]
;
diff --git a/parsing/g_tactic.ml4 b/parsing/g_tactic.ml4
index 2a00a1764..77b7b05a3 100644
--- a/parsing/g_tactic.ml4
+++ b/parsing/g_tactic.ml4
@@ -231,7 +231,7 @@ GEXTEND Gram
[ [ id = identref -> id ] ]
;
open_constr:
- [ [ c = constr -> ((),c) ] ]
+ [ [ c = constr -> c ] ]
;
uconstr:
[ [ c = constr -> c ] ]
@@ -240,7 +240,7 @@ GEXTEND Gram
[ [ n = natural -> (None,ElimOnAnonHyp n)
| test_lpar_id_rpar; c = constr_with_bindings ->
(Some false,induction_arg_of_constr c)
- | c = constr_with_bindings -> (None,induction_arg_of_constr c)
+ | c = constr_with_bindings_arg -> on_snd induction_arg_of_constr c
] ]
;
constr_with_bindings_arg:
@@ -281,19 +281,23 @@ GEXTEND Gram
intropatterns:
[ [ l = LIST0 nonsimple_intropattern -> l ]]
;
+ ne_intropatterns:
+ [ [ l = LIST1 nonsimple_intropattern -> l ]]
+ ;
or_and_intropattern:
- [ [ "["; tc = LIST1 intropatterns SEP "|"; "]" -> tc
- | "()" -> [[]]
- | "("; si = simple_intropattern; ")" -> [[si]]
+ [ [ "["; tc = LIST1 intropatterns SEP "|"; "]" -> IntroOrPattern tc
+ | "()" -> IntroAndPattern []
+ | "("; si = simple_intropattern; ")" -> IntroAndPattern [si]
| "("; si = simple_intropattern; ",";
- tc = LIST1 simple_intropattern SEP "," ; ")" -> [si::tc]
+ tc = LIST1 simple_intropattern SEP "," ; ")" ->
+ IntroAndPattern (si::tc)
| "("; si = simple_intropattern; "&";
tc = LIST1 simple_intropattern SEP "&" ; ")" ->
(* (A & B & C) is translated into (A,(B,C)) *)
let rec pairify = function
- | ([]|[_]|[_;_]) as l -> [l]
- | t::q -> [[t;(loc_of_ne_list q,IntroAction (IntroOrAndPattern (pairify q)))]]
- in pairify (si::tc) ] ]
+ | ([]|[_]|[_;_]) as l -> l
+ | t::q -> [t;(loc_of_ne_list q,IntroAction (IntroOrAndPattern (IntroAndPattern (pairify q))))]
+ in IntroAndPattern (pairify (si::tc)) ] ]
;
equality_intropattern:
[ [ "->" -> IntroRewrite true
@@ -450,15 +454,6 @@ GEXTEND Gram
[ [ check_for_coloneq; "("; id = ident; bl = LIST0 simple_binder;
":="; c = lconstr; ")" -> (id, mkCLambdaN_simple bl c) ] ]
;
- hintbases:
- [ [ "with"; "*" -> None
- | "with"; l = LIST1 [ x = IDENT -> x] -> Some l
- | -> Some [] ] ]
- ;
- auto_using:
- [ [ "using"; l = LIST1 constr SEP "," -> l
- | -> [] ] ]
- ;
eliminator:
[ [ "using"; el = constr_with_bindings -> el ] ]
;
@@ -499,12 +494,12 @@ GEXTEND Gram
[ [ id1 = id_or_meta; IDENT "into"; id2 = id_or_meta -> (id1,id2) ] ]
;
rewriter :
- [ [ "!"; c = constr_with_bindings -> (RepeatPlus,(None,c))
+ [ [ "!"; c = constr_with_bindings_arg -> (RepeatPlus,c)
| ["?"| LEFTQMARK]; c = constr_with_bindings_arg -> (RepeatStar,c)
- | n = natural; "!"; c = constr_with_bindings -> (Precisely n,(None,c))
+ | n = natural; "!"; c = constr_with_bindings_arg -> (Precisely n,c)
| n = natural; ["?" | LEFTQMARK]; c = constr_with_bindings_arg -> (UpTo n,c)
| n = natural; c = constr_with_bindings_arg -> (Precisely n,c)
- | c = constr_with_bindings -> (Precisely 1, (None,c))
+ | c = constr_with_bindings_arg -> (Precisely 1, c)
] ]
;
oriented_rewriter :
@@ -532,7 +527,10 @@ GEXTEND Gram
simple_tactic:
[ [
(* Basic tactics *)
- IDENT "intros"; pl = intropatterns -> TacAtom (!@loc, TacIntroPattern pl)
+ IDENT "intros"; pl = ne_intropatterns ->
+ TacAtom (!@loc, TacIntroPattern pl)
+ | IDENT "intros" ->
+ TacAtom (!@loc, TacIntroPattern [!@loc,IntroForthcoming false])
| IDENT "intro"; id = ident; hto = move_location ->
TacAtom (!@loc, TacIntroMove (Some id, hto))
| IDENT "intro"; hto = move_location -> TacAtom (!@loc, TacIntroMove (None, hto))
@@ -623,20 +621,6 @@ GEXTEND Gram
| IDENT "edestruct"; icl = induction_clause_list ->
TacAtom (!@loc, TacInductionDestruct(false,true,icl))
- (* Automation tactic *)
- | IDENT "trivial"; lems = auto_using; db = hintbases ->
- TacAtom (!@loc, TacTrivial (Off, lems, db))
- | IDENT "info_trivial"; lems = auto_using; db = hintbases ->
- TacAtom (!@loc, TacTrivial (Info, lems, db))
- | IDENT "debug"; IDENT "trivial"; lems = auto_using; db = hintbases ->
- TacAtom (!@loc, TacTrivial (Debug, lems, db))
- | IDENT "auto"; n = OPT int_or_var; lems = auto_using; db = hintbases ->
- TacAtom (!@loc, TacAuto (Off, n, lems, db))
- | IDENT "info_auto"; n = OPT int_or_var; lems = auto_using; db = hintbases ->
- TacAtom (!@loc, TacAuto (Info, n, lems, db))
- | IDENT "debug"; IDENT "auto"; n = OPT int_or_var; lems = auto_using; db = hintbases ->
- TacAtom (!@loc, TacAuto (Debug, n, lems, db))
-
(* Context management *)
| IDENT "clear"; "-"; l = LIST1 id_or_meta -> TacAtom (!@loc, TacClear (true, l))
| IDENT "clear"; l = LIST0 id_or_meta ->
diff --git a/parsing/g_vernac.ml4 b/parsing/g_vernac.ml4
index 839f768b9..b7b9e2a6a 100644
--- a/parsing/g_vernac.ml4
+++ b/parsing/g_vernac.ml4
@@ -89,8 +89,8 @@ let default_command_entry =
GEXTEND Gram
GLOBAL: vernac gallina_ext tactic_mode noedit_mode subprf subgoal_command;
vernac: FIRST
- [ [ IDENT "Time"; l = vernac_list -> VernacTime l
- | IDENT "Redirect"; s = ne_string; l = vernac_list -> VernacRedirect (s, l)
+ [ [ IDENT "Time"; c = located_vernac -> VernacTime c
+ | IDENT "Redirect"; s = ne_string; c = located_vernac -> VernacRedirect (s, c)
| IDENT "Timeout"; n = natural; v = vernac -> VernacTimeout(n,v)
| IDENT "Fail"; v = vernac -> VernacFail v
@@ -128,9 +128,6 @@ GEXTEND Gram
| c = subprf -> c
] ]
;
- vernac_list:
- [ [ c = located_vernac -> [c] ] ]
- ;
vernac_aux: LAST
[ [ prfcom = default_command_entry -> prfcom ] ]
;
@@ -177,13 +174,13 @@ GEXTEND Gram
;
END
-let test_plurial_form = function
+let test_plural_form = function
| [(_,([_],_))] ->
Flags.if_verbose msg_warning
(strbrk "Keywords Variables/Hypotheses/Parameters expect more than one assumption")
| _ -> ()
-let test_plurial_form_types = function
+let test_plural_form_types = function
| [([_],_)] ->
Flags.if_verbose msg_warning
(strbrk "Keywords Implicit Types expect more than one type")
@@ -204,7 +201,7 @@ GEXTEND Gram
| stre = assumption_token; nl = inline; bl = assum_list ->
VernacAssumption (stre, nl, bl)
| stre = assumptions_token; nl = inline; bl = assum_list ->
- test_plurial_form bl;
+ test_plural_form bl;
VernacAssumption (stre, nl, bl)
| d = def_token; id = pidentref; b = def_body ->
VernacDefinition (d, id, b)
@@ -736,7 +733,7 @@ GEXTEND Gram
VernacReserve bl
| IDENT "Implicit"; IDENT "Types"; bl = reserv_list ->
- test_plurial_form_types bl;
+ test_plural_form_types bl;
VernacReserve bl
| IDENT "Generalizable";
@@ -806,7 +803,7 @@ GEXTEND Gram
command:
[ [ IDENT "Ltac";
l = LIST1 tacdef_body SEP "with" ->
- VernacDeclareTacticDefinition (true, l)
+ VernacDeclareTacticDefinition l
| IDENT "Comments"; l = LIST0 comment -> VernacComments l
@@ -1168,7 +1165,7 @@ GEXTEND Gram
production_item:
[ [ s = ne_string -> TacTerm s
| nt = IDENT;
- po = OPT [ "("; p = ident; sep = [ -> "" | ","; sep = STRING -> sep ];
+ po = [ "("; p = ident; sep = [ -> "" | ","; sep = STRING -> sep ];
")" -> (p,sep) ] -> TacNonTerm (!@loc,nt,po) ] ]
;
END
diff --git a/parsing/lexer.ml4 b/parsing/lexer.ml4
index 5d96873f3..74e05ce84 100644
--- a/parsing/lexer.ml4
+++ b/parsing/lexer.ml4
@@ -8,7 +8,6 @@
open Pp
open Util
-open Compat
open Tok
(* Dictionaries: trees annotated with string options, each node being a map
@@ -81,6 +80,7 @@ module Error = struct
| Undefined_token
| Bad_token of string
| UnsupportedUnicode of int
+ | IncorrectIndex of char list
exception E of t
@@ -93,7 +93,16 @@ module Error = struct
| Undefined_token -> "Undefined token"
| Bad_token tok -> Format.sprintf "Bad token %S" tok
| UnsupportedUnicode x ->
- Printf.sprintf "Unsupported Unicode character (0x%x)" x)
+ Printf.sprintf "Unsupported Unicode character (0x%x)" x
+ | IncorrectIndex l ->
+ let l = List.map (fun c -> Char.code c - 48) l in
+ let s = match l with
+ | c::d::l ->
+ let l = List.map string_of_int (List.rev l) in
+ String.concat "" l ^ CString.ordinal (10 * d + c)
+ | [c] -> CString.ordinal c
+ | [] -> assert false in
+ Printf.sprintf "%s expected" s)
(* Require to fix the Camlp4 signature *)
let print ppf x = Pp.pp_with ppf (Pp.str (to_string x))
@@ -263,9 +272,38 @@ let rec ident_tail len = parser
ident_tail (nstore n len s) s
| _ -> len
-let rec number len = parser
- | [< ' ('0'..'9' as c); s >] -> number (store len c) s
- | [< >] -> len
+let check_no_char s =
+ match Stream.npeek 3 s with
+ | [_;_;('a'..'z' | 'A'..'Z' | '0'..'9' | ''' | '_')] -> false
+ | [_;_;_] -> true
+ | [_;_] -> true
+ | _ -> assert false
+
+let is_teen = function
+ | _::'1'::l -> true
+ | _ -> false
+
+let is_gt3 = function
+ | c::_ when c == '1' || c == '2' || c == '3' -> false
+ | _ -> true
+
+let check_gt3 l loc len =
+ if not (l == ['0']) && (is_teen l || is_gt3 l) then (false, len)
+ else err loc (IncorrectIndex l)
+
+let check_n n l loc len =
+ if List.hd l == n && not (is_teen l) then (false, len)
+ else err loc (IncorrectIndex l)
+
+let rec number_or_index bp l len = parser
+ | [< ' ('0'..'9' as c); s >] -> number_or_index bp (c::l) (store len c) s
+ | [< s >] ep ->
+ match Stream.npeek 2 s with
+ | ['s';'t'] when check_no_char s -> njunk 2 s; check_n '1' l (bp,ep) len
+ | ['n';'d'] when check_no_char s -> njunk 2 s; check_n '2' l (bp,ep) len
+ | ['r';'d'] when check_no_char s -> njunk 2 s; check_n '3' l (bp,ep) len
+ | ['t';'h'] when check_no_char s -> njunk 2 s; check_gt3 l (bp,ep) len
+ | _ -> true, len
let rec string in_comments bp len = parser
| [< ''"'; esc=(parser [<''"' >] -> true | [< >] -> false); s >] ->
@@ -520,9 +558,9 @@ let rec next_token = parser bp
let id = get_buff len in
comment_stop bp;
(try find_keyword id s with Not_found -> IDENT id), (bp, ep)
- | [< ' ('0'..'9' as c); len = number (store 0 c) >] ep ->
+ | [< ' ('0'..'9' as c); (b,len) = number_or_index bp [c] (store 0 c) >] ep ->
comment_stop bp;
- (INT (get_buff len), (bp, ep))
+ (if b then INT (get_buff len) else INDEX (get_buff len)), (bp, ep)
| [< ''\"'; len = string None bp 0 >] ep ->
comment_stop bp;
(STRING (get_buff len), (bp, ep))
@@ -571,7 +609,7 @@ let loct_add loct i loc = Hashtbl.add loct i loc
let current_location_table = ref (loct_create ())
-type location_table = (int, CompatLoc.t) Hashtbl.t
+type location_table = (int, Compat.CompatLoc.t) Hashtbl.t
let location_table () = !current_location_table
let restore_location_table t = current_location_table := t
@@ -608,7 +646,7 @@ let func cs =
Stream.from
(fun i ->
let (tok, loc) = next_token cs in
- loct_add loct i (make_loc loc); Some tok)
+ loct_add loct i (Compat.make_loc loc); Some tok)
in
current_location_table := loct;
(ts, loct_func loct)
@@ -628,10 +666,10 @@ ELSE (* official camlp4 for ocaml >= 3.10 *)
module M_ = Camlp4.ErrorHandler.Register (Error)
-module Loc = CompatLoc
+module Loc = Compat.CompatLoc
module Token = struct
include Tok (* Cf. tok.ml *)
- module Loc = CompatLoc
+ module Loc = Compat.CompatLoc
module Error = Camlp4.Struct.EmptyError
module Filter = struct
type token_filter = (Tok.t * Loc.t) Stream.t -> (Tok.t * Loc.t) Stream.t
@@ -649,7 +687,7 @@ let mk () _init_loc(*FIXME*) cs =
let rec self =
parser i
[< (tok, loc) = next_token; s >] ->
- let loc = make_loc loc in
+ let loc = Compat.make_loc loc in
loct_add loct i loc;
[< '(tok, loc); self s >]
| [< >] -> [< >]
diff --git a/parsing/parsing.mllib b/parsing/parsing.mllib
index a0cb83193..024d8607f 100644
--- a/parsing/parsing.mllib
+++ b/parsing/parsing.mllib
@@ -1,6 +1,7 @@
Tok
Compat
Lexer
+Entry
Pcoq
Egramml
Egramcoq
diff --git a/parsing/pcoq.ml4 b/parsing/pcoq.ml
index 32dbeaa4d..0525ffb77 100644
--- a/parsing/pcoq.ml4
+++ b/parsing/pcoq.ml
@@ -20,37 +20,11 @@ open Tok (* necessary for camlp4 *)
module G = GrammarMake (Lexer)
-(* TODO: this is a workaround, since there isn't such
- [warning_verbose] in new camlp4. In camlp5, this ref
- gets hidden by [Gramext.warning_verbose] *)
-let warning_verbose = ref true
-
-IFDEF CAMLP5 THEN
-open Gramext
-ELSE
-open PcamlSig.Grammar
-open G
-END
-
-(** Compatibility with Camlp5 6.x *)
-
-IFDEF CAMLP5_6_00 THEN
-let slist0sep x y = Slist0sep (x, y, false)
-let slist1sep x y = Slist1sep (x, y, false)
-ELSE
-let slist0sep x y = Slist0sep (x, y)
-let slist1sep x y = Slist1sep (x, y)
-END
-
-let gram_token_of_token tok =
-IFDEF CAMLP5 THEN
- Stoken (Tok.to_pattern tok)
-ELSE
- match tok with
- | KEYWORD s -> Skeyword s
- | tok -> Stoken ((=) tok, to_string tok)
-END
+let warning_verbose = Compat.warning_verbose
+module Symbols = GramextMake(G)
+
+let gram_token_of_token = Symbols.stoken
let gram_token_of_string s = gram_token_of_token (Lexer.terminal s)
let camlp4_verbosity silent f x =
@@ -62,26 +36,6 @@ let camlp4_verbosity silent f x =
let camlp4_verbose f x = camlp4_verbosity (Flags.is_verbose ()) f x
-(** General entry keys *)
-
-(** This intermediate abstract representation of entries can
- both be reified into mlexpr for the ML extensions and
- dynamically interpreted as entries for the Coq level extensions
-*)
-
-type prod_entry_key =
- | Alist1 of prod_entry_key
- | Alist1sep of prod_entry_key * string
- | Alist0 of prod_entry_key
- | Alist0sep of prod_entry_key * string
- | Aopt of prod_entry_key
- | Amodifiers of prod_entry_key
- | Aself
- | Anext
- | Atactic of int
- | Agram of string
- | Aentry of string * string
-
(** [grammar_object] is the superclass of all grammar entries *)
module type Gramobj =
@@ -98,31 +52,33 @@ end
(** Grammar entries with associated types *)
-type entry_type = argument_type
type grammar_object = Gramobj.grammar_object
-type typed_entry = argument_type * grammar_object G.entry
-let in_typed_entry t e = (t,Gramobj.weaken_entry e)
-let type_of_typed_entry (t,e) = t
-let object_of_typed_entry (t,e) = e
+type typed_entry = TypedEntry : 'a raw_abstract_argument_type * 'a G.entry -> typed_entry
+let object_of_typed_entry (TypedEntry (_, e)) = Gramobj.weaken_entry e
let weaken_entry x = Gramobj.weaken_entry x
-module type Gramtypes =
-sig
- val inGramObj : 'a raw_abstract_argument_type -> 'a G.entry -> typed_entry
- val outGramObj : 'a raw_abstract_argument_type -> typed_entry -> 'a G.entry
-end
+(** General entry keys *)
-module Gramtypes : Gramtypes =
-struct
- let inGramObj rawwit = in_typed_entry (unquote rawwit)
- let outGramObj (a:'a raw_abstract_argument_type) o =
- if not (argument_type_eq (type_of_typed_entry o) (unquote a))
- then anomaly ~label:"outGramObj" (str "wrong type");
- (* downcast from grammar_object *)
- Obj.magic (object_of_typed_entry o)
-end
+(** This intermediate abstract representation of entries can
+ both be reified into mlexpr for the ML extensions and
+ dynamically interpreted as entries for the Coq level extensions
+*)
-open Gramtypes
+type ('self, 'a) entry_key = ('self, 'a) Extend.symbol =
+| Atoken : Tok.t -> ('self, string) entry_key
+| Alist1 : ('self, 'a) entry_key -> ('self, 'a list) entry_key
+| Alist1sep : ('self, 'a) entry_key * string -> ('self, 'a list) entry_key
+| Alist0 : ('self, 'a) entry_key -> ('self, 'a list) entry_key
+| Alist0sep : ('self, 'a) entry_key * string -> ('self, 'a list) entry_key
+| Aopt : ('self, 'a) entry_key -> ('self, 'a option) entry_key
+| Amodifiers : ('self, 'a) entry_key -> ('self, 'a list) entry_key
+| Aself : ('self, 'self) entry_key
+| Anext : ('self, 'self) entry_key
+| Aentry : 'a Entry.t -> ('self, 'a) entry_key
+| Aentryl : 'a Entry.t * int -> ('self, 'a) entry_key
+
+type 's entry_name = EntryName :
+ 'a raw_abstract_argument_type * ('s, 'a) entry_key -> 's entry_name
(** Grammar extensions *)
@@ -158,7 +114,10 @@ let grammar_delete e reinit (pos,rls) =
(List.rev rls);
match reinit with
| Some (a,ext) ->
- let lev = match pos with Some (Level n) -> n | _ -> assert false in
+ let lev = match Option.map Compat.to_coq_position pos with
+ | Some (Level n) -> n
+ | _ -> assert false
+ in
maybe_uncurry (G.extend e) (Some ext, [Some lev,Some a,[]])
| None -> ()
@@ -190,7 +149,7 @@ module Gram =
(** This extension command is used by the Grammar constr *)
-let grammar_extend e reinit ext =
+let unsafe_grammar_extend e reinit ext =
camlp4_state := ByGrammar (weaken_entry e,reinit,ext) :: !camlp4_state;
camlp4_verbose (maybe_uncurry (G.extend e)) ext
@@ -215,22 +174,22 @@ let rec remove_grammars n =
redo();
camlp4_state := ByEXTEND (undo,redo) :: !camlp4_state)
+let make_rule r = [None, None, r]
+
(** An entry that checks we reached the end of the input. *)
let eoi_entry en =
let e = Gram.entry_create ((Gram.Entry.name en) ^ "_eoi") in
- GEXTEND Gram
- e: [ [ x = en; EOI -> x ] ]
- ;
- END;
+ let symbs = [Symbols.snterm (Gram.Entry.obj en); Symbols.stoken Tok.EOI] in
+ let act = Gram.action (fun _ x loc -> x) in
+ maybe_uncurry (Gram.extend e) (None, make_rule [symbs, act]);
e
let map_entry f en =
let e = Gram.entry_create ((Gram.Entry.name en) ^ "_map") in
- GEXTEND Gram
- e: [ [ x = en -> f x ] ]
- ;
- END;
+ let symbs = [Symbols.snterm (Gram.Entry.obj en)] in
+ let act = Gram.action (fun x loc -> f x) in
+ maybe_uncurry (Gram.extend e) (None, make_rule [symbs, act]);
e
(* Parse a string, does NOT check if the entire string was read
@@ -239,58 +198,70 @@ let map_entry f en =
let parse_string f x =
let strm = Stream.of_string x in Gram.entry_parse f (Gram.parsable strm)
-type gram_universe = string * (string, typed_entry) Hashtbl.t
+type gram_universe = Entry.universe
let trace = ref false
-(* The univ_tab is not part of the state. It contains all the grammars that
- exist or have existed before in the session. *)
+let uprim = Entry.uprim
+let uconstr = Entry.uconstr
+let utactic = Entry.utactic
+let uvernac = Entry.uvernac
+let get_univ = Entry.get_univ
-let univ_tab = (Hashtbl.create 7 : (string, gram_universe) Hashtbl.t)
+let utables : (string, (string, typed_entry) Hashtbl.t) Hashtbl.t =
+ Hashtbl.create 97
-let create_univ s =
- let u = s, Hashtbl.create 29 in Hashtbl.add univ_tab s u; u
-
-let uprim = create_univ "prim"
-let uconstr = create_univ "constr"
-let utactic = create_univ "tactic"
-let uvernac = create_univ "vernac"
-
-let get_univ s =
- try
- Hashtbl.find univ_tab s
+let get_utable u =
+ let u = Entry.univ_name u in
+ try Hashtbl.find utables u
with Not_found ->
- anomaly (Pp.str ("Unknown grammar universe: "^s))
-
-let get_entry (u, utab) s = Hashtbl.find utab s
-
-let new_entry etyp (u, utab) s =
- if !trace then (Printf.eprintf "[Creating entry %s:%s]\n" u s; flush stderr);
- let ename = u ^ ":" ^ s in
- let e = in_typed_entry etyp (Gram.entry_create ename) in
- Hashtbl.add utab s e; e
-
-let create_entry (u, utab) s etyp =
+ let table = Hashtbl.create 97 in
+ Hashtbl.add utables u table;
+ table
+
+let get_entry u s =
+ let utab = get_utable u in
+ Hashtbl.find utab s
+
+let get_typed_entry e =
+ let (u, s) = Entry.repr e in
+ let u = Entry.get_univ u in
+ get_entry u s
+
+let new_entry etyp u s =
+ let utab = get_utable u in
+ let uname = Entry.univ_name u in
+ if !trace then (Printf.eprintf "[Creating entry %s:%s]\n" uname s; flush stderr);
+ let _ = Entry.create u s in
+ let ename = uname ^ ":" ^ s in
+ let e = Gram.entry_create ename in
+ Hashtbl.add utab s (TypedEntry (etyp, e)); e
+
+let create_entry (type a) u s (etyp : a raw_abstract_argument_type) : a Gram.entry =
+ let utab = get_utable u in
try
- let e = Hashtbl.find utab s in
- if not (argument_type_eq (type_of_typed_entry e) etyp) then
+ let TypedEntry (typ, e) = Hashtbl.find utab s in
+ match abstract_argument_type_eq typ etyp with
+ | None ->
+ let u = Entry.univ_name u in
failwith ("Entry " ^ u ^ ":" ^ s ^ " already exists with another type");
- e
+ | Some Refl -> e
with Not_found ->
- new_entry etyp (u, utab) s
+ new_entry etyp u s
-let create_constr_entry s =
- outGramObj (rawwit wit_constr) (create_entry uconstr s ConstrArgType)
+let create_constr_entry s = create_entry uconstr s (rawwit wit_constr)
-let create_generic_entry s wit =
- outGramObj wit (create_entry utactic s (unquote wit))
+let create_generic_entry s wit = create_entry utactic s wit
(* [make_gen_entry] builds entries extensible by giving its name (a string) *)
(* For entries extensible only via the ML name, Gram.entry_create is enough *)
-let make_gen_entry (u,univ) rawwit s =
- let e = Gram.entry_create (u ^ ":" ^ s) in
- Hashtbl.add univ s (inGramObj rawwit e); e
+let make_gen_entry u rawwit s =
+ let univ = get_utable u in
+ let uname = Entry.univ_name u in
+ let e = Gram.entry_create (uname ^ ":" ^ s) in
+ let _ = Entry.create u s in
+ Hashtbl.add univ s (TypedEntry (rawwit, e)); e
(* Initial grammar entries *)
@@ -303,6 +274,7 @@ module Prim =
let preident = gec_gen (rawwit wit_pre_ident) "preident"
let ident = gec_gen (rawwit wit_ident) "ident"
let natural = gec_gen (rawwit wit_int) "natural"
+ let index = gec_gen (rawwit wit_int) "index"
let integer = gec_gen (rawwit wit_int) "integer"
let bigint = Gram.entry_create "Prim.bigint"
let string = gec_gen (rawwit wit_string) "string"
@@ -377,7 +349,7 @@ module Tactic =
make_gen_entry utactic (rawwit wit_bindings) "bindings"
let hypident = Gram.entry_create "hypident"
let constr_may_eval = make_gen_entry utactic (rawwit wit_constr_may_eval) "constr_may_eval"
- let constr_eval = make_gen_entry utactic (rawwit wit_constr_may_eval) "constr_may_eval"
+ let constr_eval = make_gen_entry utactic (rawwit wit_constr_may_eval) "constr_eval"
let uconstr =
make_gen_entry utactic (rawwit wit_uconstr) "uconstr"
let quantified_hypothesis =
@@ -392,8 +364,8 @@ module Tactic =
(* Main entries for ltac *)
let tactic_arg = Gram.entry_create "tactic:tactic_arg"
- let tactic_expr = Gram.entry_create "tactic:tactic_expr"
- let binder_tactic = Gram.entry_create "tactic:binder_tactic"
+ let tactic_expr = make_gen_entry utactic (rawwit wit_tactic) "tactic_expr"
+ let binder_tactic = make_gen_entry utactic (rawwit wit_tactic) "binder_tactic"
let tactic = make_gen_entry utactic (rawwit wit_tactic) "tactic"
@@ -420,11 +392,14 @@ module Vernac_ =
(* Main vernac entry *)
let main_entry = Gram.entry_create "vernac"
- GEXTEND Gram
- main_entry:
- [ [ a = vernac -> Some (!@loc, a) | EOI -> None ] ]
- ;
- END
+ let () =
+ let act_vernac = Gram.action (fun v loc -> Some (!@loc, v)) in
+ let act_eoi = Gram.action (fun _ loc -> None) in
+ let rule = [
+ ([ Symbols.stoken Tok.EOI ], act_eoi);
+ ([ Symbols.snterm (Gram.Entry.obj vernac) ], act_vernac );
+ ] in
+ maybe_uncurry (Gram.extend main_entry) (None, make_rule rule)
end
@@ -634,7 +609,10 @@ let compute_entry allow_create adjust forpat = function
let u = get_univ u in
let e =
try get_entry u n
- with Not_found when allow_create -> create_entry u n ConstrArgType in
+ with Not_found when allow_create ->
+ let wit = rawwit wit_constr in
+ TypedEntry (wit, create_entry u n wit)
+ in
object_of_typed_entry e, None, true
(* This computes the name of the level where to add a new rule *)
@@ -679,77 +657,85 @@ let make_sep_rules tkl =
let rec symbol_of_constr_prod_entry_key assoc from forpat typ =
if is_binder_level from typ then
if forpat then
- Snterml (Gram.Entry.obj Constr.pattern,"200")
+ Symbols.snterml (Gram.Entry.obj Constr.pattern,"200")
else
- Snterml (Gram.Entry.obj Constr.operconstr,"200")
+ Symbols.snterml (Gram.Entry.obj Constr.operconstr,"200")
else if is_self from typ then
- Sself
+ Symbols.sself
else
match typ with
| ETConstrList (typ',[]) ->
- Slist1 (symbol_of_constr_prod_entry_key assoc from forpat (ETConstr typ'))
+ Symbols.slist1 (symbol_of_constr_prod_entry_key assoc from forpat (ETConstr typ'))
| ETConstrList (typ',tkl) ->
- slist1sep
- (symbol_of_constr_prod_entry_key assoc from forpat (ETConstr typ'))
- (make_sep_rules tkl)
+ Symbols.slist1sep
+ (symbol_of_constr_prod_entry_key assoc from forpat (ETConstr typ'),
+ make_sep_rules tkl)
| ETBinderList (false,[]) ->
- Slist1
+ Symbols.slist1
(symbol_of_constr_prod_entry_key assoc from forpat (ETBinder false))
| ETBinderList (false,tkl) ->
- slist1sep
- (symbol_of_constr_prod_entry_key assoc from forpat (ETBinder false))
- (make_sep_rules tkl)
+ Symbols.slist1sep
+ (symbol_of_constr_prod_entry_key assoc from forpat (ETBinder false),
+ make_sep_rules tkl)
| _ ->
match interp_constr_prod_entry_key assoc from forpat typ with
- | (eobj,None,_) -> Snterm (Gram.Entry.obj eobj)
- | (eobj,Some None,_) -> Snext
+ | (eobj,None,_) -> Symbols.snterm (Gram.Entry.obj eobj)
+ | (eobj,Some None,_) -> Symbols.snext
| (eobj,Some (Some (lev,cur)),_) ->
- Snterml (Gram.Entry.obj eobj,constr_level lev)
+ Symbols.snterml (Gram.Entry.obj eobj,constr_level lev)
(** Binding general entry keys to symbol *)
-let rec symbol_of_prod_entry_key = function
- | Alist1 s -> Slist1 (symbol_of_prod_entry_key s)
+let rec symbol_of_prod_entry_key : type s a. (s, a) entry_key -> _ = function
+ | Atoken t -> Symbols.stoken t
+ | Alist1 s -> Symbols.slist1 (symbol_of_prod_entry_key s)
| Alist1sep (s,sep) ->
- slist1sep (symbol_of_prod_entry_key s) (gram_token_of_string sep)
- | Alist0 s -> Slist0 (symbol_of_prod_entry_key s)
+ Symbols.slist1sep (symbol_of_prod_entry_key s, gram_token_of_string sep)
+ | Alist0 s -> Symbols.slist0 (symbol_of_prod_entry_key s)
| Alist0sep (s,sep) ->
- slist0sep (symbol_of_prod_entry_key s) (gram_token_of_string sep)
- | Aopt s -> Sopt (symbol_of_prod_entry_key s)
+ Symbols.slist0sep (symbol_of_prod_entry_key s, gram_token_of_string sep)
+ | Aopt s -> Symbols.sopt (symbol_of_prod_entry_key s)
| Amodifiers s ->
Gram.srules'
[([], Gram.action (fun _loc -> []));
([gram_token_of_string "(";
- slist1sep (symbol_of_prod_entry_key s) (gram_token_of_string ",");
+ Symbols.slist1sep (symbol_of_prod_entry_key s, gram_token_of_string ",");
gram_token_of_string ")"],
Gram.action (fun _ l _ _loc -> l))]
- | Aself -> Sself
- | Anext -> Snext
- | Atactic 5 -> Snterm (Gram.Entry.obj Tactic.binder_tactic)
- | Atactic n ->
- Snterml (Gram.Entry.obj Tactic.tactic_expr, string_of_int n)
- | Agram s ->
- let e =
- try
- (** ppedrot: we should always generate Agram entries which have already
- been registered, so this should not fail. *)
- let (u, s) = match String.split ':' s with
- | u :: s :: [] -> (u, s)
- | _ -> raise Not_found
- in
- get_entry (get_univ u) s
- with Not_found ->
- Errors.anomaly (str "Unregistered grammar entry: " ++ str s)
- in
- Snterm (Gram.Entry.obj (object_of_typed_entry e))
- | Aentry (u,s) ->
- let e = get_entry (get_univ u) s in
- Snterm (Gram.Entry.obj (object_of_typed_entry e))
+ | Aself -> Symbols.sself
+ | Anext -> Symbols.snext
+ | Aentry e ->
+ let e = get_typed_entry e in
+ Symbols.snterm (Gram.Entry.obj (object_of_typed_entry e))
+ | Aentryl (e, n) ->
+ let e = get_typed_entry e in
+ Symbols.snterml (Gram.Entry.obj (object_of_typed_entry e), string_of_int n)
+
+let level_of_snterml e = int_of_string (Symbols.snterml_level e)
+
+let rec of_coq_rule : type self a r. (self, a, r) Extend.rule -> _ = function
+| Stop -> fun accu -> accu
+| Next (r, tok) -> fun accu ->
+ let symb = symbol_of_prod_entry_key tok in
+ of_coq_rule r (symb :: accu)
-let level_of_snterml = function
- | Snterml (_,l) -> int_of_string l
- | _ -> failwith "level_of_snterml"
+let rec of_coq_action : type a r. (r, a, Loc.t -> r) Extend.rule -> a -> Gram.action = function
+| Stop -> fun f -> Gram.action (fun loc -> f (to_coqloc loc))
+| Next (r, _) -> fun f -> Gram.action (fun x -> of_coq_action r (f x))
+
+let of_coq_production_rule : type a. a Extend.production_rule -> _ = function
+| Rule (toks, act) -> (of_coq_rule toks [], of_coq_action toks act)
+
+let of_coq_single_extend_statement (lvl, assoc, rule) =
+ (lvl, Option.map of_coq_assoc assoc, List.map of_coq_production_rule rule)
+
+let of_coq_extend_statement (pos, st) =
+ (Option.map of_coq_position pos, List.map of_coq_single_extend_statement st)
+
+let grammar_extend e reinit ext =
+ let ext = of_coq_extend_statement ext in
+ unsafe_grammar_extend e reinit ext
(**********************************************************************)
(* Interpret entry names of the form "ne_constr_list" as entry keys *)
@@ -766,71 +752,103 @@ let coincide s pat off =
done;
!break
-let tactic_level s =
- if Int.equal (String.length s) 7 && coincide s "tactic" 0 then
- let c = s.[6] in if '5' >= c && c >= '0' then Some (Char.code c - 48)
- else None
- else None
-
-let type_of_entry u s =
- type_of_typed_entry (get_entry u s)
+let name_of_entry e = match String.split ':' (Gram.Entry.name e) with
+| u :: s :: [] -> Entry.unsafe_of_name (u, s)
+| _ -> assert false
+
+let atactic n =
+ if n = 5 then Aentry (name_of_entry Tactic.binder_tactic)
+ else Aentryl (name_of_entry Tactic.tactic_expr, n)
+
+let try_get_entry u s =
+ (** Order the effects: get_entry can raise Not_found *)
+ let TypedEntry (typ, _) = get_entry u s in
+ EntryName (typ, Aentry (Entry.unsafe_of_name (Entry.univ_name u, s)))
+
+type _ target =
+| TgAny : 's target
+| TgTactic : int -> Tacexpr.raw_tactic_expr target
+
+(** Quite ad-hoc *)
+let get_tacentry (type s) (n : int) (t : s target) : s entry_name = match t with
+| TgAny -> EntryName (rawwit wit_tactic, atactic n)
+| TgTactic m ->
+ let check_lvl n =
+ Int.equal m n
+ && not (Int.equal m 5) (* Because tactic5 is at binder_tactic *)
+ && not (Int.equal m 0) (* Because tactic0 is at simple_tactic *)
+ in
+ if check_lvl n then EntryName (rawwit wit_tactic, Aself)
+ else if check_lvl (n + 1) then EntryName (rawwit wit_tactic, Anext)
+ else EntryName (rawwit wit_tactic, atactic n)
-let rec interp_entry_name static up_level s sep =
+let rec parse_user_entry s sep =
let l = String.length s in
if l > 8 && coincide s "ne_" 0 && coincide s "_list" (l - 5) then
- let t, g = interp_entry_name static up_level (String.sub s 3 (l-8)) "" in
- ListArgType t, Alist1 g
+ let entry = parse_user_entry (String.sub s 3 (l-8)) "" in
+ Ulist1 entry
else if l > 12 && coincide s "ne_" 0 &&
coincide s "_list_sep" (l-9) then
- let t, g = interp_entry_name static up_level (String.sub s 3 (l-12)) "" in
- ListArgType t, Alist1sep (g,sep)
+ let entry = parse_user_entry (String.sub s 3 (l-12)) "" in
+ Ulist1sep (entry, sep)
else if l > 5 && coincide s "_list" (l-5) then
- let t, g = interp_entry_name static up_level (String.sub s 0 (l-5)) "" in
- ListArgType t, Alist0 g
+ let entry = parse_user_entry (String.sub s 0 (l-5)) "" in
+ Ulist0 entry
else if l > 9 && coincide s "_list_sep" (l-9) then
- let t, g = interp_entry_name static up_level (String.sub s 0 (l-9)) "" in
- ListArgType t, Alist0sep (g,sep)
+ let entry = parse_user_entry (String.sub s 0 (l-9)) "" in
+ Ulist0sep (entry, sep)
else if l > 4 && coincide s "_opt" (l-4) then
- let t, g = interp_entry_name static up_level (String.sub s 0 (l-4)) "" in
- OptArgType t, Aopt g
+ let entry = parse_user_entry (String.sub s 0 (l-4)) "" in
+ Uopt entry
else if l > 5 && coincide s "_mods" (l-5) then
- let t, g = interp_entry_name static up_level (String.sub s 0 (l-1)) "" in
- ListArgType t, Amodifiers g
+ let entry = parse_user_entry (String.sub s 0 (l-1)) "" in
+ Umodifiers entry
+ else if Int.equal l 7 && coincide s "tactic" 0 && '5' >= s.[6] && s.[6] >= '0' then
+ let n = Char.code s.[6] - 48 in
+ Uentryl ("tactic", n)
else
let s = match s with "hyp" -> "var" | _ -> s in
- let check_lvl n = match up_level with
- | None -> false
- | Some m -> Int.equal m n
- && not (Int.equal m 5) (* Because tactic5 is at binder_tactic *)
- && not (Int.equal m 0) (* Because tactic0 is at simple_tactic *)
- in
- let t, se =
- match tactic_level s with
- | Some n ->
- (** Quite ad-hoc *)
- let t = unquote (rawwit wit_tactic) in
- let se =
- if check_lvl n then Aself
- else if check_lvl (n + 1) then Anext
- else Atactic n
- in
- (Some t, se)
- | None ->
- try Some (type_of_entry uprim s), Aentry ("prim",s) with Not_found ->
- try Some (type_of_entry uconstr s), Aentry ("constr",s) with Not_found ->
- try Some (type_of_entry utactic s), Aentry ("tactic",s) with Not_found ->
- if static then
- error ("Unknown entry "^s^".")
- else
- None, Aentry ("",s) in
- let t =
- match t with
- | Some t -> t
- | None -> ExtraArgType s in
- t, se
+ Uentry s
+
+let arg_list = function Rawwit t -> Rawwit (ListArg t)
+let arg_opt = function Rawwit t -> Rawwit (OptArg t)
+
+let rec interp_entry_name up_level s sep =
+ let rec eval = function
+ | Ulist1 e ->
+ let EntryName (t, g) = eval e in
+ EntryName (arg_list t, Alist1 g)
+ | Ulist1sep (e, sep) ->
+ let EntryName (t, g) = eval e in
+ EntryName (arg_list t, Alist1sep (g, sep))
+ | Ulist0 e ->
+ let EntryName (t, g) = eval e in
+ EntryName (arg_list t, Alist0 g)
+ | Ulist0sep (e, sep) ->
+ let EntryName (t, g) = eval e in
+ EntryName (arg_list t, Alist0sep (g, sep))
+ | Uopt e ->
+ let EntryName (t, g) = eval e in
+ EntryName (arg_opt t, Aopt g)
+ | Umodifiers e ->
+ let EntryName (t, g) = eval e in
+ EntryName (arg_list t, Amodifiers g)
+ | Uentry s ->
+ begin
+ try try_get_entry uprim s with Not_found ->
+ try try_get_entry uconstr s with Not_found ->
+ try try_get_entry utactic s with Not_found ->
+ error ("Unknown entry "^s^".")
+ end
+ | Uentryl (s, n) ->
+ (** FIXME: do better someday *)
+ assert (String.equal s "tactic");
+ get_tacentry n up_level
+ in
+ eval (parse_user_entry s sep)
let list_entry_names () =
- let add_entry key (entry, _) accu = (key, entry) :: accu in
- let ans = Hashtbl.fold add_entry (snd uprim) [] in
- let ans = Hashtbl.fold add_entry (snd uconstr) ans in
- Hashtbl.fold add_entry (snd utactic) ans
+ let add_entry key (TypedEntry (entry, _)) accu = (key, unquote entry) :: accu in
+ let ans = Hashtbl.fold add_entry (get_utable uprim) [] in
+ let ans = Hashtbl.fold add_entry (get_utable uconstr) ans in
+ Hashtbl.fold add_entry (get_utable utactic) ans
diff --git a/parsing/pcoq.mli b/parsing/pcoq.mli
index 24b58775a..a4b4bb22a 100644
--- a/parsing/pcoq.mli
+++ b/parsing/pcoq.mli
@@ -14,13 +14,12 @@ open Genarg
open Constrexpr
open Tacexpr
open Libnames
-open Compat
open Misctypes
open Genredexpr
(** The parser of Coq *)
-module Gram : GrammarSig
+module Gram : Compat.GrammarSig
(** The parser of Coq is built from three kinds of rule declarations:
@@ -106,28 +105,40 @@ type grammar_object
(** Type of reinitialization data *)
type gram_reinit = gram_assoc * gram_position
+(** General entry keys *)
+
+(** This intermediate abstract representation of entries can
+ both be reified into mlexpr for the ML extensions and
+ dynamically interpreted as entries for the Coq level extensions
+*)
+
+type ('self, 'a) entry_key = ('self, 'a) Extend.symbol =
+| Atoken : Tok.t -> ('self, string) entry_key
+| Alist1 : ('self, 'a) entry_key -> ('self, 'a list) entry_key
+| Alist1sep : ('self, 'a) entry_key * string -> ('self, 'a list) entry_key
+| Alist0 : ('self, 'a) entry_key -> ('self, 'a list) entry_key
+| Alist0sep : ('self, 'a) entry_key * string -> ('self, 'a list) entry_key
+| Aopt : ('self, 'a) entry_key -> ('self, 'a option) entry_key
+| Amodifiers : ('self, 'a) entry_key -> ('self, 'a list) entry_key
+| Aself : ('self, 'self) entry_key
+| Anext : ('self, 'self) entry_key
+| Aentry : 'a Entry.t -> ('self, 'a) entry_key
+| Aentryl : 'a Entry.t * int -> ('self, 'a) entry_key
+
(** Add one extension at some camlp4 position of some camlp4 entry *)
-val grammar_extend :
+val unsafe_grammar_extend :
grammar_object Gram.entry ->
gram_reinit option (** for reinitialization if ever needed *) ->
Gram.extend_statment -> unit
+val grammar_extend :
+ 'a Gram.entry ->
+ gram_reinit option (** for reinitialization if ever needed *) ->
+ 'a Extend.extend_statment -> unit
+
(** Remove the last n extensions *)
val remove_grammars : int -> unit
-
-
-
-(** The type of typed grammar objects *)
-type typed_entry
-
-(** The possible types for extensible grammars *)
-type entry_type = argument_type
-
-val type_of_typed_entry : typed_entry -> entry_type
-val object_of_typed_entry : typed_entry -> grammar_object Gram.entry
-val weaken_entry : 'a Gram.entry -> grammar_object Gram.entry
-
(** Temporary activate camlp4 verbosity *)
val camlp4_verbosity : bool -> ('a -> unit) -> 'a -> unit
@@ -138,20 +149,19 @@ val parse_string : 'a Gram.entry -> string -> 'a
val eoi_entry : 'a Gram.entry -> 'a Gram.entry
val map_entry : ('a -> 'b) -> 'a Gram.entry -> 'b Gram.entry
-(** Table of Coq statically defined grammar entries *)
-
-type gram_universe
-
-(** There are four predefined universes: "prim", "constr", "tactic", "vernac" *)
+type gram_universe = Entry.universe
val get_univ : string -> gram_universe
+type typed_entry = TypedEntry : 'a raw_abstract_argument_type * 'a Gram.entry -> typed_entry
+
val uprim : gram_universe
val uconstr : gram_universe
val utactic : gram_universe
val uvernac : gram_universe
-val create_entry : gram_universe -> string -> entry_type -> typed_entry
+val get_entry : gram_universe -> string -> typed_entry
+
val create_generic_entry : string -> ('a, rlevel) abstract_argument_type ->
'a Gram.entry
@@ -167,6 +177,7 @@ module Prim :
val pattern_identref : Id.t located Gram.entry
val base_ident : Id.t Gram.entry
val natural : int Gram.entry
+ val index : int Gram.entry
val bigint : Bigint.bigint Gram.entry
val integer : int Gram.entry
val string : string Gram.entry
@@ -212,7 +223,7 @@ module Module :
module Tactic :
sig
- val open_constr : open_constr_expr Gram.entry
+ val open_constr : constr_expr Gram.entry
val constr_with_bindings : constr_expr with_bindings Gram.entry
val bindings : constr_expr bindings Gram.entry
val hypident : (Id.t located * Locus.hyp_location_flag) Gram.entry
@@ -230,7 +241,7 @@ module Tactic :
val binder_tactic : raw_tactic_expr Gram.entry
val tactic : raw_tactic_expr Gram.entry
val tactic_eoi : raw_tactic_expr Gram.entry
- val tacdef_body : (reference * bool * raw_tactic_expr) Gram.entry
+ val tacdef_body : Vernacexpr.tacdef_body Gram.entry
end
module Vernac_ :
@@ -258,38 +269,26 @@ val symbol_of_constr_prod_entry_key : gram_assoc option ->
constr_entry_key -> bool -> constr_prod_entry_key ->
Gram.symbol
-(** General entry keys *)
-
-(** This intermediate abstract representation of entries can
- both be reified into mlexpr for the ML extensions and
- dynamically interpreted as entries for the Coq level extensions
-*)
-
-type prod_entry_key =
- | Alist1 of prod_entry_key
- | Alist1sep of prod_entry_key * string
- | Alist0 of prod_entry_key
- | Alist0sep of prod_entry_key * string
- | Aopt of prod_entry_key
- | Amodifiers of prod_entry_key
- | Aself
- | Anext
- | Atactic of int
- | Agram of string
- | Aentry of string * string
+val name_of_entry : 'a Gram.entry -> 'a Entry.t
(** Binding general entry keys to symbols *)
val symbol_of_prod_entry_key :
- prod_entry_key -> Gram.symbol
+ ('self, 'a) entry_key -> Gram.symbol
+
+type 's entry_name = EntryName :
+ 'a raw_abstract_argument_type * ('s, 'a) entry_key -> 's entry_name
(** Interpret entry names of the form "ne_constr_list" as entry keys *)
-val interp_entry_name : bool (** true to fail on unknown entry *) ->
- int option -> string -> string -> entry_type * prod_entry_key
+type _ target = TgAny : 's target | TgTactic : int -> raw_tactic_expr target
+
+val interp_entry_name : 's target -> string -> string -> 's entry_name
+
+val parse_user_entry : string -> string -> user_symbol
(** Recover the list of all known tactic notation entries. *)
-val list_entry_names : unit -> (string * entry_type) list
+val list_entry_names : unit -> (string * argument_type) list
(** Registering/resetting the level of a constr entry *)
diff --git a/parsing/tok.ml b/parsing/tok.ml
index c96b53de4..4f50c48d0 100644
--- a/parsing/tok.ml
+++ b/parsing/tok.ml
@@ -15,6 +15,7 @@ type t =
| IDENT of string
| FIELD of string
| INT of string
+ | INDEX of string
| STRING of string
| LEFTQMARK
| BULLET of string
@@ -28,6 +29,7 @@ let equal t1 t2 = match t1, t2 with
| IDENT s1, IDENT s2 -> CString.equal s1 s2
| FIELD s1, FIELD s2 -> CString.equal s1 s2
| INT s1, INT s2 -> CString.equal s1 s2
+| INDEX s1, INDEX s2 -> CString.equal s1 s2
| STRING s1, STRING s2 -> CString.equal s1 s2
| LEFTQMARK, LEFTQMARK -> true
| BULLET s1, BULLET s2 -> CString.equal s1 s2
@@ -42,6 +44,7 @@ let extract_string = function
| PATTERNIDENT s -> s
| FIELD s -> s
| INT s -> s
+ | INDEX s -> s
| LEFTQMARK -> "?"
| BULLET s -> s
| EOI -> ""
@@ -53,6 +56,7 @@ let to_string = function
| PATTERNIDENT s -> Format.sprintf "PATTERNIDENT %S" s
| FIELD s -> Format.sprintf "FIELD %S" s
| INT s -> Format.sprintf "INT %s" s
+ | INDEX s -> Format.sprintf "INDEX %s" s
| STRING s -> Format.sprintf "STRING %S" s
| LEFTQMARK -> "LEFTQMARK"
| BULLET s -> Format.sprintf "STRING %S" s
@@ -76,6 +80,7 @@ let of_pattern = function
| "PATTERNIDENT", s -> PATTERNIDENT s
| "FIELD", s -> FIELD s
| "INT", s -> INT s
+ | "INDEX", s -> INDEX s
| "STRING", s -> STRING s
| "LEFTQMARK", _ -> LEFTQMARK
| "BULLET", s -> BULLET s
@@ -89,6 +94,7 @@ let to_pattern = function
| PATTERNIDENT s -> "PATTERNIDENT", s
| FIELD s -> "FIELD", s
| INT s -> "INT", s
+ | INDEX s -> "INDEX", s
| STRING s -> "STRING", s
| LEFTQMARK -> "LEFTQMARK", ""
| BULLET s -> "BULLET", s
@@ -103,6 +109,7 @@ let match_pattern =
| "PATTERNIDENT", "" -> (function PATTERNIDENT s -> s | _ -> err ())
| "FIELD", "" -> (function FIELD s -> s | _ -> err ())
| "INT", "" -> (function INT s -> s | _ -> err ())
+ | "INDEX", "" -> (function INDEX s -> s | _ -> err ())
| "STRING", "" -> (function STRING s -> s | _ -> err ())
| "LEFTQMARK", "" -> (function LEFTQMARK -> "" | _ -> err ())
| "BULLET", "" -> (function BULLET s -> s | _ -> err ())
diff --git a/parsing/tok.mli b/parsing/tok.mli
index df006601d..f37de05a4 100644
--- a/parsing/tok.mli
+++ b/parsing/tok.mli
@@ -15,6 +15,7 @@ type t =
| IDENT of string
| FIELD of string
| INT of string
+ | INDEX of string
| STRING of string
| LEFTQMARK
| BULLET of string
diff --git a/plugins/btauto/refl_btauto.ml b/plugins/btauto/refl_btauto.ml
index 57268a9cf..5a49fc8f4 100644
--- a/plugins/btauto/refl_btauto.ml
+++ b/plugins/btauto/refl_btauto.ml
@@ -1,3 +1,4 @@
+open Proofview.Notations
let contrib_name = "btauto"
@@ -216,7 +217,7 @@ module Btauto = struct
Tacticals.tclFAIL 0 msg gl
let try_unification env =
- Proofview.Goal.nf_enter begin fun gl ->
+ Proofview.Goal.nf_enter { enter = begin fun gl ->
let concl = Proofview.Goal.concl gl in
let eq = Lazy.force eq in
let t = decomp_term concl in
@@ -228,10 +229,10 @@ module Btauto = struct
| _ ->
let msg = str "Btauto: Internal error" in
Tacticals.New.tclFAIL 0 msg
- end
+ end }
let tac =
- Proofview.Goal.nf_enter begin fun gl ->
+ Proofview.Goal.nf_enter { enter = begin fun gl ->
let concl = Proofview.Goal.concl gl in
let eq = Lazy.force eq in
let bool = Lazy.force Bool.typ in
@@ -255,6 +256,6 @@ module Btauto = struct
| _ ->
let msg = str "Cannot recognize a boolean equality" in
Tacticals.New.tclFAIL 0 msg
- end
+ end }
end
diff --git a/plugins/cc/cctac.ml b/plugins/cc/cctac.ml
index 0baa53370..09d9cf019 100644
--- a/plugins/cc/cctac.ml
+++ b/plugins/cc/cctac.ml
@@ -22,6 +22,7 @@ open Ccproof
open Pp
open Errors
open Util
+open Proofview.Notations
let reference dir s = lazy (Coqlib.gen_reference "CC" dir s)
@@ -254,13 +255,13 @@ let new_app_global f args k =
let new_refine c = Proofview.V82.tactic (refine c)
let assert_before n c =
- Proofview.Goal.enter begin fun gl ->
+ Proofview.Goal.enter { enter = begin fun gl ->
let evm, _ = Tacmach.New.pf_apply type_of gl c in
Tacticals.New.tclTHEN (Proofview.V82.tactic (Refiner.tclEVARS evm)) (assert_before n c)
- end
+ end }
let rec proof_tac p : unit Proofview.tactic =
- Proofview.Goal.nf_enter begin fun gl ->
+ Proofview.Goal.nf_enter { enter = begin fun gl ->
let type_of t = Tacmach.New.pf_unsafe_type_of gl t in
try (* type_of can raise exceptions *)
match p.p_rule with
@@ -325,10 +326,10 @@ let rec proof_tac p : unit Proofview.tactic =
app_global _f_equal [|intype;outtype;proj;ti;tj;_M 1|] in
Tacticals.New.tclTHEN (Proofview.V82.tactic (injt refine)) (proof_tac prf)
with e when Proofview.V82.catchable_exception e -> Proofview.tclZERO e
- end
+ end }
let refute_tac c t1 t2 p =
- Proofview.Goal.nf_enter begin fun gl ->
+ Proofview.Goal.nf_enter { enter = begin fun gl ->
let tt1=constr_of_term t1 and tt2=constr_of_term t2 in
let intype =
Tacmach.New.of_old (fun gls -> (* Termops.refresh_universes *) (pf_unsafe_type_of gls tt1)) gl
@@ -338,14 +339,14 @@ let refute_tac c t1 t2 p =
let false_t=mkApp (c,[|mkVar hid|]) in
Tacticals.New.tclTHENS (neweq (assert_before (Name hid)))
[proof_tac p; simplest_elim false_t]
- end
+ end }
let refine_exact_check c gl =
let evm, _ = pf_apply type_of gl c in
Tacticals.tclTHEN (Refiner.tclEVARS evm) (Proofview.V82.of_tactic (exact_check c)) gl
let convert_to_goal_tac c t1 t2 p =
- Proofview.Goal.nf_enter begin fun gl ->
+ Proofview.Goal.nf_enter { enter = begin fun gl ->
let tt1=constr_of_term t1 and tt2=constr_of_term t2 in
let sort =
Tacmach.New.of_old (fun gls -> (* Termops.refresh_universes *) (pf_unsafe_type_of gls tt2)) gl
@@ -357,20 +358,20 @@ let convert_to_goal_tac c t1 t2 p =
let endt=app_global _eq_rect [|sort;tt1;identity;c;tt2;mkVar e|] in
Tacticals.New.tclTHENS (neweq (assert_before (Name e)))
[proof_tac p; Proofview.V82.tactic (endt refine_exact_check)]
- end
+ end }
let convert_to_hyp_tac c1 t1 c2 t2 p =
- Proofview.Goal.nf_enter begin fun gl ->
+ Proofview.Goal.nf_enter { enter = begin fun gl ->
let tt2=constr_of_term t2 in
let h = Tacmach.New.of_old (pf_get_new_id (Id.of_string "H")) gl in
let false_t=mkApp (c2,[|mkVar h|]) in
Tacticals.New.tclTHENS (assert_before (Name h) tt2)
[convert_to_goal_tac c1 t1 t2 p;
simplest_elim false_t]
- end
+ end }
let discriminate_tac (cstr,u as cstru) p =
- Proofview.Goal.nf_enter begin fun gl ->
+ Proofview.Goal.nf_enter { enter = begin fun gl ->
let t1=constr_of_term p.p_lhs and t2=constr_of_term p.p_rhs in
let intype =
Tacmach.New.of_old (fun gls -> (* Termops.refresh_universes *) (pf_unsafe_type_of gls t1)) gl
@@ -384,7 +385,7 @@ let discriminate_tac (cstr,u as cstru) p =
let identity = Universes.constr_of_global (Lazy.force _I) in
(* let trivial=pf_unsafe_type_of gls identity in *)
let trivial = Universes.constr_of_global (Lazy.force _True) in
- let evm, outtype = Evd.new_sort_variable Evd.univ_flexible (Proofview.Goal.sigma gl) in
+ let evm, outtype = Evd.new_sort_variable Evd.univ_flexible (Tacmach.New.project gl) in
let outtype = mkSort outtype in
let pred=mkLambda(Name xid,outtype,mkRel 1) in
let hid = Tacmach.New.of_old (pf_get_new_id (Id.of_string "Heq")) gl in
@@ -399,7 +400,7 @@ let discriminate_tac (cstr,u as cstru) p =
Tacticals.New.tclTHEN (Proofview.Unsafe.tclEVARS evm)
(Tacticals.New.tclTHENS (neweq (assert_before (Name hid)))
[proof_tac p; Proofview.V82.tactic (endt refine_exact_check)])
- end
+ end }
(* wrap everything *)
@@ -411,7 +412,7 @@ let build_term_to_complete uf meta pac =
applistc (mkConstructU cinfo.ci_constr) all_args
let cc_tactic depth additionnal_terms =
- Proofview.Goal.nf_enter begin fun gl ->
+ Proofview.Goal.nf_enter { enter = begin fun gl ->
Coqlib.check_required_library Coqlib.logic_module_name;
let _ = debug (Pp.str "Reading subgoal ...") in
let state = Tacmach.New.of_old (fun gls -> make_prb gls depth additionnal_terms) gl in
@@ -462,7 +463,7 @@ let cc_tactic depth additionnal_terms =
convert_to_goal_tac id ta tb p
| HeqnH (ida,idb) ->
convert_to_hyp_tac ida ta idb tb p
- end
+ end }
let cc_fail gls =
errorlabstrm "Congruence" (Pp.str "congruence failed.")
@@ -485,8 +486,7 @@ let congruence_tac depth l =
let mk_eq f c1 c2 k =
Tacticals.New.pf_constr_of_global (Lazy.force f) (fun fc ->
- Proofview.Goal.enter begin
- fun gl ->
+ Proofview.Goal.enter { enter = begin fun gl ->
let open Tacmach.New in
let evm, ty = pf_apply type_of gl c1 in
let evm, ty = Evarsolve.refresh_universes (Some false) (pf_env gl) evm ty in
@@ -494,10 +494,10 @@ let mk_eq f c1 c2 k =
let evm, _ = type_of (pf_env gl) evm term in
Tacticals.New.tclTHEN (Proofview.V82.tactic (Refiner.tclEVARS evm))
(k term)
- end)
+ end })
let f_equal =
- Proofview.Goal.nf_enter begin fun gl ->
+ Proofview.Goal.nf_enter { enter = begin fun gl ->
let concl = Proofview.Goal.concl gl in
let cut_eq c1 c2 =
try (* type_of can raise an exception *)
@@ -523,4 +523,4 @@ let f_equal =
| Type_errors.TypeError _ -> Proofview.tclUNIT ()
| e -> Proofview.tclZERO ~info e
end
- end
+ end }
diff --git a/plugins/decl_mode/decl_proof_instr.ml b/plugins/decl_mode/decl_proof_instr.ml
index ba9fb728c..f47b35541 100644
--- a/plugins/decl_mode/decl_proof_instr.ml
+++ b/plugins/decl_mode/decl_proof_instr.ml
@@ -29,6 +29,7 @@ open Termops
open Namegen
open Goptions
open Misctypes
+open Sigma.Notations
(* Strictness option *)
@@ -86,7 +87,7 @@ Please \"suppose\" something or \"end\" it now."
| _ -> ()
let mk_evd metalist gls =
- let evd0= create_goal_evar_defs (sig_sig gls) in
+ let evd0= clear_metas (sig_sig gls) in
let add_one (meta,typ) evd =
meta_declare meta typ evd in
List.fold_right add_one metalist evd0
@@ -1305,7 +1306,11 @@ let understand_my_constr env sigma c concl =
Pretyping.understand_tcc env sigma ~expected_type:(Pretyping.OfType concl) (frob rawc)
let my_refine c gls =
- let oc sigma = understand_my_constr (pf_env gls) sigma c (pf_concl gls) in
+ let oc = { run = begin fun sigma ->
+ let sigma = Sigma.to_evar_map sigma in
+ let (sigma, c) = understand_my_constr (pf_env gls) sigma c (pf_concl gls) in
+ Sigma.Unsafe.of_pair (c, sigma)
+ end } in
Proofview.V82.of_tactic (Tactics.New.refine oc) gls
(* end focus/claim *)
diff --git a/plugins/derive/derive.ml b/plugins/derive/derive.ml
index ce93c5a3f..a47dc5b2f 100644
--- a/plugins/derive/derive.ml
+++ b/plugins/derive/derive.ml
@@ -93,6 +93,7 @@ let start_deriving f suchthat lemma =
ignore (Declare.declare_constant lemma lemma_def)
in
+ let terminator = Proof_global.make_terminator terminator in
let () = Proof_global.start_dependent_proof lemma kind goals terminator in
let _ = Proof_global.with_current_proof begin fun _ p ->
Proof.run_tactic env Proofview.(tclFOCUS 1 2 shelve) p
diff --git a/plugins/extraction/extraction.ml b/plugins/extraction/extraction.ml
index 10644da25..38aef62e1 100644
--- a/plugins/extraction/extraction.ml
+++ b/plugins/extraction/extraction.ml
@@ -11,7 +11,6 @@ open Util
open Names
open Term
open Vars
-open Context
open Declarations
open Declareops
open Environ
diff --git a/plugins/extraction/table.ml b/plugins/extraction/table.ml
index d7842e127..466c8054b 100644
--- a/plugins/extraction/table.ml
+++ b/plugins/extraction/table.ml
@@ -453,7 +453,7 @@ let check_loaded_modfile mp = match base_mp mp with
if not (Library.library_is_loaded dp) then begin
match base_mp (Lib.current_mp ()) with
| MPfile dp' when not (DirPath.equal dp dp') ->
- err (str ("Please load library "^(DirPath.to_string dp^" first.")))
+ err (str "Please load library " ++ pr_dirpath dp ++ str " first.")
| _ -> ()
end
| _ -> ()
diff --git a/plugins/firstorder/formula.mli b/plugins/firstorder/formula.mli
index 39d99d2e0..0f70d3ea0 100644
--- a/plugins/firstorder/formula.mli
+++ b/plugins/firstorder/formula.mli
@@ -7,7 +7,6 @@
(************************************************************************)
open Term
-open Context
open Globnames
val qflag : bool ref
@@ -27,7 +26,7 @@ type counter = bool -> metavariable
val construct_nhyps : pinductive -> Proof_type.goal Tacmach.sigma -> int array
val ind_hyps : int -> pinductive -> constr list ->
- Proof_type.goal Tacmach.sigma -> rel_context array
+ Proof_type.goal Tacmach.sigma -> Context.Rel.t array
type atoms = {positive:constr list;negative:constr list}
diff --git a/plugins/firstorder/g_ground.ml4 b/plugins/firstorder/g_ground.ml4
index 041526881..25509b4b5 100644
--- a/plugins/firstorder/g_ground.ml4
+++ b/plugins/firstorder/g_ground.ml4
@@ -52,8 +52,15 @@ let _=
in
declare_int_option gdopt
+let default_intuition_tac =
+ let tac _ _ = Auto.h_auto None [] None in
+ let name = { Tacexpr.mltac_plugin = "ground_plugin"; mltac_tactic = "auto_with"; } in
+ let entry = { Tacexpr.mltac_name = name; mltac_index = 0 } in
+ Tacenv.register_ml_tactic name [| tac |];
+ Tacexpr.TacML (Loc.ghost, entry, [])
+
let (set_default_solver, default_solver, print_default_solver) =
- Tactic_option.declare_tactic_option ~default:(<:tactic<auto with *>>) "Firstorder default solver"
+ Tactic_option.declare_tactic_option ~default:default_intuition_tac "Firstorder default solver"
VERNAC COMMAND EXTEND Firstorder_Set_Solver CLASSIFIED AS SIDEFF
| [ "Set" "Firstorder" "Solver" tactic(t) ] -> [
diff --git a/plugins/fourier/fourierR.ml b/plugins/fourier/fourierR.ml
index 72e9371be..4c0aa6c75 100644
--- a/plugins/fourier/fourierR.ml
+++ b/plugins/fourier/fourierR.ml
@@ -19,6 +19,7 @@ open Globnames
open Tacmach
open Fourier
open Contradiction
+open Proofview.Notations
(******************************************************************************
Opérations sur les combinaisons linéaires affines.
@@ -412,13 +413,6 @@ let tac_zero_infeq_false gl (n,d) =
(tac_zero_inf_pos gl (-n,d)))
;;
-let create_meta () = mkMeta(Evarutil.new_meta());;
-
-let my_cut c gl=
- let concl = pf_concl gl in
- apply_type (mkProd(Anonymous,c,concl)) [create_meta()] gl
-;;
-
let exact = exact_check;;
let tac_use h =
@@ -462,7 +456,7 @@ exception GoalDone
(* Résolution d'inéquations linéaires dans R *)
let rec fourier () =
- Proofview.Goal.nf_enter begin fun gl ->
+ Proofview.Goal.nf_enter { enter = begin fun gl ->
let concl = Proofview.Goal.concl gl in
Coqlib.check_required_library ["Coq";"fourier";"Fourier"];
let goal = strip_outer_cast concl in
@@ -586,7 +580,7 @@ let rec fourier () =
then tac_zero_inf_false gl (rational_to_fraction cres)
else tac_zero_infeq_false gl (rational_to_fraction cres)
in
- tac:=(Tacticals.New.tclTHENS (Proofview.V82.tactic (my_cut ineq))
+ tac:=(Tacticals.New.tclTHENS (cut ineq)
[Tacticals.New.tclTHEN (change_concl
(mkAppL [| get coq_not; ineq|]
))
@@ -622,7 +616,7 @@ let rec fourier () =
(* ((tclTHEN !tac (tclFAIL 1 (* 1 au hasard... *))) gl) *)
!tac
(* ((tclABSTRACT None !tac) gl) *)
- end
+ end }
;;
(*
diff --git a/plugins/funind/functional_principles_proofs.ml b/plugins/funind/functional_principles_proofs.ml
index 169a70600..4eab5f912 100644
--- a/plugins/funind/functional_principles_proofs.ml
+++ b/plugins/funind/functional_principles_proofs.ml
@@ -3,12 +3,12 @@ open Errors
open Util
open Term
open Vars
-open Context
open Namegen
open Names
open Declarations
open Pp
open Tacmach
+open Termops
open Proof_type
open Tacticals
open Tactics
@@ -52,10 +52,10 @@ let rec print_debug_queue e =
let _ =
match e with
| Some e ->
- Pp.msg_debug (lmsg ++ (str " raised exception " ++ Errors.print e) ++ str " on goal " ++ goal)
+ Pp.msg_debug (hov 0 (lmsg ++ (str " raised exception " ++ Errors.print e) ++ str " on goal" ++ fnl() ++ goal))
| None ->
begin
- Pp.msg_debug (str " from " ++ lmsg ++ str " on goal " ++ goal);
+ Pp.msg_debug (str " from " ++ lmsg ++ str " on goal" ++ fnl() ++ goal);
end in
print_debug_queue None ;
end
@@ -229,7 +229,7 @@ let nf_betaiotazeta = (* Reductionops.local_strong Reductionops.whd_betaiotazeta
-let change_eq env sigma hyp_id (context:rel_context) x t end_of_type =
+let change_eq env sigma hyp_id (context:Context.Rel.t) x t end_of_type =
let nochange ?t' msg =
begin
observe (str ("Not treating ( "^msg^" )") ++ pr_lconstr t ++ str " " ++ match t' with None -> str "" | Some t -> Printer.pr_lconstr t );
@@ -705,7 +705,7 @@ let build_proof
in
tclTHENSEQ
[
- Simple.generalize (term_eq::(List.map mkVar dyn_infos.rec_hyps));
+ generalize (term_eq::(List.map mkVar dyn_infos.rec_hyps));
thin dyn_infos.rec_hyps;
pattern_option [Locus.AllOccurrencesBut [1],t] None;
(fun g -> observe_tac "toto" (
@@ -932,7 +932,7 @@ let generalize_non_dep hyp g =
in
(* observe (str "to_revert := " ++ prlist_with_sep spc Ppconstr.pr_id to_revert); *)
tclTHEN
- ((* observe_tac "h_generalize" *) (Simple.generalize (List.map mkVar to_revert) ))
+ ((* observe_tac "h_generalize" *) (generalize (List.map mkVar to_revert) ))
((* observe_tac "thin" *) (thin to_revert))
g
@@ -1472,7 +1472,7 @@ let new_prove_with_tcc is_mes acc_inv hrec tcc_hyps eqs : tactic =
tclCOMPLETE(
Eauto.eauto_with_bases
(true,5)
- [Evd.empty,Lazy.force refl_equal]
+ [{ Tacexpr.delayed = fun _ sigma -> Sigma.here (Lazy.force refl_equal) sigma}]
[Hints.Hint_db.empty empty_transparent_state false]
)
)
@@ -1562,7 +1562,7 @@ let prove_principle_for_gen
Nameops.out_name (fresh_id (Name (Id.of_string ("Acc_"^(Id.to_string rec_arg_id)))))
in
let revert l =
- tclTHEN (Tactics.Simple.generalize (List.map mkVar l)) (clear l)
+ tclTHEN (Tactics.generalize (List.map mkVar l)) (clear l)
in
let fix_id = Nameops.out_name (fresh_id (Name hrec_id)) in
let prove_rec_arg_acc g =
diff --git a/plugins/funind/functional_principles_types.ml b/plugins/funind/functional_principles_types.ml
index c47602bda..e2c3bbb97 100644
--- a/plugins/funind/functional_principles_types.ml
+++ b/plugins/funind/functional_principles_types.ml
@@ -3,7 +3,6 @@ open Errors
open Util
open Term
open Vars
-open Context
open Namegen
open Names
open Pp
@@ -12,6 +11,7 @@ open Tactics
open Indfun_common
open Functional_principles_proofs
open Misctypes
+open Sigma.Notations
exception Toberemoved_with_rel of int*constr
exception Toberemoved
@@ -29,7 +29,7 @@ let compute_new_princ_type_from_rel rel_to_fun sorts princ_type =
let env = Global.env () in
let env_with_params = Environ.push_rel_context princ_type_info.params env in
let tbl = Hashtbl.create 792 in
- let rec change_predicates_names (avoid:Id.t list) (predicates:rel_context) : rel_context =
+ let rec change_predicates_names (avoid:Id.t list) (predicates:Context.Rel.t) : Context.Rel.t =
match predicates with
| [] -> []
|(Name x,v,t)::predicates ->
@@ -648,12 +648,15 @@ let build_case_scheme fa =
let this_block_funs_indexes = Array.to_list this_block_funs_indexes in
List.assoc_f Constant.equal (fst (destConst funs)) this_block_funs_indexes
in
- let ind_fun =
+ let (ind, sf) =
let ind = first_fun_kn,funs_indexes in
(ind,Univ.Instance.empty)(*FIXME*),prop_sort
in
- let sigma, scheme =
- (fun (ind,sf) -> Indrec.build_case_analysis_scheme_default env sigma ind sf) ind_fun in
+ let sigma = Sigma.Unsafe.of_evar_map sigma in
+ let Sigma (scheme, sigma, _) =
+ Indrec.build_case_analysis_scheme_default env sigma ind sf
+ in
+ let sigma = Sigma.to_evar_map sigma in
let scheme_type = (Typing.unsafe_type_of env sigma ) scheme in
let sorts =
(fun (_,_,x) ->
diff --git a/plugins/funind/g_indfun.ml4 b/plugins/funind/g_indfun.ml4
index a15e46bfe..97b9e95e1 100644
--- a/plugins/funind/g_indfun.ml4
+++ b/plugins/funind/g_indfun.ml4
@@ -55,7 +55,9 @@ let pr_with_bindings_typed prc prlc (c,bl) =
let pr_fun_ind_using_typed prc prlc _ opt_c =
match opt_c with
| None -> mt ()
- | Some b -> spc () ++ hov 2 (str "using" ++ spc () ++ pr_with_bindings_typed prc prlc b.Evd.it)
+ | Some b ->
+ let (b, _) = Tactics.run_delayed (Global.env ()) Evd.empty b in
+ spc () ++ hov 2 (str "using" ++ spc () ++ pr_with_bindings_typed prc prlc b)
ARGUMENT EXTEND fun_ind_using
diff --git a/plugins/funind/glob_term_to_relation.ml b/plugins/funind/glob_term_to_relation.ml
index 5d92fca5e..80de8e764 100644
--- a/plugins/funind/glob_term_to_relation.ml
+++ b/plugins/funind/glob_term_to_relation.ml
@@ -357,7 +357,7 @@ let add_pat_variables pat typ env : Environ.env =
let new_env = add_pat_variables env pat typ in
let res =
fst (
- Context.fold_rel_context
+ Context.Rel.fold_outside
(fun (na,v,t) (env,ctxt) ->
match na with
| Anonymous -> assert false
diff --git a/plugins/funind/indfun.ml b/plugins/funind/indfun.ml
index 3dbd43806..d1e109825 100644
--- a/plugins/funind/indfun.ml
+++ b/plugins/funind/indfun.ml
@@ -10,6 +10,7 @@ open Glob_term
open Declarations
open Misctypes
open Decl_kinds
+open Sigma.Notations
let is_rec_info scheme_info =
let test_branche min acc (_,_,br) =
@@ -85,7 +86,7 @@ let functional_induction with_clean c princl pat =
in
let encoded_pat_as_patlist =
List.make (List.length args + List.length c_list - 1) None @ [pat] in
- List.map2 (fun c pat -> ((None,Tacexpr.ElimOnConstr (fun env sigma -> sigma,(c,NoBindings))),(None,pat),None))
+ List.map2 (fun c pat -> ((None,Tacexpr.ElimOnConstr ({ Tacexpr.delayed = fun env sigma -> Sigma ((c,NoBindings), sigma, Sigma.refl) })),(None,pat),None))
(args@c_list) encoded_pat_as_patlist
in
let princ' = Some (princ,bindings) in
@@ -727,9 +728,9 @@ let rec add_args id new_args b =
List.map (fun (e,o) -> add_args id new_args e,o) bl)
| CCases(loc,sty,b_option,cel,cal) ->
CCases(loc,sty,Option.map (add_args id new_args) b_option,
- List.map (fun (b,(na,b_option)) ->
+ List.map (fun (b,na,b_option) ->
add_args id new_args b,
- (na, b_option)) cel,
+ na, b_option) cel,
List.map (fun (loc,cpl,e) -> (loc,cpl,add_args id new_args e)) cal
)
| CLetTuple(loc,nal,(na,b_option),b1,b2) ->
@@ -751,10 +752,8 @@ let rec add_args id new_args b =
| CCast(loc,b1,b2) ->
CCast(loc,add_args id new_args b1,
Miscops.map_cast_type (add_args id new_args) b2)
- | CRecord (loc, w, pars) ->
- CRecord (loc,
- (match w with Some w -> Some (add_args id new_args w) | _ -> None),
- List.map (fun (e,o) -> e, add_args id new_args o) pars)
+ | CRecord (loc, pars) ->
+ CRecord (loc, List.map (fun (e,o) -> e, add_args id new_args o) pars)
| CNotation _ -> anomaly ~label:"add_args " (Pp.str "CNotation")
| CGeneralization _ -> anomaly ~label:"add_args " (Pp.str "CGeneralization")
| CPrim _ -> b
diff --git a/plugins/funind/invfun.ml b/plugins/funind/invfun.ml
index a800c186a..0c9d3bb81 100644
--- a/plugins/funind/invfun.ml
+++ b/plugins/funind/invfun.ml
@@ -19,6 +19,7 @@ open Tactics
open Indfun_common
open Tacmach
open Misctypes
+open Termops
(* Some pretty printing function for debugging purpose *)
@@ -70,8 +71,8 @@ let do_observe_tac s tac g =
with reraise ->
let reraise = Errors.push reraise in
let e = Cerrors.process_vernac_interp_error reraise in
- observe (str "observation "++ s++str " raised exception " ++
- Errors.iprint e ++ str " on goal " ++ goal );
+ observe (hov 0 (str "observation "++ s++str " raised exception " ++
+ Errors.iprint e ++ str " on goal" ++ fnl() ++ goal ));
iraise reraise;;
@@ -457,7 +458,7 @@ let generalize_dependent_of x hyp g =
tclMAP
(function
| (id,None,t) when not (Id.equal id hyp) &&
- (Termops.occur_var (pf_env g) x t) -> tclTHEN (Tactics.Simple.generalize [mkVar id]) (thin [id])
+ (Termops.occur_var (pf_env g) x t) -> tclTHEN (Tactics.generalize [mkVar id]) (thin [id])
| _ -> tclIDTAC
)
(pf_hyps g)
@@ -698,7 +699,7 @@ let prove_fun_complete funcs graphs schemes lemmas_types_infos i : tactic =
})
Locusops.onConcl
;
- Simple.generalize (List.map mkVar ids);
+ generalize (List.map mkVar ids);
thin ids
]
else
@@ -737,7 +738,7 @@ let prove_fun_complete funcs graphs schemes lemmas_types_infos i : tactic =
tclTHENSEQ
[ tclMAP (fun id -> Proofview.V82.of_tactic (Simple.intro id)) (args_names@[res;hres]);
observe_tac "h_generalize"
- (Simple.generalize [mkApp(applist(graph_principle,params),Array.map (fun c -> applist(c,params)) lemmas)]);
+ (generalize [mkApp(applist(graph_principle,params),Array.map (fun c -> applist(c,params)) lemmas)]);
Proofview.V82.of_tactic (Simple.intro graph_principle_id);
observe_tac "" (tclTHEN_i
(observe_tac "elim" (Proofview.V82.of_tactic (elim false None (mkVar hres,NoBindings) (Some (mkVar graph_principle_id,NoBindings)))))
@@ -920,7 +921,7 @@ let revert_graph kn post_tac hid g =
let f_args,res = Array.chop (Array.length args - 1) args in
tclTHENSEQ
[
- Simple.generalize [applist(mkConst f_complete,(Array.to_list f_args)@[res.(0);mkVar hid])];
+ generalize [applist(mkConst f_complete,(Array.to_list f_args)@[res.(0);mkVar hid])];
thin [hid];
Proofview.V82.of_tactic (Simple.intro hid);
post_tac hid
@@ -964,7 +965,7 @@ let functional_inversion kn hid fconst f_correct : tactic =
in
tclTHENSEQ[
pre_tac hid;
- Simple.generalize [applist(f_correct,(Array.to_list f_args)@[res;mkVar hid])];
+ generalize [applist(f_correct,(Array.to_list f_args)@[res;mkVar hid])];
thin [hid];
Proofview.V82.of_tactic (Simple.intro hid);
Proofview.V82.of_tactic (Inv.inv FullInversion None (NamedHyp hid));
diff --git a/plugins/funind/merge.ml b/plugins/funind/merge.ml
index 87d7ca76d..57782dd71 100644
--- a/plugins/funind/merge.ml
+++ b/plugins/funind/merge.ml
@@ -19,7 +19,6 @@ open Pp
open Names
open Term
open Vars
-open Context
open Termops
open Declarations
open Glob_term
@@ -258,27 +257,27 @@ type merge_infos =
lnk2: int merged_arg array;
(** rec params which remain rec param (ie not linked) *)
- recprms1: rel_declaration list;
- recprms2: rel_declaration list;
+ 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: rel_declaration list;
- otherprms2: rel_declaration list;
+ otherprms1: Context.Rel.Declaration.t list;
+ otherprms2: Context.Rel.Declaration.t list;
notherprms1:int;
notherprms2:int;
(** args which remain args in merge *)
- args1:rel_declaration list;
- args2:rel_declaration list;
+ args1:Context.Rel.Declaration.t list;
+ args2:Context.Rel.Declaration.t list;
nargs1:int;
nargs2:int;
(** functional result args *)
- funresprms1: rel_declaration list;
- funresprms2: rel_declaration list;
+ funresprms1: Context.Rel.Declaration.t list;
+ funresprms2: Context.Rel.Declaration.t list;
nfunresprms1:int;
nfunresprms2:int;
}
@@ -851,7 +850,7 @@ let glob_constr_list_to_inductive_expr prms1 prms2 mib1 mib2 shift
lident , bindlist , Some cstr_expr , lcstor_expr
-let mkProd_reldecl (rdecl:rel_declaration) (t2:glob_constr) =
+let mkProd_reldecl (rdecl:Context.Rel.Declaration.t) (t2:glob_constr) =
match rdecl with
| (nme,None,t) ->
let traw = Detyping.detype false [] (Global.env()) Evd.empty t in
diff --git a/plugins/funind/recdef.ml b/plugins/funind/recdef.ml
index 065d0fe53..b09678341 100644
--- a/plugins/funind/recdef.ml
+++ b/plugins/funind/recdef.ml
@@ -29,6 +29,7 @@ open Proof_type
open Pfedit
open Glob_term
open Pretyping
+open Termops
open Constrintern
open Misctypes
open Genredexpr
@@ -38,6 +39,7 @@ open Auto
open Eauto
open Indfun_common
+open Sigma.Notations
@@ -212,10 +214,10 @@ let rec print_debug_queue b e =
begin
let lmsg,goal = Stack.pop debug_queue in
if b then
- Pp.msg_debug (lmsg ++ (str " raised exception " ++ Errors.print e) ++ str " on goal " ++ goal)
+ Pp.msg_debug (hov 1 (lmsg ++ (str " raised exception " ++ Errors.print e) ++ str " on goal" ++ fnl() ++ goal))
else
begin
- Pp.msg_debug (str " from " ++ lmsg ++ str " on goal " ++ goal);
+ Pp.msg_debug (hov 1 (str " from " ++ lmsg ++ str " on goal"++fnl() ++ goal));
end;
(* print_debug_queue false e; *)
end
@@ -685,11 +687,14 @@ let mkDestructEq :
to_revert_constr in
pf_typel new_hyps (fun _ ->
observe_tclTHENLIST (str "mkDestructEq")
- [Simple.generalize new_hyps;
+ [generalize new_hyps;
(fun g2 ->
- Proofview.V82.of_tactic (change_in_concl None
- (fun patvars sigma ->
- pattern_occs [Locus.AllOccurrencesBut [1], expr] (pf_env g2) sigma (pf_concl g2))) g2);
+ let changefun patvars = { run = fun sigma ->
+ let sigma = Sigma.to_evar_map sigma in
+ let (sigma, c) = pattern_occs [Locus.AllOccurrencesBut [1], expr] (pf_env g2) sigma (pf_concl g2) in
+ Sigma.Unsafe.of_pair (c, sigma)
+ } in
+ Proofview.V82.of_tactic (change_in_concl None changefun) g2);
Proofview.V82.of_tactic (simplest_case expr)]), to_revert
@@ -1110,7 +1115,7 @@ let termination_proof_header is_mes input_type ids args_id relation
[observe_tac (str "generalize")
(onNLastHypsId (nargs+1)
(tclMAP (fun id ->
- tclTHEN (Tactics.Simple.generalize [mkVar id]) (clear [id]))
+ tclTHEN (Tactics.generalize [mkVar id]) (clear [id]))
))
;
observe_tac (str "fix") (fix (Some hrec) (nargs+1));
@@ -1300,7 +1305,7 @@ let open_new_goal build_proof sigma using_lemmas ref_ goal_name (gls_type,decomp
let hid = next_ident_away_in_goal h_id (pf_ids_of_hyps gls) in
observe_tclTHENLIST (str "")
[
- Simple.generalize [lemma];
+ generalize [lemma];
Proofview.V82.of_tactic (Simple.intro hid);
(fun g ->
let ids = pf_ids_of_hyps g in
@@ -1327,10 +1332,10 @@ let open_new_goal build_proof sigma using_lemmas ref_ goal_name (gls_type,decomp
tclFIRST[
tclTHEN
(Proofview.V82.of_tactic (eapply_with_bindings (mkVar (List.nth !lid !h_num), NoBindings)))
- e_assumption;
+ (Proofview.V82.of_tactic e_assumption);
Eauto.eauto_with_bases
(true,5)
- [Evd.empty,Lazy.force refl_equal]
+ [{ Tacexpr.delayed = fun _ sigma -> Sigma.here (Lazy.force refl_equal) sigma}]
[Hints.Hint_db.empty empty_transparent_state false]
]
)
diff --git a/plugins/micromega/Psatz.v b/plugins/micromega/Psatz.v
index a461b26a0..50e0033e5 100644
--- a/plugins/micromega/Psatz.v
+++ b/plugins/micromega/Psatz.v
@@ -96,6 +96,14 @@ Ltac psatzl dom :=
Ltac lra :=
first [ psatzl R | psatzl Q ].
+Ltac nra :=
+ unfold Rdiv in * ;
+ xnra ;
+ abstract
+ (intros __wit __varmap __ff ;
+ change (Tauto.eval_f (Reval_formula (@find R 0%R __varmap)) __ff) ;
+ apply (RTautoChecker_sound __ff __wit); vm_compute ; reflexivity).
+
(* Local Variables: *)
diff --git a/plugins/micromega/certificate.ml b/plugins/micromega/certificate.ml
index a5fceb562..914881db0 100644
--- a/plugins/micromega/certificate.ml
+++ b/plugins/micromega/certificate.ml
@@ -63,82 +63,82 @@ let r_spec = z_spec
let dev_form n_spec p =
let rec dev_form p =
match p with
- | Mc.PEc z -> Poly.constant (n_spec.number_to_num z)
- | Mc.PEX v -> Poly.variable (C2Ml.positive v)
- | Mc.PEmul(p1,p2) ->
- let p1 = dev_form p1 in
- let p2 = dev_form p2 in
- Poly.product p1 p2
- | Mc.PEadd(p1,p2) -> Poly.addition (dev_form p1) (dev_form p2)
- | Mc.PEopp p -> Poly.uminus (dev_form p)
- | Mc.PEsub(p1,p2) -> Poly.addition (dev_form p1) (Poly.uminus (dev_form p2))
- | Mc.PEpow(p,n) ->
- let p = dev_form p in
- let n = C2Ml.n n in
- let rec pow n =
- if Int.equal n 0
- then Poly.constant (n_spec.number_to_num n_spec.unit)
- else Poly.product p (pow (n-1)) in
- pow n in
- dev_form p
+ | Mc.PEc z -> Poly.constant (n_spec.number_to_num z)
+ | Mc.PEX v -> Poly.variable (C2Ml.positive v)
+ | Mc.PEmul(p1,p2) ->
+ let p1 = dev_form p1 in
+ let p2 = dev_form p2 in
+ Poly.product p1 p2
+ | Mc.PEadd(p1,p2) -> Poly.addition (dev_form p1) (dev_form p2)
+ | Mc.PEopp p -> Poly.uminus (dev_form p)
+ | Mc.PEsub(p1,p2) -> Poly.addition (dev_form p1) (Poly.uminus (dev_form p2))
+ | Mc.PEpow(p,n) ->
+ let p = dev_form p in
+ let n = C2Ml.n n in
+ let rec pow n =
+ if Int.equal n 0
+ then Poly.constant (n_spec.number_to_num n_spec.unit)
+ else Poly.product p (pow (n-1)) in
+ pow n in
+ dev_form p
let monomial_to_polynomial mn =
Monomial.fold
(fun v i acc ->
- let v = Ml2C.positive v in
- let mn = if Int.equal i 1 then Mc.PEX v else Mc.PEpow (Mc.PEX v ,Ml2C.n i) in
- if Pervasives.(=) acc (Mc.PEc (Mc.Zpos Mc.XH)) (** FIXME *)
- then mn
- else Mc.PEmul(mn,acc))
- mn
- (Mc.PEc (Mc.Zpos Mc.XH))
+ let v = Ml2C.positive v in
+ let mn = if Int.equal i 1 then Mc.PEX v else Mc.PEpow (Mc.PEX v ,Ml2C.n i) in
+ if Pervasives.(=) acc (Mc.PEc (Mc.Zpos Mc.XH)) (** FIXME *)
+ then mn
+ else Mc.PEmul(mn,acc))
+ mn
+ (Mc.PEc (Mc.Zpos Mc.XH))
let list_to_polynomial vars l =
assert (List.for_all (fun x -> ceiling_num x =/ x) l);
let var x = monomial_to_polynomial (List.nth vars x) in
-
+
let rec xtopoly p i = function
| [] -> p
| c::l -> if c =/ (Int 0) then xtopoly p (i+1) l
- else let c = Mc.PEc (Ml2C.bigint (numerator c)) in
- let mn =
- if Pervasives.(=) c (Mc.PEc (Mc.Zpos Mc.XH))
- then var i
- else Mc.PEmul (c,var i) in
- let p' = if Pervasives.(=) p (Mc.PEc Mc.Z0) then mn else
- Mc.PEadd (mn, p) in
- xtopoly p' (i+1) l in
-
- xtopoly (Mc.PEc Mc.Z0) 0 l
+ else let c = Mc.PEc (Ml2C.bigint (numerator c)) in
+ let mn =
+ if Pervasives.(=) c (Mc.PEc (Mc.Zpos Mc.XH))
+ then var i
+ else Mc.PEmul (c,var i) in
+ let p' = if Pervasives.(=) p (Mc.PEc Mc.Z0) then mn else
+ Mc.PEadd (mn, p) in
+ xtopoly p' (i+1) l in
+
+ xtopoly (Mc.PEc Mc.Z0) 0 l
let rec fixpoint f x =
let y' = f x in
- if Pervasives.(=) y' x then y'
- else fixpoint f y'
+ if Pervasives.(=) y' x then y'
+ else fixpoint f y'
let rec_simpl_cone n_spec e =
let simpl_cone =
Mc.simpl_cone n_spec.zero n_spec.unit n_spec.mult n_spec.eqb in
let rec rec_simpl_cone = function
- | Mc.PsatzMulE(t1, t2) ->
- simpl_cone (Mc.PsatzMulE (rec_simpl_cone t1, rec_simpl_cone t2))
- | Mc.PsatzAdd(t1,t2) ->
- simpl_cone (Mc.PsatzAdd (rec_simpl_cone t1, rec_simpl_cone t2))
- | x -> simpl_cone x in
- rec_simpl_cone e
-
-
+ | Mc.PsatzMulE(t1, t2) ->
+ simpl_cone (Mc.PsatzMulE (rec_simpl_cone t1, rec_simpl_cone t2))
+ | Mc.PsatzAdd(t1,t2) ->
+ simpl_cone (Mc.PsatzAdd (rec_simpl_cone t1, rec_simpl_cone t2))
+ | x -> simpl_cone x in
+ rec_simpl_cone e
+
+
let simplify_cone n_spec c = fixpoint (rec_simpl_cone n_spec) c
type cone_prod =
- Const of cone
- | Ideal of cone *cone
- | Mult of cone * cone
- | Other of cone
+ Const of cone
+| Ideal of cone *cone
+| Mult of cone * cone
+| Other of cone
and cone = Mc.zWitness
@@ -147,32 +147,32 @@ let factorise_linear_cone c =
let rec cone_list c l =
match c with
- | Mc.PsatzAdd (x,r) -> cone_list r (x::l)
- | _ -> c :: l in
-
+ | Mc.PsatzAdd (x,r) -> cone_list r (x::l)
+ | _ -> c :: l in
+
let factorise c1 c2 =
match c1 , c2 with
- | Mc.PsatzMulC(x,y) , Mc.PsatzMulC(x',y') ->
- if Pervasives.(=) x x' then Some (Mc.PsatzMulC(x, Mc.PsatzAdd(y,y'))) else None
- | Mc.PsatzMulE(x,y) , Mc.PsatzMulE(x',y') ->
- if Pervasives.(=) x x' then Some (Mc.PsatzMulE(x, Mc.PsatzAdd(y,y'))) else None
- | _ -> None in
-
+ | Mc.PsatzMulC(x,y) , Mc.PsatzMulC(x',y') ->
+ if Pervasives.(=) x x' then Some (Mc.PsatzMulC(x, Mc.PsatzAdd(y,y'))) else None
+ | Mc.PsatzMulE(x,y) , Mc.PsatzMulE(x',y') ->
+ if Pervasives.(=) x x' then Some (Mc.PsatzMulE(x, Mc.PsatzAdd(y,y'))) else None
+ | _ -> None in
+
let rec rebuild_cone l pending =
match l with
- | [] -> (match pending with
- | None -> Mc.PsatzZ
- | Some p -> p
- )
- | e::l ->
- (match pending with
- | None -> rebuild_cone l (Some e)
- | Some p -> (match factorise p e with
- | None -> Mc.PsatzAdd(p, rebuild_cone l (Some e))
- | Some f -> rebuild_cone l (Some f) )
- ) in
+ | [] -> (match pending with
+ | None -> Mc.PsatzZ
+ | Some p -> p
+ )
+ | e::l ->
+ (match pending with
+ | None -> rebuild_cone l (Some e)
+ | Some p -> (match factorise p e with
+ | None -> Mc.PsatzAdd(p, rebuild_cone l (Some e))
+ | Some f -> rebuild_cone l (Some f) )
+ ) in
- (rebuild_cone (List.sort Pervasives.compare (cone_list c [])) None)
+ (rebuild_cone (List.sort Pervasives.compare (cone_list c [])) None)
@@ -199,28 +199,28 @@ open Mfourier
let constrain_monomial mn l =
let coeffs = List.fold_left (fun acc p -> (Poly.get mn p)::acc) [] l in
- if Pervasives.(=) mn Monomial.const
- then
- { coeffs = Vect.from_list ((Big_int unit_big_int):: (List.rev coeffs)) ;
- op = Eq ;
- cst = Big_int zero_big_int }
- else
- { coeffs = Vect.from_list ((Big_int zero_big_int):: (List.rev coeffs)) ;
- op = Eq ;
- cst = Big_int zero_big_int }
+ if Pervasives.(=) mn Monomial.const
+ then
+ { coeffs = Vect.from_list ((Big_int unit_big_int):: (List.rev coeffs)) ;
+ op = Eq ;
+ cst = Big_int zero_big_int }
+ else
+ { coeffs = Vect.from_list ((Big_int zero_big_int):: (List.rev coeffs)) ;
+ op = Eq ;
+ cst = Big_int zero_big_int }
-
+
let positivity l =
let rec xpositivity i l =
match l with
- | [] -> []
- | (_,Mc.Equal)::l -> xpositivity (i+1) l
- | (_,_)::l ->
- {coeffs = Vect.update (i+1) (fun _ -> Int 1) Vect.null ;
- op = Ge ;
- cst = Int 0 } :: (xpositivity (i+1) l)
+ | [] -> []
+ | (_,Mc.Equal)::l -> xpositivity (i+1) l
+ | (_,_)::l ->
+ {coeffs = Vect.update (i+1) (fun _ -> Int 1) Vect.null ;
+ op = Ge ;
+ cst = Int 0 } :: (xpositivity (i+1) l)
in
- xpositivity 0 l
+ xpositivity 0 l
let string_of_op = function
@@ -241,23 +241,23 @@ let build_linear_system l =
let monomials =
List.fold_left (fun acc p ->
- Poly.fold (fun m _ acc -> MonSet.add m acc) p acc)
- (MonSet.singleton Monomial.const) l'
+ Poly.fold (fun m _ acc -> MonSet.add m acc) p acc)
+ (MonSet.singleton Monomial.const) l'
in (* For each monomial, compute a constraint *)
let s0 =
MonSet.fold (fun mn res -> (constrain_monomial mn l')::res) monomials [] in
- (* I need at least something strictly positive *)
+ (* I need at least something strictly positive *)
let strict = {
coeffs = Vect.from_list ((Big_int unit_big_int)::
(List.map (fun (x,y) ->
- match y with Mc.Strict ->
- Big_int unit_big_int
- | _ -> Big_int zero_big_int) l));
+ match y with Mc.Strict ->
+ Big_int unit_big_int
+ | _ -> Big_int zero_big_int) l));
op = Ge ; cst = Big_int unit_big_int } in
(* Add the positivity constraint *)
- {coeffs = Vect.from_list ([Big_int unit_big_int]) ;
- op = Ge ;
- cst = Big_int zero_big_int}::(strict::(positivity l)@s0)
+ {coeffs = Vect.from_list ([Big_int unit_big_int]) ;
+ op = Ge ;
+ cst = Big_int zero_big_int}::(strict::(positivity l)@s0)
let big_int_to_z = Ml2C.bigint
@@ -266,32 +266,32 @@ let big_int_to_z = Ml2C.bigint
-- at a lower layer, certificates are using nums... *)
let make_certificate n_spec (cert,li) =
let bint_to_cst = n_spec.bigint_to_number in
- match cert with
- | [] -> failwith "empty_certificate"
- | e::cert' ->
-(* let cst = match compare_big_int e zero_big_int with
- | 0 -> Mc.PsatzZ
- | 1 -> Mc.PsatzC (bint_to_cst e)
- | _ -> failwith "positivity error"
- in *)
- let rec scalar_product cert l =
- match cert with
- | [] -> Mc.PsatzZ
- | c::cert ->
- match l with
- | [] -> failwith "make_certificate(1)"
- | i::l ->
- let r = scalar_product cert l in
- match compare_big_int c zero_big_int with
- | -1 -> Mc.PsatzAdd (
- Mc.PsatzMulC (Mc.Pc ( bint_to_cst c), Mc.PsatzIn (Ml2C.nat i)),
- r)
- | 0 -> r
- | _ -> Mc.PsatzAdd (
- Mc.PsatzMulE (Mc.PsatzC (bint_to_cst c), Mc.PsatzIn (Ml2C.nat i)),
- r) in
- (factorise_linear_cone
- (simplify_cone n_spec (scalar_product cert' li)))
+ match cert with
+ | [] -> failwith "empty_certificate"
+ | e::cert' ->
+ (* let cst = match compare_big_int e zero_big_int with
+ | 0 -> Mc.PsatzZ
+ | 1 -> Mc.PsatzC (bint_to_cst e)
+ | _ -> failwith "positivity error"
+ in *)
+ let rec scalar_product cert l =
+ match cert with
+ | [] -> Mc.PsatzZ
+ | c::cert ->
+ match l with
+ | [] -> failwith "make_certificate(1)"
+ | i::l ->
+ let r = scalar_product cert l in
+ match compare_big_int c zero_big_int with
+ | -1 -> Mc.PsatzAdd (
+ Mc.PsatzMulC (Mc.Pc ( bint_to_cst c), Mc.PsatzIn (Ml2C.nat i)),
+ r)
+ | 0 -> r
+ | _ -> Mc.PsatzAdd (
+ Mc.PsatzMulE (Mc.PsatzC (bint_to_cst c), Mc.PsatzIn (Ml2C.nat i)),
+ r) in
+ (factorise_linear_cone
+ (simplify_cone n_spec (scalar_product cert' li)))
exception Found of Monomial.t
@@ -301,91 +301,157 @@ exception Strict
module MonMap = Map.Make(Monomial)
let primal l =
- let vr = ref 0 in
-
- let vect_of_poly map p =
- Poly.fold (fun mn vl (map,vect) ->
- if Pervasives.(=) mn Monomial.const
- then (map,vect)
- else
- let (mn,m) = try (MonMap.find mn map,map) with Not_found -> let res = (!vr, MonMap.add mn !vr map) in incr vr ; res in
- (m,if Int.equal (sign_num vl) 0 then vect else (mn,vl)::vect)) p (map,[]) in
-
- let op_op = function Mc.NonStrict -> Ge |Mc.Equal -> Eq | _ -> raise Strict in
+ let vr = ref 0 in
+
+ let vect_of_poly map p =
+ Poly.fold (fun mn vl (map,vect) ->
+ if Pervasives.(=) mn Monomial.const
+ then (map,vect)
+ else
+ let (mn,m) = try (MonMap.find mn map,map) with Not_found -> let res = (!vr, MonMap.add mn !vr map) in incr vr ; res in
+ (m,if Int.equal (sign_num vl) 0 then vect else (mn,vl)::vect)) p (map,[]) in
+
+ let op_op = function Mc.NonStrict -> Ge |Mc.Equal -> Eq | _ -> raise Strict in
- let cmp x y = Int.compare (fst x) (fst y) in
+ let cmp x y = Int.compare (fst x) (fst y) in
- snd (List.fold_right (fun (p,op) (map,l) ->
- let (mp,vect) = vect_of_poly map p in
- let cstr = {coeffs = List.sort cmp vect; op = op_op op ; cst = minus_num (Poly.get Monomial.const p)} in
+ snd (List.fold_right (fun (p,op) (map,l) ->
+ let (mp,vect) = vect_of_poly map p in
+ let cstr = {coeffs = List.sort cmp vect; op = op_op op ; cst = minus_num (Poly.get Monomial.const p)} in
- (mp,cstr::l)) l (MonMap.empty,[]))
+ (mp,cstr::l)) l (MonMap.empty,[]))
let dual_raw_certificate (l: (Poly.t * Mc.op1) list) =
-(* List.iter (fun (p,op) -> Printf.fprintf stdout "%a %s 0\n" Poly.pp p (string_of_op op) ) l ; *)
-
+ (* List.iter (fun (p,op) -> Printf.fprintf stdout "%a %s 0\n" Poly.pp p (string_of_op op) ) l ; *)
+
let sys = build_linear_system l in
- try
- match Fourier.find_point sys with
- | Inr _ -> None
- | Inl cert -> Some (rats_to_ints (Vect.to_list cert))
- (* should not use rats_to_ints *)
- with x when Errors.noncritical x ->
- if debug
- then (Printf.printf "raw certificate %s" (Printexc.to_string x);
- flush stdout) ;
- None
+ try
+ match Fourier.find_point sys with
+ | Inr _ -> None
+ | Inl cert -> Some (rats_to_ints (Vect.to_list cert))
+ (* should not use rats_to_ints *)
+ with x when Errors.noncritical x ->
+ if debug
+ then (Printf.printf "raw certificate %s" (Printexc.to_string x);
+ flush stdout) ;
+ None
let raw_certificate l =
- try
- let p = primal l in
- match Fourier.find_point p with
- | Inr prf ->
- if debug then Printf.printf "AProof : %a\n" pp_proof prf ;
- let cert = List.map (fun (x,n) -> x+1,n) (fst (List.hd (Proof.mk_proof p prf))) in
- if debug then Printf.printf "CProof : %a" Vect.pp_vect cert ;
- Some (rats_to_ints (Vect.to_list cert))
- | Inl _ -> None
- with Strict ->
+ try
+ let p = primal l in
+ match Fourier.find_point p with
+ | Inr prf ->
+ if debug then Printf.printf "AProof : %a\n" pp_proof prf ;
+ let cert = List.map (fun (x,n) -> x+1,n) (fst (List.hd (Proof.mk_proof p prf))) in
+ if debug then Printf.printf "CProof : %a" Vect.pp_vect cert ;
+ Some (rats_to_ints (Vect.to_list cert))
+ | Inl _ -> None
+ with Strict ->
(* Fourier elimination should handle > *)
- dual_raw_certificate l
+ dual_raw_certificate l
let simple_linear_prover l =
let (lc,li) = List.split l in
- match raw_certificate lc with
- | None -> None (* No certificate *)
- | Some cert -> Some (cert,li)
-
+ match raw_certificate lc with
+ | None -> None (* No certificate *)
+ | Some cert -> Some (cert,li)
+
let linear_prover n_spec l =
- let build_system n_spec l =
- let li = List.combine l (interval 0 (List.length l -1)) in
- let (l1,l') = List.partition
- (fun (x,_) -> if Pervasives.(=) (snd x) Mc.NonEqual then true else false) li in
- List.map
- (fun ((x,y),i) -> match y with
- Mc.NonEqual -> failwith "cannot happen"
- | y -> ((dev_form n_spec x, y),i)) l' in
- let l' = build_system n_spec l in
- simple_linear_prover (*n_spec*) l'
+ let build_system n_spec l =
+ let li = List.combine l (interval 0 (List.length l -1)) in
+ let (l1,l') = List.partition
+ (fun (x,_) -> if Pervasives.(=) (snd x) Mc.NonEqual then true else false) li in
+ List.map
+ (fun ((x,y),i) -> match y with
+ Mc.NonEqual -> failwith "cannot happen"
+ | y -> ((dev_form n_spec x, y),i)) l' in
+ let l' = build_system n_spec l in
+ simple_linear_prover (*n_spec*) l'
let linear_prover n_spec l =
try linear_prover n_spec l
with x when Errors.noncritical x ->
- (print_string (Printexc.to_string x); None)
+ (print_string (Printexc.to_string x); None)
+
+let compute_max_nb_cstr l d =
+ let len = List.length l in
+ max len (max d (len * d))
+
+let linear_prover_with_cert prfdepth spec l =
+ max_nb_cstr := compute_max_nb_cstr l prfdepth ;
+ match linear_prover spec l with
+ | None -> None
+ | Some cert -> Some (make_certificate spec cert)
+
+let nlinear_prover prfdepth (sys: (Mc.q Mc.pExpr * Mc.op1) list) =
+ LinPoly.MonT.clear ();
+ max_nb_cstr := compute_max_nb_cstr sys prfdepth ;
+ (* Assign a proof to the initial hypotheses *)
+ let sys = mapi (fun c i -> (c,Mc.PsatzIn (Ml2C.nat i))) sys in
+
+
+ (* Add all the product of hypotheses *)
+ let prod = all_pairs (fun ((c,o),p) ((c',o'),p') ->
+ ((Mc.PEmul(c,c') , Mc.opMult o o') , Mc.PsatzMulE(p,p'))) sys in
+
+ (* Only filter those have a meaning *)
+ let prod = List.fold_left (fun l ((c,o),p) ->
+ match o with
+ | None -> l
+ | Some o -> ((c,o),p) :: l) [] prod in
+
+ let sys = sys @ prod in
+
+ let square =
+ (* Collect the squares and state that they are positive *)
+ let pols = List.map (fun ((p,_),_) -> dev_form q_spec p) sys in
+ let square =
+ List.fold_left (fun acc p ->
+ Poly.fold
+ (fun m _ acc ->
+ match Monomial.sqrt m with
+ | None -> acc
+ | Some s -> MonMap.add s m acc) p acc) MonMap.empty pols in
+
+ let pol_of_mon m =
+ Monomial.fold (fun x v p -> Mc.PEmul(Mc.PEpow(Mc.PEX(Ml2C.positive x),Ml2C.n v),p)) m (Mc.PEc q_spec.unit) in
+
+ let norm0 =
+ Mc.norm q_spec.zero q_spec.unit Mc.qplus Mc.qmult Mc.qminus Mc.qopp Mc.qeq_bool in
+
+
+ MonMap.fold (fun s m acc -> ((pol_of_mon m , Mc.NonStrict), Mc.PsatzSquare(norm0 (pol_of_mon s)))::acc) square [] in
+
+ Printf.printf "#square %i\n" (List.length square) ;
+ flush stdout ;
+
+ let sys = sys @ square in
-let linear_prover_with_cert spec l =
- match linear_prover spec l with
- | None -> None
- | Some cert -> Some (make_certificate spec cert)
+ (* Call the linear prover without the proofs *)
+ let sys_no_prf = List.map fst sys in
+
+ match linear_prover q_spec sys_no_prf with
+ | None -> None
+ | Some cert ->
+ let cert = make_certificate q_spec cert in
+ let rec map_psatz = function
+ | Mc.PsatzIn n -> snd (List.nth sys (C2Ml.nat n))
+ | Mc.PsatzSquare c -> Mc.PsatzSquare c
+ | Mc.PsatzMulC(c,p) -> Mc.PsatzMulC(c, map_psatz p)
+ | Mc.PsatzMulE(p1,p2) -> Mc.PsatzMulE(map_psatz p1,map_psatz p2)
+ | Mc.PsatzAdd(p1,p2) -> Mc.PsatzAdd(map_psatz p1,map_psatz p2)
+ | Mc.PsatzC c -> Mc.PsatzC c
+ | Mc.PsatzZ -> Mc.PsatzZ in
+ Some (map_psatz cert)
@@ -395,11 +461,11 @@ let make_linear_system l =
(Poly.constant (Int 0)) l' in
let monomials = Poly.fold
(fun mn _ l -> if Pervasives.(=) mn Monomial.const then l else mn::l) monomials [] in
- (List.map (fun (c,op) ->
- {coeffs = Vect.from_list (List.map (fun mn -> (Poly.get mn c)) monomials) ;
- op = op ;
- cst = minus_num ( (Poly.get Monomial.const c))}) l
- ,monomials)
+ (List.map (fun (c,op) ->
+ {coeffs = Vect.from_list (List.map (fun mn -> (Poly.get mn c)) monomials) ;
+ op = op ;
+ cst = minus_num ( (Poly.get Monomial.const c))}) l
+ ,monomials)
let pplus x y = Mc.PEadd(x,y)
@@ -413,7 +479,7 @@ let rec mem p x l =
let rec remove_assoc p x l =
match l with [] -> [] | e::l -> if p x (fst e) then
- remove_assoc p x l else e::(remove_assoc p x l)
+ remove_assoc p x l else e::(remove_assoc p x l)
let eq x y = Int.equal (Vect.compare x y) 0
@@ -424,39 +490,39 @@ let remove e l = List.fold_left (fun l x -> if eq x e then l else x::l) [] l
only searching for naive cutting planes *)
let develop_constraint z_spec (e,k) =
- match k with
- | Mc.NonStrict -> (dev_form z_spec e , Ge)
- | Mc.Equal -> (dev_form z_spec e , Eq)
- | _ -> assert false
+ match k with
+ | Mc.NonStrict -> (dev_form z_spec e , Ge)
+ | Mc.Equal -> (dev_form z_spec e , Eq)
+ | _ -> assert false
let op_of_op_compat = function
- | Ge -> Mc.NonStrict
- | Eq -> Mc.Equal
+ | Ge -> Mc.NonStrict
+ | Eq -> Mc.Equal
let integer_vector coeffs =
- let vars , coeffs = List.split coeffs in
- List.combine vars (List.map (fun x -> Big_int x) (rats_to_ints coeffs))
+ let vars , coeffs = List.split coeffs in
+ List.combine vars (List.map (fun x -> Big_int x) (rats_to_ints coeffs))
let integer_cstr {coeffs = coeffs ; op = op ; cst = cst } =
- let vars , coeffs = List.split coeffs in
- match rats_to_ints (cst::coeffs) with
- | cst :: coeffs ->
- {
- coeffs = List.combine vars (List.map (fun x -> Big_int x) coeffs) ;
- op = op ; cst = Big_int cst}
- | _ -> assert false
-
+ let vars , coeffs = List.split coeffs in
+ match rats_to_ints (cst::coeffs) with
+ | cst :: coeffs ->
+ {
+ coeffs = List.combine vars (List.map (fun x -> Big_int x) coeffs) ;
+ op = op ; cst = Big_int cst}
+ | _ -> assert false
+
let pexpr_of_cstr_compat var cstr =
- let {coeffs = coeffs ; op = op ; cst = cst } = integer_cstr cstr in
- try
- let expr = list_to_polynomial var (Vect.to_list coeffs) in
- let d = Ml2C.bigint (denominator cst) in
- let n = Ml2C.bigint (numerator cst) in
- (pplus (pmult (pconst d) expr) (popp (pconst n)), op_of_op_compat op)
- with Failure _ -> failwith "pexpr_of_cstr_compat"
+ let {coeffs = coeffs ; op = op ; cst = cst } = integer_cstr cstr in
+ try
+ let expr = list_to_polynomial var (Vect.to_list coeffs) in
+ let d = Ml2C.bigint (denominator cst) in
+ let n = Ml2C.bigint (numerator cst) in
+ (pplus (pmult (pconst d) expr) (popp (pconst n)), op_of_op_compat op)
+ with Failure _ -> failwith "pexpr_of_cstr_compat"
@@ -465,41 +531,41 @@ open Sos_types
let rec scale_term t =
match t with
- | Zero -> unit_big_int , Zero
- | Const n -> (denominator n) , Const (Big_int (numerator n))
- | Var n -> unit_big_int , Var n
- | Inv _ -> failwith "scale_term : not implemented"
- | Opp t -> let s, t = scale_term t in s, Opp t
- | Add(t1,t2) -> let s1,y1 = scale_term t1 and s2,y2 = scale_term t2 in
- let g = gcd_big_int s1 s2 in
- let s1' = div_big_int s1 g in
- let s2' = div_big_int s2 g in
- let e = mult_big_int g (mult_big_int s1' s2') in
- if Int.equal (compare_big_int e unit_big_int) 0
- then (unit_big_int, Add (y1,y2))
- else e, Add (Mul(Const (Big_int s2'), y1),
- Mul (Const (Big_int s1'), y2))
- | Sub _ -> failwith "scale term: not implemented"
- | Mul(y,z) -> let s1,y1 = scale_term y and s2,y2 = scale_term z in
- mult_big_int s1 s2 , Mul (y1, y2)
- | Pow(t,n) -> let s,t = scale_term t in
- power_big_int_positive_int s n , Pow(t,n)
- | _ -> failwith "scale_term : not implemented"
+ | Zero -> unit_big_int , Zero
+ | Const n -> (denominator n) , Const (Big_int (numerator n))
+ | Var n -> unit_big_int , Var n
+ | Inv _ -> failwith "scale_term : not implemented"
+ | Opp t -> let s, t = scale_term t in s, Opp t
+ | Add(t1,t2) -> let s1,y1 = scale_term t1 and s2,y2 = scale_term t2 in
+ let g = gcd_big_int s1 s2 in
+ let s1' = div_big_int s1 g in
+ let s2' = div_big_int s2 g in
+ let e = mult_big_int g (mult_big_int s1' s2') in
+ if Int.equal (compare_big_int e unit_big_int) 0
+ then (unit_big_int, Add (y1,y2))
+ else e, Add (Mul(Const (Big_int s2'), y1),
+ Mul (Const (Big_int s1'), y2))
+ | Sub _ -> failwith "scale term: not implemented"
+ | Mul(y,z) -> let s1,y1 = scale_term y and s2,y2 = scale_term z in
+ mult_big_int s1 s2 , Mul (y1, y2)
+ | Pow(t,n) -> let s,t = scale_term t in
+ power_big_int_positive_int s n , Pow(t,n)
+ | _ -> failwith "scale_term : not implemented"
let scale_term t =
let (s,t') = scale_term t in
- s,t'
+ s,t'
let get_index_of_ith_match f i l =
let rec get j res l =
match l with
- | [] -> failwith "bad index"
- | e::l -> if f e
- then
- (if Int.equal j i then res else get (j+1) (res+1) l )
- else get j (res+1) l in
- get 0 0 l
+ | [] -> failwith "bad index"
+ | e::l -> if f e
+ then
+ (if Int.equal j i then res else get (j+1) (res+1) l )
+ else get j (res+1) l in
+ get 0 0 l
let rec scale_certificate pos = match pos with
@@ -511,97 +577,97 @@ let rec scale_certificate pos = match pos with
| Rational_le n -> (denominator n) , Rational_le (Big_int (numerator n))
| Rational_lt n -> (denominator n) , Rational_lt (Big_int (numerator n))
| Square t -> let s,t' = scale_term t in
- mult_big_int s s , Square t'
+ mult_big_int s s , Square t'
| Eqmul (t, y) -> let s1,y1 = scale_term t and s2,y2 = scale_certificate y in
- mult_big_int s1 s2 , Eqmul (y1,y2)
+ mult_big_int s1 s2 , Eqmul (y1,y2)
| Sum (y, z) -> let s1,y1 = scale_certificate y
- and s2,y2 = scale_certificate z in
- let g = gcd_big_int s1 s2 in
- let s1' = div_big_int s1 g in
- let s2' = div_big_int s2 g in
- mult_big_int g (mult_big_int s1' s2'),
- Sum (Product(Rational_le (Big_int s2'), y1),
- Product (Rational_le (Big_int s1'), y2))
+ and s2,y2 = scale_certificate z in
+ let g = gcd_big_int s1 s2 in
+ let s1' = div_big_int s1 g in
+ let s2' = div_big_int s2 g in
+ mult_big_int g (mult_big_int s1' s2'),
+ Sum (Product(Rational_le (Big_int s2'), y1),
+ Product (Rational_le (Big_int s1'), y2))
| Product (y, z) ->
- let s1,y1 = scale_certificate y and s2,y2 = scale_certificate z in
- mult_big_int s1 s2 , Product (y1,y2)
+ let s1,y1 = scale_certificate y and s2,y2 = scale_certificate z in
+ mult_big_int s1 s2 , Product (y1,y2)
open Micromega
- let rec term_to_q_expr = function
- | Const n -> PEc (Ml2C.q n)
- | Zero -> PEc ( Ml2C.q (Int 0))
- | Var s -> PEX (Ml2C.index
- (int_of_string (String.sub s 1 (String.length s - 1))))
- | Mul(p1,p2) -> PEmul(term_to_q_expr p1, term_to_q_expr p2)
- | Add(p1,p2) -> PEadd(term_to_q_expr p1, term_to_q_expr p2)
- | Opp p -> PEopp (term_to_q_expr p)
- | Pow(t,n) -> PEpow (term_to_q_expr t,Ml2C.n n)
- | Sub(t1,t2) -> PEsub (term_to_q_expr t1, term_to_q_expr t2)
- | _ -> failwith "term_to_q_expr: not implemented"
-
- let term_to_q_pol e = Mc.norm_aux (Ml2C.q (Int 0)) (Ml2C.q (Int 1)) Mc.qplus Mc.qmult Mc.qminus Mc.qopp Mc.qeq_bool (term_to_q_expr e)
-
-
- let rec product l =
- match l with
- | [] -> Mc.PsatzZ
- | [i] -> Mc.PsatzIn (Ml2C.nat i)
- | i ::l -> Mc.PsatzMulE(Mc.PsatzIn (Ml2C.nat i), product l)
+let rec term_to_q_expr = function
+ | Const n -> PEc (Ml2C.q n)
+ | Zero -> PEc ( Ml2C.q (Int 0))
+ | Var s -> PEX (Ml2C.index
+ (int_of_string (String.sub s 1 (String.length s - 1))))
+ | Mul(p1,p2) -> PEmul(term_to_q_expr p1, term_to_q_expr p2)
+ | Add(p1,p2) -> PEadd(term_to_q_expr p1, term_to_q_expr p2)
+ | Opp p -> PEopp (term_to_q_expr p)
+ | Pow(t,n) -> PEpow (term_to_q_expr t,Ml2C.n n)
+ | Sub(t1,t2) -> PEsub (term_to_q_expr t1, term_to_q_expr t2)
+ | _ -> failwith "term_to_q_expr: not implemented"
+
+let term_to_q_pol e = Mc.norm_aux (Ml2C.q (Int 0)) (Ml2C.q (Int 1)) Mc.qplus Mc.qmult Mc.qminus Mc.qopp Mc.qeq_bool (term_to_q_expr e)
+
+
+let rec product l =
+ match l with
+ | [] -> Mc.PsatzZ
+ | [i] -> Mc.PsatzIn (Ml2C.nat i)
+ | i ::l -> Mc.PsatzMulE(Mc.PsatzIn (Ml2C.nat i), product l)
let q_cert_of_pos pos =
let rec _cert_of_pos = function
- Axiom_eq i -> Mc.PsatzIn (Ml2C.nat i)
+ Axiom_eq i -> Mc.PsatzIn (Ml2C.nat i)
| Axiom_le i -> Mc.PsatzIn (Ml2C.nat i)
| Axiom_lt i -> Mc.PsatzIn (Ml2C.nat i)
| Monoid l -> product l
| Rational_eq n | Rational_le n | Rational_lt n ->
- if Int.equal (compare_num n (Int 0)) 0 then Mc.PsatzZ else
- Mc.PsatzC (Ml2C.q n)
+ if Int.equal (compare_num n (Int 0)) 0 then Mc.PsatzZ else
+ Mc.PsatzC (Ml2C.q n)
| Square t -> Mc.PsatzSquare (term_to_q_pol t)
| Eqmul (t, y) -> Mc.PsatzMulC(term_to_q_pol t, _cert_of_pos y)
| Sum (y, z) -> Mc.PsatzAdd (_cert_of_pos y, _cert_of_pos z)
| Product (y, z) -> Mc.PsatzMulE (_cert_of_pos y, _cert_of_pos z) in
- simplify_cone q_spec (_cert_of_pos pos)
+ simplify_cone q_spec (_cert_of_pos pos)
- let rec term_to_z_expr = function
- | Const n -> PEc (Ml2C.bigint (big_int_of_num n))
- | Zero -> PEc ( Z0)
- | Var s -> PEX (Ml2C.index
- (int_of_string (String.sub s 1 (String.length s - 1))))
- | Mul(p1,p2) -> PEmul(term_to_z_expr p1, term_to_z_expr p2)
- | Add(p1,p2) -> PEadd(term_to_z_expr p1, term_to_z_expr p2)
- | Opp p -> PEopp (term_to_z_expr p)
- | Pow(t,n) -> PEpow (term_to_z_expr t,Ml2C.n n)
- | Sub(t1,t2) -> PEsub (term_to_z_expr t1, term_to_z_expr t2)
- | _ -> failwith "term_to_z_expr: not implemented"
+let rec term_to_z_expr = function
+ | Const n -> PEc (Ml2C.bigint (big_int_of_num n))
+ | Zero -> PEc ( Z0)
+ | Var s -> PEX (Ml2C.index
+ (int_of_string (String.sub s 1 (String.length s - 1))))
+ | Mul(p1,p2) -> PEmul(term_to_z_expr p1, term_to_z_expr p2)
+ | Add(p1,p2) -> PEadd(term_to_z_expr p1, term_to_z_expr p2)
+ | Opp p -> PEopp (term_to_z_expr p)
+ | Pow(t,n) -> PEpow (term_to_z_expr t,Ml2C.n n)
+ | Sub(t1,t2) -> PEsub (term_to_z_expr t1, term_to_z_expr t2)
+ | _ -> failwith "term_to_z_expr: not implemented"
- let term_to_z_pol e = Mc.norm_aux (Ml2C.z 0) (Ml2C.z 1) Mc.Z.add Mc.Z.mul Mc.Z.sub Mc.Z.opp Mc.zeq_bool (term_to_z_expr e)
+let term_to_z_pol e = Mc.norm_aux (Ml2C.z 0) (Ml2C.z 1) Mc.Z.add Mc.Z.mul Mc.Z.sub Mc.Z.opp Mc.zeq_bool (term_to_z_expr e)
let z_cert_of_pos pos =
let s,pos = (scale_certificate pos) in
let rec _cert_of_pos = function
- Axiom_eq i -> Mc.PsatzIn (Ml2C.nat i)
+ Axiom_eq i -> Mc.PsatzIn (Ml2C.nat i)
| Axiom_le i -> Mc.PsatzIn (Ml2C.nat i)
| Axiom_lt i -> Mc.PsatzIn (Ml2C.nat i)
| Monoid l -> product l
| Rational_eq n | Rational_le n | Rational_lt n ->
- if Int.equal (compare_num n (Int 0)) 0 then Mc.PsatzZ else
- Mc.PsatzC (Ml2C.bigint (big_int_of_num n))
+ if Int.equal (compare_num n (Int 0)) 0 then Mc.PsatzZ else
+ Mc.PsatzC (Ml2C.bigint (big_int_of_num n))
| Square t -> Mc.PsatzSquare (term_to_z_pol t)
| Eqmul (t, y) ->
- let is_unit =
- match t with
- | Const n -> n =/ Int 1
- | _ -> false in
- if is_unit
- then _cert_of_pos y
- else Mc.PsatzMulC(term_to_z_pol t, _cert_of_pos y)
+ let is_unit =
+ match t with
+ | Const n -> n =/ Int 1
+ | _ -> false in
+ if is_unit
+ then _cert_of_pos y
+ else Mc.PsatzMulC(term_to_z_pol t, _cert_of_pos y)
| Sum (y, z) -> Mc.PsatzAdd (_cert_of_pos y, _cert_of_pos z)
| Product (y, z) -> Mc.PsatzMulE (_cert_of_pos y, _cert_of_pos z) in
- simplify_cone z_spec (_cert_of_pos pos)
+ simplify_cone z_spec (_cert_of_pos pos)
(** All constraints (initial or derived) have an index and have a justification i.e., proof.
Given a constraint, all the coefficients are always integers.
@@ -612,116 +678,109 @@ open Num
open Big_int
open Polynomial
-(*module Mc = Micromega*)
-(*module Ml2C = Mutils.CamlToCoq
-module C2Ml = Mutils.CoqToCaml
-*)
-let debug = false
-
-
module Env =
struct
- type t = int list
+ type t = int list
- let id_of_hyp hyp l =
- let rec xid_of_hyp i l =
- match l with
- | [] -> failwith "id_of_hyp"
- | hyp'::l -> if Pervasives.(=) hyp hyp' then i else xid_of_hyp (i+1) l in
- xid_of_hyp 0 l
+ let id_of_hyp hyp l =
+ let rec xid_of_hyp i l =
+ match l with
+ | [] -> failwith "id_of_hyp"
+ | hyp'::l -> if Pervasives.(=) hyp hyp' then i else xid_of_hyp (i+1) l in
+ xid_of_hyp 0 l
end
let coq_poly_of_linpol (p,c) =
- let pol_of_mon m =
- Monomial.fold (fun x v p -> Mc.PEmul(Mc.PEpow(Mc.PEX(Ml2C.positive x),Ml2C.n v),p)) m (Mc.PEc (Mc.Zpos Mc.XH)) in
+ let pol_of_mon m =
+ Monomial.fold (fun x v p -> Mc.PEmul(Mc.PEpow(Mc.PEX(Ml2C.positive x),Ml2C.n v),p)) m (Mc.PEc (Mc.Zpos Mc.XH)) in
- List.fold_left (fun acc (x,v) ->
- let mn = LinPoly.MonT.retrieve x in
- Mc.PEadd(Mc.PEmul(Mc.PEc (Ml2C.bigint (numerator v)), pol_of_mon mn),acc)) (Mc.PEc (Ml2C.bigint (numerator c))) p
-
+ List.fold_left (fun acc (x,v) ->
+ let mn = LinPoly.MonT.retrieve x in
+ Mc.PEadd(Mc.PEmul(Mc.PEc (Ml2C.bigint (numerator v)), pol_of_mon mn),acc)) (Mc.PEc (Ml2C.bigint (numerator c))) p
+
let rec cmpl_prf_rule env = function
- | Hyp i | Def i -> Mc.PsatzIn (Ml2C.nat (Env.id_of_hyp i env))
- | Cst i -> Mc.PsatzC (Ml2C.bigint i)
- | Zero -> Mc.PsatzZ
- | MulPrf(p1,p2) -> Mc.PsatzMulE(cmpl_prf_rule env p1, cmpl_prf_rule env p2)
- | AddPrf(p1,p2) -> Mc.PsatzAdd(cmpl_prf_rule env p1 , cmpl_prf_rule env p2)
- | MulC(lp,p) -> let lp = Mc.norm0 (coq_poly_of_linpol lp) in
- Mc.PsatzMulC(lp,cmpl_prf_rule env p)
- | Square lp -> Mc.PsatzSquare (Mc.norm0 (coq_poly_of_linpol lp))
- | _ -> failwith "Cuts should already be compiled"
-
+ | Hyp i | Def i -> Mc.PsatzIn (Ml2C.nat (Env.id_of_hyp i env))
+ | Cst i -> Mc.PsatzC (Ml2C.bigint i)
+ | Zero -> Mc.PsatzZ
+ | MulPrf(p1,p2) -> Mc.PsatzMulE(cmpl_prf_rule env p1, cmpl_prf_rule env p2)
+ | AddPrf(p1,p2) -> Mc.PsatzAdd(cmpl_prf_rule env p1 , cmpl_prf_rule env p2)
+ | MulC(lp,p) -> let lp = Mc.norm0 (coq_poly_of_linpol lp) in
+ Mc.PsatzMulC(lp,cmpl_prf_rule env p)
+ | Square lp -> Mc.PsatzSquare (Mc.norm0 (coq_poly_of_linpol lp))
+ | _ -> failwith "Cuts should already be compiled"
+
let rec cmpl_proof env = function
- | Done -> Mc.DoneProof
- | Step(i,p,prf) ->
- begin
- match p with
- | CutPrf p' ->
- Mc.CutProof(cmpl_prf_rule env p', cmpl_proof (i::env) prf)
- | _ -> Mc.RatProof(cmpl_prf_rule env p,cmpl_proof (i::env) prf)
- end
- | Enum(i,p1,_,p2,l) ->
- Mc.EnumProof(cmpl_prf_rule env p1,cmpl_prf_rule env p2,List.map (cmpl_proof (i::env)) l)
+ | Done -> Mc.DoneProof
+ | Step(i,p,prf) ->
+ begin
+ match p with
+ | CutPrf p' ->
+ Mc.CutProof(cmpl_prf_rule env p', cmpl_proof (i::env) prf)
+ | _ -> Mc.RatProof(cmpl_prf_rule env p,cmpl_proof (i::env) prf)
+ end
+ | Enum(i,p1,_,p2,l) ->
+ Mc.EnumProof(cmpl_prf_rule env p1,cmpl_prf_rule env p2,List.map (cmpl_proof (i::env)) l)
let compile_proof env prf =
- let id = 1 + proof_max_id prf in
- let _,prf = normalise_proof id prf in
- if debug then Printf.fprintf stdout "compiled proof %a\n" output_proof prf;
- cmpl_proof env prf
+ let id = 1 + proof_max_id prf in
+ let _,prf = normalise_proof id prf in
+ if debug then Printf.fprintf stdout "compiled proof %a\n" output_proof prf;
+ cmpl_proof env prf
type prf_sys = (cstr_compat * prf_rule) list
let xlinear_prover sys =
- match Fourier.find_point sys with
- | Inr prf ->
- if debug then Printf.printf "AProof : %a\n" pp_proof prf ;
- let cert = (*List.map (fun (x,n) -> x+1,n)*) (fst (List.hd (Proof.mk_proof sys prf))) in
- if debug then Printf.printf "CProof : %a" Vect.pp_vect cert ;
- Some (rats_to_ints (Vect.to_list cert))
- | Inl _ -> None
+ match Fourier.find_point sys with
+ | Inr prf ->
+ if debug then Printf.printf "AProof : %a\n" pp_proof prf ;
+ let cert = (*List.map (fun (x,n) -> x+1,n)*) (fst (List.hd (Proof.mk_proof sys prf))) in
+ if debug then Printf.printf "CProof : %a" Vect.pp_vect cert ;
+ Some (rats_to_ints (Vect.to_list cert))
+ | Inl _ -> None
let output_num o n = output_string o (string_of_num n)
let output_bigint o n = output_string o (string_of_big_int n)
let proof_of_farkas prf cert =
-(* Printf.printf "\nproof_of_farkas %a , %a \n" (pp_list output_prf_rule) prf (pp_list output_bigint) cert ; *)
- let rec mk_farkas acc prf cert =
- match prf, cert with
- | _ , [] -> acc
- | [] , _ -> failwith "proof_of_farkas : not enough hyps"
- | p::prf,c::cert ->
- mk_farkas (add_proof (mul_proof c p) acc) prf cert in
- let res = mk_farkas Zero prf cert in
+ (* Printf.printf "\nproof_of_farkas %a , %a \n" (pp_list output_prf_rule) prf (pp_list output_bigint) cert ; *)
+ let rec mk_farkas acc prf cert =
+ match prf, cert with
+ | _ , [] -> acc
+ | [] , _ -> failwith "proof_of_farkas : not enough hyps"
+ | p::prf,c::cert ->
+ mk_farkas (add_proof (mul_proof c p) acc) prf cert in
+ let res = mk_farkas Zero prf cert in
(*Printf.printf "==> %a" output_prf_rule res ; *)
- res
+ res
let linear_prover sys =
- let (sysi,prfi) = List.split sys in
- match xlinear_prover sysi with
- | None -> None
- | Some cert -> Some (proof_of_farkas prfi cert)
+ let (sysi,prfi) = List.split sys in
+ match xlinear_prover sysi with
+ | None -> None
+ | Some cert -> Some (proof_of_farkas prfi cert)
let linear_prover =
- if debug
- then
- fun sys ->
- Printf.printf "<linear_prover"; flush stdout ;
- let res = linear_prover sys in
- Printf.printf ">"; flush stdout ;
- res
- else linear_prover
+ if debug
+ then
+ fun sys ->
+ Printf.printf "<linear_prover"; flush stdout ;
+ let res = linear_prover sys in
+ Printf.printf ">"; flush stdout ;
+ res
+ else linear_prover
@@ -733,11 +792,11 @@ let linear_prover =
*)
type checksat =
- | Tauto (* Tautology *)
- | Unsat of prf_rule (* Unsatisfiable *)
- | Cut of cstr_compat * prf_rule (* Cutting plane *)
- | Normalise of cstr_compat * prf_rule (* coefficients are relatively prime *)
-
+| Tauto (* Tautology *)
+| Unsat of prf_rule (* Unsatisfiable *)
+| Cut of cstr_compat * prf_rule (* Cutting plane *)
+| Normalise of cstr_compat * prf_rule (* coefficients are relatively prime *)
+
(** [check_sat]
- detects constraints that are not satisfiable;
@@ -745,83 +804,83 @@ type checksat =
*)
let check_sat (cstr,prf) =
- let {coeffs=coeffs ; op=op ; cst=cst} = cstr in
- match coeffs with
- | [] ->
- if eval_op op (Int 0) cst then Tauto else Unsat prf
- | _ ->
- let gcdi = (gcd_list (List.map snd coeffs)) in
- let gcd = Big_int gcdi in
- if eq_num gcd (Int 1)
- then Normalise(cstr,prf)
- else
- if Int.equal (sign_num (mod_num cst gcd)) 0
- then (* We can really normalise *)
- begin
- assert (sign_num gcd >=1 ) ;
- let cstr = {
- coeffs = List.map (fun (x,v) -> (x, v // gcd)) coeffs;
- op = op ; cst = cst // gcd
- } in
- Normalise(cstr,Gcd(gcdi,prf))
- (* Normalise(cstr,CutPrf prf)*)
- end
- else
- match op with
- | Eq -> Unsat (CutPrf prf)
- | Ge ->
- let cstr = {
- coeffs = List.map (fun (x,v) -> (x, v // gcd)) coeffs;
- op = op ; cst = ceiling_num (cst // gcd)
- } in Cut(cstr,CutPrf prf)
+ let {coeffs=coeffs ; op=op ; cst=cst} = cstr in
+ match coeffs with
+ | [] ->
+ if eval_op op (Int 0) cst then Tauto else Unsat prf
+ | _ ->
+ let gcdi = (gcd_list (List.map snd coeffs)) in
+ let gcd = Big_int gcdi in
+ if eq_num gcd (Int 1)
+ then Normalise(cstr,prf)
+ else
+ if Int.equal (sign_num (mod_num cst gcd)) 0
+ then (* We can really normalise *)
+ begin
+ assert (sign_num gcd >=1 ) ;
+ let cstr = {
+ coeffs = List.map (fun (x,v) -> (x, v // gcd)) coeffs;
+ op = op ; cst = cst // gcd
+ } in
+ Normalise(cstr,Gcd(gcdi,prf))
+ (* Normalise(cstr,CutPrf prf)*)
+ end
+ else
+ match op with
+ | Eq -> Unsat (CutPrf prf)
+ | Ge ->
+ let cstr = {
+ coeffs = List.map (fun (x,v) -> (x, v // gcd)) coeffs;
+ op = op ; cst = ceiling_num (cst // gcd)
+ } in Cut(cstr,CutPrf prf)
(** Proof generating pivoting over variable v *)
let pivot v (c1,p1) (c2,p2) =
- let {coeffs = v1 ; op = op1 ; cst = n1} = c1
- and {coeffs = v2 ; op = op2 ; cst = n2} = c2 in
+ let {coeffs = v1 ; op = op1 ; cst = n1} = c1
+ and {coeffs = v2 ; op = op2 ; cst = n2} = c2 in
(* Could factorise gcd... *)
- let xpivot cv1 cv2 =
- (
- {coeffs = Vect.add (Vect.mul cv1 v1) (Vect.mul cv2 v2) ;
- op = Proof.add_op op1 op2 ;
- cst = n1 */ cv1 +/ n2 */ cv2 },
+ let xpivot cv1 cv2 =
+ (
+ {coeffs = Vect.add (Vect.mul cv1 v1) (Vect.mul cv2 v2) ;
+ op = Proof.add_op op1 op2 ;
+ cst = n1 */ cv1 +/ n2 */ cv2 },
- AddPrf(mul_proof (numerator cv1) p1,mul_proof (numerator cv2) p2)) in
+ AddPrf(mul_proof (numerator cv1) p1,mul_proof (numerator cv2) p2)) in
+
+ match Vect.get v v1 , Vect.get v v2 with
+ | None , _ | _ , None -> None
+ | Some a , Some b ->
+ if Int.equal ((sign_num a) * (sign_num b)) (-1)
+ then
+ let cv1 = abs_num b
+ and cv2 = abs_num a in
+ Some (xpivot cv1 cv2)
+ else
+ if op1 == Eq
+ then
+ let cv1 = minus_num (b */ (Int (sign_num a)))
+ and cv2 = abs_num a in
+ Some (xpivot cv1 cv2)
+ else if op2 == Eq
+ then
+ let cv1 = abs_num b
+ and cv2 = minus_num (a */ (Int (sign_num b))) in
+ Some (xpivot cv1 cv2)
+ else None (* op2 could be Eq ... this might happen *)
- match Vect.get v v1 , Vect.get v v2 with
- | None , _ | _ , None -> None
- | Some a , Some b ->
- if Int.equal ((sign_num a) * (sign_num b)) (-1)
- then
- let cv1 = abs_num b
- and cv2 = abs_num a in
- Some (xpivot cv1 cv2)
- else
- if op1 == Eq
- then
- let cv1 = minus_num (b */ (Int (sign_num a)))
- and cv2 = abs_num a in
- Some (xpivot cv1 cv2)
- else if op2 == Eq
- then
- let cv1 = abs_num b
- and cv2 = minus_num (a */ (Int (sign_num b))) in
- Some (xpivot cv1 cv2)
- else None (* op2 could be Eq ... this might happen *)
-
exception FoundProof of prf_rule
let simpl_sys sys =
- List.fold_left (fun acc (c,p) ->
- match check_sat (c,p) with
- | Tauto -> acc
- | Unsat prf -> raise (FoundProof prf)
- | Cut(c,p) -> (c,p)::acc
- | Normalise (c,p) -> (c,p)::acc) [] sys
+ List.fold_left (fun acc (c,p) ->
+ match check_sat (c,p) with
+ | Tauto -> acc
+ | Unsat prf -> raise (FoundProof prf)
+ | Cut(c,p) -> (c,p)::acc
+ | Normalise (c,p) -> (c,p)::acc) [] sys
(** [ext_gcd a b] is the extended Euclid algorithm.
@@ -829,77 +888,77 @@ let simpl_sys sys =
Source: http://en.wikipedia.org/wiki/Extended_Euclidean_algorithm
*)
let rec ext_gcd a b =
- if Int.equal (sign_big_int b) 0
- then (unit_big_int,zero_big_int)
- else
- let (q,r) = quomod_big_int a b in
- let (s,t) = ext_gcd b r in
- (t, sub_big_int s (mult_big_int q t))
+ if Int.equal (sign_big_int b) 0
+ then (unit_big_int,zero_big_int)
+ else
+ let (q,r) = quomod_big_int a b in
+ let (s,t) = ext_gcd b r in
+ (t, sub_big_int s (mult_big_int q t))
let pp_ext_gcd a b =
- let a' = big_int_of_int a in
- let b' = big_int_of_int b in
-
- let (x,y) = ext_gcd a' b' in
- Printf.fprintf stdout "%s * %s + %s * %s = %s\n"
- (string_of_big_int x) (string_of_big_int a')
- (string_of_big_int y) (string_of_big_int b')
- (string_of_big_int (add_big_int (mult_big_int x a') (mult_big_int y b')))
+ let a' = big_int_of_int a in
+ let b' = big_int_of_int b in
+
+ let (x,y) = ext_gcd a' b' in
+ Printf.fprintf stdout "%s * %s + %s * %s = %s\n"
+ (string_of_big_int x) (string_of_big_int a')
+ (string_of_big_int y) (string_of_big_int b')
+ (string_of_big_int (add_big_int (mult_big_int x a') (mult_big_int y b')))
exception Result of (int * (proof * cstr_compat))
let split_equations psys =
- List.partition (fun (c,p) -> c.op == Eq)
+ List.partition (fun (c,p) -> c.op == Eq)
let extract_coprime (c1,p1) (c2,p2) =
- let rec exist2 vect1 vect2 =
- match vect1 , vect2 with
- | _ , [] | [], _ -> None
- | (v1,n1)::vect1' , (v2, n2) :: vect2' ->
- if Pervasives.(=) v1 v2
- then
- if Int.equal (compare_big_int (gcd_big_int (numerator n1) (numerator n2)) unit_big_int) 0
- then Some (v1,n1,n2)
- else
- exist2 vect1' vect2'
- else
- if v1 < v2
- then exist2 vect1' vect2
- else exist2 vect1 vect2' in
-
- if c1.op == Eq && c2.op == Eq
- then exist2 c1.coeffs c2.coeffs
- else None
+ let rec exist2 vect1 vect2 =
+ match vect1 , vect2 with
+ | _ , [] | [], _ -> None
+ | (v1,n1)::vect1' , (v2, n2) :: vect2' ->
+ if Pervasives.(=) v1 v2
+ then
+ if Int.equal (compare_big_int (gcd_big_int (numerator n1) (numerator n2)) unit_big_int) 0
+ then Some (v1,n1,n2)
+ else
+ exist2 vect1' vect2'
+ else
+ if v1 < v2
+ then exist2 vect1' vect2
+ else exist2 vect1 vect2' in
+
+ if c1.op == Eq && c2.op == Eq
+ then exist2 c1.coeffs c2.coeffs
+ else None
let extract2 pred l =
- let rec xextract2 rl l =
- match l with
- | [] -> (None,rl) (* Did not find *)
- | e::l ->
- match extract (pred e) l with
- | None,_ -> xextract2 (e::rl) l
- | Some (r,e'),l' -> Some (r,e,e'), List.rev_append rl l' in
-
- xextract2 [] l
+ let rec xextract2 rl l =
+ match l with
+ | [] -> (None,rl) (* Did not find *)
+ | e::l ->
+ match extract (pred e) l with
+ | None,_ -> xextract2 (e::rl) l
+ | Some (r,e'),l' -> Some (r,e,e'), List.rev_append rl l' in
+
+ xextract2 [] l
let extract_coprime_equation psys =
- extract2 extract_coprime psys
+ extract2 extract_coprime psys
let apply_and_normalise f psys =
- List.fold_left (fun acc pc' ->
- match f pc' with
- | None -> pc'::acc
- | Some pc' ->
- match check_sat pc' with
- | Tauto -> acc
- | Unsat prf -> raise (FoundProof prf)
- | Cut(c,p) -> (c,p)::acc
- | Normalise (c,p) -> (c,p)::acc
- ) [] psys
+ List.fold_left (fun acc pc' ->
+ match f pc' with
+ | None -> pc'::acc
+ | Some pc' ->
+ match check_sat pc' with
+ | Tauto -> acc
+ | Unsat prf -> raise (FoundProof prf)
+ | Cut(c,p) -> (c,p)::acc
+ | Normalise (c,p) -> (c,p)::acc
+ ) [] psys
@@ -908,314 +967,317 @@ let pivot_sys v pc psys = apply_and_normalise (pivot v pc) psys
let reduce_coprime psys =
- let oeq,sys = extract_coprime_equation psys in
- match oeq with
- | None -> None (* Nothing to do *)
- | Some((v,n1,n2),(c1,p1),(c2,p2) ) ->
- let (l1,l2) = ext_gcd (numerator n1) (numerator n2) in
- let l1' = Big_int l1 and l2' = Big_int l2 in
- let cstr =
- {coeffs = Vect.add (Vect.mul l1' c1.coeffs) (Vect.mul l2' c2.coeffs);
- op = Eq ;
- cst = (l1' */ c1.cst) +/ (l2' */ c2.cst)
- } in
- let prf = add_proof (mul_proof (numerator l1') p1) (mul_proof (numerator l2') p2) in
-
- Some (pivot_sys v (cstr,prf) ((c1,p1)::sys))
+ let oeq,sys = extract_coprime_equation psys in
+ match oeq with
+ | None -> None (* Nothing to do *)
+ | Some((v,n1,n2),(c1,p1),(c2,p2) ) ->
+ let (l1,l2) = ext_gcd (numerator n1) (numerator n2) in
+ let l1' = Big_int l1 and l2' = Big_int l2 in
+ let cstr =
+ {coeffs = Vect.add (Vect.mul l1' c1.coeffs) (Vect.mul l2' c2.coeffs);
+ op = Eq ;
+ cst = (l1' */ c1.cst) +/ (l2' */ c2.cst)
+ } in
+ let prf = add_proof (mul_proof (numerator l1') p1) (mul_proof (numerator l2') p2) in
+
+ Some (pivot_sys v (cstr,prf) ((c1,p1)::sys))
(** If there is an equation [eq] of the form 1.x + e = c, do a pivot over x with equation [eq] *)
let reduce_unary psys =
- let is_unary_equation (cstr,prf) =
- if cstr.op == Eq
- then
- try
- Some (fst (List.find (fun (_,n) -> n =/ (Int 1) || n=/ (Int (-1))) cstr.coeffs))
- with Not_found -> None
- else None in
-
- let (oeq,sys) = extract is_unary_equation psys in
- match oeq with
- | None -> None (* Nothing to do *)
- | Some(v,pc) ->
- Some(pivot_sys v pc sys)
+ let is_unary_equation (cstr,prf) =
+ if cstr.op == Eq
+ then
+ try
+ Some (fst (List.find (fun (_,n) -> n =/ (Int 1) || n=/ (Int (-1))) cstr.coeffs))
+ with Not_found -> None
+ else None in
+
+ let (oeq,sys) = extract is_unary_equation psys in
+ match oeq with
+ | None -> None (* Nothing to do *)
+ | Some(v,pc) ->
+ Some(pivot_sys v pc sys)
let reduce_non_lin_unary psys =
- let is_unary_equation (cstr,prf) =
- if cstr.op == Eq
- then
- try
- let x = fst (List.find (fun (x,n) -> (n =/ (Int 1) || n=/ (Int (-1))) && Monomial.is_var (LinPoly.MonT.retrieve x) ) cstr.coeffs) in
- let x' = LinPoly.MonT.retrieve x in
- if List.for_all (fun (y,_) -> Pervasives.(=) y x || Int.equal (snd (Monomial.div (LinPoly.MonT.retrieve y) x')) 0) cstr.coeffs
- then Some x
- else None
- with Not_found -> None
- else None in
-
-
- let (oeq,sys) = extract is_unary_equation psys in
- match oeq with
- | None -> None (* Nothing to do *)
- | Some(v,pc) ->
- Some(apply_and_normalise (LinPoly.pivot_eq v pc) sys)
+ let is_unary_equation (cstr,prf) =
+ if cstr.op == Eq
+ then
+ try
+ let x = fst (List.find (fun (x,n) -> (n =/ (Int 1) || n=/ (Int (-1))) && Monomial.is_var (LinPoly.MonT.retrieve x) ) cstr.coeffs) in
+ let x' = LinPoly.MonT.retrieve x in
+ if List.for_all (fun (y,_) -> Pervasives.(=) y x || Int.equal (snd (Monomial.div (LinPoly.MonT.retrieve y) x')) 0) cstr.coeffs
+ then Some x
+ else None
+ with Not_found -> None
+ else None in
+
+
+ let (oeq,sys) = extract is_unary_equation psys in
+ match oeq with
+ | None -> None (* Nothing to do *)
+ | Some(v,pc) ->
+ Some(apply_and_normalise (LinPoly.pivot_eq v pc) sys)
let reduce_var_change psys =
- let rec rel_prime vect =
- match vect with
- | [] -> None
- | (x,v)::vect ->
- let v = numerator v in
- try
- let (x',v') = List.find (fun (_,v') ->
- let v' = numerator v' in
- eq_big_int (gcd_big_int v v') unit_big_int) vect in
- Some ((x,v),(x',numerator v'))
- with Not_found -> rel_prime vect in
-
- let rel_prime (cstr,prf) = if cstr.op == Eq then rel_prime cstr.coeffs else None in
-
- let (oeq,sys) = extract rel_prime psys in
-
- match oeq with
- | None -> None
- | Some(((x,v),(x',v')),(c,p)) ->
- let (l1,l2) = ext_gcd v v' in
- let l1,l2 = Big_int l1 , Big_int l2 in
+ let rec rel_prime vect =
+ match vect with
+ | [] -> None
+ | (x,v)::vect ->
+ let v = numerator v in
+ try
+ let (x',v') = List.find (fun (_,v') ->
+ let v' = numerator v' in
+ eq_big_int (gcd_big_int v v') unit_big_int) vect in
+ Some ((x,v),(x',numerator v'))
+ with Not_found -> rel_prime vect in
- let get v vect =
- match Vect.get v vect with
- | None -> Int 0
- | Some n -> n in
+ let rel_prime (cstr,prf) = if cstr.op == Eq then rel_prime cstr.coeffs else None in
- let pivot_eq (c',p') =
- let {coeffs = coeffs ; op = op ; cst = cst} = c' in
- let vx = get x coeffs in
- let vx' = get x' coeffs in
- let m = minus_num (vx */ l1 +/ vx' */ l2) in
- Some ({coeffs =
- Vect.add (Vect.mul m c.coeffs) coeffs ; op = op ; cst = m */ c.cst +/ cst} ,
- AddPrf(MulC(([], m),p),p')) in
+ let (oeq,sys) = extract rel_prime psys in
+
+ match oeq with
+ | None -> None
+ | Some(((x,v),(x',v')),(c,p)) ->
+ let (l1,l2) = ext_gcd v v' in
+ let l1,l2 = Big_int l1 , Big_int l2 in
- Some (apply_and_normalise pivot_eq sys)
+ let get v vect =
+ match Vect.get v vect with
+ | None -> Int 0
+ | Some n -> n in
+ let pivot_eq (c',p') =
+ let {coeffs = coeffs ; op = op ; cst = cst} = c' in
+ let vx = get x coeffs in
+ let vx' = get x' coeffs in
+ let m = minus_num (vx */ l1 +/ vx' */ l2) in
+ Some ({coeffs =
+ Vect.add (Vect.mul m c.coeffs) coeffs ; op = op ; cst = m */ c.cst +/ cst} ,
+ AddPrf(MulC(([], m),p),p')) in
+ Some (apply_and_normalise pivot_eq sys)
- let reduce_pivot psys =
- let is_equation (cstr,prf) =
- if cstr.op == Eq
- then
- try
- Some (fst (List.hd cstr.coeffs))
- with Not_found -> None
- else None in
- let (oeq,sys) = extract is_equation psys in
- match oeq with
- | None -> None (* Nothing to do *)
- | Some(v,pc) ->
- if debug then
- Printf.printf "Bad news : loss of completeness %a=%s" Vect.pp_vect (fst pc).coeffs (string_of_num (fst pc).cst);
- Some(pivot_sys v pc sys)
+let reduce_pivot psys =
+ let is_equation (cstr,prf) =
+ if cstr.op == Eq
+ then
+ try
+ Some (fst (List.hd cstr.coeffs))
+ with Not_found -> None
+ else None in
+ let (oeq,sys) = extract is_equation psys in
+ match oeq with
+ | None -> None (* Nothing to do *)
+ | Some(v,pc) ->
+ if debug then
+ Printf.printf "Bad news : loss of completeness %a=%s" Vect.pp_vect (fst pc).coeffs (string_of_num (fst pc).cst);
+ Some(pivot_sys v pc sys)
- let iterate_until_stable f x =
- let rec iter x =
- match f x with
- | None -> x
- | Some x' -> iter x' in
- iter x
- let rec app_funs l x =
- match l with
- | [] -> None
- | f::fl ->
- match f x with
- | None -> app_funs fl x
- | Some x' -> Some x'
- let reduction_equations psys =
- iterate_until_stable (app_funs
- [reduce_unary ; reduce_coprime ;
- reduce_var_change (*; reduce_pivot*)]) psys
+let iterate_until_stable f x =
+ let rec iter x =
+ match f x with
+ | None -> x
+ | Some x' -> iter x' in
+ iter x
- let reduction_non_lin_equations psys =
- iterate_until_stable (app_funs
- [reduce_non_lin_unary (*; reduce_coprime ;
- reduce_var_change ; reduce_pivot *)]) psys
+let rec app_funs l x =
+ match l with
+ | [] -> None
+ | f::fl ->
+ match f x with
+ | None -> app_funs fl x
+ | Some x' -> Some x'
+
+let reduction_equations psys =
+ iterate_until_stable (app_funs
+ [reduce_unary ; reduce_coprime ;
+ reduce_var_change (*; reduce_pivot*)]) psys
+
+let reduction_non_lin_equations psys =
+ iterate_until_stable (app_funs
+ [reduce_non_lin_unary (*; reduce_coprime ;
+ reduce_var_change ; reduce_pivot *)]) psys
(** [get_bound sys] returns upon success an interval (lb,e,ub) with proofs *)
- let get_bound sys =
- let is_small (v,i) =
- match Itv.range i with
- | None -> false
- | Some i -> i <=/ (Int 1) in
-
- let select_best (x1,i1) (x2,i2) =
- if Itv.smaller_itv i1 i2
- then (x1,i1) else (x2,i2) in
+let get_bound sys =
+ let is_small (v,i) =
+ match Itv.range i with
+ | None -> false
+ | Some i -> i <=/ (Int 1) in
+
+ let select_best (x1,i1) (x2,i2) =
+ if Itv.smaller_itv i1 i2
+ then (x1,i1) else (x2,i2) in
(* For lia, there are no equations => these precautions are not needed *)
(* For nlia, there are equations => do not enumerate over equations! *)
- let all_planes sys =
- let (eq,ineq) = List.partition (fun c -> c.op == Eq) sys in
- match eq with
- | [] -> List.rev_map (fun c -> c.coeffs) ineq
- | _ ->
- List.fold_left (fun acc c ->
- if List.exists (fun c' -> Vect.equal c.coeffs c'.coeffs) eq
- then acc else c.coeffs ::acc) [] ineq in
-
- let smallest_interval =
- List.fold_left
- (fun acc vect ->
- if is_small acc
- then acc
- else
- match Fourier.optimise vect sys with
- | None -> acc
- | Some i ->
- if debug then Printf.printf "Found a new bound %a" Vect.pp_vect vect ;
- select_best (vect,i) acc) (Vect.null, (None,None)) (all_planes sys) in
- let smallest_interval =
- match smallest_interval
- with
- | (x,(Some i, Some j)) -> Some(i,x,j)
- | x -> None (* This should not be possible *)
- in
- match smallest_interval with
- | Some (lb,e,ub) ->
- let (lbn,lbd) = (sub_big_int (numerator lb) unit_big_int, denominator lb) in
- let (ubn,ubd) = (add_big_int unit_big_int (numerator ub) , denominator ub) in
- (match
+ let all_planes sys =
+ let (eq,ineq) = List.partition (fun c -> c.op == Eq) sys in
+ match eq with
+ | [] -> List.rev_map (fun c -> c.coeffs) ineq
+ | _ ->
+ List.fold_left (fun acc c ->
+ if List.exists (fun c' -> Vect.equal c.coeffs c'.coeffs) eq
+ then acc else c.coeffs ::acc) [] ineq in
+
+ let smallest_interval =
+ List.fold_left
+ (fun acc vect ->
+ if is_small acc
+ then acc
+ else
+ match Fourier.optimise vect sys with
+ | None -> acc
+ | Some i ->
+ if debug then Printf.printf "Found a new bound %a" Vect.pp_vect vect ;
+ select_best (vect,i) acc) (Vect.null, (None,None)) (all_planes sys) in
+ let smallest_interval =
+ match smallest_interval
+ with
+ | (x,(Some i, Some j)) -> Some(i,x,j)
+ | x -> None (* This should not be possible *)
+ in
+ match smallest_interval with
+ | Some (lb,e,ub) ->
+ let (lbn,lbd) = (sub_big_int (numerator lb) unit_big_int, denominator lb) in
+ let (ubn,ubd) = (add_big_int unit_big_int (numerator ub) , denominator ub) in
+ (match
(* x <= ub -> x > ub *)
- xlinear_prover ({coeffs = Vect.mul (Big_int ubd) e ; op = Ge ; cst = Big_int ubn} :: sys),
+ xlinear_prover ({coeffs = Vect.mul (Big_int ubd) e ; op = Ge ; cst = Big_int ubn} :: sys),
(* lb <= x -> lb > x *)
- xlinear_prover
- ({coeffs = Vect.mul (minus_num (Big_int lbd)) e ; op = Ge ; cst = minus_num (Big_int lbn)} :: sys)
- with
- | Some cub , Some clb -> Some(List.tl clb,(lb,e,ub), List.tl cub)
- | _ -> failwith "Interval without proof"
- )
- | None -> None
-
-
- let check_sys sys =
- List.for_all (fun (c,p) -> List.for_all (fun (_,n) -> sign_num n <> 0) c.coeffs) sys
-
-
- let xlia reduction_equations sys =
-
- let rec enum_proof (id:int) (sys:prf_sys) : proof option =
- if debug then (Printf.printf "enum_proof\n" ; flush stdout) ;
- assert (check_sys sys) ;
-
- let nsys,prf = List.split sys in
- match get_bound nsys with
- | None -> None (* Is the systeme really unbounded ? *)
- | Some(prf1,(lb,e,ub),prf2) ->
- if debug then Printf.printf "Found interval: %a in [%s;%s] -> " Vect.pp_vect e (string_of_num lb) (string_of_num ub) ;
- (match start_enum id e (ceiling_num lb) (floor_num ub) sys
- with
- | Some prfl ->
- Some(Enum(id,proof_of_farkas prf prf1,e, proof_of_farkas prf prf2,prfl))
- | None -> None
- )
-
- and start_enum id e clb cub sys =
- if clb >/ cub
- then Some []
- else
- let eq = {coeffs = e ; op = Eq ; cst = clb} in
- match aux_lia (id+1) ((eq, Def id) :: sys) with
- | None -> None
- | Some prf ->
- match start_enum id e (clb +/ (Int 1)) cub sys with
- | None -> None
- | Some l -> Some (prf::l)
-
- and aux_lia (id:int) (sys:prf_sys) : proof option =
- assert (check_sys sys) ;
- if debug then Printf.printf "xlia: %a \n" (pp_list (fun o (c,_) -> output_cstr o c)) sys ;
- try
- let sys = reduction_equations sys in
- if debug then
+ xlinear_prover
+ ({coeffs = Vect.mul (minus_num (Big_int lbd)) e ; op = Ge ; cst = minus_num (Big_int lbn)} :: sys)
+ with
+ | Some cub , Some clb -> Some(List.tl clb,(lb,e,ub), List.tl cub)
+ | _ -> failwith "Interval without proof"
+ )
+ | None -> None
+
+
+let check_sys sys =
+ List.for_all (fun (c,p) -> List.for_all (fun (_,n) -> sign_num n <> 0) c.coeffs) sys
+
+
+let xlia (can_enum:bool) reduction_equations sys =
+
+
+ let rec enum_proof (id:int) (sys:prf_sys) : proof option =
+ if debug then (Printf.printf "enum_proof\n" ; flush stdout) ;
+ assert (check_sys sys) ;
+
+ let nsys,prf = List.split sys in
+ match get_bound nsys with
+ | None -> None (* Is the systeme really unbounded ? *)
+ | Some(prf1,(lb,e,ub),prf2) ->
+ if debug then Printf.printf "Found interval: %a in [%s;%s] -> " Vect.pp_vect e (string_of_num lb) (string_of_num ub) ;
+ (match start_enum id e (ceiling_num lb) (floor_num ub) sys
+ with
+ | Some prfl ->
+ Some(Enum(id,proof_of_farkas prf prf1,e, proof_of_farkas prf prf2,prfl))
+ | None -> None
+ )
+
+ and start_enum id e clb cub sys =
+ if clb >/ cub
+ then Some []
+ else
+ let eq = {coeffs = e ; op = Eq ; cst = clb} in
+ match aux_lia (id+1) ((eq, Def id) :: sys) with
+ | None -> None
+ | Some prf ->
+ match start_enum id e (clb +/ (Int 1)) cub sys with
+ | None -> None
+ | Some l -> Some (prf::l)
+
+ and aux_lia (id:int) (sys:prf_sys) : proof option =
+ assert (check_sys sys) ;
+ if debug then Printf.printf "xlia: %a \n" (pp_list (fun o (c,_) -> output_cstr o c)) sys ;
+ try
+ let sys = reduction_equations sys in
+ if debug then
Printf.printf "after reduction: %a \n" (pp_list (fun o (c,_) -> output_cstr o c)) sys ;
- match linear_prover sys with
- | Some prf -> Some (Step(id,prf,Done))
- | None -> enum_proof id sys
- with FoundProof prf ->
+ match linear_prover sys with
+ | Some prf -> Some (Step(id,prf,Done))
+ | None -> if can_enum then enum_proof id sys else None
+ with FoundProof prf ->
(* [reduction_equations] can find a proof *)
- Some(Step(id,prf,Done)) in
+ Some(Step(id,prf,Done)) in
(* let sys' = List.map (fun (p,o) -> Mc.norm0 p , o) sys in*)
- let id = List.length sys in
- let orpf =
- try
- let sys = simpl_sys sys in
- aux_lia id sys
- with FoundProof pr -> Some(Step(id,pr,Done)) in
- match orpf with
- | None -> None
- | Some prf ->
+ let id = List.length sys in
+ let orpf =
+ try
+ let sys = simpl_sys sys in
+ aux_lia id sys
+ with FoundProof pr -> Some(Step(id,pr,Done)) in
+ match orpf with
+ | None -> None
+ | Some prf ->
(*Printf.printf "direct proof %a\n" output_proof prf ; *)
- let env = mapi (fun _ i -> i) sys in
- let prf = compile_proof env prf in
+ let env = mapi (fun _ i -> i) sys in
+ let prf = compile_proof env prf in
(*try
if Mc.zChecker sys' prf then Some prf else
raise Certificate.BadCertificate
with Failure s -> (Printf.printf "%s" s ; Some prf)
*) Some prf
-
-
- let cstr_compat_of_poly (p,o) =
- let (v,c) = LinPoly.linpol_of_pol p in
- {coeffs = v ; op = o ; cst = minus_num c }
-
-
- let lia sys =
- LinPoly.MonT.clear ();
- let sys = List.map (develop_constraint z_spec) sys in
- let (sys:cstr_compat list) = List.map cstr_compat_of_poly sys in
- let sys = mapi (fun c i -> (c,Hyp i)) sys in
- xlia reduction_equations sys
-
-
- let nlia sys =
- LinPoly.MonT.clear ();
- let sys = List.map (develop_constraint z_spec) sys in
- let sys = mapi (fun c i -> (c,Hyp i)) sys in
-
- let is_linear = List.for_all (fun ((p,_),_) -> Poly.is_linear p) sys in
-
- let collect_square =
- List.fold_left (fun acc ((p,_),_) -> Poly.fold
- (fun m _ acc ->
- match Monomial.sqrt m with
- | None -> acc
- | Some s -> MonMap.add s m acc) p acc) MonMap.empty sys in
- let sys = MonMap.fold (fun s m acc ->
- let s = LinPoly.linpol_of_pol (Poly.add s (Int 1) (Poly.constant (Int 0))) in
- let m = Poly.add m (Int 1) (Poly.constant (Int 0)) in
- ((m, Ge), (Square s))::acc) collect_square sys in
-
-(* List.iter (fun ((p,_),_) -> Printf.printf "square %a\n" Poly.pp p) gen_square*)
-
- let sys =
- if is_linear then sys
- else sys @ (all_sym_pairs (fun ((c,o),p) ((c',o'),p') ->
- ((Poly.product c c',opMult o o'), MulPrf(p,p'))) sys) in
+
- let sys = List.map (fun (c,p) -> cstr_compat_of_poly c,p) sys in
- assert (check_sys sys) ;
- xlia (if is_linear then reduction_equations else reduction_non_lin_equations) sys
+let cstr_compat_of_poly (p,o) =
+ let (v,c) = LinPoly.linpol_of_pol p in
+ {coeffs = v ; op = o ; cst = minus_num c }
+
+
+let lia (can_enum:bool) (prfdepth:int) sys =
+ LinPoly.MonT.clear ();
+ max_nb_cstr := compute_max_nb_cstr sys prfdepth ;
+ let sys = List.map (develop_constraint z_spec) sys in
+ let (sys:cstr_compat list) = List.map cstr_compat_of_poly sys in
+ let sys = mapi (fun c i -> (c,Hyp i)) sys in
+ xlia can_enum reduction_equations sys
+
+
+let nlia enum prfdepth sys =
+ LinPoly.MonT.clear ();
+ max_nb_cstr := compute_max_nb_cstr sys prfdepth;
+ let sys = List.map (develop_constraint z_spec) sys in
+ let sys = mapi (fun c i -> (c,Hyp i)) sys in
+
+ let is_linear = List.for_all (fun ((p,_),_) -> Poly.is_linear p) sys in
+
+ let collect_square =
+ List.fold_left (fun acc ((p,_),_) -> Poly.fold
+ (fun m _ acc ->
+ match Monomial.sqrt m with
+ | None -> acc
+ | Some s -> MonMap.add s m acc) p acc) MonMap.empty sys in
+ let sys = MonMap.fold (fun s m acc ->
+ let s = LinPoly.linpol_of_pol (Poly.add s (Int 1) (Poly.constant (Int 0))) in
+ let m = Poly.add m (Int 1) (Poly.constant (Int 0)) in
+ ((m, Ge), (Square s))::acc) collect_square sys in
+
+ (* List.iter (fun ((p,_),_) -> Printf.printf "square %a\n" Poly.pp p) gen_square*)
+
+ let sys =
+ if is_linear then sys
+ else sys @ (all_sym_pairs (fun ((c,o),p) ((c',o'),p') ->
+ ((Poly.product c c',opMult o o'), MulPrf(p,p'))) sys) in
+
+ let sys = List.map (fun (c,p) -> cstr_compat_of_poly c,p) sys in
+ assert (check_sys sys) ;
+ xlia enum (if is_linear then reduction_equations else reduction_non_lin_equations) sys
diff --git a/plugins/micromega/coq_micromega.ml b/plugins/micromega/coq_micromega.ml
index cce0a7280..1dd53a3fd 100644
--- a/plugins/micromega/coq_micromega.ml
+++ b/plugins/micromega/coq_micromega.ml
@@ -18,6 +18,9 @@
open Pp
open Mutils
+open Proofview
+open Goptions
+open Proofview.Notations
(**
* Debug flag
@@ -37,6 +40,53 @@ let time str f x =
flush stdout);
res
+
+(* Limit the proof search *)
+
+let max_depth = max_int
+
+(* Search limit for provers over Q R *)
+let lra_proof_depth = ref max_depth
+
+
+(* Search limit for provers over Z *)
+let lia_enum = ref true
+let lia_proof_depth = ref max_depth
+
+let get_lia_option () =
+ (!lia_enum,!lia_proof_depth)
+
+let get_lra_option () =
+ !lra_proof_depth
+
+
+
+let _ =
+
+ let int_opt l vref =
+ {
+ optsync = true;
+ optdepr = false;
+ optname = List.fold_right (^) l "";
+ optkey = l ;
+ optread = (fun () -> Some !vref);
+ optwrite = (fun x -> vref := (match x with None -> max_depth | Some v -> v))
+ } in
+
+ let lia_enum_opt =
+ {
+ optsync = true;
+ optdepr = false;
+ optname = "Lia Enum";
+ optkey = ["Lia";"Enum"];
+ optread = (fun () -> !lia_enum);
+ optwrite = (fun x -> lia_enum := x)
+ } in
+ let _ = declare_int_option (int_opt ["Lra"; "Depth"] lra_proof_depth) in
+ let _ = declare_int_option (int_opt ["Lia"; "Depth"] lia_proof_depth) in
+ let _ = declare_bool_option lia_enum_opt in
+ ()
+
(**
* Initialize a tag type to the Tag module declaration (see Mutils).
*)
@@ -359,6 +409,7 @@ struct
let coq_Qmake = lazy (constant "Qmake")
let coq_Rcst = lazy (constant "Rcst")
+
let coq_C0 = lazy (m_constant "C0")
let coq_C1 = lazy (m_constant "C1")
let coq_CQ = lazy (m_constant "CQ")
@@ -1094,10 +1145,6 @@ struct
| N (a) -> Mc.N(f2f a)
| I(a,_,b) -> Mc.I(f2f a,f2f b)
- let is_prop t =
- match t with
- | Names.Anonymous -> true (* Not quite right *)
- | Names.Name x -> false
let mkC f1 f2 = C(f1,f2)
let mkD f1 f2 = D(f1,f2)
@@ -1121,6 +1168,11 @@ struct
(A(at,tg,t), env,Tag.next tg)
with e when Errors.noncritical e -> (X(t),env,tg) in
+ let is_prop term =
+ let ty = Typing.unsafe_type_of (Tacmach.pf_env gl) (Tacmach.project gl) term in
+ let sort = Typing.sort_of (Tacmach.pf_env gl) (ref (Tacmach.project gl)) ty in
+ Term.is_prop_sort sort in
+
let rec xparse_formula env tg term =
match kind_of_term term with
| App(l,rst) ->
@@ -1140,13 +1192,15 @@ struct
let g,env,tg = xparse_formula env tg b in
mkformula_binary mkIff term f g,env,tg
| _ -> parse_atom env tg term)
- | Prod(typ,a,b) when not (Termops.dependent (mkRel 1) b) ->
+ | Prod(typ,a,b) when not (Termops.dependent (mkRel 1) b)->
let f,env,tg = xparse_formula env tg a in
let g,env,tg = xparse_formula env tg b in
mkformula_binary mkI term f g,env,tg
| _ when eq_constr term (Lazy.force coq_True) -> (TT,env,tg)
| _ when eq_constr term (Lazy.force coq_False) -> (FF,env,tg)
- | _ -> X(term),env,tg in
+ | _ when is_prop term -> X(term),env,tg
+ | _ -> raise ParseError
+ in
xparse_formula env tg ((*Reductionops.whd_zeta*) term)
let dump_formula typ dump_atom f =
@@ -1377,50 +1431,57 @@ let rcst_domain_spec = lazy {
dump_proof = dump_psatz coq_Q dump_q
}
+open Proofview.Notations
+
+
(**
* Instanciate the current Coq goal with a Micromega formula, a varmap, and a
* witness.
*)
-
-
-let micromega_order_change spec cert cert_typ env ff : Tacmach.tactic =
+let micromega_order_change spec cert cert_typ env ff (*: unit Proofview.tactic*) =
let ids = Util.List.map_i (fun i _ -> (Names.Id.of_string ("__z"^(string_of_int i)))) 0 env in
let formula_typ = (Term.mkApp (Lazy.force coq_Cstr,[|spec.coeff|])) in
let ff = dump_formula formula_typ (dump_cstr spec.coeff spec.dump_coeff) ff in
let vm = dump_varmap (spec.typ) env in
- (* todo : directly generate the proof term - or generalize befor conversion? *)
- Tacticals.tclTHENSEQ [
- (fun gl ->
- Proofview.V82.of_tactic (Tactics.change_concl
- (set
- [
- ("__ff", ff, Term.mkApp(Lazy.force coq_Formula, [|formula_typ |]));
- ("__varmap", vm, Term.mkApp
- (Coqlib.gen_constant_in_modules "VarMap"
- [["Coq" ; "micromega" ; "VarMap"] ; ["VarMap"]] "t", [|spec.typ|]));
- ("__wit", cert, cert_typ)
- ]
- (Tacmach.pf_concl gl))) gl);
- Tactics.generalize env ;
- Tacticals.tclTHENSEQ (List.map (fun id -> Proofview.V82.of_tactic (Tactics.introduction id)) ids) ;
- ]
-
+ (* todo : directly generate the proof term - or generalize before conversion? *)
+ Proofview.Goal.nf_enter { enter = begin fun gl ->
+ let gl = Tacmach.New.of_old (fun x -> x) gl in
+ Tacticals.New.tclTHENLIST
+ [
+ Tactics.change_concl
+ (set
+ [
+ ("__ff", ff, Term.mkApp(Lazy.force coq_Formula, [|formula_typ |]));
+ ("__varmap", vm, Term.mkApp
+ (Coqlib.gen_constant_in_modules "VarMap"
+ [["Coq" ; "micromega" ; "VarMap"] ; ["VarMap"]] "t", [|spec.typ|]));
+ ("__wit", cert, cert_typ)
+ ]
+ (Tacmach.pf_concl gl))
+ ;
+ Tactics.new_generalize env ;
+ Tacticals.New.tclTHENLIST (List.map (fun id -> (Tactics.introduction id)) ids)
+ ]
+ end }
(**
* The datastructures that aggregate prover attributes.
*)
-type ('a,'prf) prover = {
+type ('option,'a,'prf) prover = {
name : string ; (* name of the prover *)
- prover : 'a list -> 'prf option ; (* the prover itself *)
+ get_option : unit ->'option ; (* find the options of the prover *)
+ prover : 'option * 'a list -> 'prf option ; (* the prover itself *)
hyps : 'prf -> ISet.t ; (* extract the indexes of the hypotheses really used in the proof *)
compact : 'prf -> (int -> int) -> 'prf ; (* remap the hyp indexes according to function *)
pp_prf : out_channel -> 'prf -> unit ;(* pretting printing of proof *)
pp_f : out_channel -> 'a -> unit (* pretty printing of the formulas (polynomials)*)
}
+
+
(**
* Given a list of provers and a disjunction of atoms, find a proof of any of
* the atoms. Returns an (optional) pair of a proof and a prover
@@ -1430,7 +1491,7 @@ type ('a,'prf) prover = {
let find_witness provers polys1 =
let provers = List.map (fun p ->
(fun l ->
- match p.prover l with
+ match p.prover (p.get_option (),l) with
| None -> None
| Some prf -> Some(prf,p)) , p.name) provers in
try_any provers (List.map fst polys1)
@@ -1485,7 +1546,7 @@ let compact_proofs (cnf_ff: 'cst cnf) res (cnf_ff': 'cst cnf) =
let res = try prover.compact prf remap with x when Errors.noncritical x ->
if debug then Printf.fprintf stdout "Proof compaction %s" (Printexc.to_string x) ;
(* This should not happen -- this is the recovery plan... *)
- match prover.prover (List.map fst new_cl) with
+ match prover.prover (prover.get_option () ,List.map fst new_cl) with
| None -> failwith "proof compaction error"
| Some p -> p
in
@@ -1646,58 +1707,76 @@ let micromega_gen
(negate:'cst atom -> 'cst mc_cnf)
(normalise:'cst atom -> 'cst mc_cnf)
unsat deduce
- spec prover gl =
- let concl = Tacmach.pf_concl gl in
- let hyps = Tacmach.pf_hyps_types gl in
- try
- let (hyps,concl,env) = parse_goal gl parse_arith Env.empty hyps concl in
- let env = Env.elements env in
- let spec = Lazy.force spec in
-
+ spec prover =
+ Proofview.Goal.nf_enter { enter = begin fun gl ->
+ let gl = Tacmach.New.of_old (fun x -> x) gl in
+ let concl = Tacmach.pf_concl gl in
+ let hyps = Tacmach.pf_hyps_types gl in
+ try
+ let (hyps,concl,env) = parse_goal gl parse_arith Env.empty hyps concl in
+ let env = Env.elements env in
+ let spec = Lazy.force spec in
+
match micromega_tauto negate normalise unsat deduce spec prover env hyps concl gl with
- | None -> Tacticals.tclFAIL 0 (Pp.str " Cannot find witness") gl
- | Some (ids,ff',res') ->
- (Tacticals.tclTHENSEQ
- [
- Tactics.generalize (List.map Term.mkVar ids) ;
- micromega_order_change spec res'
- (Term.mkApp(Lazy.force coq_list, [|spec.proof_typ|])) env ff'
- ]) gl
- with
- | ParseError -> Tacticals.tclFAIL 0 (Pp.str "Bad logical fragment") gl
- | CsdpNotFound -> flush stdout ; Pp.pp_flush () ;
- Tacticals.tclFAIL 0 (Pp.str
- (" Skipping what remains of this tactic: the complexity of the goal requires "
- ^ "the use of a specialized external tool called csdp. \n\n"
- ^ "Unfortunately Coq isn't aware of the presence of any \"csdp\" executable in the path. \n\n"
- ^ "Csdp packages are provided by some OS distributions; binaries and source code can be downloaded from https://projects.coin-or.org/Csdp")) gl
-
-
-
-let micromega_order_changer cert env ff gl =
- let coeff = Lazy.force coq_Rcst in
- let dump_coeff = dump_Rcst in
- let typ = Lazy.force coq_R in
- let cert_typ = (Term.mkApp(Lazy.force coq_list, [|Lazy.force coq_QWitness |])) in
+ | None -> Tacticals.New.tclFAIL 0 (Pp.str " Cannot find witness")
+ | Some (ids,ff',res') ->
+ (Tacticals.New.tclTHENLIST
+ [
+ Tactics.new_generalize (List.map Term.mkVar ids) ;
+ micromega_order_change spec res'
+ (Term.mkApp(Lazy.force coq_list, [|spec.proof_typ|])) env ff'
+ ])
+ with
+ | ParseError -> Tacticals.New.tclFAIL 0 (Pp.str "Bad logical fragment")
+ | Mfourier.TimeOut -> Tacticals.New.tclFAIL 0 (Pp.str "Timeout")
+ | CsdpNotFound -> flush stdout ; Pp.pp_flush () ;
+ Tacticals.New.tclFAIL 0 (Pp.str
+ (" Skipping what remains of this tactic: the complexity of the goal requires "
+ ^ "the use of a specialized external tool called csdp. \n\n"
+ ^ "Unfortunately Coq isn't aware of the presence of any \"csdp\" executable in the path. \n\n"
+ ^ "Csdp packages are provided by some OS distributions; binaries and source code can be downloaded from https://projects.coin-or.org/Csdp"))
+ end }
+
+let micromega_gen parse_arith
+ (negate:'cst atom -> 'cst mc_cnf)
+ (normalise:'cst atom -> 'cst mc_cnf)
+ unsat deduce
+ spec prover =
+ (micromega_gen parse_arith negate normalise unsat deduce spec prover)
+
+
+let micromega_order_changer cert env ff =
+ let ids = Util.List.map_i (fun i _ -> (Names.Id.of_string ("__z"^(string_of_int i)))) 0 env in
+ let coeff = Lazy.force coq_Rcst in
+ let dump_coeff = dump_Rcst in
+ let typ = Lazy.force coq_R in
+ let cert_typ = (Term.mkApp(Lazy.force coq_list, [|Lazy.force coq_QWitness |])) in
+
let formula_typ = (Term.mkApp (Lazy.force coq_Cstr,[| coeff|])) in
let ff = dump_formula formula_typ (dump_cstr coeff dump_coeff) ff in
let vm = dump_varmap (typ) env in
- Proofview.V82.of_tactic (Tactics.change_concl
- (set
+ Proofview.Goal.nf_enter { enter = begin fun gl ->
+ let gl = Tacmach.New.of_old (fun x -> x) gl in
+ Tacticals.New.tclTHENLIST
[
- ("__ff", ff, Term.mkApp(Lazy.force coq_Formula, [|formula_typ |]));
- ("__varmap", vm, Term.mkApp
- (Coqlib.gen_constant_in_modules "VarMap"
- [["Coq" ; "micromega" ; "VarMap"] ; ["VarMap"]] "t", [|typ|]));
- ("__wit", cert, cert_typ)
+ (Tactics.change_concl
+ (set
+ [
+ ("__ff", ff, Term.mkApp(Lazy.force coq_Formula, [|formula_typ |]));
+ ("__varmap", vm, Term.mkApp
+ (Coqlib.gen_constant_in_modules "VarMap"
+ [["Coq" ; "micromega" ; "VarMap"] ; ["VarMap"]] "t", [|typ|]));
+ ("__wit", cert, cert_typ)
+ ]
+ (Tacmach.pf_concl gl)));
+ Tactics.new_generalize env ;
+ Tacticals.New.tclTHENLIST (List.map (fun id -> (Tactics.introduction id)) ids)
]
- (Tacmach.pf_concl gl)
- ))
- gl
+ end }
-let micromega_genr prover gl =
+let micromega_genr prover =
let parse_arith = parse_rarith in
let negate = Mc.rnegate in
let normalise = Mc.rnormalise in
@@ -1710,39 +1789,41 @@ let micromega_genr prover gl =
proof_typ = Lazy.force coq_QWitness ;
dump_proof = dump_psatz coq_Q dump_q
} in
-
- let concl = Tacmach.pf_concl gl in
- let hyps = Tacmach.pf_hyps_types gl in
- try
- let (hyps,concl,env) = parse_goal gl parse_arith Env.empty hyps concl in
- let env = Env.elements env in
- let spec = Lazy.force spec in
-
- let hyps' = List.map (fun (n,f) -> (n, map_atoms (Micromega.map_Formula Micromega.q_of_Rcst) f)) hyps in
- let concl' = map_atoms (Micromega.map_Formula Micromega.q_of_Rcst) concl in
-
- match micromega_tauto negate normalise unsat deduce spec prover env hyps' concl' gl with
- | None -> Tacticals.tclFAIL 0 (Pp.str " Cannot find witness") gl
+ Proofview.Goal.nf_enter { enter = begin fun gl ->
+ let gl = Tacmach.New.of_old (fun x -> x) gl in
+ let concl = Tacmach.pf_concl gl in
+ let hyps = Tacmach.pf_hyps_types gl in
+ try
+ let (hyps,concl,env) = parse_goal gl parse_arith Env.empty hyps concl in
+ let env = Env.elements env in
+ let spec = Lazy.force spec in
+
+ let hyps' = List.map (fun (n,f) -> (n, map_atoms (Micromega.map_Formula Micromega.q_of_Rcst) f)) hyps in
+ let concl' = map_atoms (Micromega.map_Formula Micromega.q_of_Rcst) concl in
+
+ match micromega_tauto negate normalise unsat deduce spec prover env hyps' concl' gl with
+ | None -> Tacticals.New.tclFAIL 0 (Pp.str " Cannot find witness")
| Some (ids,ff',res') ->
let (ff,ids') = formula_hyps_concl
(List.filter (fun (n,_) -> List.mem n ids) hyps) concl in
-
- (Tacticals.tclTHENSEQ
+ (Tacticals.New.tclTHENLIST
[
- Tactics.generalize (List.map Term.mkVar ids) ;
+ Tactics.new_generalize (List.map Term.mkVar ids) ;
micromega_order_changer res' env (abstract_wrt_formula ff' ff)
- ]) gl
+ ])
with
- | ParseError -> Tacticals.tclFAIL 0 (Pp.str "Bad logical fragment") gl
- | CsdpNotFound -> flush stdout ; Pp.pp_flush () ;
- Tacticals.tclFAIL 0 (Pp.str
+ | Mfourier.TimeOut -> Tacticals.New.tclFAIL 0 (Pp.str "TimeOut")
+ | ParseError -> Tacticals.New.tclFAIL 0 (Pp.str "Bad logical fragment")
+ | CsdpNotFound -> flush stdout ; Pp.pp_flush () ;
+ Tacticals.New.tclFAIL 0 (Pp.str
(" Skipping what remains of this tactic: the complexity of the goal requires "
^ "the use of a specialized external tool called csdp. \n\n"
^ "Unfortunately Coq isn't aware of the presence of any \"csdp\" executable in the path. \n\n"
- ^ "Csdp packages are provided by some OS distributions; binaries and source code can be downloaded from https://projects.coin-or.org/Csdp")) gl
-
+ ^ "Csdp packages are provided by some OS distributions; binaries and source code can be downloaded from https://projects.coin-or.org/Csdp"))
+ end }
+let micromega_genr prover = (micromega_genr prover)
let lift_ratproof prover l =
@@ -1898,38 +1979,61 @@ let compact_pt pt f =
let lift_pexpr_prover p l = p (List.map (fun (e,o) -> Mc.denorm e , o) l)
-let linear_prover_Z = {
- name = "linear prover" ;
- prover = lift_ratproof (lift_pexpr_prover (Certificate.linear_prover_with_cert Certificate.z_spec)) ;
- hyps = hyps_of_pt ;
- compact = compact_pt ;
- pp_prf = pp_proof_term;
- pp_f = fun o x -> pp_pol pp_z o (fst x)
-}
+module CacheZ = PHashtable(struct
+ type prover_option = bool * int
+ type t = prover_option * ((Mc.z Mc.pol * Mc.op1) list)
+ let equal = (=)
+ let hash = Hashtbl.hash
+end)
+
+module CacheQ = PHashtable(struct
+ type t = int * ((Mc.q Mc.pol * Mc.op1) list)
+ let equal = (=)
+ let hash = Hashtbl.hash
+end)
+
+let memo_zlinear_prover = CacheZ.memo "lia.cache" (fun ((ce,b),s) -> lift_pexpr_prover (Certificate.lia ce b) s)
+let memo_nlia = CacheZ.memo "nlia.cache" (fun ((ce,b),s) -> lift_pexpr_prover (Certificate.nlia ce b) s)
+let memo_nra = CacheQ.memo "nra.cache" (fun (o,s) -> lift_pexpr_prover (Certificate.nlinear_prover o) s)
+
+
+
let linear_prover_Q = {
- name = "linear prover";
- prover = lift_pexpr_prover (Certificate.linear_prover_with_cert Certificate.q_spec) ;
- hyps = hyps_of_cone ;
- compact = compact_cone ;
- pp_prf = pp_psatz pp_q ;
- pp_f = fun o x -> pp_pol pp_q o (fst x)
+ name = "linear prover";
+ get_option = get_lra_option ;
+ prover = (fun (o,l) -> lift_pexpr_prover (Certificate.linear_prover_with_cert o Certificate.q_spec) l) ;
+ hyps = hyps_of_cone ;
+ compact = compact_cone ;
+ pp_prf = pp_psatz pp_q ;
+ pp_f = fun o x -> pp_pol pp_q o (fst x)
}
let linear_prover_R = {
name = "linear prover";
- prover = lift_pexpr_prover (Certificate.linear_prover_with_cert Certificate.q_spec) ;
+ get_option = get_lra_option ;
+ prover = (fun (o,l) -> lift_pexpr_prover (Certificate.linear_prover_with_cert o Certificate.q_spec) l) ;
hyps = hyps_of_cone ;
compact = compact_cone ;
pp_prf = pp_psatz pp_q ;
pp_f = fun o x -> pp_pol pp_q o (fst x)
}
+let nlinear_prover_R = {
+ name = "nra";
+ get_option = get_lra_option;
+ prover = memo_nra ;
+ hyps = hyps_of_cone ;
+ compact = compact_cone ;
+ pp_prf = pp_psatz pp_q ;
+ pp_f = fun o x -> pp_pol pp_q o (fst x)
+}
let non_linear_prover_Q str o = {
name = "real nonlinear prover";
- prover = call_csdpcert_q (str, o);
+ get_option = (fun () -> (str,o));
+ prover = (fun (o,l) -> call_csdpcert_q o l);
hyps = hyps_of_cone;
compact = compact_cone ;
pp_prf = pp_psatz pp_q ;
@@ -1938,7 +2042,8 @@ let non_linear_prover_Q str o = {
let non_linear_prover_R str o = {
name = "real nonlinear prover";
- prover = call_csdpcert_q (str, o);
+ get_option = (fun () -> (str,o));
+ prover = (fun (o,l) -> call_csdpcert_q o l);
hyps = hyps_of_cone;
compact = compact_cone;
pp_prf = pp_psatz pp_q;
@@ -1947,30 +2052,19 @@ let non_linear_prover_R str o = {
let non_linear_prover_Z str o = {
name = "real nonlinear prover";
- prover = lift_ratproof (call_csdpcert_z (str, o));
+ get_option = (fun () -> (str,o));
+ prover = (fun (o,l) -> lift_ratproof (call_csdpcert_z o) l);
hyps = hyps_of_pt;
compact = compact_pt;
pp_prf = pp_proof_term;
pp_f = fun o x -> pp_pol pp_z o (fst x)
}
-module CacheZ = PHashtable(struct
- type t = (Mc.z Mc.pol * Mc.op1) list
- let equal = Pervasives.(=)
- let hash = Hashtbl.hash
-end)
-
-let memo_zlinear_prover = CacheZ.memo "lia.cache" (lift_pexpr_prover Certificate.lia)
-let memo_nlia = CacheZ.memo "nlia.cache" (lift_pexpr_prover Certificate.nlia)
-
-(*let memo_zlinear_prover = (lift_pexpr_prover Lia.lia)*)
-(*let memo_zlinear_prover = CacheZ.memo "lia.cache" (lift_pexpr_prover Certificate.zlinear_prover)*)
-
-
let linear_Z = {
name = "lia";
- prover = memo_zlinear_prover ;
+ get_option = get_lia_option;
+ prover = memo_zlinear_prover ;
hyps = hyps_of_pt;
compact = compact_pt;
pp_prf = pp_proof_term;
@@ -1979,7 +2073,8 @@ let linear_Z = {
let nlinear_Z = {
name = "nlia";
- prover = memo_nlia ;
+ get_option = get_lia_option;
+ prover = memo_nlia ;
hyps = hyps_of_pt;
compact = compact_pt;
pp_prf = pp_proof_term;
@@ -2001,56 +2096,56 @@ let tauto_lia ff =
* solvers
*)
-let psatzl_Z gl =
+let psatzl_Z =
micromega_gen parse_zarith Mc.negate Mc.normalise Mc.zunsat Mc.zdeduce zz_domain_spec
- [ linear_prover_Z ] gl
+ [ linear_Z ]
-let psatzl_Q gl =
+let psatzl_Q =
micromega_gen parse_qarith Mc.qnegate Mc.qnormalise Mc.qunsat Mc.qdeduce qq_domain_spec
- [ linear_prover_Q ] gl
+ [ linear_prover_Q ]
-let psatz_Q i gl =
+let psatz_Q i =
micromega_gen parse_qarith Mc.qnegate Mc.qnormalise Mc.qunsat Mc.qdeduce qq_domain_spec
- [ non_linear_prover_Q "real_nonlinear_prover" (Some i) ] gl
-
-
-let psatzl_R gl =
- micromega_genr [ linear_prover_R ] gl
+ [ non_linear_prover_Q "real_nonlinear_prover" (Some i) ]
+let psatzl_R =
+ micromega_genr [ linear_prover_R ]
-let psatz_R i gl =
- micromega_genr [ non_linear_prover_R "real_nonlinear_prover" (Some i) ] gl
+let psatz_R i =
+ micromega_genr [ non_linear_prover_R "real_nonlinear_prover" (Some i) ]
-let psatz_Z i gl =
+let psatz_Z i =
micromega_gen parse_zarith Mc.negate Mc.normalise Mc.zunsat Mc.zdeduce zz_domain_spec
- [ non_linear_prover_Z "real_nonlinear_prover" (Some i) ] gl
+ [ non_linear_prover_Z "real_nonlinear_prover" (Some i) ]
-let sos_Z gl =
+let sos_Z =
micromega_gen parse_zarith Mc.negate Mc.normalise Mc.zunsat Mc.zdeduce zz_domain_spec
- [ non_linear_prover_Z "pure_sos" None ] gl
+ [ non_linear_prover_Z "pure_sos" None ]
-let sos_Q gl =
+let sos_Q =
micromega_gen parse_qarith Mc.qnegate Mc.qnormalise Mc.qunsat Mc.qdeduce qq_domain_spec
- [ non_linear_prover_Q "pure_sos" None ] gl
+ [ non_linear_prover_Q "pure_sos" None ]
-let sos_R gl =
- micromega_genr [ non_linear_prover_R "pure_sos" None ] gl
+let sos_R =
+ micromega_genr [ non_linear_prover_R "pure_sos" None ]
-let xlia gl =
+let xlia =
try
micromega_gen parse_zarith Mc.negate Mc.normalise Mc.zunsat Mc.zdeduce zz_domain_spec
- [ linear_Z ] gl
+ [ linear_Z ]
with reraise -> (*Printexc.print_backtrace stdout ;*) raise reraise
-let xnlia gl =
+let xnlia =
try
micromega_gen parse_zarith Mc.negate Mc.normalise Mc.zunsat Mc.zdeduce zz_domain_spec
- [ nlinear_Z ] gl
+ [ nlinear_Z ]
with reraise -> (*Printexc.print_backtrace stdout ;*) raise reraise
+let nra =
+ micromega_genr [ nlinear_prover_R ]
(* Local Variables: *)
diff --git a/plugins/micromega/g_micromega.ml4 b/plugins/micromega/g_micromega.ml4
index 75237aaa5..bfc9c727d 100644
--- a/plugins/micromega/g_micromega.ml4
+++ b/plugins/micromega/g_micromega.ml4
@@ -21,58 +21,50 @@ open Misctypes
DECLARE PLUGIN "micromega_plugin"
-let out_arg = function
- | ArgVar _ -> anomaly (Pp.str "Unevaluated or_var variable")
- | ArgArg x -> x
-
TACTIC EXTEND PsatzZ
-| [ "psatz_Z" int_or_var(i) ] -> [ Proofview.V82.tactic (Coq_micromega.psatz_Z (out_arg i)) ]
-| [ "psatz_Z" ] -> [ Proofview.V82.tactic (Coq_micromega.psatz_Z (-1)) ]
+| [ "psatz_Z" int_or_var(i) ] -> [ (Coq_micromega.psatz_Z i) ]
+| [ "psatz_Z" ] -> [ (Coq_micromega.psatz_Z (-1)) ]
END
TACTIC EXTEND Lia
-[ "xlia" ] -> [ Proofview.V82.tactic (Coq_micromega.xlia) ]
+[ "xlia" ] -> [ (Coq_micromega.xlia) ]
END
TACTIC EXTEND Nia
-[ "xnlia" ] -> [ Proofview.V82.tactic (Coq_micromega.xnlia) ]
+[ "xnlia" ] -> [ (Coq_micromega.xnlia) ]
END
-
+TACTIC EXTEND NRA
+[ "xnra" ] -> [ (Coq_micromega.nra)]
+END
TACTIC EXTEND Sos_Z
-| [ "sos_Z" ] -> [ Proofview.V82.tactic (Coq_micromega.sos_Z) ]
+| [ "sos_Z" ] -> [ (Coq_micromega.sos_Z) ]
END
TACTIC EXTEND Sos_Q
-| [ "sos_Q" ] -> [ Proofview.V82.tactic (Coq_micromega.sos_Q) ]
+| [ "sos_Q" ] -> [ (Coq_micromega.sos_Q) ]
END
TACTIC EXTEND Sos_R
-| [ "sos_R" ] -> [ Proofview.V82.tactic (Coq_micromega.sos_R) ]
-END
-
-(*
-TACTIC EXTEND Omicron
-[ "psatzl_Z" ] -> [ Proofview.V82.tactic (Coq_micromega.psatzl_Z) ]
+| [ "sos_R" ] -> [ (Coq_micromega.sos_R) ]
END
-*)
TACTIC EXTEND LRA_Q
-[ "psatzl_Q" ] -> [ Proofview.V82.tactic (Coq_micromega.psatzl_Q) ]
+[ "psatzl_Q" ] -> [ (Coq_micromega.psatzl_Q) ]
END
TACTIC EXTEND LRA_R
-[ "psatzl_R" ] -> [ Proofview.V82.tactic (Coq_micromega.psatzl_R) ]
+[ "psatzl_R" ] -> [ (Coq_micromega.psatzl_R) ]
END
TACTIC EXTEND PsatzR
-| [ "psatz_R" int_or_var(i) ] -> [ Proofview.V82.tactic (Coq_micromega.psatz_R (out_arg i)) ]
-| [ "psatz_R" ] -> [ Proofview.V82.tactic (Coq_micromega.psatz_R (-1)) ]
+| [ "psatz_R" int_or_var(i) ] -> [ (Coq_micromega.psatz_R i) ]
+| [ "psatz_R" ] -> [ (Coq_micromega.psatz_R (-1)) ]
END
TACTIC EXTEND PsatzQ
-| [ "psatz_Q" int_or_var(i) ] -> [ Proofview.V82.tactic (Coq_micromega.psatz_Q (out_arg i)) ]
-| [ "psatz_Q" ] -> [ Proofview.V82.tactic (Coq_micromega.psatz_Q (-1)) ]
+| [ "psatz_Q" int_or_var(i) ] -> [ (Coq_micromega.psatz_Q i) ]
+| [ "psatz_Q" ] -> [ (Coq_micromega.psatz_Q (-1)) ]
END
diff --git a/plugins/micromega/mfourier.ml b/plugins/micromega/mfourier.ml
index a36369d22..e22fe5843 100644
--- a/plugins/micromega/mfourier.ml
+++ b/plugins/micromega/mfourier.ml
@@ -98,12 +98,12 @@ module PSet = ISet
module System = Hashtbl.Make(Vect)
- type proof =
- | Hyp of int
- | Elim of var * proof * proof
- | And of proof * proof
-
+type proof =
+| Hyp of int
+| Elim of var * proof * proof
+| And of proof * proof
+let max_nb_cstr = ref max_int
type system = {
sys : cstr_info ref System.t ;
@@ -120,7 +120,7 @@ and cstr_info = {
(** A system of constraints has the form [\{sys = s ; vars = v\}].
[s] is a hashtable mapping a normalised vector to a [cstr_info] record where
- [bound] is an interval
- - [prf_idx] is the set of hypothese indexes (i.e. constraints in the initial system) used to obtain the current constraint.
+ - [prf_idx] is the set of hypothesis indexes (i.e. constraints in the initial system) used to obtain the current constraint.
In the initial system, each constraint is given an unique singleton proof_idx.
When a new constraint c is computed by a function f(c1,...,cn), its proof_idx is ISet.fold union (List.map (fun x -> x.proof_idx) [c1;...;cn]
- [pos] is the number of positive values of the vector
@@ -208,8 +208,7 @@ let merge_cstr_info i1 i2 =
*)
let xadd_cstr vect cstr_info sys =
- if debug && Int.equal (System.length sys mod 1000) 0 then (print_string "*" ; flush stdout) ;
- try
+ try
let info = System.find sys vect in
match merge_cstr_info cstr_info !info with
| None -> raise (SystemContradiction (And(cstr_info.prf, (!info).prf)))
@@ -217,6 +216,13 @@ let xadd_cstr vect cstr_info sys =
with
| Not_found -> System.replace sys vect (ref cstr_info)
+exception TimeOut
+
+let xadd_cstr vect cstr_info sys =
+ if debug && Int.equal (System.length sys mod 1000) 0 then (print_string "*" ; flush stdout) ;
+ if System.length sys < !max_nb_cstr
+ then xadd_cstr vect cstr_info sys
+ else raise TimeOut
type cstr_ext =
| Contradiction (** The constraint is contradictory.
@@ -866,7 +872,7 @@ let mk_proof hyps prf =
| Elim(v,prf1,prf2) ->
let prfsl = mk_proof prf1
and prfsr = mk_proof prf2 in
- (* I take only the pairs for which the elimination is meaningfull *)
+ (* I take only the pairs for which the elimination is meaningful *)
forall_pairs (pivot v) prfsl prfsr
| And(prf1,prf2) ->
let prfsl1 = mk_proof prf1
diff --git a/plugins/micromega/mutils.ml b/plugins/micromega/mutils.ml
index 2dd443f00..c13e8fc28 100644
--- a/plugins/micromega/mutils.ml
+++ b/plugins/micromega/mutils.ml
@@ -66,6 +66,15 @@ let all_sym_pairs f l =
| e::l -> xpairs (pair_with acc e l) l in
xpairs [] l
+let all_pairs f l =
+ let pair_with acc e l = List.fold_left (fun acc x -> (f e x) ::acc) acc l in
+
+ let rec xpairs acc l =
+ match l with
+ | [] -> acc
+ | e::lx -> xpairs (pair_with acc e l) lx in
+ xpairs [] l
+
let rec map3 f l1 l2 l3 =
diff --git a/plugins/omega/coq_omega.ml b/plugins/omega/coq_omega.ml
index 8a2a957cd..7e38109d6 100644
--- a/plugins/omega/coq_omega.ml
+++ b/plugins/omega/coq_omega.ml
@@ -27,6 +27,7 @@ open Globnames
open Nametab
open Contradiction
open Misctypes
+open Proofview.Notations
module OmegaSolver = Omega.MakeOmegaSolver (Bigint)
open OmegaSolver
@@ -34,9 +35,9 @@ open OmegaSolver
(* Added by JCF, 09/03/98 *)
let elim_id id =
- Proofview.Goal.nf_enter begin fun gl ->
+ Proofview.Goal.nf_enter { enter = begin fun gl ->
simplest_elim (Tacmach.New.pf_global id gl)
- end
+ end }
let resolve_id id gl = Proofview.V82.of_tactic (apply (pf_global gl id)) gl
let timing timer_name f arg = f arg
@@ -1416,7 +1417,7 @@ let reintroduce id =
open Proofview.Notations
let coq_omega =
- Proofview.Goal.nf_enter begin fun gl ->
+ Proofview.Goal.nf_enter { enter = begin fun gl ->
clear_constr_tables ();
let hyps_types = Tacmach.New.pf_hyps_types gl in
let destructure_omega = Tacmach.New.of_old destructure_omega gl in
@@ -1464,12 +1465,12 @@ let coq_omega =
Tacticals.New.tclTHEN prelude (replay_history tactic_normalisation path)
with NO_CONTRADICTION -> Tacticals.New.tclZEROMSG (Pp.str"Omega can't solve this system")
end
- end
+ end }
let coq_omega = coq_omega
let nat_inject =
- Proofview.Goal.nf_enter begin fun gl ->
+ Proofview.Goal.nf_enter { enter = begin fun gl ->
let is_conv = Tacmach.New.pf_apply Reductionops.is_conv gl in
let rec explore p t : unit Proofview.tactic =
try match destructurate_term t with
@@ -1603,7 +1604,7 @@ let nat_inject =
in
let hyps_types = Tacmach.New.pf_hyps_types gl in
loop (List.rev hyps_types)
- end
+ end }
let dec_binop = function
| Zne -> coq_dec_Zne
@@ -1673,22 +1674,22 @@ let onClearedName id tac =
(* so renaming may be necessary *)
Tacticals.New.tclTHEN
(Proofview.V82.tactic (tclTRY (clear [id])))
- (Proofview.Goal.nf_enter begin fun gl ->
+ (Proofview.Goal.nf_enter { enter = begin fun gl ->
let id = Tacmach.New.of_old (fresh_id [] id) gl in
Tacticals.New.tclTHEN (introduction id) (tac id)
- end)
+ end })
let onClearedName2 id tac =
Tacticals.New.tclTHEN
(Proofview.V82.tactic (tclTRY (clear [id])))
- (Proofview.Goal.nf_enter begin fun gl ->
+ (Proofview.Goal.nf_enter { enter = begin fun gl ->
let id1 = Tacmach.New.of_old (fresh_id [] (add_suffix id "_left")) gl in
let id2 = Tacmach.New.of_old (fresh_id [] (add_suffix id "_right")) gl in
Tacticals.New.tclTHENLIST [ introduction id1; introduction id2; tac id1 id2 ]
- end)
+ end })
let destructure_hyps =
- Proofview.Goal.nf_enter begin fun gl ->
+ Proofview.Goal.nf_enter { enter = begin fun gl ->
let type_of = Tacmach.New.pf_unsafe_type_of gl in
let decidability = Tacmach.New.of_old decidability gl in
let pf_nf = Tacmach.New.of_old pf_nf gl in
@@ -1828,10 +1829,10 @@ let destructure_hyps =
in
let hyps = Proofview.Goal.hyps gl in
loop hyps
- end
+ end }
let destructure_goal =
- Proofview.Goal.nf_enter begin fun gl ->
+ Proofview.Goal.nf_enter { enter = begin fun gl ->
let concl = Proofview.Goal.concl gl in
let decidability = Tacmach.New.of_old decidability gl in
let rec loop t =
@@ -1855,7 +1856,7 @@ let destructure_goal =
Tacticals.New.tclTHEN goal_tac destructure_hyps
in
(loop concl)
- end
+ end }
let destructure_goal = destructure_goal
diff --git a/plugins/quote/quote.ml b/plugins/quote/quote.ml
index ff6acf139..dbd7460e2 100644
--- a/plugins/quote/quote.ml
+++ b/plugins/quote/quote.ml
@@ -109,6 +109,7 @@ open Pattern
open Patternops
open Constr_matching
open Tacmach
+open Proofview.Notations
(*i*)
(*s First, we need to access some Coq constants
@@ -227,7 +228,7 @@ let compute_ivs f cs gl =
let (args3, body3) = decompose_lam body2 in
let nargs3 = List.length args3 in
let env = Proofview.Goal.env gl in
- let sigma = Proofview.Goal.sigma gl in
+ let sigma = Tacmach.New.project gl in
let is_conv = Reductionops.is_conv env sigma in
begin match decomp_term body3 with
| Case(_,p,c,lci) -> (* <p> Case c of c1 ... cn end *)
@@ -446,7 +447,7 @@ let quote_terms ivs lc =
yet. *)
let quote f lid =
- Proofview.Goal.nf_enter begin fun gl ->
+ Proofview.Goal.nf_enter { enter = begin fun gl ->
let f = Tacmach.New.pf_global f gl in
let cl = List.map (fun id -> Tacmach.New.pf_global id gl) lid in
let ivs = compute_ivs f cl gl in
@@ -459,10 +460,10 @@ let quote f lid =
match ivs.variable_lhs with
| None -> Tactics.convert_concl (mkApp (f, [| p |])) DEFAULTcast
| Some _ -> Tactics.convert_concl (mkApp (f, [| vm; p |])) DEFAULTcast
- end
+ end }
let gen_quote cont c f lid =
- Proofview.Goal.nf_enter begin fun gl ->
+ Proofview.Goal.nf_enter { enter = begin fun gl ->
let f = Tacmach.New.pf_global f gl in
let cl = List.map (fun id -> Tacmach.New.pf_global id gl) lid in
let ivs = compute_ivs f cl gl in
@@ -474,7 +475,7 @@ let gen_quote cont c f lid =
match ivs.variable_lhs with
| None -> cont (mkApp (f, [| p |]))
| Some _ -> cont (mkApp (f, [| vm; p |]))
- end
+ end }
(*i
diff --git a/plugins/setoid_ring/g_newring.ml4 b/plugins/setoid_ring/g_newring.ml4
new file mode 100644
index 000000000..856ec0db5
--- /dev/null
+++ b/plugins/setoid_ring/g_newring.ml4
@@ -0,0 +1,90 @@
+(************************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2015 *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(************************************************************************)
+
+(*i camlp4deps: "grammar/grammar.cma" i*)
+
+open Pp
+open Util
+open Libnames
+open Printer
+open Newring_ast
+open Newring
+
+DECLARE PLUGIN "newring_plugin"
+
+TACTIC EXTEND protect_fv
+ [ "protect_fv" string(map) "in" ident(id) ] ->
+ [ Proofview.V82.tactic (protect_tac_in map id) ]
+| [ "protect_fv" string(map) ] ->
+ [ Proofview.V82.tactic (protect_tac map) ]
+END
+
+TACTIC EXTEND closed_term
+ [ "closed_term" constr(t) "[" ne_reference_list(l) "]" ] ->
+ [ Proofview.V82.tactic (closed_term t l) ]
+END
+
+VERNAC ARGUMENT EXTEND ring_mod
+ | [ "decidable" constr(eq_test) ] -> [ Ring_kind(Computational eq_test) ]
+ | [ "abstract" ] -> [ Ring_kind Abstract ]
+ | [ "morphism" constr(morph) ] -> [ Ring_kind(Morphism morph) ]
+ | [ "constants" "[" tactic(cst_tac) "]" ] -> [ Const_tac(CstTac cst_tac) ]
+ | [ "closed" "[" ne_global_list(l) "]" ] -> [ Const_tac(Closed l) ]
+ | [ "preprocess" "[" tactic(pre) "]" ] -> [ Pre_tac pre ]
+ | [ "postprocess" "[" tactic(post) "]" ] -> [ Post_tac post ]
+ | [ "setoid" constr(sth) constr(ext) ] -> [ Setoid(sth,ext) ]
+ | [ "sign" constr(sign_spec) ] -> [ Sign_spec sign_spec ]
+ | [ "power" constr(pow_spec) "[" ne_global_list(l) "]" ] ->
+ [ Pow_spec (Closed l, pow_spec) ]
+ | [ "power_tac" constr(pow_spec) "[" tactic(cst_tac) "]" ] ->
+ [ Pow_spec (CstTac cst_tac, pow_spec) ]
+ | [ "div" constr(div_spec) ] -> [ Div_spec div_spec ]
+END
+
+VERNAC COMMAND EXTEND AddSetoidRing CLASSIFIED AS SIDEFF
+ | [ "Add" "Ring" ident(id) ":" constr(t) ring_mods(l) ] ->
+ [ let (k,set,cst,pre,post,power,sign, div) = process_ring_mods l in
+ add_theory id (ic t) set k cst (pre,post) power sign div]
+ | [ "Print" "Rings" ] => [Vernac_classifier.classify_as_query] -> [
+ msg_notice (strbrk "The following ring structures have been declared:");
+ Spmap.iter (fun fn fi ->
+ msg_notice (hov 2
+ (Ppconstr.pr_id (Libnames.basename fn)++spc()++
+ str"with carrier "++ pr_constr fi.ring_carrier++spc()++
+ str"and equivalence relation "++ pr_constr fi.ring_req))
+ ) !from_name ]
+END
+
+TACTIC EXTEND ring_lookup
+| [ "ring_lookup" tactic0(f) "[" constr_list(lH) "]" ne_constr_list(lrt) ] ->
+ [ let (t,lr) = List.sep_last lrt in ring_lookup f lH lr t]
+END
+
+VERNAC ARGUMENT EXTEND field_mod
+ | [ ring_mod(m) ] -> [ Ring_mod m ]
+ | [ "completeness" constr(inj) ] -> [ Inject inj ]
+END
+
+VERNAC COMMAND EXTEND AddSetoidField CLASSIFIED AS SIDEFF
+| [ "Add" "Field" ident(id) ":" constr(t) field_mods(l) ] ->
+ [ let (k,set,inj,cst_tac,pre,post,power,sign,div) = process_field_mods l in
+ add_field_theory id (ic t) set k cst_tac inj (pre,post) power sign div]
+| [ "Print" "Fields" ] => [Vernac_classifier.classify_as_query] -> [
+ msg_notice (strbrk "The following field structures have been declared:");
+ Spmap.iter (fun fn fi ->
+ msg_notice (hov 2
+ (Ppconstr.pr_id (Libnames.basename fn)++spc()++
+ str"with carrier "++ pr_constr fi.field_carrier++spc()++
+ str"and equivalence relation "++ pr_constr fi.field_req))
+ ) !field_from_name ]
+END
+
+TACTIC EXTEND field_lookup
+| [ "field_lookup" tactic(f) "[" constr_list(lH) "]" ne_constr_list(lt) ] ->
+ [ let (t,l) = List.sep_last lt in field_lookup f lH l t ]
+END
diff --git a/plugins/setoid_ring/newring.ml4 b/plugins/setoid_ring/newring.ml
index e704c466e..e203b9f65 100644
--- a/plugins/setoid_ring/newring.ml4
+++ b/plugins/setoid_ring/newring.ml
@@ -30,8 +30,8 @@ open Declare
open Decl_kinds
open Entries
open Misctypes
-
-DECLARE PLUGIN "newring_plugin"
+open Newring_ast
+open Proofview.Notations
(****************************************************************************)
(* controlled reduction *)
@@ -105,13 +105,6 @@ let protect_tac_in map id =
Tactics.reduct_option (protect_red map,DEFAULTcast) (Some(id, Locus.InHyp));;
-TACTIC EXTEND protect_fv
- [ "protect_fv" string(map) "in" ident(id) ] ->
- [ Proofview.V82.tactic (protect_tac_in map id) ]
-| [ "protect_fv" string(map) ] ->
- [ Proofview.V82.tactic (protect_tac map) ]
-END;;
-
(****************************************************************************)
let closed_term t l =
@@ -120,12 +113,6 @@ let closed_term t l =
if Quote.closed_under cs t then tclIDTAC else tclFAIL 0 (mt())
;;
-TACTIC EXTEND closed_term
- [ "closed_term" constr(t) "[" ne_reference_list(l) "]" ] ->
- [ Proofview.V82.tactic (closed_term t l) ]
-END
-;;
-
(* TACTIC EXTEND echo
| [ "echo" constr(t) ] ->
[ Pp.msg (Termops.print_constr t); Tacinterp.eval_tactic (TacId []) ]
@@ -143,11 +130,15 @@ let closed_term_ast l =
mltac_plugin = "newring_plugin";
mltac_tactic = "closed_term";
} in
+ let tacname = {
+ mltac_name = tacname;
+ mltac_index = 0;
+ } in
let l = List.map (fun gr -> ArgArg(Loc.ghost,gr)) l in
TacFun([Some(Id.of_string"t")],
TacML(Loc.ghost,tacname,
- [Genarg.in_gen (Genarg.glbwit Constrarg.wit_constr) (GVar(Loc.ghost,Id.of_string"t"),None);
- Genarg.in_gen (Genarg.glbwit (Genarg.wit_list Constrarg.wit_ref)) l]))
+ [TacGeneric (Genarg.in_gen (Genarg.glbwit Constrarg.wit_constr) (GVar(Loc.ghost,Id.of_string"t"),None));
+ TacGeneric (Genarg.in_gen (Genarg.glbwit (Genarg.wit_list Constrarg.wit_ref)) l)]))
(*
let _ = add_tacdef false ((Loc.ghost,Id.of_string"ring_closed_term"
*)
@@ -188,16 +179,20 @@ let ltac_lcall tac args =
let ltac_letin (x, e1) e2 =
TacLetIn(false,[(Loc.ghost,Id.of_string x),e1],e2)
-let ltac_apply (f:glob_tactic_expr) (args:glob_tactic_arg list) =
- Tacinterp.eval_tactic
+let ltac_apply (f:glob_tactic_expr) (args: Tacinterp.Value.t list) =
+ let fold arg (i, vars, lfun) =
+ let id = Id.of_string ("x" ^ string_of_int i) in
+ let x = Reference (ArgVar (Loc.ghost, id)) in
+ (succ i, x :: vars, Id.Map.add id arg lfun)
+ in
+ let (_, args, lfun) = List.fold_right fold args (0, [], Id.Map.empty) in
+ let ist = { (Tacinterp.default_ist ()) with Tacinterp.lfun = lfun; } in
+ Tacinterp.eval_tactic_ist ist
(ltac_letin ("F", Tacexp f) (ltac_lcall "F" args))
let ltac_record flds =
TacFun([Some(Id.of_string"proj")], ltac_lcall "proj" flds)
-
-let carg c = TacDynamic(Loc.ghost,Pretyping.constr_in c)
-
let dummy_goal env sigma =
let (gl,_,sigma) =
Goal.V82.mk_goal sigma (named_context_val env) mkProp Evd.Store.empty in
@@ -207,20 +202,39 @@ let constr_of v = match Value.to_constr v with
| Some c -> c
| None -> failwith "Ring.exec_tactic: anomaly"
+let tactic_res = ref [||]
+
+let get_res =
+ let open Tacexpr in
+ let name = { mltac_plugin = "newring_plugin"; mltac_tactic = "get_res"; } in
+ let entry = { mltac_name = name; mltac_index = 0 } in
+ let tac args ist =
+ let n = Tacinterp.Value.cast (Genarg.topwit Stdarg.wit_int) (List.hd args) in
+ let init i = Id.Map.find (Id.of_string ("x" ^ string_of_int i)) ist.lfun in
+ tactic_res := Array.init n init;
+ Proofview.tclUNIT ()
+ in
+ Tacenv.register_ml_tactic name [| tac |];
+ entry
+
let exec_tactic env evd n f args =
+ let fold arg (i, vars, lfun) =
+ let id = Id.of_string ("x" ^ string_of_int i) in
+ let x = Reference (ArgVar (Loc.ghost, id)) in
+ (succ i, x :: vars, Id.Map.add id (Value.of_constr arg) lfun)
+ in
+ let (_, args, lfun) = List.fold_right fold args (0, [], Id.Map.empty) in
+ let ist = { (Tacinterp.default_ist ()) with Tacinterp.lfun = lfun; } in
+ (** Build the getter *)
let lid = List.init n (fun i -> Id.of_string("x"^string_of_int i)) in
- let res = ref [||] in
- let get_res ist =
- let l = List.map (fun id -> Id.Map.find id ist.lfun) lid in
- res := Array.of_list l;
- TacId[] in
- let getter =
- Tacexp(TacFun(List.map(fun id -> Some id) lid,
- Tacintern.glob_tactic(tacticIn get_res))) in
+ let n = Genarg.in_gen (Genarg.glbwit Stdarg.wit_int) n in
+ let get_res = TacML (Loc.ghost, get_res, [TacGeneric n]) in
+ let getter = Tacexp (TacFun (List.map (fun id -> Some id) lid, get_res)) in
+ (** Evaluate the whole result *)
let gl = dummy_goal env evd in
- let gls = Proofview.V82.of_tactic (Tacinterp.eval_tactic(ltac_call f (args@[getter]))) gl in
+ let gls = Proofview.V82.of_tactic (Tacinterp.eval_tactic_ist ist (ltac_call f (args@[getter]))) gl in
let evd, nf = Evarutil.nf_evars_and_universes (Refiner.project gls) in
- Array.map (fun x -> nf (constr_of x)) !res, snd (Evd.universe_context evd)
+ Array.map (fun x -> nf (constr_of x)) !tactic_res, snd (Evd.universe_context evd)
let stdlib_modules =
[["Coq";"Setoids";"Setoid"];
@@ -355,20 +369,6 @@ let _ = add_map "ring"
(****************************************************************************)
(* Ring database *)
-type ring_info =
- { ring_carrier : types;
- ring_req : constr;
- ring_setoid : constr;
- ring_ext : constr;
- ring_morph : constr;
- ring_th : constr;
- ring_cst_tac : glob_tactic_expr;
- ring_pow_tac : glob_tactic_expr;
- ring_lemma1 : constr;
- ring_lemma2 : constr;
- ring_pre_tac : glob_tactic_expr;
- ring_post_tac : glob_tactic_expr }
-
module Cmap = Map.Make(Constr)
let from_carrier = Summary.ref Cmap.empty ~name:"ring-tac-carrier-table"
@@ -600,13 +600,6 @@ let dest_morph env sigma m_spec =
(c,czero,cone,cadd,cmul,None,None,ceqb,phi)
| _ -> error "bad morphism structure"
-
-type 'constr coeff_spec =
- Computational of 'constr (* equality test *)
- | Abstract (* coeffs = Z *)
- | Morphism of 'constr (* general morphism *)
-
-
let reflect_coeff rkind =
(* We build an ill-typed terms on purpose... *)
match rkind with
@@ -614,10 +607,6 @@ let reflect_coeff rkind =
| Computational c -> lapp coq_comp [|c|]
| Morphism m -> lapp coq_morph [|m|]
-type cst_tac_spec =
- CstTac of raw_tactic_expr
- | Closed of reference list
-
let interp_cst_tac env sigma rk kind (zero,one,add,mul,opp) cst_tac =
match cst_tac with
Some (CstTac t) -> Tacintern.glob_tactic t
@@ -686,7 +675,7 @@ let add_theory name (sigma,rth) eqth morphth cst_tac (pre,post) power sign div =
let rk = reflect_coeff morphth in
let params,ctx =
exec_tactic env !evd 5 (zltac "ring_lemmas")
- (List.map carg[sth;ext;rth;pspec;sspec;dspec;rk]) in
+ [sth;ext;rth;pspec;sspec;dspec;rk] in
let lemma1 = params.(3) in
let lemma2 = params.(4) in
@@ -721,41 +710,12 @@ let add_theory name (sigma,rth) eqth morphth cst_tac (pre,post) power sign div =
ring_post_tac = posttac }) in
()
-type 'constr ring_mod =
- Ring_kind of 'constr coeff_spec
- | Const_tac of cst_tac_spec
- | Pre_tac of raw_tactic_expr
- | Post_tac of raw_tactic_expr
- | Setoid of Constrexpr.constr_expr * Constrexpr.constr_expr
- | Pow_spec of cst_tac_spec * Constrexpr.constr_expr
- (* Syntaxification tactic , correctness lemma *)
- | Sign_spec of Constrexpr.constr_expr
- | Div_spec of Constrexpr.constr_expr
-
-
let ic_coeff_spec = function
| Computational t -> Computational (ic_unsafe t)
| Morphism t -> Morphism (ic_unsafe t)
| Abstract -> Abstract
-VERNAC ARGUMENT EXTEND ring_mod
- | [ "decidable" constr(eq_test) ] -> [ Ring_kind(Computational eq_test) ]
- | [ "abstract" ] -> [ Ring_kind Abstract ]
- | [ "morphism" constr(morph) ] -> [ Ring_kind(Morphism morph) ]
- | [ "constants" "[" tactic(cst_tac) "]" ] -> [ Const_tac(CstTac cst_tac) ]
- | [ "closed" "[" ne_global_list(l) "]" ] -> [ Const_tac(Closed l) ]
- | [ "preprocess" "[" tactic(pre) "]" ] -> [ Pre_tac pre ]
- | [ "postprocess" "[" tactic(post) "]" ] -> [ Post_tac post ]
- | [ "setoid" constr(sth) constr(ext) ] -> [ Setoid(sth,ext) ]
- | [ "sign" constr(sign_spec) ] -> [ Sign_spec sign_spec ]
- | [ "power" constr(pow_spec) "[" ne_global_list(l) "]" ] ->
- [ Pow_spec (Closed l, pow_spec) ]
- | [ "power_tac" constr(pow_spec) "[" tactic(cst_tac) "]" ] ->
- [ Pow_spec (CstTac cst_tac, pow_spec) ]
- | [ "div" constr(div_spec) ] -> [ Div_spec div_spec ]
-END
-
let set_once s r v =
if Option.is_empty !r then r := Some v else error (s^" cannot be set twice")
@@ -780,20 +740,6 @@ let process_ring_mods l =
let k = match !kind with Some k -> k | None -> Abstract in
(k, !set, !cst_tac, !pre, !post, !power, !sign, !div)
-VERNAC COMMAND EXTEND AddSetoidRing CLASSIFIED AS SIDEFF
- | [ "Add" "Ring" ident(id) ":" constr(t) ring_mods(l) ] ->
- [ let (k,set,cst,pre,post,power,sign, div) = process_ring_mods l in
- add_theory id (ic t) set k cst (pre,post) power sign div]
- | [ "Print" "Rings" ] => [Vernac_classifier.classify_as_query] -> [
- msg_notice (strbrk "The following ring structures have been declared:");
- Spmap.iter (fun fn fi ->
- msg_notice (hov 2
- (Ppconstr.pr_id (Libnames.basename fn)++spc()++
- str"with carrier "++ pr_constr fi.ring_carrier++spc()++
- str"and equivalence relation "++ pr_constr fi.ring_req))
- ) !from_name ]
-END
-
(*****************************************************************************)
(* The tactics consist then only in a lookup in the ring database and
call the appropriate ltac. *)
@@ -809,24 +755,28 @@ let make_term_list env evd carrier rl =
(plapp evd coq_nil [|carrier|])
in Typing.solve_evars env evd l
+let carg = Tacinterp.Value.of_constr
+let tacarg expr =
+ Tacinterp.Value.of_closure (Tacinterp.default_ist ()) expr
+
let ltac_ring_structure e =
let req = carg e.ring_req in
let sth = carg e.ring_setoid in
let ext = carg e.ring_ext in
let morph = carg e.ring_morph in
let th = carg e.ring_th in
- let cst_tac = Tacexp e.ring_cst_tac in
- let pow_tac = Tacexp e.ring_pow_tac in
+ let cst_tac = tacarg e.ring_cst_tac in
+ let pow_tac = tacarg e.ring_pow_tac in
let lemma1 = carg e.ring_lemma1 in
let lemma2 = carg e.ring_lemma2 in
- let pretac = Tacexp(TacFun([None],e.ring_pre_tac)) in
- let posttac = Tacexp(TacFun([None],e.ring_post_tac)) in
+ let pretac = tacarg (TacFun([None],e.ring_pre_tac)) in
+ let posttac = tacarg (TacFun([None],e.ring_post_tac)) in
[req;sth;ext;morph;th;cst_tac;pow_tac;
lemma1;lemma2;pretac;posttac]
let ring_lookup (f:glob_tactic_expr) lH rl t =
- Proofview.Goal.enter begin fun gl ->
- let sigma = Proofview.Goal.sigma gl in
+ Proofview.Goal.enter { enter = begin fun gl ->
+ let sigma = Tacmach.New.project gl in
let env = Proofview.Goal.env gl in
try (* find_ring_strucure can raise an exception *)
let evdref = ref sigma in
@@ -837,14 +787,7 @@ let ring_lookup (f:glob_tactic_expr) lH rl t =
let ring = ltac_ring_structure e in
Proofview.tclTHEN (Proofview.Unsafe.tclEVARS !evdref) (ltac_apply f (ring@[lH;rl]))
with e when Proofview.V82.catchable_exception e -> Proofview.tclZERO e
- end
-
-TACTIC EXTEND ring_lookup
-| [ "ring_lookup" tactic0(f) "[" constr_list(lH) "]" ne_constr_list(lrt) ] ->
- [ let (t,lr) = List.sep_last lrt in ring_lookup f lH lr t]
-END
-
-
+ end }
(***********************************************************************)
@@ -919,19 +862,6 @@ let dest_field env evd th_spec =
(Some true,r,zero,one,add,mul,None,None,div,inv,req,rth)
| _ -> error "bad field structure"
-type field_info =
- { field_carrier : types;
- field_req : constr;
- field_cst_tac : glob_tactic_expr;
- field_pow_tac : glob_tactic_expr;
- field_ok : constr;
- field_simpl_eq_ok : constr;
- field_simpl_ok : constr;
- field_simpl_eq_in_ok : constr;
- field_cond : constr;
- field_pre_tac : glob_tactic_expr;
- field_post_tac : glob_tactic_expr }
-
let field_from_carrier = Summary.ref Cmap.empty ~name:"field-tac-carrier-table"
let field_from_name = Summary.ref Spmap.empty ~name:"field-tac-name-table"
@@ -1034,7 +964,7 @@ let add_field_theory name (sigma,fth) eqth morphth cst_tac inj (pre,post) power
let rk = reflect_coeff morphth in
let params,ctx =
exec_tactic env !evd 9 (field_ltac"field_lemmas")
- (List.map carg[sth;ext;inv_m;fth;pspec;sspec;dspec;rk]) in
+ [sth;ext;inv_m;fth;pspec;sspec;dspec;rk] in
let lemma1 = params.(3) in
let lemma2 = params.(4) in
let lemma3 = params.(5) in
@@ -1078,15 +1008,6 @@ let add_field_theory name (sigma,fth) eqth morphth cst_tac inj (pre,post) power
field_pre_tac = pretac;
field_post_tac = posttac }) in ()
-type 'constr field_mod =
- Ring_mod of 'constr ring_mod
- | Inject of Constrexpr.constr_expr
-
-VERNAC ARGUMENT EXTEND field_mod
- | [ ring_mod(m) ] -> [ Ring_mod m ]
- | [ "completeness" constr(inj) ] -> [ Inject inj ]
-END
-
let process_field_mods l =
let kind = ref None in
let set = ref None in
@@ -1111,38 +1032,23 @@ let process_field_mods l =
let k = match !kind with Some k -> k | None -> Abstract in
(k, !set, !inj, !cst_tac, !pre, !post, !power, !sign, !div)
-VERNAC COMMAND EXTEND AddSetoidField CLASSIFIED AS SIDEFF
-| [ "Add" "Field" ident(id) ":" constr(t) field_mods(l) ] ->
- [ let (k,set,inj,cst_tac,pre,post,power,sign,div) = process_field_mods l in
- add_field_theory id (ic t) set k cst_tac inj (pre,post) power sign div]
-| [ "Print" "Fields" ] => [Vernac_classifier.classify_as_query] -> [
- msg_notice (strbrk "The following field structures have been declared:");
- Spmap.iter (fun fn fi ->
- msg_notice (hov 2
- (Ppconstr.pr_id (Libnames.basename fn)++spc()++
- str"with carrier "++ pr_constr fi.field_carrier++spc()++
- str"and equivalence relation "++ pr_constr fi.field_req))
- ) !field_from_name ]
-END
-
-
let ltac_field_structure e =
let req = carg e.field_req in
- let cst_tac = Tacexp e.field_cst_tac in
- let pow_tac = Tacexp e.field_pow_tac in
+ let cst_tac = tacarg e.field_cst_tac in
+ let pow_tac = tacarg e.field_pow_tac in
let field_ok = carg e.field_ok in
let field_simpl_ok = carg e.field_simpl_ok in
let field_simpl_eq_ok = carg e.field_simpl_eq_ok in
let field_simpl_eq_in_ok = carg e.field_simpl_eq_in_ok in
let cond_ok = carg e.field_cond in
- let pretac = Tacexp(TacFun([None],e.field_pre_tac)) in
- let posttac = Tacexp(TacFun([None],e.field_post_tac)) in
+ let pretac = tacarg (TacFun([None],e.field_pre_tac)) in
+ let posttac = tacarg (TacFun([None],e.field_post_tac)) in
[req;cst_tac;pow_tac;field_ok;field_simpl_ok;field_simpl_eq_ok;
field_simpl_eq_in_ok;cond_ok;pretac;posttac]
let field_lookup (f:glob_tactic_expr) lH rl t =
- Proofview.Goal.enter begin fun gl ->
- let sigma = Proofview.Goal.sigma gl in
+ Proofview.Goal.enter { enter = begin fun gl ->
+ let sigma = Tacmach.New.project gl in
let env = Proofview.Goal.env gl in
try
let evdref = ref sigma in
@@ -1153,10 +1059,4 @@ let field_lookup (f:glob_tactic_expr) lH rl t =
let field = ltac_field_structure e in
Proofview.tclTHEN (Proofview.Unsafe.tclEVARS !evdref) (ltac_apply f (field@[lH;rl]))
with e when Proofview.V82.catchable_exception e -> Proofview.tclZERO e
- end
-
-
-TACTIC EXTEND field_lookup
-| [ "field_lookup" tactic(f) "[" constr_list(lH) "]" ne_constr_list(lt) ] ->
- [ let (t,l) = List.sep_last lt in field_lookup f lH l t ]
-END
+ end }
diff --git a/plugins/setoid_ring/newring.mli b/plugins/setoid_ring/newring.mli
new file mode 100644
index 000000000..4bd3383d6
--- /dev/null
+++ b/plugins/setoid_ring/newring.mli
@@ -0,0 +1,78 @@
+(************************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2015 *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(************************************************************************)
+
+open Names
+open Constr
+open Libnames
+open Globnames
+open Constrexpr
+open Tacexpr
+open Proof_type
+open Newring_ast
+
+val protect_tac_in : string -> Id.t -> tactic
+
+val protect_tac : string -> tactic
+
+val closed_term : constr -> global_reference list -> tactic
+
+val process_ring_mods :
+ constr_expr ring_mod list ->
+ constr coeff_spec * (constr * constr) option *
+ cst_tac_spec option * raw_tactic_expr option *
+ raw_tactic_expr option *
+ (cst_tac_spec * constr_expr) option *
+ constr_expr option * constr_expr option
+
+val add_theory :
+ Id.t ->
+ Evd.evar_map * constr ->
+ (constr * constr) option ->
+ constr coeff_spec ->
+ cst_tac_spec option ->
+ raw_tactic_expr option * raw_tactic_expr option ->
+ (cst_tac_spec * constr_expr) option ->
+ constr_expr option ->
+ constr_expr option -> unit
+
+val ic : constr_expr -> Evd.evar_map * constr
+
+val from_name : ring_info Spmap.t ref
+
+val ring_lookup :
+ glob_tactic_expr ->
+ constr list ->
+ constr list -> constr -> unit Proofview.tactic
+
+val process_field_mods :
+ constr_expr field_mod list ->
+ constr coeff_spec *
+ (constr * constr) option * constr option *
+ cst_tac_spec option * raw_tactic_expr option *
+ raw_tactic_expr option *
+ (cst_tac_spec * constr_expr) option *
+ constr_expr option * constr_expr option
+
+val add_field_theory :
+ Id.t ->
+ Evd.evar_map * constr ->
+ (constr * constr) option ->
+ constr coeff_spec ->
+ cst_tac_spec option ->
+ constr option ->
+ raw_tactic_expr option * raw_tactic_expr option ->
+ (cst_tac_spec * constr_expr) option ->
+ constr_expr option ->
+ constr_expr option -> unit
+
+val field_from_name : field_info Spmap.t ref
+
+val field_lookup :
+ glob_tactic_expr ->
+ constr list ->
+ constr list -> constr -> unit Proofview.tactic
diff --git a/plugins/setoid_ring/newring_ast.mli b/plugins/setoid_ring/newring_ast.mli
new file mode 100644
index 000000000..c26fcc8d1
--- /dev/null
+++ b/plugins/setoid_ring/newring_ast.mli
@@ -0,0 +1,63 @@
+(************************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2015 *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(************************************************************************)
+
+open Constr
+open Libnames
+open Constrexpr
+open Tacexpr
+
+type 'constr coeff_spec =
+ Computational of 'constr (* equality test *)
+ | Abstract (* coeffs = Z *)
+ | Morphism of 'constr (* general morphism *)
+
+type cst_tac_spec =
+ CstTac of raw_tactic_expr
+ | Closed of reference list
+
+type 'constr ring_mod =
+ Ring_kind of 'constr coeff_spec
+ | Const_tac of cst_tac_spec
+ | Pre_tac of raw_tactic_expr
+ | Post_tac of raw_tactic_expr
+ | Setoid of constr_expr * constr_expr
+ | Pow_spec of cst_tac_spec * constr_expr
+ (* Syntaxification tactic , correctness lemma *)
+ | Sign_spec of constr_expr
+ | Div_spec of constr_expr
+
+type 'constr field_mod =
+ Ring_mod of 'constr ring_mod
+ | Inject of constr_expr
+
+type ring_info =
+ { ring_carrier : types;
+ ring_req : constr;
+ ring_setoid : constr;
+ ring_ext : constr;
+ ring_morph : constr;
+ ring_th : constr;
+ ring_cst_tac : glob_tactic_expr;
+ ring_pow_tac : glob_tactic_expr;
+ ring_lemma1 : constr;
+ ring_lemma2 : constr;
+ ring_pre_tac : glob_tactic_expr;
+ ring_post_tac : glob_tactic_expr }
+
+type field_info =
+ { field_carrier : types;
+ field_req : constr;
+ field_cst_tac : glob_tactic_expr;
+ field_pow_tac : glob_tactic_expr;
+ field_ok : constr;
+ field_simpl_eq_ok : constr;
+ field_simpl_ok : constr;
+ field_simpl_eq_in_ok : constr;
+ field_cond : constr;
+ field_pre_tac : glob_tactic_expr;
+ field_post_tac : glob_tactic_expr }
diff --git a/plugins/setoid_ring/newring_plugin.mllib b/plugins/setoid_ring/newring_plugin.mllib
index a98392f1e..7d6c49588 100644
--- a/plugins/setoid_ring/newring_plugin.mllib
+++ b/plugins/setoid_ring/newring_plugin.mllib
@@ -1,2 +1,3 @@
Newring
Newring_plugin_mod
+G_newring
diff --git a/pretyping/cases.ml b/pretyping/cases.ml
index 3d6fa38d0..2cbf3a265 100644
--- a/pretyping/cases.ml
+++ b/pretyping/cases.ml
@@ -13,7 +13,6 @@ open Names
open Nameops
open Term
open Vars
-open Context
open Termops
open Namegen
open Declarations
@@ -131,7 +130,7 @@ type tomatch_status =
| Pushed of (bool*((constr * tomatch_type) * int list * Name.t))
| Alias of (bool*(Name.t * constr * (constr * types)))
| NonDepAlias
- | Abstract of int * rel_declaration
+ | Abstract of int * Context.Rel.Declaration.t
type tomatch_stack = tomatch_status list
@@ -602,7 +601,7 @@ let relocate_index_tomatch n1 n2 =
NonDepAlias :: genrec depth rest
| Abstract (i,d) :: rest ->
let i = relocate_rel n1 n2 depth i in
- Abstract (i,map_rel_declaration (relocate_index n1 n2 depth) d)
+ Abstract (i, Context.Rel.Declaration.map (relocate_index n1 n2 depth) d)
:: genrec (depth+1) rest in
genrec 0
@@ -635,7 +634,7 @@ let replace_tomatch n c =
| NonDepAlias :: rest ->
NonDepAlias :: replrec depth rest
| Abstract (i,d) :: rest ->
- Abstract (i,map_rel_declaration (replace_term n c depth) d)
+ Abstract (i, Context.Rel.Declaration.map (replace_term n c depth) d)
:: replrec (depth+1) rest in
replrec 0
@@ -660,7 +659,7 @@ let rec liftn_tomatch_stack n depth = function
NonDepAlias :: liftn_tomatch_stack n depth rest
| Abstract (i,d)::rest ->
let i = if i<depth then i else i+n in
- Abstract (i,map_rel_declaration (liftn n depth) d)
+ Abstract (i, Context.Rel.Declaration.map (liftn n depth) d)
::(liftn_tomatch_stack n (depth+1) rest)
let lift_tomatch_stack n = liftn_tomatch_stack n 1
@@ -837,10 +836,10 @@ let regeneralize_index_predicate n = map_predicate (relocate_index n 1) 0
let substnl_predicate sigma = map_predicate (substnl sigma)
(* This is parallel bindings *)
-let subst_predicate (args,copt) ccl tms =
+let subst_predicate (subst,copt) ccl tms =
let sigma = match copt with
- | None -> List.rev args
- | Some c -> c::(List.rev args) in
+ | None -> subst
+ | Some c -> c::subst in
substnl_predicate sigma 0 ccl tms
let specialize_predicate_var (cur,typ,dep) tms ccl =
@@ -921,7 +920,7 @@ let abstract_predicate env sigma indf cur realargs (names,na) tms ccl =
let tms = List.fold_right2 (fun par arg tomatch ->
match kind_of_term par with
| Rel i -> relocate_index_tomatch (i+n) (destRel arg) tomatch
- | _ -> tomatch) (realargs@[cur]) (extended_rel_list 0 sign)
+ | _ -> tomatch) (realargs@[cur]) (Context.Rel.to_extended_list 0 sign)
(lift_tomatch_stack n tms) in
(* Pred is already dependent in the current term to match (if *)
(* (na<>Anonymous) and its realargs; we just need to adjust it to *)
@@ -1018,7 +1017,7 @@ let specialize_predicate newtomatchs (names,depna) arsign cs tms ccl =
(* We prepare the substitution of X and x:I(X) *)
let realargsi =
if not (Int.equal nrealargs 0) then
- adjust_subst_to_rel_context arsign (Array.to_list cs.cs_concl_realargs)
+ subst_of_rel_context_instance arsign (Array.to_list cs.cs_concl_realargs)
else
[] in
let copti = match depna with
@@ -1118,7 +1117,7 @@ let postprocess_dependencies evd tocheck brs tomatch pred deps cs =
let rec aux k brs tomatch pred tocheck deps = match deps, tomatch with
| [], _ -> brs,tomatch,pred,[]
| n::deps, Abstract (i,d) :: tomatch ->
- let d = map_rel_declaration (nf_evar evd) d in
+ let d = Context.Rel.Declaration.map (nf_evar evd) d in
let is_d = match d with (_, None, _) -> false | _ -> true in
if is_d || List.exists (fun c -> dependent_decl (lift k c) d) tocheck
&& Array.exists (is_dependent_branch k) brs then
@@ -1187,7 +1186,7 @@ let group_equations pb ind current cstrs mat =
let rec generalize_problem names pb = function
| [] -> pb, []
| i::l ->
- let (na,b,t as d) = map_rel_declaration (lift i) (Environ.lookup_rel i pb.env) in
+ let (na,b,t as d) = Context.Rel.Declaration.map (lift i) (Environ.lookup_rel i pb.env) in
let pb',deps = generalize_problem names pb l in
begin match (na, b) with
| Anonymous, Some _ -> pb', deps
@@ -1230,7 +1229,7 @@ let build_branch initial current realargs deps (realnames,curname) pb arsign eqn
(* We adjust the terms to match in the context they will be once the *)
(* context [x1:T1,..,xn:Tn] will have been pushed on the current env *)
let typs' =
- List.map_i (fun i d -> (mkRel i,map_rel_declaration (lift i) d)) 1 typs in
+ List.map_i (fun i d -> (mkRel i, Context.Rel.Declaration.map (lift i) d)) 1 typs in
let extenv = push_rel_context typs pb.env in
@@ -1560,8 +1559,8 @@ let matx_of_eqns env eqns =
*)
let adjust_to_extended_env_and_remove_deps env extenv subst t =
- let n = rel_context_length (rel_context env) in
- let n' = rel_context_length (rel_context extenv) in
+ let n = Context.Rel.length (rel_context env) in
+ let n' = Context.Rel.length (rel_context extenv) in
(* We first remove the bindings that are dependently typed (they are
difficult to manage and it is not sure these are so useful in practice);
Notes:
@@ -1673,8 +1672,8 @@ let build_tycon loc env tycon_env s subst tycon extenv evdref t =
| None ->
(* This is the situation we are building a return predicate and
we are in an impossible branch *)
- let n = rel_context_length (rel_context env) in
- let n' = rel_context_length (rel_context tycon_env) in
+ let n = Context.Rel.length (rel_context env) in
+ let n' = Context.Rel.length (rel_context tycon_env) in
let impossible_case_type, u =
e_new_type_evar (reset_context env) evdref univ_flexible_alg ~src:(loc,Evar_kinds.ImpossibleCase) in
(lift (n'-n) impossible_case_type, mkSort u)
@@ -1744,7 +1743,7 @@ let build_inversion_problem loc env sigma tms t =
let n = List.length sign in
let decls =
- List.map_i (fun i d -> (mkRel i,map_rel_declaration (lift i) d)) 1 sign in
+ List.map_i (fun i d -> (mkRel i, Context.Rel.Declaration.map (lift i) d)) 1 sign in
let pb_env = push_rel_context sign env in
let decls =
diff --git a/pretyping/cases.mli b/pretyping/cases.mli
index ab00aa165..257d1e578 100644
--- a/pretyping/cases.mli
+++ b/pretyping/cases.mli
@@ -8,7 +8,6 @@
open Names
open Term
-open Context
open Evd
open Environ
open Inductiveops
@@ -45,11 +44,11 @@ val compile_cases :
val constr_of_pat :
Environ.env ->
Evd.evar_map ref ->
- rel_declaration list ->
+ Context.Rel.Declaration.t list ->
Glob_term.cases_pattern ->
Names.Id.t list ->
Glob_term.cases_pattern *
- (rel_declaration list * Term.constr *
+ (Context.Rel.Declaration.t list * Term.constr *
(Term.types * Term.constr list) * Glob_term.cases_pattern) *
Names.Id.t list
@@ -83,7 +82,7 @@ type tomatch_status =
| Pushed of (bool*((constr * tomatch_type) * int list * Name.t))
| Alias of (bool * (Name.t * constr * (constr * types)))
| NonDepAlias
- | Abstract of int * rel_declaration
+ | Abstract of int * Context.Rel.Declaration.t
type tomatch_stack = tomatch_status list
@@ -117,7 +116,7 @@ val prepare_predicate : Loc.t ->
Environ.env ->
Evd.evar_map ->
(Term.types * tomatch_type) list ->
- Context.rel_context list ->
+ Context.Rel.t list ->
Constr.constr option ->
'a option -> (Evd.evar_map * Names.name list * Term.constr) list
diff --git a/pretyping/constr_matching.ml b/pretyping/constr_matching.ml
index ee3c43d8d..69c1dfb47 100644
--- a/pretyping/constr_matching.ml
+++ b/pretyping/constr_matching.ml
@@ -17,7 +17,6 @@ open Termops
open Reductionops
open Term
open Vars
-open Context
open Pattern
open Patternops
open Misctypes
@@ -269,8 +268,8 @@ let matches_core env sigma convert allow_partial_app allow_bound_rels
| PIf (a1,b1,b1'), Case (ci,_,a2,[|b2;b2'|]) ->
let ctx_b2,b2 = decompose_lam_n_decls ci.ci_cstr_ndecls.(0) b2 in
let ctx_b2',b2' = decompose_lam_n_decls ci.ci_cstr_ndecls.(1) b2' in
- let n = rel_context_length ctx_b2 in
- let n' = rel_context_length ctx_b2' in
+ let n = Context.Rel.length ctx_b2 in
+ let n' = Context.Rel.length ctx_b2' in
if noccur_between 1 n b2 && noccur_between 1 n' b2' then
let f l (na,_,t) = (Anonymous,na,t)::l in
let ctx_br = List.fold_left f ctx ctx_b2 in
diff --git a/pretyping/detyping.ml b/pretyping/detyping.ml
index c3877c56e..c8ecf91d3 100644
--- a/pretyping/detyping.ml
+++ b/pretyping/detyping.ml
@@ -12,7 +12,6 @@ open Util
open Names
open Term
open Vars
-open Context
open Inductiveops
open Environ
open Glob_term
@@ -199,7 +198,7 @@ let computable p k =
engendrera un prédicat non dépendant) *)
let sign,ccl = decompose_lam_assum p in
- Int.equal (rel_context_length sign) (k + 1)
+ Int.equal (Context.Rel.length sign) (k + 1)
&&
noccur_between 1 (k+1) ccl
@@ -315,7 +314,7 @@ let is_nondep_branch c l =
try
(* FIXME: do better using tags from l *)
let sign,ccl = decompose_lam_n_decls (List.length l) c in
- noccur_between 1 (rel_context_length sign) ccl
+ noccur_between 1 (Context.Rel.length sign) ccl
with e when Errors.noncritical e -> (* Not eta-expanded or not reduced *)
false
@@ -673,7 +672,13 @@ and detype_binder (lax,isgoal as flags) bk avoid env sigma na body ty c =
match bk with
| BProd -> GProd (dl, na',Explicit,detype (lax,false) avoid env sigma ty, r)
| BLambda -> GLambda (dl, na',Explicit,detype (lax,false) avoid env sigma ty, r)
- | BLetIn -> GLetIn (dl, na',detype (lax,false) avoid env sigma (Option.get body), r)
+ | BLetIn ->
+ let c = detype (lax,false) avoid env sigma (Option.get body) in
+ (* Heuristic: we display the type if in Prop *)
+ let s = Retyping.get_sort_family_of (snd env) sigma ty in
+ let c = if s != InProp then c else
+ GCast (dl, c, CastConv (detype (lax,false) avoid env sigma ty)) in
+ GLetIn (dl, na', c, r)
let detype_rel_context ?(lax=false) where avoid env sigma sign =
let where = Option.map (fun c -> it_mkLambda_or_LetIn c sign) where in
diff --git a/pretyping/detyping.mli b/pretyping/detyping.mli
index 838588dc4..c51cb0f44 100644
--- a/pretyping/detyping.mli
+++ b/pretyping/detyping.mli
@@ -8,7 +8,6 @@
open Names
open Term
-open Context
open Environ
open Glob_term
open Termops
@@ -46,7 +45,7 @@ val detype_case :
val detype_sort : evar_map -> sorts -> glob_sort
val detype_rel_context : ?lax:bool -> constr option -> Id.t list -> (names_context * env) ->
- evar_map -> rel_context -> glob_decl list
+ evar_map -> Context.Rel.t -> glob_decl list
val detype_closed_glob : ?lax:bool -> bool -> Id.t list -> env -> evar_map -> closed_glob_constr -> glob_constr
diff --git a/pretyping/evarconv.ml b/pretyping/evarconv.ml
index 637a9e50e..99e51330e 100644
--- a/pretyping/evarconv.ml
+++ b/pretyping/evarconv.ml
@@ -22,6 +22,7 @@ open Evarsolve
open Globnames
open Evd
open Pretype_errors
+open Sigma.Notations
type unify_fun = transparent_state ->
env -> evar_map -> conv_pb -> constr -> constr -> Evarsolve.unification_result
@@ -830,7 +831,9 @@ and conv_record trs env evd (ctx,(h,h2),c,bs,(params,params1),(us,us2),(sk1,sk2)
(i,t2::ks, m-1, test)
else
let dloc = (Loc.ghost,Evar_kinds.InternalHole) in
- let (i',ev) = new_evar env i ~src:dloc (substl ks b) in
+ let i = Sigma.Unsafe.of_evar_map i in
+ let Sigma (ev, i', _) = Evarutil.new_evar env i ~src:dloc (substl ks b) in
+ let i' = Sigma.to_evar_map i' in
(i', ev :: ks, m - 1,test))
(evd,[],List.length bs,fun i -> Success i) bs
in
@@ -1096,7 +1099,7 @@ let apply_conversion_problem_heuristic ts env evd pbty t1 t2 =
| Some evd -> Success evd
| None -> UnifFailure (evd, ConversionFailed (env,term1,term2)))
| Evar (evk1,args1), Evar (evk2,args2) when Evar.equal evk1 evk2 ->
- let f env evd pbty x y = is_trans_fconv pbty ts env evd x y in
+ let f env evd pbty x y = is_fconv ~reds:ts pbty env evd x y in
Success (solve_refl ~can_drop:true f env evd
(position_problem true pbty) evk1 args1 args2)
| Evar ev1, Evar ev2 ->
diff --git a/pretyping/evarsolve.ml b/pretyping/evarsolve.ml
index 3bf6f3764..0dd0ad2e0 100644
--- a/pretyping/evarsolve.ml
+++ b/pretyping/evarsolve.ml
@@ -11,7 +11,6 @@ open Errors
open Names
open Term
open Vars
-open Context
open Environ
open Termops
open Evd
@@ -501,7 +500,7 @@ let solve_pattern_eqn env l c =
match kind_of_term a with
(* Rem: if [a] links to a let-in, do as if it were an assumption *)
| Rel n ->
- let d = map_rel_declaration (lift n) (lookup_rel n env) in
+ let d = Context.Rel.Declaration.map (lift n) (lookup_rel n env) in
mkLambda_or_LetIn d c'
| Var id ->
let d = lookup_named id env in mkNamedLambda_or_LetIn d c'
@@ -1007,21 +1006,6 @@ let postpone_non_unique_projection env evd pbty (evk,argsv as ev) sols rhs =
* Note: argument f is the function used to instantiate evars.
*)
-let are_canonical_instances args1 args2 env =
- let n1 = Array.length args1 in
- let n2 = Array.length args2 in
- let rec aux n = function
- | (id,_,c)::sign
- when n < n1 && isVarId id args1.(n) && isVarId id args2.(n) ->
- aux (n+1) sign
- | [] ->
- let rec aux2 n =
- Int.equal n n1 ||
- (isRelN (n1-n) args1.(n) && isRelN (n1-n) args2.(n) && aux2 (n+1))
- in aux2 n
- | _ -> false in
- Int.equal n1 n2 && aux 0 (named_context env)
-
let filter_compatible_candidates conv_algo env evd evi args rhs c =
let c' = instantiate_evar_array evi c args in
match conv_algo env evd Reduction.CONV rhs c' with
diff --git a/pretyping/evarutil.ml b/pretyping/evarutil.ml
index e23e5a53a..8c210e283 100644
--- a/pretyping/evarutil.ml
+++ b/pretyping/evarutil.ml
@@ -12,7 +12,6 @@ open Pp
open Names
open Term
open Vars
-open Context
open Termops
open Namegen
open Pre_env
@@ -78,12 +77,12 @@ let tj_nf_evar sigma {utj_val=v;utj_type=t} =
let env_nf_evar sigma env =
process_rel_context
- (fun d e -> push_rel (map_rel_declaration (nf_evar sigma) d) e) env
+ (fun d e -> push_rel (Context.Rel.Declaration.map (nf_evar sigma) d) e) env
let env_nf_betaiotaevar sigma env =
process_rel_context
(fun d e ->
- push_rel (map_rel_declaration (Reductionops.nf_betaiota sigma) d) e) env
+ push_rel (Context.Rel.Declaration.map (Reductionops.nf_betaiota sigma) d) e) env
let nf_evars_universes evm =
Universes.nf_evars_and_universes_opt_subst (Reductionops.safe_evar_value evm)
@@ -106,10 +105,10 @@ let nf_evar_map_universes evm =
Evd.raw_map (fun _ -> map_evar_info f) evm, f
let nf_named_context_evar sigma ctx =
- Context.map_named_context (nf_evar sigma) ctx
+ Context.Named.map (nf_evar sigma) ctx
let nf_rel_context_evar sigma ctx =
- Context.map_rel_context (nf_evar sigma) ctx
+ Context.Rel.map (nf_evar sigma) ctx
let nf_env_evar sigma env =
let nc' = nf_named_context_evar sigma (Environ.named_context env) in
@@ -239,17 +238,6 @@ let make_pure_subst evi args =
| _ -> anomaly (Pp.str "Instance does not match its signature"))
(evar_filtered_context evi) (Array.rev_to_list args,[]))
-(**********************)
-(* Creating new evars *)
-(**********************)
-
-let evar_counter_summary_name = "evar counter"
-
-(* Generator of existential names *)
-let new_untyped_evar =
- let evar_ctr = Summary.ref 0 ~name:evar_counter_summary_name in
- fun () -> incr evar_ctr; Evar.unsafe_of_int !evar_ctr
-
(*------------------------------------*
* functional operations on evar sets *
*------------------------------------*)
@@ -314,7 +302,7 @@ let push_rel_context_to_named_context env typ =
(* with vars of the rel context *)
(* We do keep the instances corresponding to local definition (see above) *)
let (subst, vsubst, _, env) =
- Context.fold_rel_context
+ Context.Rel.fold_outside
(fun (na,c,t) (subst, vsubst, avoid, env) ->
let id =
(* ppedrot: we want to infer nicer names for the refine tactic, but
@@ -354,17 +342,15 @@ let push_rel_context_to_named_context env typ =
let default_source = (Loc.ghost,Evar_kinds.InternalHole)
let restrict_evar evd evk filter candidates =
- let evk' = new_untyped_evar () in
- let evd = Evd.restrict evk evk' filter ?candidates evd in
+ let evd, evk' = Evd.restrict evk filter ?candidates evd in
Evd.declare_future_goal evk' evd, evk'
let new_pure_evar_full evd evi =
- let evk = new_untyped_evar () in
- let evd = Evd.add evd evk evi in
+ let (evd, evk) = Evd.new_evar evd evi in
let evd = Evd.declare_future_goal evk evd in
(evd, evk)
-let new_pure_evar sign evd ?(src=default_source) ?filter ?candidates ?store ?naming ?(principal=false) typ =
+let new_pure_evar sign evd ?(src=default_source) ?(filter = Filter.identity) ?candidates ?(store = Store.empty) ?naming ?(principal=false) typ =
let default_naming =
if principal then
(* waiting for a more principled approach
@@ -374,8 +360,16 @@ let new_pure_evar sign evd ?(src=default_source) ?filter ?candidates ?store ?nam
Misctypes.IntroAnonymous
in
let naming = Option.default default_naming naming in
- let newevk = new_untyped_evar() in
- let evd = evar_declare sign newevk typ ~src ?filter ?candidates ?store ~naming evd in
+ let evi = {
+ evar_hyps = sign;
+ evar_concl = typ;
+ evar_body = Evar_empty;
+ evar_filter = filter;
+ evar_source = src;
+ evar_candidates = candidates;
+ evar_extra = store; }
+ in
+ let (evd, newevk) = Evd.new_evar evd ~naming evi in
let evd =
if principal then Evd.declare_principal_goal newevk evd
else Evd.declare_future_goal newevk evd
@@ -390,7 +384,7 @@ let new_evar_instance sign evd typ ?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 new_evar_unsafe env evd ?src ?filter ?candidates ?store ?naming ?principal typ =
let sign,typ',instance,subst,vsubst = push_rel_context_to_named_context env typ in
let candidates = Option.map (List.map (subst2 subst vsubst)) candidates in
let instance =
@@ -399,9 +393,14 @@ let new_evar env evd ?src ?filter ?candidates ?store ?naming ?principal typ =
| Some filter -> Filter.filter_list filter instance in
new_evar_instance sign evd typ' ?src ?filter ?candidates ?store ?naming ?principal instance
+let new_evar env evd ?src ?filter ?candidates ?store ?naming ?principal typ =
+ let evd = Sigma.to_evar_map evd in
+ let (sigma, c) = new_evar_unsafe env evd ?src ?filter ?candidates ?store ?naming ?principal typ in
+ Sigma.Unsafe.of_pair (c, sigma)
+
let new_type_evar env evd ?src ?filter ?naming ?principal rigid =
let evd', s = new_sort_variable rigid evd in
- let evd', e = new_evar env evd' ?src ?filter ?naming ?principal (mkSort s) in
+ let evd', e = new_evar_unsafe env evd' ?src ?filter ?naming ?principal (mkSort s) in
evd', (e, s)
let e_new_type_evar env evdref ?src ?filter ?naming ?principal rigid =
@@ -419,7 +418,7 @@ let e_new_Type ?(rigid=Evd.univ_flexible) env evdref =
(* The same using side-effect *)
let e_new_evar env evdref ?(src=default_source) ?filter ?candidates ?store ?naming ?principal ty =
- let (evd',ev) = new_evar env !evdref ~src:src ?filter ?candidates ?store ?naming ?principal ty in
+ let (evd',ev) = new_evar_unsafe env !evdref ~src:src ?filter ?candidates ?store ?naming ?principal ty in
evdref := evd';
ev
@@ -723,7 +722,7 @@ let define_pure_evar_as_product evd evk =
let filter = Filter.extend 1 (evar_filter evi) in
if is_prop_sort s then
(* Impredicative product, conclusion must fall in [Prop]. *)
- new_evar newenv evd1 concl ~src ~filter
+ new_evar_unsafe newenv evd1 concl ~src ~filter
else
let status = univ_flexible_alg in
let evd3, (rng, srng) =
@@ -770,7 +769,7 @@ let define_pure_evar_as_lambda env evd evk =
let newenv = push_named (id, None, dom) evenv in
let filter = Filter.extend 1 (evar_filter evi) in
let src = evar_source evk evd1 in
- let evd2,body = new_evar newenv evd1 ~src (subst1 (mkVar id) rng) ~filter in
+ let evd2,body = new_evar_unsafe newenv evd1 ~src (subst1 (mkVar id) rng) ~filter in
let lam = mkLambda (Name id, dom, subst_var id body) in
Evd.define evk lam evd2, lam
@@ -860,13 +859,14 @@ let kind_of_term_upto sigma t =
let eq_constr_univs_test sigma1 sigma2 t u =
(* spiwack: mild code duplication with {!Evd.eq_constr_univs}. *)
let open Evd in
- let b, c =
+ let fold cstr sigma =
+ try Some (add_universe_constraints sigma cstr)
+ with Univ.UniverseInconsistency _ | UniversesDiffer -> None
+ in
+ let ans =
Universes.eq_constr_univs_infer_with
(fun t -> kind_of_term_upto sigma1 t)
(fun u -> kind_of_term_upto sigma2 u)
- (universes sigma2) t u
+ (universes sigma2) fold t u sigma2
in
- if b then
- try let _ = add_universe_constraints sigma2 c in true
- with Univ.UniverseInconsistency _ | UniversesDiffer -> false
- else false
+ match ans with None -> false | Some _ -> true
diff --git a/pretyping/evarutil.mli b/pretyping/evarutil.mli
index f68651a74..d87c7ef8d 100644
--- a/pretyping/evarutil.mli
+++ b/pretyping/evarutil.mli
@@ -8,7 +8,6 @@
open Names
open Term
-open Context
open Evd
open Environ
@@ -22,10 +21,10 @@ val mk_new_meta : unit -> constr
(** {6 Creating a fresh evar given their type and context} *)
val new_evar :
- env -> evar_map -> ?src:Loc.t * Evar_kinds.t -> ?filter:Filter.t ->
+ env -> 'r Sigma.t -> ?src:Loc.t * Evar_kinds.t -> ?filter:Filter.t ->
?candidates:constr list -> ?store:Store.t ->
?naming:Misctypes.intro_pattern_naming_expr ->
- ?principal:bool -> types -> evar_map * constr
+ ?principal:bool -> types -> (constr, 'r) Sigma.sigma
val new_pure_evar :
named_context_val -> evar_map -> ?src:Loc.t * Evar_kinds.t -> ?filter:Filter.t ->
@@ -129,7 +128,7 @@ val gather_dependent_evars : evar_map -> evar list -> (Evar.Set.t option) Evar.M
[nf_evar]. *)
val undefined_evars_of_term : evar_map -> constr -> Evar.Set.t
-val undefined_evars_of_named_context : evar_map -> named_context -> Evar.Set.t
+val undefined_evars_of_named_context : evar_map -> Context.Named.t -> Evar.Set.t
val undefined_evars_of_evar_info : evar_map -> evar_info -> Evar.Set.t
(** [occur_evar_upto sigma k c] returns [true] if [k] appears in
@@ -170,8 +169,8 @@ val jv_nf_evar :
val tj_nf_evar :
evar_map -> unsafe_type_judgment -> unsafe_type_judgment
-val nf_named_context_evar : evar_map -> named_context -> named_context
-val nf_rel_context_evar : evar_map -> rel_context -> rel_context
+val nf_named_context_evar : evar_map -> Context.Named.t -> Context.Named.t
+val nf_rel_context_evar : evar_map -> Context.Rel.t -> Context.Rel.t
val nf_env_evar : evar_map -> env -> env
val nf_evar_info : evar_map -> evar_info -> evar_info
@@ -252,4 +251,3 @@ val subterm_source : existential_key -> Evar_kinds.t Loc.located ->
Evar_kinds.t Loc.located
val meta_counter_summary_name : string
-val evar_counter_summary_name : string
diff --git a/pretyping/find_subterm.mli b/pretyping/find_subterm.mli
index 28108f8ca..c741ab048 100644
--- a/pretyping/find_subterm.mli
+++ b/pretyping/find_subterm.mli
@@ -7,7 +7,6 @@
(************************************************************************)
open Locus
-open Context
open Term
open Evd
open Pretype_errors
@@ -50,7 +49,7 @@ val replace_term_occ_modulo : occurrences or_like_first ->
val replace_term_occ_decl_modulo :
(occurrences * hyp_location_flag) or_like_first ->
'a testing_function -> (unit -> constr) ->
- named_declaration -> named_declaration
+ Context.Named.Declaration.t -> Context.Named.Declaration.t
(** [subst_closed_term_occ occl c d] replaces occurrences of
closed [c] at positions [occl] by [Rel 1] in [d] (see also Note OCC),
@@ -62,7 +61,7 @@ val subst_closed_term_occ : env -> evar_map -> occurrences or_like_first ->
closed [c] at positions [occl] by [Rel 1] in [decl]. *)
val subst_closed_term_occ_decl : env -> evar_map ->
(occurrences * hyp_location_flag) or_like_first ->
- constr -> named_declaration -> named_declaration * evar_map
+ constr -> Context.Named.Declaration.t -> Context.Named.Declaration.t * evar_map
(** Miscellaneous *)
val error_invalid_occurrence : int list -> 'a
diff --git a/pretyping/indrec.ml b/pretyping/indrec.ml
index d5f6e9b30..92573a94f 100644
--- a/pretyping/indrec.ml
+++ b/pretyping/indrec.ml
@@ -19,7 +19,6 @@ open Globnames
open Nameops
open Term
open Vars
-open Context
open Namegen
open Declarations
open Declareops
@@ -28,6 +27,7 @@ open Inductiveops
open Environ
open Reductionops
open Nametab
+open Sigma.Notations
type dep_flag = bool
@@ -60,7 +60,7 @@ let check_privacy_block mib =
let mis_make_case_com dep env sigma (ind, u as pind) (mib,mip as specif) kind =
let lnamespar = Vars.subst_instance_context u mib.mind_params_ctxt in
- let indf = make_ind_family(pind, Termops.extended_rel_list 0 lnamespar) in
+ let indf = make_ind_family(pind, Context.Rel.to_extended_list 0 lnamespar) in
let constrs = get_constructors env indf in
let projs = get_projections env indf in
@@ -91,8 +91,8 @@ let mis_make_case_com dep env sigma (ind, u as pind) (mib,mip as specif) kind =
let pbody =
appvect
(mkRel (ndepar + nbprod),
- if dep then Termops.extended_rel_vect 0 deparsign
- else Termops.extended_rel_vect 1 arsign) in
+ if dep then Context.Rel.to_extended_vect 0 deparsign
+ else Context.Rel.to_extended_vect 1 arsign) in
let p =
it_mkLambda_or_LetIn_name env'
((if dep then mkLambda_name env' else mkLambda)
@@ -120,13 +120,14 @@ let mis_make_case_com dep env sigma (ind, u as pind) (mib,mip as specif) kind =
mkLambda_string "f" t
(add_branch (push_rel (Anonymous, None, t) env) (k+1))
in
- let sigma, s = Evd.fresh_sort_in_family ~rigid:Evd.univ_flexible_alg env sigma kind in
+ let Sigma (s, sigma, p) = Sigma.fresh_sort_in_family ~rigid:Evd.univ_flexible_alg env sigma kind in
let typP = make_arity env' dep indf s in
let c =
it_mkLambda_or_LetIn_name env
(mkLambda_string "P" typP
(add_branch (push_rel (Anonymous,None,typP) env') 0)) lnamespar
- in sigma, c
+ in
+ Sigma (c, sigma, p)
(* check if the type depends recursively on one of the inductive scheme *)
@@ -163,7 +164,7 @@ let type_rec_branch is_rec dep env sigma (vargs,depPvect,decP) tyi cs recargs =
let base = applist (lift i pk,realargs) in
if depK then
Reduction.beta_appvect
- base [|applist (mkRel (i+1), Termops.extended_rel_list 0 sign)|]
+ base [|applist (mkRel (i+1), Context.Rel.to_extended_list 0 sign)|]
else
base
| _ -> assert false
@@ -235,7 +236,7 @@ let make_rec_branch_arg env sigma (nparrec,fvect,decF) f cstr recargs =
mkLetIn (n,b,t,prec (push_rel d env) (i+1) (d::hyps) c)
| Ind _ ->
let realargs = List.skipn nparrec largs
- and arg = appvect (mkRel (i+1), Termops.extended_rel_vect 0 hyps) in
+ and arg = appvect (mkRel (i+1), Context.Rel.to_extended_vect 0 hyps) in
applist(lift i fk,realargs@[arg])
| _ -> assert false
in
@@ -275,24 +276,13 @@ let make_rec_branch_arg env sigma (nparrec,fvect,decF) f cstr recargs =
in
process_constr env 0 f (List.rev cstr.cs_args, recargs)
-
-(* Cut a context ctx in 2 parts (ctx1,ctx2) with ctx1 containing k
- variables *)
-let context_chop k ctx =
- let rec chop_aux acc = function
- | (0, l2) -> (List.rev acc, l2)
- | (n, ((_,Some _,_ as h)::t)) -> chop_aux (h::acc) (n, t)
- | (n, (h::t)) -> chop_aux (h::acc) (pred n, t)
- | (_, []) -> failwith "context_chop"
- in chop_aux [] (k,ctx)
-
(* Main function *)
let mis_make_indrec env sigma listdepkind mib u =
let nparams = mib.mind_nparams in
let nparrec = mib.mind_nparams_rec in
let evdref = ref sigma in
let lnonparrec,lnamesparrec =
- context_chop (nparams-nparrec) (Vars.subst_instance_context u mib.mind_params_ctxt) in
+ Termops.context_chop (nparams-nparrec) (Vars.subst_instance_context u mib.mind_params_ctxt) in
let nrec = List.length listdepkind in
let depPvec =
Array.make mib.mind_ntypes (None : (bool * constr) option) in
@@ -321,29 +311,29 @@ let mis_make_indrec env sigma listdepkind mib u =
(* arity in the context of the fixpoint, i.e.
P1..P_nrec f1..f_nbconstruct *)
- let args = Termops.extended_rel_list (nrec+nbconstruct) lnamesparrec in
+ let args = Context.Rel.to_extended_list (nrec+nbconstruct) lnamesparrec in
let indf = make_ind_family((indi,u),args) in
let arsign,_ = get_arity env indf in
let depind = build_dependent_inductive env indf in
let deparsign = (Anonymous,None,depind)::arsign in
- let nonrecpar = rel_context_length lnonparrec in
- let larsign = rel_context_length deparsign in
+ let nonrecpar = Context.Rel.length lnonparrec in
+ let larsign = Context.Rel.length deparsign in
let ndepar = larsign - nonrecpar in
let dect = larsign+nrec+nbconstruct in
(* constructors in context of the Cases expr, i.e.
P1..P_nrec f1..f_nbconstruct F_1..F_nrec a_1..a_nar x:I *)
- let args' = Termops.extended_rel_list (dect+nrec) lnamesparrec in
- let args'' = Termops.extended_rel_list ndepar lnonparrec in
+ let args' = Context.Rel.to_extended_list (dect+nrec) lnamesparrec in
+ let args'' = Context.Rel.to_extended_list ndepar lnonparrec in
let indf' = make_ind_family((indi,u),args'@args'') in
let branches =
let constrs = get_constructors env indf' in
let fi = Termops.rel_vect (dect-i-nctyi) nctyi in
let vecfi = Array.map
- (fun f -> appvect (f, Termops.extended_rel_vect ndepar lnonparrec))
+ (fun f -> appvect (f, Context.Rel.to_extended_vect ndepar lnonparrec))
fi
in
Array.map3
@@ -364,9 +354,9 @@ let mis_make_indrec env sigma listdepkind mib u =
let deparsign' = (Anonymous,None,depind')::arsign' in
let pargs =
- let nrpar = Termops.extended_rel_list (2*ndepar) lnonparrec
- and nrar = if dep then Termops.extended_rel_list 0 deparsign'
- else Termops.extended_rel_list 1 arsign'
+ let nrpar = Context.Rel.to_extended_list (2*ndepar) lnonparrec
+ and nrar = if dep then Context.Rel.to_extended_list 0 deparsign'
+ else Context.Rel.to_extended_list 1 arsign'
in nrpar@nrar
in
@@ -409,14 +399,14 @@ let mis_make_indrec env sigma listdepkind mib u =
let typtyi =
let concl =
- let pargs = if dep then Termops.extended_rel_vect 0 deparsign
- else Termops.extended_rel_vect 1 arsign
+ let pargs = if dep then Context.Rel.to_extended_vect 0 deparsign
+ else Context.Rel.to_extended_vect 1 arsign
in appvect (mkRel (nbconstruct+ndepar+nonrecpar+j),pargs)
in it_mkProd_or_LetIn_name env
concl
deparsign
in
- mrec (i+nctyi) (rel_context_nhyps arsign ::ln) (typtyi::ltyp)
+ mrec (i+nctyi) (Context.Rel.nhyps arsign ::ln) (typtyi::ltyp)
(deftyi::ldef) rest
| [] ->
let fixn = Array.of_list (List.rev ln) in
@@ -437,7 +427,7 @@ let mis_make_indrec env sigma listdepkind mib u =
else
let recarg = (dest_subterms recargsvec.(tyi)).(j) in
let recarg = recargpar@recarg in
- let vargs = Termops.extended_rel_list (nrec+i+j) lnamesparrec in
+ let vargs = Context.Rel.to_extended_list (nrec+i+j) lnamesparrec in
let cs = get_constructor ((indi,u),mibi,mipi,vargs) (j+1) in
let p_0 =
type_rec_branch
@@ -451,7 +441,7 @@ let mis_make_indrec env sigma listdepkind mib u =
in
let rec put_arity env i = function
| ((indi,u),_,_,dep,kinds)::rest ->
- let indf = make_ind_family ((indi,u), Termops.extended_rel_list i lnamesparrec) in
+ let indf = make_ind_family ((indi,u), Context.Rel.to_extended_list i lnamesparrec) in
let s =
Evarutil.evd_comb1 (Evd.fresh_sort_in_family ~rigid:Evd.univ_flexible_alg env)
evdref kinds
@@ -474,7 +464,9 @@ let mis_make_indrec env sigma listdepkind mib u =
it_mkLambda_or_LetIn_name env (put_arity env' 0 listdepkind)
lnamesparrec
else
- let evd', c = mis_make_case_com dep env !evdref (indi,u) (mibi,mipi) kind in
+ let sigma = Sigma.Unsafe.of_evar_map !evdref in
+ let Sigma (c, sigma, _) = mis_make_case_com dep env sigma (indi,u) (mibi,mipi) kind in
+ let evd' = Sigma.to_evar_map sigma in
evdref := evd'; c
in
(* Body of mis_make_indrec *)
diff --git a/pretyping/indrec.mli b/pretyping/indrec.mli
index 4d81a59ef..f0736d2dd 100644
--- a/pretyping/indrec.mli
+++ b/pretyping/indrec.mli
@@ -25,13 +25,13 @@ type dep_flag = bool
(** Build a case analysis elimination scheme in some sort family *)
-val build_case_analysis_scheme : env -> evar_map -> pinductive ->
- dep_flag -> sorts_family -> evar_map * constr
+val build_case_analysis_scheme : env -> 'r Sigma.t -> pinductive ->
+ dep_flag -> sorts_family -> (constr, 'r) Sigma.sigma
(** Build a dependent case elimination predicate unless type is in Prop *)
-val build_case_analysis_scheme_default : env -> evar_map -> pinductive ->
- sorts_family -> evar_map * constr
+val build_case_analysis_scheme_default : env -> 'r Sigma.t -> pinductive ->
+ sorts_family -> (constr, 'r) Sigma.sigma
(** Builds a recursive induction scheme (Peano-induction style) in the same
sort family as the inductive family; it is dependent if not in Prop *)
diff --git a/pretyping/inductiveops.ml b/pretyping/inductiveops.ml
index fb180b8b7..bb38c72f2 100644
--- a/pretyping/inductiveops.ml
+++ b/pretyping/inductiveops.ml
@@ -12,7 +12,6 @@ open Names
open Univ
open Term
open Vars
-open Context
open Termops
open Declarations
open Declareops
@@ -142,12 +141,12 @@ let constructor_nallargs_env env ((kn,i),j) =
let constructor_nalldecls (indsp,j) = (* TOCHANGE en decls *)
let (mib,mip) = Global.lookup_inductive indsp in
- mip.mind_consnrealdecls.(j-1) + rel_context_length (mib.mind_params_ctxt)
+ mip.mind_consnrealdecls.(j-1) + Context.Rel.length (mib.mind_params_ctxt)
let constructor_nalldecls_env env ((kn,i),j) = (* TOCHANGE en decls *)
let mib = Environ.lookup_mind kn env in
let mip = mib.mind_packets.(i) in
- mip.mind_consnrealdecls.(j-1) + rel_context_length (mib.mind_params_ctxt)
+ mip.mind_consnrealdecls.(j-1) + Context.Rel.length (mib.mind_params_ctxt)
(* Arity of constructors excluding params, excluding local defs *)
@@ -213,21 +212,21 @@ let inductive_nparams_env env ind =
let inductive_nparamdecls ind =
let (mib,mip) = Global.lookup_inductive ind in
- rel_context_length mib.mind_params_ctxt
+ Context.Rel.length mib.mind_params_ctxt
let inductive_nparamdecls_env env ind =
let (mib,mip) = Inductive.lookup_mind_specif env ind in
- rel_context_length mib.mind_params_ctxt
+ Context.Rel.length mib.mind_params_ctxt
(* Full length of arity (with local defs) *)
let inductive_nalldecls ind =
let (mib,mip) = Global.lookup_inductive ind in
- rel_context_length (mib.mind_params_ctxt) + mip.mind_nrealdecls
+ Context.Rel.length (mib.mind_params_ctxt) + mip.mind_nrealdecls
let inductive_nalldecls_env env ind =
let (mib,mip) = Inductive.lookup_mind_specif env ind in
- rel_context_length (mib.mind_params_ctxt) + mip.mind_nrealdecls
+ Context.Rel.length (mib.mind_params_ctxt) + mip.mind_nrealdecls
(* Others *)
@@ -249,13 +248,13 @@ let inductive_alldecls_env env (ind,u) =
let constructor_has_local_defs (indsp,j) =
let (mib,mip) = Global.lookup_inductive indsp in
- let l1 = mip.mind_consnrealdecls.(j-1) + rel_context_length (mib.mind_params_ctxt) in
+ let l1 = mip.mind_consnrealdecls.(j-1) + Context.Rel.length (mib.mind_params_ctxt) in
let l2 = recarg_length mip.mind_recargs j + mib.mind_nparams in
not (Int.equal l1 l2)
let inductive_has_local_defs ind =
let (mib,mip) = Global.lookup_inductive ind in
- let l1 = rel_context_length (mib.mind_params_ctxt) + mip.mind_nrealdecls in
+ let l1 = Context.Rel.length (mib.mind_params_ctxt) + mip.mind_nrealdecls in
let l2 = mib.mind_nparams + mip.mind_nrealargs in
not (Int.equal l1 l2)
@@ -273,11 +272,11 @@ let projection_nparams p = projection_nparams_env (Global.env ()) p
let make_case_info env ind style =
let (mib,mip) = Inductive.lookup_mind_specif env ind in
let ind_tags =
- rel_context_tags (List.firstn mip.mind_nrealdecls mip.mind_arity_ctxt) in
+ Context.Rel.to_tags (List.firstn mip.mind_nrealdecls mip.mind_arity_ctxt) in
let cstr_tags =
Array.map2 (fun c n ->
let d,_ = decompose_prod_assum c in
- rel_context_tags (List.firstn n d))
+ Context.Rel.to_tags (List.firstn n d))
mip.mind_nf_lc mip.mind_consnrealdecls in
let print_info = { ind_tags; cstr_tags; style } in
{ ci_ind = ind;
@@ -292,7 +291,7 @@ type constructor_summary = {
cs_cstr : pconstructor;
cs_params : constr list;
cs_nargs : int;
- cs_args : rel_context;
+ cs_args : Context.Rel.t;
cs_concl_realargs : constr array
}
@@ -303,21 +302,15 @@ let lift_constructor n cs = {
cs_args = lift_rel_context n cs.cs_args;
cs_concl_realargs = Array.map (liftn n (cs.cs_nargs+1)) cs.cs_concl_realargs
}
-(* Accept less parameters than in the signature *)
-
-let instantiate_params t args sign =
- let rec inst s t = function
- | ((_,None,_)::ctxt,a::args) ->
- (match kind_of_term t with
- | Prod(_,_,t) -> inst (a::s) t (ctxt,args)
- | _ -> anomaly ~label:"instantiate_params" (Pp.str "type, ctxt and args mismatch"))
- | ((_,(Some b),_)::ctxt,args) ->
- (match kind_of_term t with
- | LetIn(_,_,_,t) -> inst ((substl s b)::s) t (ctxt,args)
- | _ -> anomaly ~label:"instantiate_params" (Pp.str "type, ctxt and args mismatch"))
- | _, [] -> substl s t
- | _ -> anomaly ~label:"instantiate_params" (Pp.str "type, ctxt and args mismatch")
- in inst [] t (List.rev sign,args)
+
+(* Accept either all parameters or only recursively uniform ones *)
+let instantiate_params t params sign =
+ let nnonrecpar = Context.Rel.nhyps sign - List.length params in
+ (* Adjust the signature if recursively non-uniform parameters are not here *)
+ let _,sign = context_chop nnonrecpar sign in
+ let _,t = decompose_prod_n_assum (Context.Rel.length sign) t in
+ let subst = subst_of_rel_context_instance sign params in
+ substl subst t
let get_constructor ((ind,u as indu),mib,mip,params) j =
assert (j <= Array.length mip.mind_consnames);
@@ -329,7 +322,7 @@ let get_constructor ((ind,u as indu),mib,mip,params) j =
let vargs = List.skipn (List.length params) allargs in
{ cs_cstr = (ith_constructor_of_inductive ind j,u);
cs_params = params;
- cs_nargs = rel_context_length args;
+ cs_nargs = Context.Rel.length args;
cs_args = args;
cs_concl_realargs = Array.of_list vargs }
@@ -354,14 +347,6 @@ let substnl_rel_context subst n sign =
let substl_rel_context subst = substnl_rel_context subst 0
-let instantiate_context sign args =
- let rec aux subst = function
- | (_,None,_)::sign, a::args -> aux (a::subst) (sign,args)
- | (_,Some b,_)::sign, args -> aux (substl subst b::subst) (sign,args)
- | [], [] -> subst
- | _ -> anomaly (Pp.str "Signature/instance mismatch in inductive family")
- in aux [] (List.rev sign,args)
-
let get_arity env ((ind,u),params) =
let (mib,mip) = Inductive.lookup_mind_specif env ind in
let parsign =
@@ -379,7 +364,7 @@ let get_arity env ((ind,u),params) =
let parsign = Vars.subst_instance_context u parsign in
let arproperlength = List.length mip.mind_arity_ctxt - List.length parsign in
let arsign,_ = List.chop arproperlength mip.mind_arity_ctxt in
- let subst = instantiate_context parsign params in
+ let subst = subst_of_rel_context_instance parsign params in
let arsign = Vars.subst_instance_context u arsign in
(substl_rel_context subst arsign, Inductive.inductive_sort_family mip)
@@ -388,14 +373,14 @@ let build_dependent_constructor cs =
applist
(mkConstructU cs.cs_cstr,
(List.map (lift cs.cs_nargs) cs.cs_params)
- @(extended_rel_list 0 cs.cs_args))
+ @(Context.Rel.to_extended_list 0 cs.cs_args))
let build_dependent_inductive env ((ind, params) as indf) =
let arsign,_ = get_arity env indf in
let nrealargs = List.length arsign in
applist
(mkIndU ind,
- (List.map (lift nrealargs) params)@(extended_rel_list 0 arsign))
+ (List.map (lift nrealargs) params)@(Context.Rel.to_extended_list 0 arsign))
(* builds the arity of an elimination predicate in sort [s] *)
@@ -430,12 +415,15 @@ let extract_mrectype t =
| Ind ind -> (ind, l)
| _ -> raise Not_found
-let find_mrectype env sigma c =
- let (t, l) = decompose_app (whd_betadeltaiota env sigma c) in
+let find_mrectype_vect env sigma c =
+ let (t, l) = decompose_appvect (whd_betadeltaiota env sigma c) in
match kind_of_term t with
| Ind ind -> (ind, l)
| _ -> raise Not_found
+let find_mrectype env sigma c =
+ let (ind, v) = find_mrectype_vect env sigma c in (ind, Array.to_list v)
+
let find_rectype env sigma c =
let (t, l) = decompose_app (whd_betadeltaiota env sigma c) in
match kind_of_term t with
@@ -517,7 +505,7 @@ let set_pattern_names env ind brv =
let arities =
Array.map
(fun c ->
- rel_context_length ((prod_assum c)) -
+ Context.Rel.length ((prod_assum c)) -
mib.mind_nparams)
mip.mind_nf_lc in
Array.map2 (set_names env) arities brv
@@ -529,7 +517,7 @@ let type_case_branches_with_names env indspec p c =
let (params,realargs) = List.chop nparams args in
let lbrty = Inductive.build_branches_type ind specif params p in
(* Build case type *)
- let conclty = Reduction.betazeta_appvect (mip.mind_nrealdecls+1) p (Array.of_list (realargs@[c])) in
+ let conclty = lambda_appvect_assum (mip.mind_nrealdecls+1) p (Array.of_list (realargs@[c])) in
(* Adjust names *)
if is_elim_predicate_explicitly_dependent env p (ind,params) then
(set_pattern_names env (fst ind) lbrty, conclty)
diff --git a/pretyping/inductiveops.mli b/pretyping/inductiveops.mli
index 7cd2ff2af..d25f8a837 100644
--- a/pretyping/inductiveops.mli
+++ b/pretyping/inductiveops.mli
@@ -8,7 +8,6 @@
open Names
open Term
-open Context
open Declarations
open Environ
open Evd
@@ -92,12 +91,12 @@ val inductive_nparamdecls : inductive -> int
val inductive_nparamdecls_env : env -> inductive -> int
(** @return params context *)
-val inductive_paramdecls : pinductive -> rel_context
-val inductive_paramdecls_env : env -> pinductive -> rel_context
+val inductive_paramdecls : pinductive -> Context.Rel.t
+val inductive_paramdecls_env : env -> pinductive -> Context.Rel.t
(** @return full arity context, hence with letin *)
-val inductive_alldecls : pinductive -> rel_context
-val inductive_alldecls_env : env -> pinductive -> rel_context
+val inductive_alldecls : pinductive -> Context.Rel.t
+val inductive_alldecls_env : env -> pinductive -> Context.Rel.t
(** {7 Extract information from a constructor name} *)
@@ -133,9 +132,9 @@ val type_of_projection_knowing_arg : env -> evar_map -> Projection.t ->
type constructor_summary = {
cs_cstr : pconstructor; (* internal name of the constructor plus universes *)
- cs_params : constr list; (* parameters of the constructor in current ctx *)
- cs_nargs : int; (* length of arguments signature (letin included) *)
- cs_args : rel_context; (* signature of the arguments (letin included) *)
+ cs_params : constr list; (* parameters of the constructor in current ctx *)
+ cs_nargs : int; (* length of arguments signature (letin included) *)
+ cs_args : Context.Rel.t; (* signature of the arguments (letin included) *)
cs_concl_realargs : constr array; (* actual realargs in the concl of cstr *)
}
val lift_constructor : int -> constructor_summary -> constructor_summary
@@ -148,17 +147,18 @@ val get_projections : env -> inductive_family -> constant array option
(** [get_arity] returns the arity of the inductive family instantiated
with the parameters; if recursively non-uniform parameters are not
part of the inductive family, they appears in the arity *)
-val get_arity : env -> inductive_family -> rel_context * sorts_family
+val get_arity : env -> inductive_family -> Context.Rel.t * sorts_family
val build_dependent_constructor : constructor_summary -> constr
val build_dependent_inductive : env -> inductive_family -> constr
-val make_arity_signature : env -> bool -> inductive_family -> rel_context
+val make_arity_signature : env -> bool -> inductive_family -> Context.Rel.t
val make_arity : env -> bool -> inductive_family -> sorts -> types
val build_branch_type : env -> bool -> constr -> constructor_summary -> types
(** Raise [Not_found] if not given a valid inductive type *)
val extract_mrectype : constr -> pinductive * constr list
val find_mrectype : env -> evar_map -> types -> pinductive * constr list
+val find_mrectype_vect : env -> evar_map -> types -> pinductive * constr array
val find_rectype : env -> evar_map -> types -> inductive_type
val find_inductive : env -> evar_map -> types -> pinductive * constr list
val find_coinductive : env -> evar_map -> types -> pinductive * constr list
diff --git a/pretyping/nativenorm.mli b/pretyping/nativenorm.mli
index bbda55f48..0b1ce8e51 100644
--- a/pretyping/nativenorm.mli
+++ b/pretyping/nativenorm.mli
@@ -8,7 +8,6 @@
open Term
open Environ
open Evd
-open Nativelambda
(** This module implements normalization by evaluation to OCaml code *)
diff --git a/pretyping/patternops.mli b/pretyping/patternops.mli
index 5f877814d..1f63565d6 100644
--- a/pretyping/patternops.mli
+++ b/pretyping/patternops.mli
@@ -6,7 +6,6 @@
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
-open Context
open Term
open Globnames
open Glob_term
diff --git a/pretyping/pretyping.ml b/pretyping/pretyping.ml
index ac0104d9f..6166fffbc 100644
--- a/pretyping/pretyping.ml
+++ b/pretyping/pretyping.ml
@@ -28,7 +28,6 @@ open Names
open Evd
open Term
open Vars
-open Context
open Termops
open Reductionops
open Environ
@@ -47,7 +46,7 @@ open Misctypes
type typing_constraint = OfType of types | IsType | WithoutTypeConstraint
type var_map = constr_under_binders Id.Map.t
type uconstr_var_map = Glob_term.closed_glob_constr Id.Map.t
-type unbound_ltac_var_map = Genarg.tlevel Genarg.generic_argument Id.Map.t
+type unbound_ltac_var_map = Genarg.Val.t Id.Map.t
type ltac_var_map = {
ltac_constrs : var_map;
ltac_uconstrs : uconstr_var_map;
@@ -95,10 +94,6 @@ let search_guard loc env possible_indexes fixdefs =
user_err_loc (loc,"search_guard", Pp.str errmsg)
with Found indexes -> indexes)
-(* To embed constr in glob_constr *)
-let ((constr_in : constr -> Dyn.t),
- (constr_out : Dyn.t -> constr)) = Dyn.create "constr"
-
(* To force universe name declaration before use *)
let strict_universe_declarations = ref true
@@ -134,7 +129,7 @@ let interp_universe_level_name evd (loc,s) =
let level = Univ.Level.make dp num in
let evd =
try Evd.add_global_univ evd level
- with Univ.AlreadyDeclared -> evd
+ with UGraph.AlreadyDeclared -> evd
in evd, level
else
try
@@ -321,7 +316,7 @@ let ltac_interp_name_env k0 lvar env =
specification of pretype which accepts to start with a non empty
rel_context) *)
(* tail is the part of the env enriched by pretyping *)
- let n = rel_context_length (rel_context env) - k0 in
+ let n = Context.Rel.length (rel_context env) - k0 in
let ctxt,_ = List.chop n (rel_context env) in
let env = pop_rel_context n env in
let ctxt = List.map (fun (na,c,t) -> ltac_interp_name lvar na,c,t) ctxt in
@@ -454,26 +449,12 @@ let new_type_evar env evdref loc =
univ_flexible_alg ~src:(loc,Evar_kinds.InternalHole)) evdref
in e
-let get_projection env cst =
- let cb = lookup_constant cst env in
- match cb.Declarations.const_proj with
- | Some {Declarations.proj_ind = mind; proj_npars = n;
- proj_arg = m; proj_type = ty} ->
- (cst,mind,n,m,ty)
- | None -> raise Not_found
-
let (f_genarg_interp, genarg_interp_hook) = Hook.make ()
(* [pretype tycon env evdref lvar lmeta cstr] attempts to type [cstr] *)
(* in environment [env], with existential variables [evdref] and *)
(* the type constraint tycon *)
-let is_GHole = function
- | GHole _ -> true
- | _ -> false
-
-let evars = ref Id.Map.empty
-
let rec pretype k0 resolve_tc (tycon : type_constraint) env evdref (lvar : ltac_var_map) t =
let inh_conv_coerce_to_tycon = inh_conv_coerce_to_tycon resolve_tc in
let pretype_type = pretype_type k0 resolve_tc in
@@ -539,14 +520,14 @@ let rec pretype k0 resolve_tc (tycon : type_constraint) env evdref (lvar : ltac_
let ty' = pretype_type empty_valcon env evdref lvar ty in
let dcl = (na,None,ty'.utj_val) in
let dcl' = (ltac_interp_name lvar na,None,ty'.utj_val) in
- type_bl (push_rel dcl env) (add_rel_decl dcl' ctxt) bl
+ type_bl (push_rel dcl env) (Context.Rel.add dcl' ctxt) bl
| (na,bk,Some bd,ty)::bl ->
let ty' = pretype_type empty_valcon env evdref lvar ty in
let bd' = pretype (mk_tycon ty'.utj_val) env evdref lvar bd in
let dcl = (na,Some bd'.uj_val,ty'.utj_val) in
let dcl' = (ltac_interp_name lvar na,Some bd'.uj_val,ty'.utj_val) in
- type_bl (push_rel dcl env) (add_rel_decl dcl' ctxt) bl in
- let ctxtv = Array.map (type_bl env empty_rel_context) bl in
+ type_bl (push_rel dcl env) (Context.Rel.add dcl' ctxt) bl in
+ let ctxtv = Array.map (type_bl env Context.Rel.empty) bl in
let larj =
Array.map2
(fun e ar ->
@@ -573,7 +554,7 @@ let rec pretype k0 resolve_tc (tycon : type_constraint) env evdref (lvar : ltac_
(* we lift nbfix times the type in tycon, because of
* the nbfix variables pushed to newenv *)
let (ctxt,ty) =
- decompose_prod_n_assum (rel_context_length ctxt)
+ decompose_prod_n_assum (Context.Rel.length ctxt)
(lift nbfix ftys.(i)) in
let nenv = push_rel_context ctxt newenv in
let j = pretype (mk_tycon ty) nenv evdref lvar def in
@@ -894,7 +875,7 @@ let rec pretype k0 resolve_tc (tycon : type_constraint) env evdref (lvar : ltac_
let pred = nf_evar !evdref pred in
let p = nf_evar !evdref p in
let f cs b =
- let n = rel_context_length cs.cs_args in
+ let n = Context.Rel.length cs.cs_args in
let pi = lift n pred in (* liftn n 2 pred ? *)
let pi = beta_applist (pi, [build_dependent_constructor cs]) in
let csgn =
@@ -1027,7 +1008,7 @@ and pretype_type k0 resolve_tc valcon env evdref lvar = function
let ise_pretype_gen flags env sigma lvar kind c =
let evdref = ref sigma in
- let k0 = rel_context_length (rel_context env) in
+ let k0 = Context.Rel.length (rel_context env) in
let c' = match kind with
| WithoutTypeConstraint ->
(pretype k0 flags.use_typeclasses empty_tycon env evdref lvar c).uj_val
@@ -1069,7 +1050,7 @@ let on_judgment f j =
let understand_judgment env sigma c =
let evdref = ref sigma in
- let k0 = rel_context_length (rel_context env) in
+ let k0 = Context.Rel.length (rel_context env) in
let j = pretype k0 true empty_tycon env evdref empty_lvar c in
let j = on_judgment (fun c ->
let evd, c = process_inference_flags all_and_fail_flags env sigma (!evdref,c) in
@@ -1077,7 +1058,7 @@ let understand_judgment env sigma c =
in j, Evd.evar_universe_context !evdref
let understand_judgment_tcc env evdref c =
- let k0 = rel_context_length (rel_context env) in
+ let k0 = Context.Rel.length (rel_context env) in
let j = pretype k0 true empty_tycon env evdref empty_lvar c in
on_judgment (fun c ->
let (evd,c) = process_inference_flags all_no_fail_flags env Evd.empty (!evdref,c) in
diff --git a/pretyping/pretyping.mli b/pretyping/pretyping.mli
index ac899a786..bfb4e7325 100644
--- a/pretyping/pretyping.mli
+++ b/pretyping/pretyping.mli
@@ -29,7 +29,7 @@ type typing_constraint = OfType of types | IsType | WithoutTypeConstraint
type var_map = Pattern.constr_under_binders Id.Map.t
type uconstr_var_map = Glob_term.closed_glob_constr Id.Map.t
-type unbound_ltac_var_map = Genarg.tlevel Genarg.generic_argument Id.Map.t
+type unbound_ltac_var_map = Genarg.Val.t Id.Map.t
type ltac_var_map = {
ltac_constrs : var_map;
@@ -148,12 +148,9 @@ val ise_pretype_gen :
(** To embed constr in glob_constr *)
-val constr_in : constr -> Dyn.t
-val constr_out : Dyn.t -> constr
-
val interp_sort : evar_map -> glob_sort -> evar_map * sorts
val interp_elimination_sort : glob_sort -> sorts_family
val genarg_interp_hook :
- (types -> env -> evar_map -> Genarg.typed_generic_argument Id.Map.t ->
+ (types -> env -> evar_map -> unbound_ltac_var_map ->
Genarg.glob_generic_argument -> constr * evar_map) Hook.t
diff --git a/pretyping/pretyping.mllib b/pretyping/pretyping.mllib
index a644e3d10..b59589bda 100644
--- a/pretyping/pretyping.mllib
+++ b/pretyping/pretyping.mllib
@@ -1,7 +1,4 @@
Locusops
-Termops
-Namegen
-Evd
Reductionops
Inductiveops
Vnorm
diff --git a/pretyping/recordops.ml b/pretyping/recordops.ml
index 560beb6f1..6499ddd53 100644
--- a/pretyping/recordops.ml
+++ b/pretyping/recordops.ml
@@ -299,7 +299,7 @@ let check_and_decompose_canonical_structure ref =
| Construct ((indsp,1),u) -> indsp
| _ -> error_not_structure ref in
let s = try lookup_structure indsp with Not_found -> error_not_structure ref in
- let ntrue_projs = List.length (List.filter (fun (_, x) -> x) s.s_PROJKIND) 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;
(sp,indsp)
diff --git a/pretyping/reductionops.ml b/pretyping/reductionops.ml
index 13b7fb407..5e21154a6 100644
--- a/pretyping/reductionops.ml
+++ b/pretyping/reductionops.ml
@@ -11,7 +11,6 @@ open Util
open Names
open Term
open Vars
-open Context
open Termops
open Univ
open Evd
@@ -1256,28 +1255,26 @@ let report_anomaly _ =
let e = Errors.push e in
iraise e
-let test_trans_conversion (f: ?l2r:bool-> ?evars:'a->'b) reds env sigma x y =
+let test_trans_conversion (f: constr Reduction.extended_conversion_function) reds env sigma x y =
try
let evars ev = safe_evar_value sigma ev in
- let _ = f ~evars reds env (Evd.universes sigma) x y in
+ let _ = f ~reds env ~evars:(evars, Evd.universes sigma) x y in
true
with Reduction.NotConvertible -> false
| e when is_anomaly e -> report_anomaly e
-let is_trans_conv reds env sigma = test_trans_conversion Reduction.trans_conv_universes reds env sigma
-let is_trans_conv_leq reds env sigma = test_trans_conversion Reduction.trans_conv_leq_universes reds env sigma
-let is_trans_fconv = function Reduction.CONV -> is_trans_conv | Reduction.CUMUL -> is_trans_conv_leq
-
-let is_conv = is_trans_conv full_transparent_state
-let is_conv_leq = is_trans_conv_leq full_transparent_state
-let is_fconv = function | Reduction.CONV -> is_conv | Reduction.CUMUL -> is_conv_leq
+let is_conv ?(reds=full_transparent_state) env sigma = test_trans_conversion Reduction.conv reds env sigma
+let is_conv_leq ?(reds=full_transparent_state) env sigma = test_trans_conversion Reduction.conv_leq reds env sigma
+let is_fconv ?(reds=full_transparent_state) = function
+ | Reduction.CONV -> is_conv ~reds
+ | Reduction.CUMUL -> is_conv_leq ~reds
let check_conv ?(pb=Reduction.CUMUL) ?(ts=full_transparent_state) env sigma x y =
let f = match pb with
- | Reduction.CONV -> Reduction.trans_conv_universes
- | Reduction.CUMUL -> Reduction.trans_conv_leq_universes
+ | Reduction.CONV -> Reduction.conv
+ | Reduction.CUMUL -> Reduction.conv_leq
in
- try f ~evars:(safe_evar_value sigma) ts env (Evd.universes sigma) x y; true
+ try f ~reds:ts env ~evars:(safe_evar_value sigma, Evd.universes sigma) x y; true
with Reduction.NotConvertible -> false
| Univ.UniverseInconsistency _ -> false
| e when is_anomaly e -> report_anomaly e
@@ -1299,18 +1296,21 @@ let sigma_univ_state =
let infer_conv_gen conv_fun ?(catch_incon=true) ?(pb=Reduction.CUMUL)
?(ts=full_transparent_state) env sigma x y =
- try
+ try
+ let fold cstr sigma =
+ try Some (Evd.add_universe_constraints sigma cstr)
+ with Univ.UniverseInconsistency _ | Evd.UniversesDiffer -> None
+ in
let b, sigma =
- let b, cstrs =
+ let ans =
if pb == Reduction.CUMUL then
- Universes.leq_constr_univs_infer (Evd.universes sigma) x y
+ Universes.leq_constr_univs_infer (Evd.universes sigma) fold x y sigma
else
- Universes.eq_constr_univs_infer (Evd.universes sigma) x y
+ Universes.eq_constr_univs_infer (Evd.universes sigma) fold x y sigma
in
- if b then
- try true, Evd.add_universe_constraints sigma cstrs
- with Univ.UniverseInconsistency _ | Evd.UniversesDiffer -> false, sigma
- else false, sigma
+ match ans with
+ | None -> false, sigma
+ | Some sigma -> true, sigma
in
if b then sigma, true
else
@@ -1465,17 +1465,17 @@ let splay_prod_assum env sigma =
match kind_of_term t with
| Prod (x,t,c) ->
prodec_rec (push_rel (x,None,t) env)
- (add_rel_decl (x, None, t) l) c
+ (Context.Rel.add (x, None, t) l) c
| LetIn (x,b,t,c) ->
prodec_rec (push_rel (x, Some b, t) env)
- (add_rel_decl (x, Some b, t) l) c
+ (Context.Rel.add (x, Some b, t) l) c
| Cast (c,_,_) -> prodec_rec env l c
| _ ->
let t' = whd_betadeltaiota env sigma t in
if Term.eq_constr t t' then l,t
else prodec_rec env l t'
in
- prodec_rec env empty_rel_context
+ prodec_rec env Context.Rel.empty
let splay_arity env sigma c =
let l, c = splay_prod env sigma c in
@@ -1490,20 +1490,20 @@ let splay_prod_n env sigma n =
match kind_of_term (whd_betadeltaiota env sigma c) with
| Prod (n,a,c0) ->
decrec (push_rel (n,None,a) env)
- (m-1) (add_rel_decl (n,None,a) ln) c0
+ (m-1) (Context.Rel.add (n,None,a) ln) c0
| _ -> invalid_arg "splay_prod_n"
in
- decrec env n empty_rel_context
+ decrec env n Context.Rel.empty
let splay_lam_n env sigma n =
let rec decrec env m ln c = if Int.equal m 0 then (ln,c) else
match kind_of_term (whd_betadeltaiota env sigma c) with
| Lambda (n,a,c0) ->
decrec (push_rel (n,None,a) env)
- (m-1) (add_rel_decl (n,None,a) ln) c0
+ (m-1) (Context.Rel.add (n,None,a) ln) c0
| _ -> invalid_arg "splay_lam_n"
in
- decrec env n empty_rel_context
+ decrec env n Context.Rel.empty
let is_sort env sigma t =
match kind_of_term (whd_betadeltaiota env sigma t) with
diff --git a/pretyping/reductionops.mli b/pretyping/reductionops.mli
index aea0a9ae2..e65ab83b2 100644
--- a/pretyping/reductionops.mli
+++ b/pretyping/reductionops.mli
@@ -8,7 +8,6 @@
open Names
open Term
-open Context
open Univ
open Evd
open Environ
@@ -218,11 +217,10 @@ val splay_prod : env -> evar_map -> constr -> (Name.t * constr) list * constr
val splay_lam : env -> evar_map -> constr -> (Name.t * constr) list * constr
val splay_arity : env -> evar_map -> constr -> (Name.t * constr) list * sorts
val sort_of_arity : env -> evar_map -> constr -> sorts
-val splay_prod_n : env -> evar_map -> int -> constr -> rel_context * constr
-val splay_lam_n : env -> evar_map -> int -> constr -> rel_context * constr
+val splay_prod_n : env -> evar_map -> int -> constr -> Context.Rel.t * constr
+val splay_lam_n : env -> evar_map -> int -> constr -> Context.Rel.t * constr
val splay_prod_assum :
- env -> evar_map -> constr -> rel_context * constr
-val is_sort : env -> evar_map -> types -> bool
+ env -> evar_map -> constr -> Context.Rel.t * constr
type 'a miota_args = {
mP : constr; (** the result type *)
@@ -251,13 +249,9 @@ type conversion_test = constraints -> constraints
val pb_is_equal : conv_pb -> bool
val pb_equal : conv_pb -> conv_pb
-val is_conv : env -> evar_map -> constr -> constr -> bool
-val is_conv_leq : env -> evar_map -> constr -> constr -> bool
-val is_fconv : conv_pb -> env -> evar_map -> constr -> constr -> bool
-
-val is_trans_conv : transparent_state -> env -> evar_map -> constr -> constr -> bool
-val is_trans_conv_leq : transparent_state -> env -> evar_map -> constr -> constr -> bool
-val is_trans_fconv : conv_pb -> transparent_state -> env -> evar_map -> constr -> constr -> bool
+val is_conv : ?reds:transparent_state -> env -> evar_map -> constr -> constr -> bool
+val is_conv_leq : ?reds:transparent_state -> env -> evar_map -> constr -> constr -> bool
+val is_fconv : ?reds:transparent_state -> conv_pb -> env -> evar_map -> constr -> constr -> bool
(** [check_conv] Checks universe constraints only.
pb defaults to CUMUL and ts to a full transparent state.
diff --git a/pretyping/retyping.mli b/pretyping/retyping.mli
index 37cec0c63..e4cca2679 100644
--- a/pretyping/retyping.mli
+++ b/pretyping/retyping.mli
@@ -8,7 +8,6 @@
open Term
open Evd
-open Context
open Environ
(** This family of functions assumes its constr argument is known to be
@@ -44,6 +43,6 @@ val type_of_global_reference_knowing_parameters : env -> evar_map -> constr ->
val type_of_global_reference_knowing_conclusion :
env -> evar_map -> constr -> types -> evar_map * types
-val sorts_of_context : env -> evar_map -> rel_context -> sorts list
+val sorts_of_context : env -> evar_map -> Context.Rel.t -> sorts list
val expand_projection : env -> evar_map -> Names.projection -> constr -> constr list -> constr
diff --git a/pretyping/tacred.ml b/pretyping/tacred.ml
index 7c4f28cac..bd46911c9 100644
--- a/pretyping/tacred.ml
+++ b/pretyping/tacred.ml
@@ -940,8 +940,6 @@ let matches_head env sigma c t =
| Proj (p, _) -> Constr_matching.matches env sigma c (mkConst (Projection.constant p))
| _ -> raise Constr_matching.PatternMatchingFailure
-let is_pattern_meta = function Pattern.PMeta _ -> true | _ -> false
-
(** FIXME: Specific function to handle projections: it ignores what happens on the
parameters. This is a temporary fix while rewrite etc... are not up to equivalence
of the projection and its eta expanded form.
@@ -1055,10 +1053,6 @@ let unfold env sigma name =
else
error (string_of_evaluable_ref env name^" is opaque.")
-let is_projection env = function
- | EvalVarRef _ -> false
- | EvalConstRef c -> Environ.is_projection c env
-
(* [unfoldoccs : (readable_constraints -> (int list * full_path) -> constr -> constr)]
* Unfolds the constant name in a term c following a list of occurrences occl.
* at the occurrences of occ_list. If occ_list is empty, unfold all occurrences.
diff --git a/pretyping/typeclasses.ml b/pretyping/typeclasses.ml
index 3be98a1ae..3d6196c35 100644
--- a/pretyping/typeclasses.ml
+++ b/pretyping/typeclasses.ml
@@ -12,7 +12,6 @@ open Globnames
open Decl_kinds
open Term
open Vars
-open Context
open Evd
open Util
open Typeclasses_errors
@@ -59,10 +58,10 @@ type typeclass = {
cl_impl : global_reference;
(* Context in which the definitions are typed. Includes both typeclass parameters and superclasses. *)
- cl_context : (global_reference * bool) option list * rel_context;
+ cl_context : (global_reference * bool) option list * Context.Rel.t;
(* Context of definitions and properties on defs, will not be shared *)
- cl_props : rel_context;
+ cl_props : Context.Rel.t;
(* The method implementaions as projections. *)
cl_projs : (Name.t * (direction * int option) option * constant option) list;
@@ -127,7 +126,7 @@ let typeclass_univ_instance (cl,u') =
in Array.fold_left2 (fun subst u u' -> Univ.LMap.add u u' subst)
Univ.LMap.empty (Univ.Instance.to_array u) (Univ.Instance.to_array u')
in
- let subst_ctx = Context.map_rel_context (subst_univs_level_constr subst) in
+ let subst_ctx = Context.Rel.map (subst_univs_level_constr subst) in
{ cl with cl_context = fst cl.cl_context, subst_ctx (snd cl.cl_context);
cl_props = subst_ctx cl.cl_props}, u'
@@ -204,7 +203,7 @@ let discharge_class (_,cl) =
(decl :: ctx', n :: subst)
) ctx ([], []) in
let discharge_rel_context subst n rel =
- let rel = map_rel_context (Cooking.expmod_constr repl) rel in
+ let rel = Context.Rel.map (Cooking.expmod_constr repl) rel in
let ctx, _ =
List.fold_right
(fun (id, b, t) (ctx, k) ->
@@ -287,7 +286,7 @@ let build_subclasses ~check env sigma glob pri =
| None -> []
| Some (rels, ((tc,u), args)) ->
let instapp =
- Reductionops.whd_beta sigma (appvectc c (Termops.extended_rel_vect 0 rels))
+ Reductionops.whd_beta sigma (appvectc c (Context.Rel.to_extended_vect 0 rels))
in
let projargs = Array.of_list (args @ [instapp]) in
let projs = List.map_filter
@@ -436,7 +435,7 @@ let instance_constructor (cl,u) args =
| None -> true
| Some _ -> false
in
- let lenpars = List.length (List.filter filter (snd cl.cl_context)) in
+ let lenpars = List.count filter (snd cl.cl_context) in
let pars = fst (List.chop lenpars args) in
match cl.cl_impl with
| IndRef ind ->
diff --git a/pretyping/typeclasses.mli b/pretyping/typeclasses.mli
index 9e018f616..7bb0ef3ab 100644
--- a/pretyping/typeclasses.mli
+++ b/pretyping/typeclasses.mli
@@ -9,7 +9,6 @@
open Names
open Globnames
open Term
-open Context
open Evd
open Environ
@@ -24,10 +23,10 @@ type typeclass = {
(** Context in which the definitions are typed. Includes both typeclass parameters and superclasses.
The boolean indicates if the typeclass argument is a direct superclass and the global reference
gives a direct link to the class itself. *)
- cl_context : (global_reference * bool) option list * rel_context;
+ cl_context : (global_reference * bool) option list * Context.Rel.t;
(** Context of definitions and properties on defs, will not be shared *)
- cl_props : rel_context;
+ cl_props : Context.Rel.t;
(** The methods implementations of the typeclass as projections.
Some may be undefinable due to sorting restrictions or simply undefined if
@@ -68,7 +67,7 @@ val dest_class_app : env -> constr -> typeclass puniverses * constr list
val typeclass_univ_instance : typeclass puniverses -> typeclass puniverses
(** Just return None if not a class *)
-val class_of_constr : constr -> (rel_context * (typeclass puniverses * constr list)) option
+val class_of_constr : constr -> (Context.Rel.t * (typeclass puniverses * constr list)) option
val instance_impl : instance -> global_reference
diff --git a/pretyping/typeclasses_errors.ml b/pretyping/typeclasses_errors.ml
index a0f631984..b1dfb19a0 100644
--- a/pretyping/typeclasses_errors.ml
+++ b/pretyping/typeclasses_errors.ml
@@ -9,7 +9,6 @@
(*i*)
open Names
open Term
-open Context
open Environ
open Constrexpr
open Globnames
@@ -20,7 +19,7 @@ type contexts = Parameters | Properties
type typeclass_error =
| NotAClass of constr
| UnboundMethod of global_reference * Id.t Loc.located (* Class name, method *)
- | MismatchedContextInstance of contexts * constr_expr list * rel_context (* found, expected *)
+ | MismatchedContextInstance of contexts * constr_expr list * Context.Rel.t (* found, expected *)
exception TypeClassError of env * typeclass_error
diff --git a/pretyping/typeclasses_errors.mli b/pretyping/typeclasses_errors.mli
index 7facb06f0..ee76f6383 100644
--- a/pretyping/typeclasses_errors.mli
+++ b/pretyping/typeclasses_errors.mli
@@ -9,7 +9,6 @@
open Loc
open Names
open Term
-open Context
open Environ
open Constrexpr
open Globnames
@@ -19,7 +18,7 @@ type contexts = Parameters | Properties
type typeclass_error =
| NotAClass of constr
| UnboundMethod of global_reference * Id.t located (** Class name, method *)
- | MismatchedContextInstance of contexts * constr_expr list * rel_context (** found, expected *)
+ | MismatchedContextInstance of contexts * constr_expr list * Context.Rel.t (** found, expected *)
exception TypeClassError of env * typeclass_error
@@ -27,5 +26,5 @@ val not_a_class : env -> constr -> 'a
val unbound_method : env -> global_reference -> Id.t located -> 'a
-val mismatched_ctx_inst : env -> contexts -> constr_expr list -> rel_context -> 'a
+val mismatched_ctx_inst : env -> contexts -> constr_expr list -> Context.Rel.t -> 'a
diff --git a/pretyping/typing.ml b/pretyping/typing.ml
index eb16628b1..fb0c49320 100644
--- a/pretyping/typing.ml
+++ b/pretyping/typing.ml
@@ -111,9 +111,8 @@ let e_type_case_branches env evdref (ind,largs) pj c =
let p = pj.uj_val in
let univ = e_is_correct_arity env evdref c pj ind specif params in
let lc = build_branches_type ind specif params p in
- let n = (snd specif).Declarations.mind_nrealargs in
- let ty =
- whd_betaiota !evdref (Reduction.betazeta_appvect (n+1) p (Array.of_list (realargs@[c]))) in
+ let n = (snd specif).Declarations.mind_nrealdecls in
+ let ty = whd_betaiota !evdref (lambda_applist_assum (n+1) p (realargs@[c])) in
(lc, ty, univ)
let e_judge_of_case env evdref ci pj cj lfj =
diff --git a/pretyping/unification.ml b/pretyping/unification.ml
index f97f6fbc5..b5e882bc4 100644
--- a/pretyping/unification.ml
+++ b/pretyping/unification.ml
@@ -27,6 +27,7 @@ open Recordops
open Locus
open Locusops
open Find_subterm
+open Sigma.Notations
let keyed_unification = ref (false)
let _ = Goptions.declare_bool_option {
@@ -107,7 +108,9 @@ let set_occurrences_of_last_arg args =
Some AllOccurrences :: List.tl (Array.map_to_list (fun _ -> None) args)
let abstract_list_all_with_dependencies env evd typ c l =
- let evd,ev = new_evar env evd typ in
+ let evd = Sigma.Unsafe.of_evar_map evd in
+ let Sigma (ev, evd, _) = new_evar env evd typ in
+ let evd = Sigma.to_evar_map evd in
let evd,ev' = evar_absorb_arguments env evd (destEvar ev) l in
let n = List.length l in
let argoccs = set_occurrences_of_last_arg (Array.sub (snd ev') 0 n) in
@@ -556,6 +559,19 @@ let isAllowedEvar flags c = match kind_of_term c with
| Evar (evk,_) -> not (Evar.Set.mem evk flags.frozen_evars)
| _ -> false
+
+let subst_defined_metas_evars (bl,el) c =
+ let rec substrec c = match kind_of_term c with
+ | Meta i ->
+ let select (j,_,_) = Int.equal i j in
+ substrec (pi2 (List.find select bl))
+ | Evar (evk,args) ->
+ let select (_,(evk',args'),_) = Evar.equal evk evk' && Array.equal Constr.equal args args' in
+ (try substrec (pi3 (List.find select el))
+ with Not_found -> map_constr substrec c)
+ | _ -> map_constr substrec c
+ in try Some (substrec c) with Not_found -> None
+
let check_compatibility env pbty flags (sigma,metasubst,evarsubst) tyM tyN =
match subst_defined_metas_evars (metasubst,[]) tyM with
| None -> sigma
@@ -1154,20 +1170,20 @@ let merge_instances env sigma flags st1 st2 c1 c2 =
* close it off. But this might not always work,
* since other metavars might also need to be resolved. *)
-let applyHead env evd n c =
- let rec apprec n c cty evd =
+let applyHead env (type r) (evd : r Sigma.t) n c =
+ let rec apprec : type s. _ -> _ -> _ -> (r, s) Sigma.le -> s Sigma.t -> (constr, r) Sigma.sigma =
+ fun n c cty p evd ->
if Int.equal n 0 then
- (evd, c)
+ Sigma (c, evd, p)
else
- match kind_of_term (whd_betadeltaiota env evd cty) with
+ match kind_of_term (whd_betadeltaiota env (Sigma.to_evar_map evd) cty) with
| Prod (_,c1,c2) ->
- let (evd',evar) =
- Evarutil.new_evar env evd ~src:(Loc.ghost,Evar_kinds.GoalEvar) c1 in
- apprec (n-1) (mkApp(c,[|evar|])) (subst1 evar c2) evd'
+ let Sigma (evar, evd', q) = Evarutil.new_evar env evd ~src:(Loc.ghost,Evar_kinds.GoalEvar) c1 in
+ apprec (n-1) (mkApp(c,[|evar|])) (subst1 evar c2) (p +> q) evd'
| _ -> error "Apply_Head_Then"
in
- apprec n c (Typing.unsafe_type_of env evd c) evd
-
+ apprec n c (Typing.unsafe_type_of env (Sigma.to_evar_map evd) c) Sigma.refl evd
+
let is_mimick_head ts f =
match kind_of_term f with
| Const (c,u) -> not (Closure.is_transparent_constant ts c)
@@ -1327,7 +1343,9 @@ let w_merge env with_types flags (evd,metas,evars) =
and mimick_undefined_evar evd flags hdc nargs sp =
let ev = Evd.find_undefined evd sp in
let sp_env = Global.env_of_context ev.evar_hyps in
- let (evd', c) = applyHead sp_env evd nargs hdc in
+ let evd = Sigma.Unsafe.of_evar_map evd in
+ let Sigma (c, evd', _) = applyHead sp_env evd nargs hdc in
+ let evd' = Sigma.to_evar_map evd' in
let (evd'',mc,ec) =
unify_0 sp_env evd' CUMUL flags
(get_type_of sp_env evd' c) ev.evar_concl in
@@ -1436,9 +1454,10 @@ let indirect_dependency d decls =
pi1 (List.hd (List.filter (fun (id,_,_) -> dependent_in_decl (mkVar id) d) decls))
let finish_evar_resolution ?(flags=Pretyping.all_and_fail_flags) env current_sigma (pending,c) =
+ let current_sigma = Sigma.to_evar_map current_sigma in
let sigma = Pretyping.solve_remaining_evars flags env current_sigma pending in
let sigma, subst = nf_univ_variables sigma in
- sigma, subst_univs_constr subst (nf_evar sigma c)
+ Sigma.Unsafe.of_pair (subst_univs_constr subst (nf_evar sigma c), sigma)
let default_matching_core_flags sigma =
let ts = Names.full_transparent_state in {
@@ -1565,7 +1584,7 @@ let make_abstraction_core name (test,out) env sigma c ty occs check_occs concl =
| AllOccurrences, InHyp as occ ->
let occ = if likefirst then LikeFirst else AtOccs occ in
let newdecl = replace_term_occ_decl_modulo occ test mkvarid d in
- if Context.eq_named_declaration d newdecl
+ if Context.Named.Declaration.equal d newdecl
&& not (indirectly_dependent c d depdecls)
then
if check_occs && not (in_every_hyp occs)
@@ -1589,7 +1608,11 @@ let make_abstraction_core name (test,out) env sigma c ty occs check_occs concl =
in
let lastlhyp =
if List.is_empty depdecls then None else Some (pi1(List.last depdecls)) in
- (id,sign,depdecls,lastlhyp,ccl,out test)
+ let res = match out test with
+ | None -> None
+ | Some (sigma, c) -> Some (Sigma.Unsafe.of_pair (c, sigma))
+ in
+ (id,sign,depdecls,lastlhyp,ccl,res)
with
SubtermUnificationError e ->
raise (PretypeError (env,sigma,CannotUnifyOccurrences e))
@@ -1611,12 +1634,13 @@ type abstraction_request =
| AbstractPattern of prefix_of_inductive_support_flag * (types -> bool) * Name.t * pending_constr * clause * bool
| AbstractExact of Name.t * constr * types option * clause * bool
-type abstraction_result =
+type 'r abstraction_result =
Names.Id.t * named_context_val *
- Context.named_declaration list * Names.Id.t option *
- types * (Evd.evar_map * constr) option
+ Context.Named.Declaration.t list * Names.Id.t option *
+ types * (constr, 'r) Sigma.sigma option
let make_abstraction env evd ccl abs =
+ let evd = Sigma.to_evar_map evd in
match abs with
| AbstractPattern (from_prefix,check,name,c,occs,check_occs) ->
make_abstraction_core name
diff --git a/pretyping/unification.mli b/pretyping/unification.mli
index d5d5caf9e..0ad882a9f 100644
--- a/pretyping/unification.mli
+++ b/pretyping/unification.mli
@@ -75,15 +75,15 @@ type abstraction_request =
| AbstractExact of Names.Name.t * constr * types option * Locus.clause * bool
val finish_evar_resolution : ?flags:Pretyping.inference_flags ->
- env -> Evd.evar_map -> pending_constr -> Evd.evar_map * constr
+ env -> 'r Sigma.t -> pending_constr -> (constr, 'r) Sigma.sigma
-type abstraction_result =
+type 'r abstraction_result =
Names.Id.t * named_context_val *
- Context.named_declaration list * Names.Id.t option *
- types * (Evd.evar_map * constr) option
+ Context.Named.Declaration.t list * Names.Id.t option *
+ types * (constr, 'r) Sigma.sigma option
-val make_abstraction : env -> Evd.evar_map -> constr ->
- abstraction_request -> abstraction_result
+val make_abstraction : env -> 'r Sigma.t -> constr ->
+ abstraction_request -> 'r abstraction_result
val pose_all_metas_as_evars : env -> evar_map -> constr -> evar_map * constr
diff --git a/pretyping/vnorm.ml b/pretyping/vnorm.ml
index 7d86fad92..8b9c2d6c9 100644
--- a/pretyping/vnorm.ml
+++ b/pretyping/vnorm.ml
@@ -45,13 +45,7 @@ let invert_tag cst tag reloc_tbl =
with Find_at j -> (j+1)
(* Argggg, ces constructeurs de ... qui commencent a 1*)
-let find_rectype_a env c =
- let (t, l) =
- let t = whd_betadeltaiota env c in
- try destApp t with DestKO -> (t,[||]) in
- match kind_of_term t with
- | Ind ind -> (ind, l)
- | _ -> raise Not_found
+let find_rectype_a env c = Inductiveops.find_mrectype_vect env Evd.empty c
(* Instantiate inductives and parameters in constructor type *)
@@ -59,11 +53,11 @@ let type_constructor mind mib u typ params =
let s = ind_subst mind mib u in
let ctyp = substl s typ in
let ctyp = subst_instance_constr u ctyp in
- let ndecls = Context.rel_context_length mib.mind_params_ctxt in
+ let ndecls = Context.Rel.length mib.mind_params_ctxt in
if Int.equal ndecls 0 then ctyp
else
let _,ctyp = decompose_prod_n_assum ndecls ctyp in
- substl (List.rev (Termops.adjust_subst_to_rel_context mib.mind_params_ctxt (Array.to_list params)))
+ substl (List.rev (adjust_subst_to_rel_context mib.mind_params_ctxt (Array.to_list params)))
ctyp
diff --git a/pretyping/vnorm.mli b/pretyping/vnorm.mli
index bdc6c1db6..58f5b14e1 100644
--- a/pretyping/vnorm.mli
+++ b/pretyping/vnorm.mli
@@ -8,7 +8,6 @@
open Term
open Environ
-open Evd
(** {6 Reduction functions } *)
val cbv_vm : env -> constr -> types -> constr
diff --git a/printing/genprint.ml b/printing/genprint.ml
index d4f792b75..d8bd81c4c 100644
--- a/printing/genprint.ml
+++ b/printing/genprint.ml
@@ -40,6 +40,6 @@ let raw_print wit v = (Print.obj wit).raw v
let glb_print wit v = (Print.obj wit).glb v
let top_print wit v = (Print.obj wit).top v
-let generic_raw_print v = unpack { unpacker = fun w v -> raw_print w (raw v); } v
-let generic_glb_print v = unpack { unpacker = fun w v -> glb_print w (glb v); } v
-let generic_top_print v = unpack { unpacker = fun w v -> top_print w (top v); } v
+let generic_raw_print (GenArg (Rawwit w, v)) = raw_print w v
+let generic_glb_print (GenArg (Glbwit w, v)) = glb_print w v
+let generic_top_print (GenArg (Topwit w, v)) = top_print w v
diff --git a/printing/miscprint.ml b/printing/miscprint.ml
index 22db3d0bf..5e86c6bd7 100644
--- a/printing/miscprint.ml
+++ b/printing/miscprint.ml
@@ -33,9 +33,9 @@ and pr_intro_pattern_action prc = function
| IntroRewrite false -> str "<-"
and pr_or_and_intro_pattern prc = function
- | [pl] ->
+ | IntroAndPattern pl ->
str "(" ++ hv 0 (prlist_with_sep pr_comma (pr_intro_pattern prc) pl) ++ str ")"
- | pll ->
+ | IntroOrPattern pll ->
str "[" ++
hv 0 (prlist_with_sep pr_bar (prlist_with_sep spc (pr_intro_pattern prc)) pll)
++ str "]"
diff --git a/printing/ppconstr.ml b/printing/ppconstr.ml
index e21bfa007..8a0df18ca 100644
--- a/printing/ppconstr.ml
+++ b/printing/ppconstr.ml
@@ -136,8 +136,6 @@ end) = struct
let pr_sep_com sep f c = pr_with_comments (constr_loc c) (sep() ++ f c)
- let pr_in_comment pr x = str "(* " ++ pr x ++ str " *)"
-
let pr_univ l =
match l with
| [_,x] -> str x
@@ -153,11 +151,11 @@ end) = struct
let pr_qualid sp =
let (sl, id) = repr_qualid sp in
- let id = tag_ref (str (Id.to_string id)) in
+ let id = tag_ref (pr_id id) in
let sl = match List.rev (DirPath.repr sl) with
| [] -> mt ()
| sl ->
- let pr dir = tag_path (str (Id.to_string dir)) ++ str "." in
+ let pr dir = tag_path (pr_id dir) ++ str "." in
prlist pr sl
in
sl ++ id
@@ -182,7 +180,7 @@ end) = struct
let pr_reference = function
| Qualid (_, qid) -> pr_qualid qid
- | Ident (_, id) -> tag_var (str (Id.to_string id))
+ | Ident (_, id) -> tag_var (pr_id id)
let pr_cref ref us =
pr_reference ref ++ pr_universe_instance us
@@ -457,7 +455,7 @@ end) = struct
(pr_decl true) dl ++
fnl() ++ keyword "for" ++ spc () ++ pr_id id
- let pr_asin pr (na,indnalopt) =
+ let pr_asin pr na indnalopt =
(match na with (* Decision of printing "_" or not moved to constrextern.ml *)
| Some na -> spc () ++ keyword "as" ++ spc () ++ pr_lname na
| None -> mt ()) ++
@@ -465,8 +463,8 @@ end) = struct
| None -> mt ()
| Some t -> spc () ++ keyword "in" ++ spc () ++ pr_patt lsimplepatt t)
- let pr_case_item pr (tm,asin) =
- hov 0 (pr (lcast,E) tm ++ pr_asin pr asin)
+ let pr_case_item pr (tm,as_clause, in_clause) =
+ hov 0 (pr (lcast,E) tm ++ pr_asin pr as_clause in_clause)
let pr_case_type pr po =
match po with
@@ -595,28 +593,20 @@ end) = struct
return (p, lproj)
| CApp (_,(None,a),l) ->
return (pr_app (pr mt) a l, lapp)
- | CRecord (_,w,l) ->
- let beg =
- match w with
- | None ->
- spc ()
- | Some t ->
- spc () ++ pr spc ltop t ++ spc ()
- ++ keyword "with" ++ spc ()
- in
+ | CRecord (_,l) ->
return (
- hv 0 (str"{|" ++ beg ++
+ hv 0 (str"{|" ++ spc () ++
prlist_with_sep pr_semicolon
(fun (id, c) -> h 1 (pr_reference id ++ spc () ++ str":=" ++ pr spc ltop c)) l
++ str" |}"),
latom
)
- | CCases (_,LetPatternStyle,rtntypopt,[c,asin],[(_,[(loc,[p])],b)]) ->
+ | CCases (_,LetPatternStyle,rtntypopt,[c,as_clause,in_clause],[(_,[(loc,[p])],b)]) ->
return (
hv 0 (
keyword "let" ++ spc () ++ str"'" ++
hov 0 (pr_patt ltop p ++
- pr_asin (pr_dangling_with_for mt pr) asin ++
+ pr_asin (pr_dangling_with_for mt pr) as_clause in_clause ++
str " :=" ++ pr spc ltop c ++
pr_case_type (pr_dangling_with_for mt pr) rtntypopt ++
spc () ++ keyword "in" ++ pr spc ltop b)),
diff --git a/printing/pptactic.ml b/printing/pptactic.ml
index 7e903d2d3..c00036bb3 100644
--- a/printing/pptactic.ml
+++ b/printing/pptactic.ml
@@ -26,21 +26,22 @@ open Printer
let pr_global x = Nametab.pr_global_env Id.Set.empty x
-type grammar_terminals = string option list
+type grammar_terminals = Tacexpr.raw_tactic_expr Egramml.grammar_prod_item list
type pp_tactic = {
- pptac_args : argument_type list;
- pptac_prods : int * grammar_terminals;
+ pptac_level : int;
+ pptac_prods : grammar_terminals;
}
(* ML Extensions *)
-let prtac_tab = Hashtbl.create 17
+let prtac_tab : (ml_tactic_name, pp_tactic array) Hashtbl.t =
+ Hashtbl.create 17
(* Tactic notations *)
let prnotation_tab = Summary.ref ~name:"pptactic-notation" KNmap.empty
let declare_ml_tactic_pprule key pt =
- Hashtbl.add prtac_tab (key, pt.pptac_args) pt.pptac_prods
+ Hashtbl.add prtac_tab key pt
let declare_notation_tactic_pprule kn pt =
prnotation_tab := KNmap.add kn pt !prnotation_tab
@@ -264,149 +265,89 @@ module Make
let with_evars ev s = if ev then "e" ^ s else s
- let rec pr_raw_generic prc prlc prtac prpat prref (x:Genarg.rlevel Genarg.generic_argument) =
- match Genarg.genarg_tag x with
- | IntOrVarArgType -> pr_or_var int (out_gen (rawwit wit_int_or_var) x)
- | IdentArgType -> pr_id (out_gen (rawwit wit_ident) x)
- | VarArgType -> pr_located pr_id (out_gen (rawwit wit_var) x)
- | GenArgType -> pr_raw_generic prc prlc prtac prpat prref (out_gen (rawwit wit_genarg) x)
- | ConstrArgType -> prc (out_gen (rawwit wit_constr) x)
- | ConstrMayEvalArgType ->
- pr_may_eval prc prlc (pr_or_by_notation prref) prpat
- (out_gen (rawwit wit_constr_may_eval) x)
- | QuantHypArgType -> pr_quantified_hypothesis (out_gen (rawwit wit_quant_hyp) x)
- | RedExprArgType ->
- pr_red_expr (prc,prlc,pr_or_by_notation prref,prpat)
- (out_gen (rawwit wit_red_expr) x)
- | OpenConstrArgType -> prc (snd (out_gen (rawwit wit_open_constr) x))
- | ConstrWithBindingsArgType ->
- pr_with_bindings prc prlc (out_gen (rawwit wit_constr_with_bindings) x)
- | BindingsArgType ->
- pr_bindings_no_with prc prlc (out_gen (rawwit wit_bindings) x)
- | ListArgType _ ->
- let list_unpacker wit l =
- let map x = pr_raw_generic prc prlc prtac prpat prref (in_gen (rawwit wit) x) in
- pr_sequence map (raw l)
- in
- hov 0 (list_unpack { list_unpacker } x)
- | OptArgType _ ->
- let opt_unpacker wit o = match raw o with
+ let rec pr_raw_generic_rec prc prlc prtac prpat prref (GenArg (Rawwit wit, x)) =
+ match wit with
+ | ListArg wit ->
+ let map x = pr_raw_generic_rec prc prlc prtac prpat prref (in_gen (rawwit wit) x) in
+ let ans = pr_sequence map x in
+ hov 0 ans
+ | OptArg wit ->
+ let ans = match x with
| None -> mt ()
- | Some x -> pr_raw_generic prc prlc prtac prpat prref (in_gen (rawwit wit) x)
- in
- hov 0 (opt_unpack { opt_unpacker } x)
- | PairArgType _ ->
- let pair_unpacker wit1 wit2 o =
- let p, q = raw o in
- let p = in_gen (rawwit wit1) p in
- let q = in_gen (rawwit wit2) q in
- pr_sequence (pr_raw_generic prc prlc prtac prpat prref) [p; q]
+ | Some x -> pr_raw_generic_rec prc prlc prtac prpat prref (in_gen (rawwit wit) x)
in
- hov 0 (pair_unpack { pair_unpacker } x)
- | ExtraArgType s ->
- try pi1 (String.Map.find s !genarg_pprule) prc prlc prtac x
- with Not_found -> Genprint.generic_raw_print x
-
-
- let rec pr_glb_generic prc prlc prtac prpat x =
- match Genarg.genarg_tag x with
- | IntOrVarArgType -> pr_or_var int (out_gen (glbwit wit_int_or_var) x)
- | IdentArgType -> pr_id (out_gen (glbwit wit_ident) x)
- | VarArgType -> pr_located pr_id (out_gen (glbwit wit_var) x)
- | GenArgType -> pr_glb_generic prc prlc prtac prpat (out_gen (glbwit wit_genarg) x)
- | ConstrArgType -> prc (out_gen (glbwit wit_constr) x)
- | ConstrMayEvalArgType ->
- pr_may_eval prc prlc
- (pr_or_var (pr_and_short_name pr_evaluable_reference)) prpat
- (out_gen (glbwit wit_constr_may_eval) x)
- | QuantHypArgType ->
- pr_quantified_hypothesis (out_gen (glbwit wit_quant_hyp) x)
- | RedExprArgType ->
- pr_red_expr
- (prc,prlc,pr_or_var (pr_and_short_name pr_evaluable_reference),prpat)
- (out_gen (glbwit wit_red_expr) x)
- | OpenConstrArgType -> prc (snd (out_gen (glbwit wit_open_constr) x))
- | ConstrWithBindingsArgType ->
- pr_with_bindings prc prlc (out_gen (glbwit wit_constr_with_bindings) x)
- | BindingsArgType ->
- pr_bindings_no_with prc prlc (out_gen (glbwit wit_bindings) x)
- | ListArgType _ ->
- let list_unpacker wit l =
- let map x = pr_glb_generic prc prlc prtac prpat (in_gen (glbwit wit) x) in
- pr_sequence map (glb l)
- in
- hov 0 (list_unpack { list_unpacker } x)
- | OptArgType _ ->
- let opt_unpacker wit o = match glb o with
+ hov 0 ans
+ | PairArg (wit1, wit2) ->
+ let p, q = x in
+ let p = in_gen (rawwit wit1) p in
+ let q = in_gen (rawwit wit2) q in
+ hov 0 (pr_sequence (pr_raw_generic_rec prc prlc prtac prpat prref) [p; q])
+ | ExtraArg s ->
+ try pi1 (String.Map.find (ArgT.repr s) !genarg_pprule) prc prlc prtac (in_gen (rawwit wit) x)
+ with Not_found -> Genprint.generic_raw_print (in_gen (rawwit wit) x)
+
+
+ let rec pr_glb_generic_rec prc prlc prtac prpat (GenArg (Glbwit wit, x)) =
+ match wit with
+ | ListArg wit ->
+ let map x = pr_glb_generic_rec prc prlc prtac prpat (in_gen (glbwit wit) x) in
+ let ans = pr_sequence map x in
+ hov 0 ans
+ | OptArg wit ->
+ let ans = match x with
| None -> mt ()
- | Some x -> pr_glb_generic prc prlc prtac prpat (in_gen (glbwit wit) x)
- in
- hov 0 (opt_unpack { opt_unpacker } x)
- | PairArgType _ ->
- let pair_unpacker wit1 wit2 o =
- let p, q = glb o in
- let p = in_gen (glbwit wit1) p in
- let q = in_gen (glbwit wit2) q in
- pr_sequence (pr_glb_generic prc prlc prtac prpat) [p; q]
+ | Some x -> pr_glb_generic_rec prc prlc prtac prpat (in_gen (glbwit wit) x)
in
- hov 0 (pair_unpack { pair_unpacker } x)
- | ExtraArgType s ->
- try pi2 (String.Map.find s !genarg_pprule) prc prlc prtac x
- with Not_found -> Genprint.generic_glb_print x
-
- let rec pr_top_generic prc prlc prtac prpat x =
- match Genarg.genarg_tag x with
- | IntOrVarArgType -> pr_or_var int (out_gen (topwit wit_int_or_var) x)
- | IdentArgType -> pr_id (out_gen (topwit wit_ident) x)
- | VarArgType -> pr_id (out_gen (topwit wit_var) x)
- | GenArgType -> pr_top_generic prc prlc prtac prpat (out_gen (topwit wit_genarg) x)
- | ConstrArgType -> prc (out_gen (topwit wit_constr) x)
- | ConstrMayEvalArgType -> prc (out_gen (topwit wit_constr_may_eval) x)
- | QuantHypArgType -> pr_quantified_hypothesis (out_gen (topwit wit_quant_hyp) x)
- | RedExprArgType ->
- pr_red_expr (prc,prlc,pr_evaluable_reference,prpat)
- (out_gen (topwit wit_red_expr) x)
- | OpenConstrArgType -> prc (snd (out_gen (topwit wit_open_constr) x))
- | ConstrWithBindingsArgType ->
- let (c,b) = (out_gen (topwit wit_constr_with_bindings) x).Evd.it in
- pr_with_bindings prc prlc (c,b)
- | BindingsArgType ->
- pr_bindings_no_with prc prlc (out_gen (topwit wit_bindings) x).Evd.it
- | ListArgType _ ->
- let list_unpacker wit l =
- let map x = pr_top_generic prc prlc prtac prpat (in_gen (topwit wit) x) in
- pr_sequence map (top l)
- in
- hov 0 (list_unpack { list_unpacker } x)
- | OptArgType _ ->
- let opt_unpacker wit o = match top o with
+ hov 0 ans
+ | PairArg (wit1, wit2) ->
+ let p, q = x in
+ let p = in_gen (glbwit wit1) p in
+ let q = in_gen (glbwit wit2) q in
+ let ans = pr_sequence (pr_glb_generic_rec prc prlc prtac prpat) [p; q] in
+ hov 0 ans
+ | ExtraArg s ->
+ try pi2 (String.Map.find (ArgT.repr s) !genarg_pprule) prc prlc prtac (in_gen (glbwit wit) x)
+ with Not_found -> Genprint.generic_glb_print (in_gen (glbwit wit) x)
+
+ let rec pr_top_generic_rec prc prlc prtac prpat (GenArg (Topwit wit, x)) =
+ match wit with
+ | ListArg wit ->
+ let map x = pr_top_generic_rec prc prlc prtac prpat (in_gen (topwit wit) x) in
+ let ans = pr_sequence map x in
+ hov 0 ans
+ | OptArg wit ->
+ let ans = match x with
| None -> mt ()
- | Some x -> pr_top_generic prc prlc prtac prpat (in_gen (topwit wit) x)
- in
- hov 0 (opt_unpack { opt_unpacker } x)
- | PairArgType _ ->
- let pair_unpacker wit1 wit2 o =
- let p, q = top o in
- let p = in_gen (topwit wit1) p in
- let q = in_gen (topwit wit2) q in
- pr_sequence (pr_top_generic prc prlc prtac prpat) [p; q]
+ | Some x -> pr_top_generic_rec prc prlc prtac prpat (in_gen (topwit wit) x)
in
- hov 0 (pair_unpack { pair_unpacker } x)
- | ExtraArgType s ->
- try pi3 (String.Map.find s !genarg_pprule) prc prlc prtac x
- with Not_found -> Genprint.generic_top_print x
+ hov 0 ans
+ | PairArg (wit1, wit2) ->
+ let p, q = x in
+ let p = in_gen (topwit wit1) p in
+ let q = in_gen (topwit wit2) q in
+ let ans = pr_sequence (pr_top_generic_rec prc prlc prtac prpat) [p; q] in
+ hov 0 ans
+ | ExtraArg s ->
+ try pi3 (String.Map.find (ArgT.repr s) !genarg_pprule) prc prlc prtac (in_gen (topwit wit) x)
+ with Not_found -> Genprint.generic_top_print (in_gen (topwit wit) x)
let rec tacarg_using_rule_token pr_gen = function
- | Some s :: l, al -> keyword s :: tacarg_using_rule_token pr_gen (l,al)
- | None :: l, a :: al ->
+ | Egramml.GramTerminal s :: l, al -> keyword s :: tacarg_using_rule_token pr_gen (l,al)
+ | Egramml.GramNonTerminal _ :: l, a :: al ->
let r = tacarg_using_rule_token pr_gen (l,al) in
pr_gen a :: r
| [], [] -> []
| _ -> failwith "Inconsistent arguments of extended tactic"
+ type any_arg = AnyArg : 'a Genarg.raw_abstract_argument_type -> any_arg
+
+ let filter_arg = function
+ | Egramml.GramTerminal _ -> None
+ | Egramml.GramNonTerminal (_, t, _) -> Some (AnyArg t)
+
let pr_tacarg_using_rule pr_gen l =
let l = match l with
- | (Some s :: l, al) ->
+ | (Egramml.GramTerminal s :: l, al) ->
(** First terminal token should be considered as the name of the tactic,
so we tag it differently than the other terminal tokens. *)
primitive s :: (tacarg_using_rule_token pr_gen (l, al))
@@ -414,42 +355,54 @@ module Make
in
pr_sequence (fun x -> x) l
- let pr_extend_gen pr_gen lev s l =
+ let pr_extend_gen check pr_gen lev { mltac_name = s; mltac_index = i } l =
try
- let tags = List.map genarg_tag l in
- let (lev',pl) = Hashtbl.find prtac_tab (s,tags) in
- let p = pr_tacarg_using_rule pr_gen (pl,l) in
- if lev' > lev then surround p else p
+ let pp_rules = Hashtbl.find prtac_tab s in
+ let pp = pp_rules.(i) in
+ let args = List.map_filter filter_arg pp.pptac_prods in
+ let () = if not (List.for_all2eq check args l) then raise Not_found in
+ let p = pr_tacarg_using_rule pr_gen (pp.pptac_prods, l) in
+ if pp.pptac_level > lev then surround p else p
with Not_found ->
- let name = str s.mltac_plugin ++ str "::" ++ str s.mltac_tactic in
+ let name =
+ str s.mltac_plugin ++ str "::" ++ str s.mltac_tactic ++
+ str "@" ++ int i
+ in
let args = match l with
| [] -> mt ()
| _ -> spc() ++ pr_sequence pr_gen l
in
str "<" ++ name ++ str ">" ++ args
- let pr_alias_gen pr_gen lev key l =
+ let pr_alias_gen check pr_gen lev key l =
try
let pp = KNmap.find key !prnotation_tab in
- let (lev', pl) = pp.pptac_prods in
- let p = pr_tacarg_using_rule pr_gen (pl, l) in
- if lev' > lev then surround p else p
+ let args = List.map_filter filter_arg pp.pptac_prods in
+ let () = if not (List.for_all2eq check args l) then raise Not_found in
+ let p = pr_tacarg_using_rule pr_gen (pp.pptac_prods, l) in
+ if pp.pptac_level > lev then surround p else p
with Not_found ->
KerName.print key ++ spc() ++ pr_sequence pr_gen l ++ str" (* Generic printer *)"
- let pr_raw_extend prc prlc prtac prpat =
- pr_extend_gen (pr_raw_generic prc prlc prtac prpat pr_reference)
- let pr_glob_extend prc prlc prtac prpat =
- pr_extend_gen (pr_glb_generic prc prlc prtac prpat)
- let pr_extend prc prlc prtac prpat =
- pr_extend_gen (pr_top_generic prc prlc prtac prpat)
+ let check_type t arg = match t, arg with
+ | AnyArg t, TacGeneric arg -> argument_type_eq (unquote t) (genarg_tag arg)
+ | _ -> false
+
+ let unwrap_gen f = function TacGeneric x -> f x | _ -> assert false
+
+ let pr_raw_extend_rec prc prlc prtac prpat =
+ pr_extend_gen check_type (unwrap_gen (pr_raw_generic_rec prc prlc prtac prpat pr_reference))
+ let pr_glob_extend_rec prc prlc prtac prpat =
+ pr_extend_gen check_type (unwrap_gen (pr_glb_generic_rec prc prlc prtac prpat))
+ let pr_extend_rec prc prlc prtac prpat =
+ pr_extend_gen check_type (unwrap_gen (pr_top_generic_rec prc prlc prtac prpat))
let pr_raw_alias prc prlc prtac prpat =
- pr_alias_gen (pr_raw_generic prc prlc prtac prpat pr_reference)
+ pr_alias_gen check_type (unwrap_gen (pr_raw_generic_rec prc prlc prtac prpat pr_reference))
let pr_glob_alias prc prlc prtac prpat =
- pr_alias_gen (pr_glb_generic prc prlc prtac prpat)
+ pr_alias_gen check_type (unwrap_gen (pr_glb_generic_rec prc prlc prtac prpat))
let pr_alias prc prlc prtac prpat =
- pr_alias_gen (pr_top_generic prc prlc prtac prpat)
+ pr_alias_gen check_type (unwrap_gen (pr_top_generic_rec prc prlc prtac prpat))
(**********************************************************************)
(* The tactic printer *)
@@ -716,11 +669,6 @@ module Make
| l -> spc () ++
hov 2 (keyword "using" ++ spc () ++ prlist_with_sep pr_comma prc l)
- let string_of_debug = function
- | Off -> ""
- | Debug -> "debug "
- | Info -> "info_"
-
let pr_then () = str ";"
let ltop = (5,E)
@@ -755,8 +703,8 @@ module Make
pr_reference : 'ref -> std_ppcmds;
pr_name : 'nam -> std_ppcmds;
pr_generic : 'lev generic_argument -> std_ppcmds;
- pr_extend : int -> ml_tactic_name -> 'lev generic_argument list -> std_ppcmds;
- pr_alias : int -> KerName.t -> 'lev generic_argument list -> std_ppcmds;
+ pr_extend : int -> ml_tactic_entry -> 'a gen_tactic_arg list -> std_ppcmds;
+ pr_alias : int -> KerName.t -> 'a gen_tactic_arg list -> std_ppcmds;
}
constraint 'a = <
@@ -843,8 +791,6 @@ module Make
let rec pr_atom0 a = tag_atom a (match a with
| TacIntroPattern [] -> primitive "intros"
| TacIntroMove (None,MoveLast) -> primitive "intro"
- | TacTrivial (d,[],Some []) -> str (string_of_debug d) ++ primitive "trivial"
- | TacAuto (d,None,[],Some []) -> str (string_of_debug d) ++ primitive "auto"
| TacClear (true,[]) -> primitive "clear"
| t -> str "(" ++ pr_atom1 t ++ str ")"
)
@@ -953,23 +899,6 @@ module Make
++ pr_arg pr_quantified_hypothesis h2
)
- (* Automation tactics *)
- | TacTrivial (_,[],Some []) as x ->
- pr_atom0 x
- | TacTrivial (d,lems,db) ->
- hov 0 (
- str (string_of_debug d) ++ primitive "trivial"
- ++ pr_auto_using pr.pr_constr lems ++ pr_hintbases db
- )
- | TacAuto (_,None,[],Some []) as x ->
- pr_atom0 x
- | TacAuto (d,n,lems,db) ->
- hov 0 (
- str (string_of_debug d) ++ primitive "auto"
- ++ pr_opt (pr_or_var int) n
- ++ pr_auto_using pr.pr_constr lems ++ pr_hintbases db
- )
-
(* Context management *)
| TacClear (true,[]) as t ->
pr_atom0 t
@@ -1251,16 +1180,13 @@ module Make
| TacML (loc,s,l) ->
pr_with_comments loc (pr.pr_extend 1 s l), lcall
| TacAlias (loc,kn,l) ->
- pr_with_comments loc (pr.pr_alias (level_of inherited) kn (List.map snd l)), latom
+ pr_with_comments loc (pr.pr_alias (level_of inherited) kn l), latom
)
in
if prec_less prec inherited then strm
else str"(" ++ strm ++ str")"
and pr_tacarg = function
- | TacDynamic (loc,t) ->
- pr_with_comments loc
- (str "<" ++ keyword "dynamic" ++ str " [" ++ str (Dyn.tag t) ++ str "]>")
| MetaIdArg (loc,true,s) ->
pr_with_comments loc (str "$" ++ str s)
| MetaIdArg (loc,false,s) ->
@@ -1307,7 +1233,7 @@ module Make
pr_reference = pr_reference;
pr_name = pr_lident;
pr_generic = Genprint.generic_raw_print;
- pr_extend = pr_raw_extend pr_constr_expr pr_lconstr_expr pr_raw_tactic_level pr_constr_pattern_expr;
+ pr_extend = pr_raw_extend_rec pr_constr_expr pr_lconstr_expr pr_raw_tactic_level pr_constr_pattern_expr;
pr_alias = pr_raw_alias pr_constr_expr pr_lconstr_expr pr_raw_tactic_level pr_constr_pattern_expr;
} in
make_pr_tac
@@ -1321,7 +1247,7 @@ module Make
let pr_pat_and_constr_expr pr ((c,_),_) = pr c
- let rec pr_glob_tactic_level env n t =
+ let pr_glob_tactic_level env n t =
let glob_printers =
(strip_prod_binders_glob_constr)
in
@@ -1338,7 +1264,7 @@ module Make
pr_reference = pr_ltac_or_var (pr_located pr_ltac_constant);
pr_name = pr_lident;
pr_generic = Genprint.generic_glb_print;
- pr_extend = pr_glob_extend
+ pr_extend = pr_glob_extend_rec
(pr_and_constr_expr (pr_glob_constr_env env)) (pr_and_constr_expr (pr_lglob_constr_env env))
prtac (pr_pat_and_constr_expr (pr_glob_constr_env env));
pr_alias = pr_glob_alias
@@ -1374,13 +1300,13 @@ module Make
pr_uconstr = pr_closed_glob_env env Evd.empty;
pr_dconstr = pr_and_constr_expr (pr_glob_constr_env env);
pr_lconstr = pr_lconstr_env env Evd.empty;
- pr_pattern = pr_pat_and_constr_expr (pr_glob_constr_env env);
- pr_lpattern = pr_pat_and_constr_expr (pr_lglob_constr_env env);
- pr_constant = pr_and_short_name (pr_evaluable_reference_env env);
+ pr_pattern = pr_constr_pattern_env env Evd.empty;
+ pr_lpattern = pr_lconstr_pattern_env env Evd.empty;
+ pr_constant = pr_evaluable_reference_env env;
pr_reference = pr_located pr_ltac_constant;
pr_name = pr_id;
pr_generic = Genprint.generic_top_print;
- pr_extend = pr_extend
+ pr_extend = pr_extend_rec
(pr_constr_env env Evd.empty) (pr_lconstr_env env Evd.empty)
(pr_glob_tactic_level env) pr_constr_pattern;
pr_alias = pr_alias
@@ -1395,6 +1321,39 @@ module Make
in
prtac n t
+ let pr_raw_generic env = pr_raw_generic_rec
+ pr_constr_expr pr_lconstr_expr pr_raw_tactic_level pr_constr_pattern_expr pr_reference
+
+ let pr_glb_generic env = pr_glb_generic_rec
+ (pr_and_constr_expr (pr_glob_constr_env env)) (pr_and_constr_expr (pr_lglob_constr_env env))
+ (pr_glob_tactic_level env) (pr_pat_and_constr_expr (pr_glob_constr_env env))
+
+ let pr_top_generic env = pr_top_generic_rec
+ (pr_constr_env env Evd.empty) (pr_lconstr_env env Evd.empty)
+ (pr_glob_tactic_level env) pr_constr_pattern
+
+ let pr_raw_extend env = pr_raw_extend_rec
+ pr_constr_expr pr_lconstr_expr pr_raw_tactic_level pr_constr_pattern_expr
+
+ let pr_glob_extend env = pr_glob_extend_rec
+ (pr_and_constr_expr (pr_glob_constr_env env)) (pr_and_constr_expr (pr_lglob_constr_env env))
+ (pr_glob_tactic_level env) (pr_pat_and_constr_expr (pr_glob_constr_env env))
+
+ let check_val_type t arg =
+ let AnyArg t = t in
+(* let t = Genarg.val_tag (Obj.magic t) in *)
+(* let Val.Dyn (t', _) = arg in *)
+(* match Genarg.Val.eq t t' with *)
+(* | None -> false *)
+(* | Some _ -> true *)
+ true (** FIXME *)
+
+ let pr_alias pr lev key args =
+ pr_alias_gen check_val_type pr lev key args
+
+ let pr_extend pr lev ml args =
+ pr_extend_gen check_val_type pr lev ml args
+
let pr_tactic env = pr_tactic_level env ltop
end
@@ -1431,17 +1390,26 @@ end)
(** Registering *)
+let run_delayed c =
+ Sigma.run Evd.empty { Sigma.run = fun sigma -> c.delayed (Global.env ()) sigma }
+
let () =
let pr_bool b = if b then str "true" else str "false" in
let pr_unit _ = str "()" in
let pr_string s = str "\"" ++ str s ++ str "\"" in
+ Genprint.register_print0 Constrarg.wit_int_or_var
+ (pr_or_var int) (pr_or_var int) int;
Genprint.register_print0 Constrarg.wit_ref
pr_reference (pr_or_var (pr_located pr_global)) pr_global;
+ Genprint.register_print0 Constrarg.wit_ident
+ pr_id pr_id pr_id;
+ Genprint.register_print0 Constrarg.wit_var
+ (pr_located pr_id) (pr_located pr_id) pr_id;
Genprint.register_print0
Constrarg.wit_intro_pattern
(Miscprint.pr_intro_pattern pr_constr_expr)
(Miscprint.pr_intro_pattern (fun (c,_) -> pr_glob_constr c))
- (Miscprint.pr_intro_pattern (fun c -> pr_constr (snd (c (Global.env()) Evd.empty))));
+ (Miscprint.pr_intro_pattern (fun c -> pr_constr (fst (run_delayed c))));
Genprint.register_print0
Constrarg.wit_clause_dft_concl
(pr_clauses (Some true) pr_lident)
@@ -1451,11 +1419,41 @@ let () =
Genprint.register_print0 Constrarg.wit_sort
pr_glob_sort pr_glob_sort (pr_sort Evd.empty);
Genprint.register_print0
+ Constrarg.wit_constr
+ Ppconstr.pr_constr_expr
+ (fun (c, _) -> Printer.pr_glob_constr c)
+ Printer.pr_constr
+ ;
+ Genprint.register_print0
Constrarg.wit_uconstr
Ppconstr.pr_constr_expr
(fun (c,_) -> Printer.pr_glob_constr c)
Printer.pr_closed_glob
;
+ Genprint.register_print0
+ Constrarg.wit_open_constr
+ Ppconstr.pr_constr_expr
+ (fun (c, _) -> Printer.pr_glob_constr c)
+ Printer.pr_constr
+ ;
+ Genprint.register_print0 Constrarg.wit_red_expr
+ (pr_red_expr (pr_constr_expr, pr_lconstr_expr, pr_or_by_notation pr_reference, pr_constr_pattern_expr))
+ (pr_red_expr (pr_and_constr_expr pr_glob_constr, pr_lglob_constr, pr_or_var (pr_and_short_name pr_evaluable_reference), pr_pat_and_constr_expr pr_glob_constr))
+ (pr_red_expr (pr_constr, pr_lconstr, pr_evaluable_reference, pr_constr_pattern));
+ Genprint.register_print0 Constrarg.wit_quant_hyp pr_quantified_hypothesis pr_quantified_hypothesis pr_quantified_hypothesis;
+ Genprint.register_print0 Constrarg.wit_bindings
+ (pr_bindings_no_with pr_constr_expr pr_lconstr_expr)
+ (pr_bindings_no_with (pr_and_constr_expr pr_glob_constr) (pr_and_constr_expr pr_lglob_constr))
+ (fun it -> pr_bindings_no_with pr_constr pr_lconstr (fst (run_delayed it)));
+ Genprint.register_print0 Constrarg.wit_constr_may_eval
+ (pr_may_eval pr_constr_expr pr_lconstr_expr (pr_or_by_notation pr_reference) pr_constr_pattern_expr)
+ (pr_may_eval (pr_and_constr_expr pr_glob_constr) (pr_and_constr_expr pr_lglob_constr)
+ (pr_or_var (pr_and_short_name pr_evaluable_reference)) (pr_pat_and_constr_expr pr_glob_constr))
+ pr_constr;
+ Genprint.register_print0 Constrarg.wit_constr_with_bindings
+ (pr_with_bindings pr_constr_expr pr_lconstr_expr)
+ (pr_with_bindings (pr_and_constr_expr pr_glob_constr) (pr_and_constr_expr pr_lglob_constr))
+ (fun it -> pr_with_bindings pr_constr pr_lconstr (fst (run_delayed it)));
Genprint.register_print0 Stdarg.wit_int int int int;
Genprint.register_print0 Stdarg.wit_bool pr_bool pr_bool pr_bool;
Genprint.register_print0 Stdarg.wit_unit pr_unit pr_unit pr_unit;
diff --git a/printing/pptactic.mli b/printing/pptactic.mli
index 313465614..2bc64509f 100644
--- a/printing/pptactic.mli
+++ b/printing/pptactic.mli
@@ -41,14 +41,14 @@ val declare_extra_genarg_pprule :
'b glob_extra_genarg_printer ->
'c extra_genarg_printer -> unit
-type grammar_terminals = string option list
+type grammar_terminals = Tacexpr.raw_tactic_expr Egramml.grammar_prod_item list
type pp_tactic = {
- pptac_args : argument_type list;
- pptac_prods : int * grammar_terminals;
+ pptac_level : int;
+ pptac_prods : grammar_terminals;
}
-val declare_ml_tactic_pprule : ml_tactic_name -> pp_tactic -> unit
+val declare_ml_tactic_pprule : ml_tactic_name -> pp_tactic array -> unit
val declare_notation_tactic_pprule : KerName.t -> pp_tactic -> unit
(** The default pretty-printers produce {!Pp.std_ppcmds} that are
diff --git a/printing/pptacticsig.mli b/printing/pptacticsig.mli
index b2323acba..c5ec6bb09 100644
--- a/printing/pptacticsig.mli
+++ b/printing/pptacticsig.mli
@@ -8,11 +8,9 @@
open Pp
open Genarg
-open Constrexpr
open Tacexpr
open Ppextend
open Environ
-open Pattern
open Misctypes
module type Pp = sig
@@ -32,46 +30,24 @@ module type Pp = sig
val pr_clauses : bool option ->
('a -> Pp.std_ppcmds) -> 'a Locus.clause_expr -> Pp.std_ppcmds
- val pr_raw_generic :
- (constr_expr -> std_ppcmds) ->
- (constr_expr -> std_ppcmds) ->
- (tolerability -> raw_tactic_expr -> std_ppcmds) ->
- (constr_expr -> std_ppcmds) ->
- (Libnames.reference -> std_ppcmds) -> rlevel generic_argument ->
- std_ppcmds
-
- val pr_glb_generic :
- (glob_constr_and_expr -> Pp.std_ppcmds) ->
- (glob_constr_and_expr -> Pp.std_ppcmds) ->
- (tolerability -> glob_tactic_expr -> std_ppcmds) ->
- (glob_constr_pattern_and_expr -> std_ppcmds) ->
- glevel generic_argument -> std_ppcmds
-
- val pr_top_generic :
- (Term.constr -> std_ppcmds) ->
- (Term.constr -> std_ppcmds) ->
- (tolerability -> glob_tactic_expr -> std_ppcmds) ->
- (Pattern.constr_pattern -> std_ppcmds) ->
- tlevel generic_argument ->
- std_ppcmds
-
- val pr_raw_extend:
- (constr_expr -> std_ppcmds) -> (constr_expr -> std_ppcmds) ->
- (tolerability -> raw_tactic_expr -> std_ppcmds) ->
- (constr_expr -> std_ppcmds) -> int ->
- ml_tactic_name -> raw_generic_argument list -> std_ppcmds
-
- val pr_glob_extend:
- (glob_constr_and_expr -> std_ppcmds) -> (glob_constr_and_expr -> std_ppcmds) ->
- (tolerability -> glob_tactic_expr -> std_ppcmds) ->
- (glob_constr_pattern_and_expr -> std_ppcmds) -> int ->
- ml_tactic_name -> glob_generic_argument list -> std_ppcmds
+
+ val pr_raw_generic : env -> rlevel generic_argument -> std_ppcmds
+
+ val pr_glb_generic : env -> glevel generic_argument -> std_ppcmds
+
+ val pr_top_generic : env -> tlevel generic_argument -> std_ppcmds
+
+ val pr_raw_extend: env -> int ->
+ ml_tactic_entry -> raw_tactic_arg list -> std_ppcmds
+
+ val pr_glob_extend: env -> int ->
+ ml_tactic_entry -> glob_tactic_arg list -> std_ppcmds
val pr_extend :
- (Term.constr -> std_ppcmds) -> (Term.constr -> std_ppcmds) ->
- (tolerability -> glob_tactic_expr -> std_ppcmds) ->
- (constr_pattern -> std_ppcmds) -> int ->
- ml_tactic_name -> typed_generic_argument list -> std_ppcmds
+ (Val.t -> std_ppcmds) -> int -> ml_tactic_entry -> Val.t list -> std_ppcmds
+
+ val pr_alias : (Val.t -> std_ppcmds) ->
+ int -> Names.KerName.t -> Val.t list -> std_ppcmds
val pr_ltac_constant : Nametab.ltac_constant -> std_ppcmds
diff --git a/printing/ppvernac.ml b/printing/ppvernac.ml
index d2f59e7b8..ccf470946 100644
--- a/printing/ppvernac.ml
+++ b/printing/ppvernac.ml
@@ -79,13 +79,7 @@ module Make
| VernacEndSubproof -> str""
| _ -> str"."
- let pr_gen t =
- pr_raw_generic
- pr_constr_expr
- pr_lconstr_expr
- pr_raw_tactic_level
- pr_constr_expr
- pr_reference t
+ let pr_gen t = pr_raw_generic (Global.env ()) t
let sep = fun _ -> spc()
let sep_v2 = fun _ -> str"," ++ spc()
@@ -111,10 +105,9 @@ module Make
else id
let pr_production_item = function
- | TacNonTerm (loc,nt,Some (p,sep)) ->
+ | TacNonTerm (loc, nt, (p, sep)) ->
let pp_sep = if not (String.is_empty sep) then str "," ++ quote (str sep) else mt () in
str nt ++ str"(" ++ pr_id (strip_meta p) ++ pp_sep ++ str")"
- | TacNonTerm (loc,nt,None) -> str nt
| TacTerm s -> qs s
let pr_comment pr_c = function
@@ -641,10 +634,10 @@ module Make
else
spc() ++ qs s
)
- | VernacTime v ->
- return (keyword "Time" ++ spc() ++ pr_vernac_list v)
- | VernacRedirect (s, v) ->
- return (keyword "Redirect" ++ spc() ++ qs s ++ spc() ++ pr_vernac_list v)
+ | VernacTime (_,v) ->
+ return (keyword "Time" ++ spc() ++ pr_vernac v)
+ | VernacRedirect (s, (_,v)) ->
+ return (keyword "Redirect" ++ spc() ++ qs s ++ spc() ++ pr_vernac v)
| VernacTimeout(n,v) ->
return (keyword "Timeout " ++ int n ++ spc() ++ pr_vernac v)
| VernacFail v ->
@@ -1036,13 +1029,18 @@ module Make
return (keyword "Cd" ++ pr_opt qs s)
(* Commands *)
- | VernacDeclareTacticDefinition (rc,l) ->
- let pr_tac_body (id, redef, body) =
+ | VernacDeclareTacticDefinition l ->
+ let pr_tac_body tacdef_body =
+ let id, redef, body =
+ match tacdef_body with
+ | TacticDefinition ((_,id), body) -> pr_id id, false, body
+ | TacticRedefinition (id, body) -> pr_ltac_ref id, true, body
+ in
let idl, body =
match body with
| Tacexpr.TacFun (idl,b) -> idl,b
| _ -> [], body in
- pr_ltac_ref id ++
+ id ++
prlist (function None -> str " _"
| Some id -> spc () ++ pr_id id) idl
++ (if redef then str" ::=" else str" :=") ++ brk(1,1) ++
@@ -1230,8 +1228,6 @@ module Make
(keyword "Comments" ++ spc()
++ prlist_with_sep sep (pr_comment pr_constr) l)
)
- | VernacNop ->
- mt()
(* Toplevel control *)
| VernacToplevelControl exn ->
@@ -1268,11 +1264,6 @@ module Make
| VernacEndSubproof ->
return (str "}")
- and pr_vernac_list l =
- hov 2 (str"[" ++ spc() ++
- prlist (fun v -> pr_located pr_vernac v ++ sep_end (snd v) ++ fnl()) l
- ++ spc() ++ str"]")
-
and pr_extend s cl =
let pr_arg a =
try pr_gen a
diff --git a/printing/prettyp.ml b/printing/prettyp.ml
index fd51fd6b0..b448df337 100644
--- a/printing/prettyp.ml
+++ b/printing/prettyp.ml
@@ -132,7 +132,7 @@ let print_renames_list prefix l =
let need_expansion impl ref =
let typ = Global.type_of_global_unsafe ref in
let ctx = prod_assum typ in
- let nprods = List.length (List.filter (fun (_,b,_) -> Option.is_empty b) ctx) in
+ let nprods = List.count (fun (_,b,_) -> Option.is_empty b) ctx in
not (List.is_empty impl) && List.length impl >= nprods &&
let _,lastimpl = List.chop nprods impl in
List.exists is_status_implicit lastimpl
diff --git a/printing/printer.ml b/printing/printer.ml
index 5ad0e4531..93850e41f 100644
--- a/printing/printer.ml
+++ b/printing/printer.ml
@@ -293,7 +293,7 @@ let pr_named_context_of env sigma =
hv 0 (prlist_with_sep (fun _ -> ws 2) (fun x -> x) psl)
let pr_named_context env sigma ne_context =
- hv 0 (Context.fold_named_context
+ hv 0 (Context.Named.fold_outside
(fun d pps -> pps ++ ws 2 ++ pr_var_decl env sigma d)
ne_context ~init:(mt ()))
@@ -306,7 +306,7 @@ let pr_rel_context_of env sigma =
(* Prints an env (variables and de Bruijn). Separator: newline *)
let pr_context_unlimited env sigma =
let sign_env =
- Context.fold_named_list_context
+ Context.NamedList.fold
(fun d pps ->
let pidt = pr_var_list_decl env sigma d in
(pps ++ fnl () ++ pidt))
@@ -333,7 +333,7 @@ let pr_context_limit n env sigma =
else
let k = lgsign-n in
let _,sign_env =
- Context.fold_named_list_context
+ Context.NamedList.fold
(fun d (i,pps) ->
if i < k then
(i+1, (pps ++str "."))
@@ -639,8 +639,8 @@ let pr_open_subgoals ?(proof=Proof_global.give_me_the_proof ()) () =
| _ , _, _ ->
let end_cmd =
str "This subproof is complete, but there are some unfocused goals." ++
- (match Proof_global.Bullet.suggest p
- with None -> str"" | Some s -> fnl () ++ str s) ++
+ (let s = Proof_global.Bullet.suggest p in
+ if Pp.is_empty s then s else fnl () ++ s) ++
fnl ()
in
pr_subgoals ~pr_first:false (Some end_cmd) bsigma seeds shelf [] bgoals
@@ -726,7 +726,7 @@ let prterm = pr_lconstr
type context_object =
| Variable of Id.t (* A section variable or a Let definition *)
- | Axiom of constant * (Label.t * Context.rel_context * types) list
+ | Axiom of constant * (Label.t * Context.Rel.t * types) list
| Opaque of constant (* An opaque constant. *)
| Transparent of constant
@@ -777,7 +777,7 @@ let pr_assumptionset env s =
let (v, a, o, tr) = accu in
match t with
| Variable id ->
- let var = str (Id.to_string id) ++ str " : " ++ pr_ltype typ in
+ let var = pr_id id ++ str " : " ++ pr_ltype typ in
(var :: v, a, o, tr)
| Axiom (kn,[]) ->
let ax = safe_pr_constant env kn ++ safe_pr_ltype typ in
@@ -786,7 +786,7 @@ let pr_assumptionset env s =
let ax = safe_pr_constant env kn ++ safe_pr_ltype typ ++
cut() ++
prlist_with_sep cut (fun (lbl, ctx, ty) ->
- str " used in " ++ str (Names.Label.to_string lbl) ++
+ str " used in " ++ pr_label lbl ++
str " to prove:" ++ safe_pr_ltype_relctx (ctx,ty))
l in
(v, ax :: a, o, tr)
diff --git a/printing/printer.mli b/printing/printer.mli
index 3424c41dc..70993bb72 100644
--- a/printing/printer.mli
+++ b/printing/printer.mli
@@ -10,7 +10,6 @@ open Pp
open Names
open Globnames
open Term
-open Context
open Environ
open Pattern
open Evd
@@ -109,13 +108,13 @@ val pr_pconstructor : env -> pconstructor -> std_ppcmds
val pr_context_unlimited : env -> evar_map -> std_ppcmds
val pr_ne_context_of : std_ppcmds -> env -> evar_map -> std_ppcmds
-val pr_var_decl : env -> evar_map -> named_declaration -> std_ppcmds
-val pr_var_list_decl : env -> evar_map -> named_list_declaration -> std_ppcmds
-val pr_rel_decl : env -> evar_map -> rel_declaration -> std_ppcmds
+val pr_var_decl : env -> evar_map -> Context.Named.Declaration.t -> std_ppcmds
+val pr_var_list_decl : env -> evar_map -> Context.NamedList.Declaration.t -> std_ppcmds
+val pr_rel_decl : env -> evar_map -> Context.Rel.Declaration.t -> std_ppcmds
-val pr_named_context : env -> evar_map -> named_context -> std_ppcmds
+val pr_named_context : env -> evar_map -> Context.Named.t -> std_ppcmds
val pr_named_context_of : env -> evar_map -> std_ppcmds
-val pr_rel_context : env -> evar_map -> rel_context -> std_ppcmds
+val pr_rel_context : env -> evar_map -> Context.Rel.t -> std_ppcmds
val pr_rel_context_of : env -> evar_map -> std_ppcmds
val pr_context_of : env -> evar_map -> std_ppcmds
@@ -165,7 +164,7 @@ val prterm : constr -> std_ppcmds (** = pr_lconstr *)
type context_object =
| Variable of Id.t (** A section variable or a Let definition *)
(** An axiom and the type it inhabits (if an axiom of the empty type) *)
- | Axiom of constant * (Label.t * Context.rel_context * types) list
+ | Axiom of constant * (Label.t * Context.Rel.t * types) list
| Opaque of constant (** An opaque constant. *)
| Transparent of constant (** A transparent constant *)
diff --git a/printing/printmod.ml b/printing/printmod.ml
index c154b0aaa..9354cd28d 100644
--- a/printing/printmod.ml
+++ b/printing/printmod.ml
@@ -89,7 +89,7 @@ let print_one_inductive env sigma mib ((_,i) as ind) =
else Univ.Instance.empty in
let mip = mib.mind_packets.(i) in
let params = Inductive.inductive_paramdecls (mib,u) in
- let args = extended_rel_list 0 params in
+ let args = Context.Rel.to_extended_list 0 params in
let arity = hnf_prod_applist env (build_ind_type env ((mib,mip),u)) args in
let cstrtypes = Inductive.type_of_constructors (ind,u) (mib,mip) in
let cstrtypes = Array.map (fun c -> hnf_prod_applist env c args) cstrtypes in
@@ -143,7 +143,7 @@ let print_record env mind mib =
in
let mip = mib.mind_packets.(0) in
let params = Inductive.inductive_paramdecls (mib,u) in
- let args = extended_rel_list 0 params in
+ let args = Context.Rel.to_extended_list 0 params in
let arity = hnf_prod_applist env (build_ind_type env ((mib,mip),u)) args in
let cstrtypes = Inductive.type_of_constructors ((mind,0),u) (mib,mip) in
let cstrtype = hnf_prod_applist env cstrtypes.(0) args in
@@ -263,7 +263,7 @@ let nametab_register_modparam mbid mtb =
List.iter (nametab_register_body mp dir) struc
let print_body is_impl env mp (l,body) =
- let name = str (Label.to_string l) in
+ let name = pr_label l in
hov 2 (match body with
| SFBmodule _ -> keyword "Module" ++ spc () ++ name
| SFBmodtype _ -> keyword "Module Type" ++ spc () ++ name
diff --git a/proofs/clenv.ml b/proofs/clenv.ml
index 88e1bce95..1ef0b087b 100644
--- a/proofs/clenv.ml
+++ b/proofs/clenv.ml
@@ -24,6 +24,7 @@ open Pretype_errors
open Evarutil
open Unification
open Misctypes
+open Sigma.Notations
(* Abbreviations *)
@@ -119,7 +120,7 @@ let clenv_environments evd bound t =
clrec (evd,[]) bound t
let mk_clenv_from_env env sigma n (c,cty) =
- let evd = create_goal_evar_defs sigma in
+ let evd = clear_metas sigma in
let (evd,args,concl) = clenv_environments evd n cty in
{ templval = mk_freelisted (applist (c,args));
templtyp = mk_freelisted concl;
@@ -335,22 +336,15 @@ let clenv_pose_metas_as_evars clenv dep_mvs =
else
let src = evar_source_of_meta mv clenv.evd in
let src = adjust_meta_source clenv.evd mv src in
- let (evd,evar) = new_evar (cl_env clenv) clenv.evd ~src ty in
+ let evd = Sigma.Unsafe.of_evar_map clenv.evd in
+ let Sigma (evar, evd, _) = new_evar (cl_env clenv) evd ~src ty in
+ let evd = Sigma.to_evar_map evd in
let clenv = clenv_assign mv evar {clenv with evd=evd} in
fold clenv mvs in
fold clenv dep_mvs
(******************************************************************)
-let connect_clenv gls clenv =
- let evd = evars_reset_evd ~with_conv_pbs:true gls.sigma clenv.evd in
- { clenv with
- evd = evd ;
- env = Goal.V82.env evd (sig_it gls) }
-
-(* let connect_clenv_key = Profile.declare_profile "connect_clenv";; *)
-(* let connect_clenv = Profile.profile2 connect_clenv_key connect_clenv *)
-
(* [clenv_fchain mv clenv clenv']
*
* Resolves the value of "mv" (which must be undefined) in clenv to be
@@ -432,6 +426,44 @@ let check_bindings bl =
str " occurs more than once in binding list.")
| [] -> ()
+let explain_no_such_bound_variable evd id =
+ let fold l (n, clb) =
+ let na = match clb with
+ | Cltyp (na, _) -> na
+ | Clval (na, _, _) -> na
+ in
+ if na != Anonymous then out_name na :: l else l
+ in
+ let mvl = List.fold_left fold [] (Evd.meta_list evd) in
+ errorlabstrm "Evd.meta_with_name"
+ (str"No such bound variable " ++ pr_id id ++
+ (if mvl == [] then str " (no bound variables at all in the expression)."
+ else
+ (str" (possible name" ++
+ str (if List.length mvl == 1 then " is: " else "s are: ") ++
+ pr_enum pr_id mvl ++ str").")))
+
+let meta_with_name evd id =
+ let na = Name id in
+ let fold (l1, l2 as l) (n, clb) =
+ let (na',def) = match clb with
+ | Cltyp (na, _) -> (na, false)
+ | Clval (na, _, _) -> (na, true)
+ in
+ if Name.equal na na' then if def then (n::l1,l2) else (n::l1,n::l2)
+ else l
+ in
+ let (mvl, mvnodef) = List.fold_left fold ([], []) (Evd.meta_list evd) in
+ match mvnodef, mvl with
+ | _,[] ->
+ explain_no_such_bound_variable evd id
+ | ([n],_|_,[n]) ->
+ n
+ | _ ->
+ errorlabstrm "Evd.meta_with_name"
+ (str "Binder name \"" ++ pr_id id ++
+ strbrk "\" occurs more than once in clause.")
+
let meta_of_binder clause loc mvs = function
| NamedHyp s -> meta_with_name clause.evd s
| AnonHyp n ->
@@ -576,7 +608,9 @@ let make_evar_clause env sigma ?len t =
| Cast (t, _, _) -> clrec (sigma, holes) n t
| Prod (na, t1, t2) ->
let store = Typeclasses.set_resolvable Evd.Store.empty false in
- let sigma, ev = new_evar ~store env sigma t1 in
+ let sigma = Sigma.Unsafe.of_evar_map sigma in
+ let Sigma (ev, sigma, _) = new_evar ~store env sigma t1 in
+ let sigma = Sigma.to_evar_map sigma in
let dep = dependent (mkRel 1) t2 in
let hole = {
hole_evar = ev;
diff --git a/proofs/clenv.mli b/proofs/clenv.mli
index 7ecc26ec9..59b166ea0 100644
--- a/proofs/clenv.mli
+++ b/proofs/clenv.mli
@@ -49,7 +49,6 @@ val refresh_undefined_univs : clausenv -> clausenv * Univ.universe_level_subst
(** {6 linking of clenvs } *)
-val connect_clenv : Goal.goal sigma -> clausenv -> clausenv
val clenv_fchain :
?with_univs:bool -> ?flags:unify_flags -> metavariable -> clausenv -> clausenv -> clausenv
diff --git a/proofs/clenvtac.ml b/proofs/clenvtac.ml
index 8e9225992..08e6c91de 100644
--- a/proofs/clenvtac.ml
+++ b/proofs/clenvtac.ml
@@ -16,7 +16,7 @@ open Logic
open Reduction
open Tacmach
open Clenv
-
+open Proofview.Notations
(* This function put casts around metavariables whose type could not be
* infered by the refiner, that is head of applications, predicates and
@@ -83,10 +83,10 @@ open Unification
let dft = default_unify_flags
let res_pf ?(with_evars=false) ?(with_classes=true) ?(flags=dft ()) clenv =
- Proofview.Goal.enter begin fun gl ->
+ Proofview.Goal.enter { enter = begin fun gl ->
let clenv gl = clenv_unique_resolver ~flags clenv gl in
clenv_refine with_evars ~with_classes (Tacmach.New.of_old clenv (Proofview.Goal.assume gl))
- end
+ end }
(* [unifyTerms] et [unify] ne semble pas gérer les Meta, en
particulier ne semblent pas vérifier que des instances différentes
@@ -118,12 +118,12 @@ let fail_quick_unif_flags = {
(* let unifyTerms m n = walking (fun wc -> fst (w_Unify CONV m n [] wc)) *)
let unify ?(flags=fail_quick_unif_flags) m =
- Proofview.Goal.enter begin fun gl ->
+ Proofview.Goal.enter { enter = begin fun gl ->
let env = Tacmach.New.pf_env gl in
let n = Tacmach.New.pf_nf_concl gl in
- let evd = create_goal_evar_defs (Proofview.Goal.sigma gl) in
+ let evd = clear_metas (Tacmach.New.project gl) in
try
let evd' = w_unify env evd CONV ~flags m n in
Proofview.Unsafe.tclEVARSADVANCE evd'
with e when Errors.noncritical e -> Proofview.tclZERO e
- end
+ end }
diff --git a/proofs/goal.mli b/proofs/goal.mli
index 6152826ca..8a3d6e815 100644
--- a/proofs/goal.mli
+++ b/proofs/goal.mli
@@ -67,7 +67,7 @@ module V82 : sig
val same_goal : Evd.evar_map -> goal -> Evd.evar_map -> goal -> bool
(* Used for congruence closure *)
- val new_goal_with : Evd.evar_map -> goal -> Context.named_context -> goal Evd.sigma
+ val new_goal_with : Evd.evar_map -> goal -> Context.Named.t -> goal Evd.sigma
(* Used by the compatibility layer and typeclasses *)
val nf_evar : Evd.evar_map -> goal -> goal * Evd.evar_map
diff --git a/proofs/logic.ml b/proofs/logic.ml
index ed3a1df1a..99e32db04 100644
--- a/proofs/logic.ml
+++ b/proofs/logic.ml
@@ -95,12 +95,12 @@ let check_typability env sigma c =
forces the user to give them in order). *)
let clear_hyps env sigma ids sign cl =
- let evdref = ref (Evd.create_goal_evar_defs sigma) in
+ let evdref = ref (Evd.clear_metas sigma) in
let (hyps,cl) = Evarutil.clear_hyps_in_evi env evdref sign cl ids in
(hyps, cl, !evdref)
let clear_hyps2 env sigma ids sign t cl =
- let evdref = ref (Evd.create_goal_evar_defs sigma) in
+ let evdref = ref (Evd.clear_metas sigma) in
let (hyps,t,cl) = Evarutil.clear_hyps2_in_evi env evdref sign t cl ids in
(hyps, t, cl, !evdref)
@@ -532,7 +532,7 @@ let prim_refiner r sigma goal =
push_named_context_val (id,None,t) sign,t,cl,sigma) in
let (sg2,ev2,sigma) =
Goal.V82.mk_goal sigma sign cl (Goal.V82.extra sigma goal) in
- let oterm = Term.mkApp (mkNamedLambda id t ev2 , [| ev1 |]) in
+ let oterm = Term.mkNamedLetIn id ev1 t ev2 in
let sigma = Goal.V82.partial_solution_to sigma goal sg2 oterm in
if b then ([sg1;sg2],sigma) else ([sg2;sg1],sigma)
diff --git a/proofs/logic.mli b/proofs/logic.mli
index ed99d3a38..9aa4ac207 100644
--- a/proofs/logic.mli
+++ b/proofs/logic.mli
@@ -53,4 +53,4 @@ exception RefinerError of refiner_error
val catchable_exception : exn -> bool
val convert_hyp : bool -> Environ.named_context_val -> evar_map ->
- Context.named_declaration -> Environ.named_context_val
+ Context.Named.Declaration.t -> Environ.named_context_val
diff --git a/proofs/pfedit.ml b/proofs/pfedit.ml
index b635cc963..20d696fd9 100644
--- a/proofs/pfedit.ml
+++ b/proofs/pfedit.ml
@@ -138,7 +138,8 @@ let next = let n = ref 0 in fun () -> incr n; !n
let build_constant_by_tactic id ctx sign ?(goal_kind = Global, false, Proof Theorem) typ tac =
let evd = Evd.from_ctx ctx in
- start_proof id goal_kind evd sign typ (fun _ -> ());
+ let terminator = Proof_global.make_terminator (fun _ -> ()) in
+ start_proof id goal_kind evd sign typ terminator;
try
let status = by tac in
let _,(const,univs,_) = cook_proof () in
@@ -214,7 +215,7 @@ let solve_by_implicit_tactic env sigma evk =
match (!implicit_tactic, snd (evar_source evk sigma)) with
| Some tac, (Evar_kinds.ImplicitArg _ | Evar_kinds.QuestionMark _)
when
- Context.named_context_equal (Environ.named_context_of_val evi.evar_hyps)
+ Context.Named.equal (Environ.named_context_of_val evi.evar_hyps)
(Environ.named_context env) ->
let tac = Proofview.tclTHEN tac (Proofview.tclEXTEND [] (Proofview.tclZERO (Errors.UserError ("",Pp.str"Proof is not complete."))) []) in
(try
diff --git a/proofs/proof_global.ml b/proofs/proof_global.ml
index f22cdbcc8..fc33e9a65 100644
--- a/proofs/proof_global.ml
+++ b/proofs/proof_global.ml
@@ -92,6 +92,9 @@ type pstate = {
universe_binders: universe_binders option;
}
+let make_terminator f = f
+let apply_terminator f = f
+
(* The head of [!pstates] is the actual current proof, the other ones are
to be resumed when the current proof is closed or aborted. *)
let pstates = ref ([] : pstate list)
@@ -299,6 +302,11 @@ let get_open_goals () =
(List.map (fun (l1,l2) -> List.length l1 + List.length l2) gll) +
List.length shelf
+let constrain_variables init uctx =
+ let levels = Univ.Instance.levels (Univ.UContext.instance init) in
+ let cstrs = UState.constrain_variables levels uctx in
+ Univ.ContextSet.add_constraints cstrs (UState.context_set uctx)
+
let close_proof ~keep_body_ucst_separate ?feedback_id ~now fpl =
let { pid; section_vars; strength; proof; terminator; universe_binders } =
cur_pstate () in
@@ -329,7 +337,7 @@ let close_proof ~keep_body_ucst_separate ?feedback_id ~now fpl =
if keep_body_ucst_separate ||
not (Safe_typing.empty_private_constants = eff) then
let initunivs = Evd.evar_context_universe_context initial_euctx in
- let ctx = Evd.evar_universe_context_set initunivs universes in
+ let ctx = constrain_variables initunivs universes in
(* For vi2vo compilation proofs are computed now but we need to
* complement the univ constraints of the typ with the ones of
* the body. So we keep the two sets distinct. *)
@@ -338,7 +346,7 @@ let close_proof ~keep_body_ucst_separate ?feedback_id ~now fpl =
(initunivs, typ), ((body, ctx_body), eff)
else
let initunivs = Univ.UContext.empty in
- let ctx = Evd.evar_universe_context_set initunivs universes in
+ let ctx = constrain_variables initunivs universes in
(* Since the proof is computed now, we can simply have 1 set of
* constraints in which we merge the ones for the body and the ones
* for the typ *)
@@ -353,7 +361,7 @@ let close_proof ~keep_body_ucst_separate ?feedback_id ~now fpl =
let initunivs = Evd.evar_context_universe_context initial_euctx in
Future.from_val (initunivs, nf t),
Future.chain ~pure:true p (fun (pt,eff) ->
- (pt,Evd.evar_universe_context_set initunivs (Future.force univs)),eff)
+ (pt,constrain_variables initunivs (Future.force univs)),eff)
in
let entries =
Future.map2 (fun p (_, t) ->
@@ -458,7 +466,7 @@ module Bullet = struct
type behavior = {
name : string;
put : Proof.proof -> t -> Proof.proof;
- suggest: Proof.proof -> string option
+ suggest: Proof.proof -> std_ppcmds
}
let behaviors = Hashtbl.create 4
@@ -468,7 +476,7 @@ module Bullet = struct
let none = {
name = "None";
put = (fun x _ -> x);
- suggest = (fun _ -> None)
+ suggest = (fun _ -> mt ())
}
let _ = register_behavior none
@@ -484,26 +492,20 @@ module Bullet = struct
(* give a message only if more informative than the standard coq message *)
let suggest_on_solved_goal sugg =
match sugg with
- | NeedClosingBrace -> Some "Try unfocusing with \"}\"."
- | NoBulletInUse -> None
- | ProofFinished -> None
- | Suggest b -> Some ("Focus next goal with bullet "
- ^ Pp.string_of_ppcmds (Pp.(pr_bullet b))
- ^".")
- | Unfinished b -> Some ("The current bullet "
- ^ Pp.string_of_ppcmds (Pp.(pr_bullet b))
- ^ " is unfinished.")
+ | NeedClosingBrace -> str"Try unfocusing with \"}\"."
+ | NoBulletInUse -> mt ()
+ | ProofFinished -> mt ()
+ | Suggest b -> str"Focus next goal with bullet " ++ pr_bullet b ++ str"."
+ | Unfinished b -> str"The current bullet " ++ pr_bullet b ++ str" is unfinished."
(* give always a message. *)
let suggest_on_error sugg =
match sugg with
- | NeedClosingBrace -> "Try unfocusing with \"}\"."
+ | NeedClosingBrace -> str"Try unfocusing with \"}\"."
| NoBulletInUse -> assert false (* This should never raise an error. *)
- | ProofFinished -> "No more subgoals."
- | Suggest b -> ("Bullet " ^ Pp.string_of_ppcmds (Pp.(pr_bullet b))
- ^ " is mandatory here.")
- | Unfinished b -> ("Current bullet " ^ Pp.string_of_ppcmds (Pp.(pr_bullet b))
- ^ " is not finished.")
+ | ProofFinished -> str"No more subgoals."
+ | Suggest b -> str"Bullet " ++ pr_bullet b ++ str" is mandatory here."
+ | Unfinished b -> str"Current bullet " ++ pr_bullet b ++ str" is not finished."
exception FailedBullet of t * suggestion
@@ -511,8 +513,8 @@ module Bullet = struct
Errors.register_handler
(function
| FailedBullet (b,sugg) ->
- let prefix = "Wrong bullet " ^ Pp.string_of_ppcmds (Pp.(pr_bullet b)) ^ " : " in
- Errors.errorlabstrm "Focus" (str prefix ++ str (suggest_on_error sugg))
+ let prefix = str"Wrong bullet " ++ pr_bullet b ++ str" : " in
+ Errors.errorlabstrm "Focus" (prefix ++ suggest_on_error sugg)
| _ -> raise Errors.Unhandled)
diff --git a/proofs/proof_global.mli b/proofs/proof_global.mli
index 7fbd183e6..ebe7f6d6f 100644
--- a/proofs/proof_global.mli
+++ b/proofs/proof_global.mli
@@ -70,9 +70,12 @@ type proof_ending =
| Proved of Vernacexpr.opacity_flag *
(Vernacexpr.lident * Decl_kinds.theorem_kind option) option *
proof_object
-type proof_terminator = proof_ending -> unit
+type proof_terminator
type closed_proof = proof_object * proof_terminator
+val make_terminator : (proof_ending -> unit) -> proof_terminator
+val apply_terminator : proof_terminator -> proof_ending -> unit
+
(** [start_proof id str goals terminator] starts a proof of name [id]
with goals [goals] (a list of pairs of environment and
conclusion); [str] describes what kind of theorem/definition this
@@ -169,7 +172,7 @@ module Bullet : sig
type behavior = {
name : string;
put : Proof.proof -> t -> Proof.proof;
- suggest: Proof.proof -> string option
+ suggest: Proof.proof -> Pp.std_ppcmds
}
(** A registered behavior can then be accessed in Coq
@@ -186,7 +189,7 @@ module Bullet : sig
(** Handles focusing/defocusing with bullets:
*)
val put : Proof.proof -> t -> Proof.proof
- val suggest : Proof.proof -> string option
+ val suggest : Proof.proof -> Pp.std_ppcmds
end
diff --git a/proofs/proofs.mllib b/proofs/proofs.mllib
index 32bf5576f..1bd701cb9 100644
--- a/proofs/proofs.mllib
+++ b/proofs/proofs.mllib
@@ -4,8 +4,6 @@ Evar_refiner
Proof_using
Proof_type
Proof_errors
-Logic_monad
-Proofview_monad
Logic
Proofview
Proof
diff --git a/proofs/proofview.ml b/proofs/proofview.ml
index a6d9735f1..ff8effcda 100644
--- a/proofs/proofview.ml
+++ b/proofs/proofview.ml
@@ -16,6 +16,7 @@
open Pp
open Util
open Proofview_monad
+open Sigma.Notations
(** Main state of tactics *)
type proofview = Proofview_monad.proofview
@@ -64,7 +65,9 @@ let dependent_init =
let rec aux = function
| TNil sigma -> [], { solution = sigma; comb = []; shelf = [] }
| TCons (env, sigma, typ, t) ->
- let (sigma, econstr ) = Evarutil.new_evar env sigma ~src ~store typ in
+ let sigma = Sigma.Unsafe.of_evar_map sigma in
+ let Sigma (econstr, sigma, _) = Evarutil.new_evar env sigma ~src ~store typ in
+ let sigma = Sigma.to_evar_map sigma in
let ret, { solution = sol; comb = comb } = aux (t sigma econstr) in
let (gl, _) = Term.destEvar econstr in
let entry = (econstr, typ) :: ret in
@@ -350,7 +353,7 @@ exception NoSuchGoals of int
(* This hook returns a string to be appended to the usual message.
Primarily used to add a suggestion about the right bullet to use to
focus the next goal, if applicable. *)
-let nosuchgoals_hook:(int -> string option) ref = ref ((fun n -> None))
+let nosuchgoals_hook:(int -> std_ppcmds) ref = ref (fun n -> mt ())
let set_nosuchgoals_hook f = nosuchgoals_hook := f
@@ -358,10 +361,9 @@ let set_nosuchgoals_hook f = nosuchgoals_hook := f
(* This uses the hook above *)
let _ = Errors.register_handler begin function
| NoSuchGoals n ->
- let suffix:string option = (!nosuchgoals_hook) n in
+ let suffix = !nosuchgoals_hook n in
Errors.errorlabstrm ""
- (str "No such " ++ str (String.plural n "goal") ++ str "."
- ++ pr_opt str suffix)
+ (str "No such " ++ str (String.plural n "goal") ++ str "." ++ suffix)
| _ -> raise Errors.Unhandled
end
@@ -907,19 +909,11 @@ module Unsafe = struct
end
+module UnsafeRepr = Proof.Unsafe
-
-(** {7 Notations} *)
-
-module Notations = struct
- let (>>=) = tclBIND
- let (<*>) = tclTHEN
- let (<+>) t1 t2 = tclOR t1 (fun _ -> t2)
-end
-
-open Notations
-
-
+let (>>=) = tclBIND
+let (<*>) = tclTHEN
+let (<+>) t1 t2 = tclOR t1 (fun _ -> t2)
(** {6 Goal-dependent tactics} *)
@@ -933,17 +927,20 @@ let catchable_exception = function
module Goal = struct
- type 'a t = {
+ type ('a, 'r) t = {
env : Environ.env;
sigma : Evd.evar_map;
concl : Term.constr ;
self : Evar.t ; (* for compatibility with old-style definitions *)
}
- let assume (gl : 'a t) = (gl :> [ `NF ] t)
+ type ('a, 'b) enter =
+ { enter : 'r. ('a, 'r) t -> 'b }
+
+ let assume (gl : ('a, 'r) t) = (gl :> ([ `NF ], 'r) t)
let env { env=env } = env
- let sigma { sigma=sigma } = sigma
+ let sigma { sigma=sigma } = Sigma.Unsafe.of_evar_map sigma
let hyps { env=env } = Environ.named_context env
let concl { concl=concl } = concl
let extra { sigma=sigma; self=self } = Goal.V82.extra sigma self
@@ -969,7 +966,7 @@ module Goal = struct
tclEVARMAP >>= fun sigma ->
try
let (gl, sigma) = nf_gmake env sigma goal in
- tclTHEN (Unsafe.tclEVARS sigma) (InfoL.tag (Info.DBranch) (f gl))
+ tclTHEN (Unsafe.tclEVARS sigma) (InfoL.tag (Info.DBranch) (f.enter gl))
with e when catchable_exception e ->
let (e, info) = Errors.push e in
tclZERO ~info e
@@ -987,7 +984,7 @@ module Goal = struct
gmake_with info env sigma goal
let enter f =
- let f gl = InfoL.tag (Info.DBranch) (f gl) in
+ let f gl = InfoL.tag (Info.DBranch) (f.enter gl) in
InfoL.tag (Info.Dispatch) begin
iter_goal begin fun goal ->
Env.get >>= fun env ->
@@ -999,6 +996,41 @@ module Goal = struct
end
end
+ type ('a, 'b) s_enter =
+ { s_enter : 'r. ('a, 'r) t -> ('b, 'r) Sigma.sigma }
+
+ let s_enter f =
+ InfoL.tag (Info.Dispatch) begin
+ iter_goal begin fun goal ->
+ Env.get >>= fun env ->
+ tclEVARMAP >>= fun sigma ->
+ try
+ let gl = gmake env sigma goal in
+ let Sigma (tac, sigma, _) = f.s_enter gl in
+ let sigma = Sigma.to_evar_map sigma in
+ tclTHEN (Unsafe.tclEVARS sigma) (InfoL.tag (Info.DBranch) tac)
+ with e when catchable_exception e ->
+ let (e, info) = Errors.push e in
+ tclZERO ~info e
+ end
+ end
+
+ let nf_s_enter f =
+ InfoL.tag (Info.Dispatch) begin
+ iter_goal begin fun goal ->
+ Env.get >>= fun env ->
+ tclEVARMAP >>= fun sigma ->
+ try
+ let (gl, sigma) = nf_gmake env sigma goal in
+ let Sigma (tac, sigma, _) = f.s_enter gl in
+ let sigma = Sigma.to_evar_map sigma in
+ tclTHEN (Unsafe.tclEVARS sigma) (InfoL.tag (Info.DBranch) tac)
+ with e when catchable_exception e ->
+ let (e, info) = Errors.push e in
+ tclZERO ~info e
+ end
+ end
+
let goals =
Env.get >>= fun env ->
Pv.get >>= fun step ->
@@ -1018,6 +1050,8 @@ module Goal = struct
(* compatibility *)
let goal { self=self } = self
+ let lift (gl : ('a, 'r) t) _ = (gl :> ('a, 's) t)
+
end
@@ -1066,8 +1100,9 @@ struct
let (pr_constrv,pr_constr) =
Hook.make ~default:(fun _env _sigma _c -> Pp.str"<constr>") ()
- let refine ?(unsafe = true) f = Goal.enter begin fun gl ->
+ let refine ?(unsafe = true) f = Goal.enter { Goal.enter = begin fun gl ->
let sigma = Goal.sigma gl in
+ let sigma = Sigma.to_evar_map sigma in
let env = Goal.env gl in
let concl = Goal.concl gl in
(** Save the [future_goals] state to restore them after the
@@ -1075,7 +1110,7 @@ struct
let prev_future_goals = Evd.future_goals sigma in
let prev_principal_goal = Evd.principal_future_goal sigma in
(** Create the refinement term *)
- let (sigma, c) = f (Evd.reset_future_goals sigma) in
+ let (c, sigma) = Sigma.run (Evd.reset_future_goals sigma) f in
let evs = Evd.future_goals sigma in
let evkmain = Evd.principal_future_goal sigma in
(** Check that the introduced evars are well-typed *)
@@ -1103,7 +1138,7 @@ struct
let open Proof in
InfoL.leaf (Info.Tactic (fun () -> Pp.(hov 2 (str"refine"++spc()++ Hook.get pr_constrv env sigma c)))) >>
Pv.modify (fun ps -> { ps with solution = sigma; comb; })
- end
+ end }
(** Useful definitions *)
@@ -1115,12 +1150,16 @@ struct
in
evd , j'.Environ.uj_val
- let refine_casted ?unsafe f = Goal.enter begin fun gl ->
+ let refine_casted ?unsafe f = Goal.enter { Goal.enter = begin fun gl ->
let concl = Goal.concl gl in
let env = Goal.env gl in
- let f h = let (h, c) = f h in with_type env h c concl in
+ let f = { run = fun h ->
+ let Sigma (c, h, p) = f.run h in
+ let sigma, c = with_type env (Sigma.to_evar_map h) c concl in
+ Sigma (c, Sigma.Unsafe.of_evar_map sigma, p)
+ } in
refine ?unsafe f
- end
+ end }
end
@@ -1255,3 +1294,15 @@ module V82 = struct
let (e, info) = Errors.push e in tclZERO ~info e
end
+
+(** {7 Notations} *)
+
+module Notations = struct
+ let (>>=) = tclBIND
+ let (<*>) = tclTHEN
+ let (<+>) t1 t2 = tclOR t1 (fun _ -> t2)
+ type ('a, 'b) enter = ('a, 'b) Goal.enter =
+ { enter : 'r. ('a, 'r) Goal.t -> 'b }
+ type ('a, 'b) s_enter = ('a, 'b) Goal.s_enter =
+ { s_enter : 'r. ('a, 'r) Goal.t -> ('b, 'r) Sigma.sigma }
+end
diff --git a/proofs/proofview.mli b/proofs/proofview.mli
index 2157459f4..dc97e44b6 100644
--- a/proofs/proofview.mli
+++ b/proofs/proofview.mli
@@ -235,7 +235,7 @@ val tclBREAK : (iexn -> iexn option) -> 'a tactic -> 'a tactic
This hook is used to add a suggestion about bullets when
applicable. *)
exception NoSuchGoals of int
-val set_nosuchgoals_hook: (int -> string option) -> unit
+val set_nosuchgoals_hook: (int -> Pp.std_ppcmds) -> unit
val tclFOCUS : int -> int -> 'a tactic -> 'a tactic
@@ -409,65 +409,84 @@ module Unsafe : sig
val mark_as_goal : proofview -> Evar.t -> proofview
end
-(** {7 Notations} *)
-
-module Notations : sig
-
- (** {!tclBIND} *)
- val (>>=) : 'a tactic -> ('a -> 'b tactic) -> 'b tactic
- (** {!tclTHEN} *)
- val (<*>) : unit tactic -> 'a tactic -> 'a tactic
- (** {!tclOR}: [t1+t2] = [tclOR t1 (fun _ -> t2)]. *)
- val (<+>) : 'a tactic -> 'a tactic -> 'a tactic
-
+(** This module gives access to the innards of the monad. Its use is
+ restricted to very specific cases. *)
+module UnsafeRepr :
+sig
+ type state = Proofview_monad.Logical.Unsafe.state
+ val repr : 'a tactic -> ('a, state, state, iexn) Logic_monad.BackState.t
+ val make : ('a, state, state, iexn) Logic_monad.BackState.t -> 'a tactic
end
-
(** {6 Goal-dependent tactics} *)
module Goal : sig
- (** The type of goals. The parameter type is a phantom argument indicating
- whether the data contained in the goal has been normalized w.r.t. the
- current sigma. If it is the case, it is flagged [ `NF ]. You may still
- access the un-normalized data using {!assume} if you known you do not rely
- on the assumption of being normalized, at your own risk. *)
- type 'a t
+ (** Type of goals.
+
+ The first parameter type is a phantom argument indicating whether the data
+ contained in the goal has been normalized w.r.t. the current sigma. If it
+ is the case, it is flagged [ `NF ]. You may still access the un-normalized
+ data using {!assume} if you known you do not rely on the assumption of
+ being normalized, at your own risk.
+
+ The second parameter is a stage indicating where the goal belongs. See
+ module {!Sigma}.
+ *)
+ type ('a, 'r) t
(** Assume that you do not need the goal to be normalized. *)
- val assume : 'a t -> [ `NF ] t
+ val assume : ('a, 'r) t -> ([ `NF ], 'r) t
(** Normalises the argument goal. *)
- val normalize : 'a t -> [ `NF ] t tactic
+ val normalize : ('a, 'r) t -> ([ `NF ], 'r) t tactic
(** [concl], [hyps], [env] and [sigma] given a goal [gl] return
respectively the conclusion of [gl], the hypotheses of [gl], the
environment of [gl] (i.e. the global environment and the
hypotheses) and the current evar map. *)
- val concl : [ `NF ] t -> Term.constr
- val hyps : [ `NF ] t -> Context.named_context
- val env : 'a t -> Environ.env
- val sigma : 'a t -> Evd.evar_map
- val extra : 'a t -> Evd.Store.t
+ val concl : ([ `NF ], 'r) t -> Term.constr
+ val hyps : ([ `NF ], 'r) t -> Context.Named.t
+ val env : ('a, 'r) t -> Environ.env
+ val sigma : ('a, 'r) t -> 'r Sigma.t
+ val extra : ('a, 'r) t -> Evd.Store.t
(** Returns the goal's conclusion even if the goal is not
normalised. *)
- val raw_concl : 'a t -> Term.constr
+ val raw_concl : ('a, 'r) t -> Term.constr
+
+ type ('a, 'b) enter =
+ { enter : 'r. ('a, 'r) t -> 'b }
(** [nf_enter t] applies the goal-dependent tactic [t] in each goal
independently, in the manner of {!tclINDEPENDENT} except that
the current goal is also given as an argument to [t]. The goal
is normalised with respect to evars. *)
- val nf_enter : ([ `NF ] t -> unit tactic) -> unit tactic
+ val nf_enter : ([ `NF ], unit tactic) enter -> unit tactic
(** Like {!nf_enter}, but does not normalize the goal beforehand. *)
- val enter : ([ `LZ ] t -> unit tactic) -> unit tactic
+ val enter : ([ `LZ ], unit tactic) enter -> unit tactic
+
+ type ('a, 'b) s_enter =
+ { s_enter : 'r. ('a, 'r) t -> ('b, 'r) Sigma.sigma }
- (** Recover the list of current goals under focus, without evar-normalization *)
- val goals : [ `LZ ] t tactic list tactic
+ (** A variant of {!enter} allows to work with a monotonic state. The evarmap
+ returned by the argument is put back into the current state before firing
+ the returned tactic. *)
+ val s_enter : ([ `LZ ], unit tactic) s_enter -> unit tactic
+
+ (** Like {!s_enter}, but normalizes the goal beforehand. *)
+ val nf_s_enter : ([ `NF ], unit tactic) s_enter -> unit tactic
+
+ (** Recover the list of current goals under focus, without evar-normalization.
+ FIXME: encapsulate the level in an existential type. *)
+ val goals : ([ `LZ ], 'r) t tactic list tactic
(** Compatibility: avoid if possible *)
- val goal : [ `NF ] t -> Evar.t
+ val goal : ([ `NF ], 'r) t -> Evar.t
+
+ (** Every goal is valid at a later stage. FIXME: take a later evarmap *)
+ val lift : ('a, 'r) t -> ('r, 's) Sigma.le -> ('a, 's) t
end
@@ -482,7 +501,7 @@ module Refine : sig
(** {7 Refinement primitives} *)
- val refine : ?unsafe:bool -> (Evd.evar_map -> Evd.evar_map * Constr.t) -> unit tactic
+ val refine : ?unsafe:bool -> Constr.t Sigma.run -> unit tactic
(** In [refine ?unsafe t], [t] is a term with holes under some
[evar_map] context. The term [t] is used as a partial solution
for the current goal (refine is a goal-dependent tactic), the
@@ -498,7 +517,7 @@ module Refine : sig
(** [with_type env sigma c t] ensures that [c] is of type [t]
inserting a coercion if needed. *)
- val refine_casted : ?unsafe:bool -> (Evd.evar_map -> Evd.evar_map*Constr.t) -> unit tactic
+ val refine_casted : ?unsafe:bool -> Constr.t Sigma.run -> unit tactic
(** Like {!refine} except the refined term is coerced to the conclusion of the
current goal. *)
@@ -578,3 +597,20 @@ module V82 : sig
the monad. *)
val wrap_exceptions : (unit -> 'a tactic) -> 'a tactic
end
+
+(** {7 Notations} *)
+
+module Notations : sig
+
+ (** {!tclBIND} *)
+ val (>>=) : 'a tactic -> ('a -> 'b tactic) -> 'b tactic
+ (** {!tclTHEN} *)
+ val (<*>) : unit tactic -> 'a tactic -> 'a tactic
+ (** {!tclOR}: [t1+t2] = [tclOR t1 (fun _ -> t2)]. *)
+ val (<+>) : 'a tactic -> 'a tactic -> 'a tactic
+
+ type ('a, 'b) enter = ('a, 'b) Goal.enter =
+ { enter : 'r. ('a, 'r) Goal.t -> 'b }
+ type ('a, 'b) s_enter = ('a, 'b) Goal.s_enter =
+ { s_enter : 'r. ('a, 'r) Goal.t -> ('b, 'r) Sigma.sigma }
+end
diff --git a/proofs/redexpr.ml b/proofs/redexpr.ml
index ea21917ac..818805a56 100644
--- a/proofs/redexpr.ml
+++ b/proofs/redexpr.ml
@@ -158,8 +158,6 @@ let make_flag env f =
f.rConst red
in red
-let is_reference = function PRef _ | PVar _ -> true | _ -> false
-
(* table of custom reductino fonctions, not synchronized,
filled via ML calls to [declare_reduction] *)
let reduction_tab = ref String.Map.empty
diff --git a/proofs/refiner.ml b/proofs/refiner.ml
index 14493458c..8d6bdf6ae 100644
--- a/proofs/refiner.ml
+++ b/proofs/refiner.ml
@@ -197,10 +197,10 @@ let tclNOTSAMEGOAL (tac : tactic) goal =
destruct), this is not detected by this tactical. *)
let tclSHOWHYPS (tac : tactic) (goal: Goal.goal Evd.sigma)
:Proof_type.goal list Evd.sigma =
- let oldhyps:Context.named_context = pf_hyps goal in
+ let oldhyps:Context.Named.t = pf_hyps goal in
let rslt:Proof_type.goal list Evd.sigma = tac goal in
let { it = gls; sigma = sigma; } = rslt in
- let hyps:Context.named_context list =
+ let hyps:Context.Named.t list =
List.map (fun gl -> pf_hyps { it = gl; sigma=sigma; }) gls in
let cmp (i1, c1, t1) (i2, c2, t2) = Names.Id.equal i1 i2 in
let newhyps =
diff --git a/proofs/refiner.mli b/proofs/refiner.mli
index 13a9be59e..dd9153a02 100644
--- a/proofs/refiner.mli
+++ b/proofs/refiner.mli
@@ -6,7 +6,6 @@
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
-open Context
open Evd
open Proof_type
@@ -16,7 +15,7 @@ val sig_it : 'a sigma -> 'a
val project : 'a sigma -> evar_map
val pf_env : goal sigma -> Environ.env
-val pf_hyps : goal sigma -> named_context
+val pf_hyps : goal sigma -> Context.Named.t
val unpackage : 'a sigma -> evar_map ref * 'a
val repackage : evar_map ref -> 'a -> 'a sigma
diff --git a/proofs/tacmach.ml b/proofs/tacmach.ml
index a75b6fa0f..a1ebacea8 100644
--- a/proofs/tacmach.ml
+++ b/proofs/tacmach.ml
@@ -48,7 +48,7 @@ let pf_last_hyp gl = List.hd (pf_hyps gl)
let pf_get_hyp gls id =
try
- Context.lookup_named id (pf_hyps gls)
+ Context.Named.lookup id (pf_hyps gls)
with Not_found ->
raise (RefinerError (NoSuchHyp id))
@@ -158,11 +158,15 @@ let pr_glls glls =
(* Variants of [Tacmach] functions built with the new proof engine *)
module New = struct
+ let project gl =
+ let sigma = Proofview.Goal.sigma gl in
+ Sigma.to_evar_map sigma
+
let pf_apply f gl =
- f (Proofview.Goal.env gl) (Proofview.Goal.sigma gl)
+ f (Proofview.Goal.env gl) (project gl)
let of_old f gl =
- f { Evd.it = Proofview.Goal.goal gl ; sigma = Proofview.Goal.sigma gl }
+ f { Evd.it = Proofview.Goal.goal gl ; sigma = project gl; }
let pf_global id gl =
(** We only check for the existence of an [id] in [hyps] *)
@@ -194,7 +198,7 @@ module New = struct
let pf_get_hyp id gl =
let hyps = Proofview.Goal.hyps gl in
let sign =
- try Context.lookup_named id hyps
+ try Context.Named.lookup id hyps
with Not_found -> raise (RefinerError (NoSuchHyp id))
in
sign
@@ -212,11 +216,11 @@ module New = struct
let hyps = Proofview.Goal.hyps gl in
List.hd hyps
- let pf_nf_concl (gl : [ `LZ ] Proofview.Goal.t) =
+ let pf_nf_concl (gl : ([ `LZ ], 'r) Proofview.Goal.t) =
(** We normalize the conclusion just after *)
let gl = Proofview.Goal.assume gl in
let concl = Proofview.Goal.concl gl in
- let sigma = Proofview.Goal.sigma gl in
+ let sigma = project gl in
nf_evar sigma concl
let pf_whd_betadeltaiota gl t = pf_apply whd_betadeltaiota gl t
@@ -235,6 +239,6 @@ module New = struct
let pf_whd_betadeltaiota gl t = pf_apply whd_betadeltaiota gl t
let pf_compute gl t = pf_apply compute gl t
- let pf_nf_evar gl t = nf_evar (Proofview.Goal.sigma gl) t
+ let pf_nf_evar gl t = nf_evar (project gl) t
end
diff --git a/proofs/tacmach.mli b/proofs/tacmach.mli
index 7e943cb18..f786b5f21 100644
--- a/proofs/tacmach.mli
+++ b/proofs/tacmach.mli
@@ -8,7 +8,6 @@
open Names
open Term
-open Context
open Environ
open Evd
open Proof_type
@@ -34,18 +33,18 @@ val apply_sig_tac :
val pf_concl : goal sigma -> types
val pf_env : goal sigma -> env
-val pf_hyps : goal sigma -> named_context
+val pf_hyps : goal sigma -> Context.Named.t
(*i val pf_untyped_hyps : goal sigma -> (Id.t * constr) list i*)
val pf_hyps_types : goal sigma -> (Id.t * types) list
val pf_nth_hyp_id : goal sigma -> int -> Id.t
-val pf_last_hyp : goal sigma -> named_declaration
+val pf_last_hyp : goal sigma -> Context.Named.Declaration.t
val pf_ids_of_hyps : goal sigma -> Id.t list
val pf_global : goal sigma -> Id.t -> constr
val pf_unsafe_type_of : goal sigma -> constr -> types
val pf_type_of : goal sigma -> constr -> evar_map * types
val pf_hnf_type_of : goal sigma -> constr -> types
-val pf_get_hyp : goal sigma -> Id.t -> named_declaration
+val pf_get_hyp : goal sigma -> Id.t -> Context.Named.Declaration.t
val pf_get_hyp_typ : goal sigma -> Id.t -> types
val pf_get_new_id : Id.t -> goal sigma -> Id.t
@@ -106,36 +105,38 @@ val pr_glls : goal list sigma -> Pp.std_ppcmds
(* Variants of [Tacmach] functions built with the new proof engine *)
module New : sig
- val pf_apply : (env -> evar_map -> 'a) -> 'b Proofview.Goal.t -> 'a
- val pf_global : identifier -> 'a Proofview.Goal.t -> constr
- val of_old : (Proof_type.goal Evd.sigma -> 'a) -> [ `NF ] Proofview.Goal.t -> 'a
+ val pf_apply : (env -> evar_map -> 'a) -> ('b, 'r) Proofview.Goal.t -> 'a
+ val pf_global : identifier -> ('a, 'r) Proofview.Goal.t -> constr
+ (** FIXME: encapsulate the level in an existential type. *)
+ val of_old : (Proof_type.goal Evd.sigma -> 'a) -> ([ `NF ], 'r) Proofview.Goal.t -> 'a
- val pf_env : 'a Proofview.Goal.t -> Environ.env
- val pf_concl : [ `NF ] Proofview.Goal.t -> types
+ val project : ('a, 'r) Proofview.Goal.t -> Evd.evar_map
+ val pf_env : ('a, 'r) Proofview.Goal.t -> Environ.env
+ val pf_concl : ([ `NF ], 'r) Proofview.Goal.t -> types
- val pf_unsafe_type_of : 'a Proofview.Goal.t -> Term.constr -> Term.types
- val pf_type_of : 'a Proofview.Goal.t -> Term.constr -> evar_map * Term.types
- val pf_conv_x : 'a Proofview.Goal.t -> Term.constr -> Term.constr -> bool
+ val pf_unsafe_type_of : ('a, 'r) Proofview.Goal.t -> Term.constr -> Term.types
+ val pf_type_of : ('a, 'r) Proofview.Goal.t -> Term.constr -> evar_map * Term.types
+ val pf_conv_x : ('a, 'r) Proofview.Goal.t -> Term.constr -> Term.constr -> bool
- val pf_get_new_id : identifier -> [ `NF ] Proofview.Goal.t -> identifier
- val pf_ids_of_hyps : 'a Proofview.Goal.t -> identifier list
- val pf_hyps_types : 'a Proofview.Goal.t -> (identifier * types) list
+ val pf_get_new_id : identifier -> ([ `NF ], 'r) Proofview.Goal.t -> identifier
+ val pf_ids_of_hyps : ('a, 'r) Proofview.Goal.t -> identifier list
+ val pf_hyps_types : ('a, 'r) Proofview.Goal.t -> (identifier * types) list
- val pf_get_hyp : identifier -> [ `NF ] Proofview.Goal.t -> named_declaration
- val pf_get_hyp_typ : identifier -> [ `NF ] Proofview.Goal.t -> types
- val pf_last_hyp : [ `NF ] Proofview.Goal.t -> named_declaration
+ val pf_get_hyp : identifier -> ([ `NF ], 'r) Proofview.Goal.t -> Context.Named.Declaration.t
+ val pf_get_hyp_typ : identifier -> ([ `NF ], 'r) Proofview.Goal.t -> types
+ val pf_last_hyp : ([ `NF ], 'r) Proofview.Goal.t -> Context.Named.Declaration.t
- val pf_nf_concl : [ `LZ ] Proofview.Goal.t -> types
- val pf_reduce_to_quantified_ind : 'a Proofview.Goal.t -> types -> pinductive * types
+ val pf_nf_concl : ([ `LZ ], 'r) Proofview.Goal.t -> types
+ val pf_reduce_to_quantified_ind : ('a, 'r) Proofview.Goal.t -> types -> pinductive * types
- val pf_hnf_constr : 'a Proofview.Goal.t -> constr -> types
- val pf_hnf_type_of : 'a Proofview.Goal.t -> constr -> types
+ val pf_hnf_constr : ('a, 'r) Proofview.Goal.t -> constr -> types
+ val pf_hnf_type_of : ('a, 'r) Proofview.Goal.t -> constr -> types
- val pf_whd_betadeltaiota : 'a Proofview.Goal.t -> constr -> constr
- val pf_compute : 'a Proofview.Goal.t -> constr -> constr
+ val pf_whd_betadeltaiota : ('a, 'r) Proofview.Goal.t -> constr -> constr
+ val pf_compute : ('a, 'r) Proofview.Goal.t -> constr -> constr
- val pf_matches : 'a Proofview.Goal.t -> constr_pattern -> constr -> patvar_map
+ val pf_matches : ('a, 'r) Proofview.Goal.t -> constr_pattern -> constr -> patvar_map
- val pf_nf_evar : 'a Proofview.Goal.t -> constr -> constr
+ val pf_nf_evar : ('a, 'r) Proofview.Goal.t -> constr -> constr
end
diff --git a/proofs/tactic_debug.ml b/proofs/tactic_debug.ml
index a4a447e88..d33278ff8 100644
--- a/proofs/tactic_debug.ml
+++ b/proofs/tactic_debug.ml
@@ -12,6 +12,7 @@ open Pp
open Tacexpr
open Termops
open Nameops
+open Proofview.Notations
let (prtac, tactic_printer) = Hook.make ()
let (prmatchpatt, match_pattern_printer) = Hook.make ()
@@ -47,10 +48,10 @@ let db_pr_goal gl =
str" " ++ pc) ++ fnl ()
let db_pr_goal =
- Proofview.Goal.nf_enter begin fun gl ->
+ Proofview.Goal.nf_enter { enter = begin fun gl ->
let pg = db_pr_goal gl in
Proofview.tclLIFT (msg_tac_notice (str "Goal:" ++ fnl () ++ pg))
- end
+ end }
(* Prints the commands *)
diff --git a/stm/asyncTaskQueue.ml b/stm/asyncTaskQueue.ml
index cc9732604..bb312e3b1 100644
--- a/stm/asyncTaskQueue.ml
+++ b/stm/asyncTaskQueue.ml
@@ -60,9 +60,7 @@ module Make(T : Task) = struct
type more_data =
| MoreDataUnivLevel of Univ.universe_level list
-
- let request_expiry_of_task (t, c) = T.request_of_task t, c
-
+
let slave_respond (Request r) =
let res = T.perform r in
Response res
@@ -298,7 +296,7 @@ module Make(T : Task) = struct
let slave_feeder oc fb =
Marshal.to_channel oc (RespFeedback fb) []; flush oc in
Pp.set_feeder (fun x -> slave_feeder (Option.get !slave_oc) x);
- Pp.log_via_feedback ();
+ Pp.log_via_feedback (fun msg -> Richpp.repr (Richpp.richpp_of_pp msg));
Universes.set_remote_new_univ_level (bufferize (fun () ->
marshal_response (Option.get !slave_oc) RespGetCounterNewUnivLevel;
match unmarshal_more_data (Option.get !slave_ic) with
diff --git a/stm/lemmas.ml b/stm/lemmas.ml
index f06abfcce..845f83a40 100644
--- a/stm/lemmas.ml
+++ b/stm/lemmas.ml
@@ -329,7 +329,8 @@ let check_exist =
)
let universe_proof_terminator compute_guard hook =
- let open Proof_global in function
+ let open Proof_global in
+ make_terminator begin function
| Admitted (id,k,pe,(ctx,pl)) ->
admit (id,k,pe) pl (hook (Some ctx)) ();
Pp.feedback Feedback.AddedAxiom
@@ -347,12 +348,16 @@ let universe_proof_terminator compute_guard hook =
save_anonymous_with_strength ~export_seff proof kind id
end;
check_exist exports
+ end
let standard_proof_terminator compute_guard hook =
universe_proof_terminator compute_guard (fun _ -> hook)
-let start_proof id ?pl kind sigma ?sign c ?init_tac ?(compute_guard=[]) hook =
- let terminator = standard_proof_terminator compute_guard hook in
+let start_proof id ?pl kind sigma ?terminator ?sign c ?init_tac ?(compute_guard=[]) hook =
+ let terminator = match terminator with
+ | None -> standard_proof_terminator compute_guard hook
+ | Some terminator -> terminator compute_guard hook
+ in
let sign =
match sign with
| Some sign -> sign
@@ -361,8 +366,11 @@ let start_proof id ?pl kind sigma ?sign c ?init_tac ?(compute_guard=[]) hook =
!start_hook c;
Pfedit.start_proof id ?pl kind sigma sign c ?init_tac terminator
-let start_proof_univs id ?pl kind sigma ?sign c ?init_tac ?(compute_guard=[]) hook =
- let terminator = universe_proof_terminator compute_guard hook in
+let start_proof_univs id ?pl kind sigma ?terminator ?sign c ?init_tac ?(compute_guard=[]) hook =
+ let terminator = match terminator with
+ | None -> universe_proof_terminator compute_guard hook
+ | Some terminator -> terminator compute_guard hook
+ in
let sign =
match sign with
| Some sign -> sign
@@ -422,7 +430,7 @@ let start_proof_with_initialization kind ctx recguard thms snl hook =
let body,opaq = retrieve_first_recthm ref in
let subst = Evd.evar_universe_context_subst ctx in
let norm c = Universes.subst_opt_univs_constr subst c in
- let ctx = Evd.evar_universe_context_set (*FIXME*) Univ.UContext.empty ctx in
+ let ctx = UState.context_set (*FIXME*) ctx in
let body = Option.map norm body in
List.map_i (save_remaining_recthms kind norm ctx body opaq) 1 other_thms in
let thms_data = (strength,ref,imps)::other_thms_data in
@@ -494,7 +502,7 @@ let save_proof ?proof = function
Admitted(id,k,(sec_vars, pi2 k, (typ, ctx), None),
(universes, Some binders))
in
- Proof_global.get_terminator() pe
+ Proof_global.apply_terminator (Proof_global.get_terminator ()) pe
| Vernacexpr.Proved (is_opaque,idopt) ->
let (proof_obj,terminator) =
match proof with
@@ -504,7 +512,7 @@ let save_proof ?proof = function
in
(* if the proof is given explicitly, nothing has to be deleted *)
if Option.is_empty proof then Pfedit.delete_current_proof ();
- terminator (Proof_global.Proved (is_opaque,idopt,proof_obj))
+ Proof_global.(apply_terminator terminator (Proved (is_opaque,idopt,proof_obj)))
(* Miscellaneous *)
diff --git a/stm/lemmas.mli b/stm/lemmas.mli
index 16e54e318..9120787d1 100644
--- a/stm/lemmas.mli
+++ b/stm/lemmas.mli
@@ -9,8 +9,6 @@
open Names
open Term
open Decl_kinds
-open Constrexpr
-open Vernacexpr
open Pfedit
type 'a declaration_hook
@@ -24,11 +22,13 @@ val call_hook :
val set_start_hook : (types -> unit) -> unit
val start_proof : Id.t -> ?pl:universe_binders -> goal_kind -> Evd.evar_map ->
+ ?terminator:(lemma_possible_guards -> unit declaration_hook -> Proof_global.proof_terminator) ->
?sign:Environ.named_context_val -> types ->
?init_tac:unit Proofview.tactic -> ?compute_guard:lemma_possible_guards ->
unit declaration_hook -> unit
val start_proof_univs : Id.t -> ?pl:universe_binders -> goal_kind -> Evd.evar_map ->
+ ?terminator:(lemma_possible_guards -> (Evd.evar_universe_context option -> unit declaration_hook) -> Proof_global.proof_terminator) ->
?sign:Environ.named_context_val -> types ->
?init_tac:unit Proofview.tactic -> ?compute_guard:lemma_possible_guards ->
(Evd.evar_universe_context option -> unit declaration_hook) -> unit
@@ -43,6 +43,11 @@ val start_proof_with_initialization :
(types * (Name.t list * Impargs.manual_explicitation list))) list
-> int list option -> unit declaration_hook -> unit
+val universe_proof_terminator :
+ Proof_global.lemma_possible_guards ->
+ (Evd.evar_universe_context option -> unit declaration_hook) ->
+ Proof_global.proof_terminator
+
val standard_proof_terminator :
Proof_global.lemma_possible_guards -> unit declaration_hook ->
Proof_global.proof_terminator
diff --git a/stm/stm.ml b/stm/stm.ml
index d8b2de4a2..e8b500a62 100644
--- a/stm/stm.ml
+++ b/stm/stm.ml
@@ -89,7 +89,7 @@ let vernac_interp ?proof id ?route { verbose; loc; expr } =
| VernacResetName _ | VernacResetInitial | VernacBack _
| VernacBackTo _ | VernacRestart | VernacUndo _ | VernacUndoTo _
| VernacBacktrack _ | VernacAbortAll | VernacAbort _ -> true
- | VernacTime el | VernacRedirect (_,el) -> List.for_all (fun (_,e) -> internal_command e) el
+ | VernacTime (_,e) | VernacRedirect (_,(_,e)) -> internal_command e
| _ -> false in
if internal_command expr then begin
prerr_endline ("ignoring " ^ string_of_ppcmds(pr_vernac expr))
@@ -174,7 +174,7 @@ type visit = { step : step; next : Stateid.t }
(* Parts of the system state that are morally part of the proof state *)
let summary_pstate = [ Evarutil.meta_counter_summary_name;
- Evarutil.evar_counter_summary_name;
+ Evd.evar_counter_summary_name;
"program-tcc-table" ]
type state = {
system : States.state;
@@ -634,10 +634,9 @@ end = struct (* {{{ *)
States.unfreeze system; Proof_global.unfreeze proof
(* hack to make futures functional *)
- let in_t, out_t = Dyn.create "state4future"
let () = Future.set_freeze
- (fun () -> in_t (freeze_global_state `No, !cur_id))
- (fun t -> let s,i = out_t t in unfreeze_global_state s; cur_id := i)
+ (fun () -> Obj.magic (freeze_global_state `No, !cur_id))
+ (fun t -> let s,i = Obj.magic t in unfreeze_global_state s; cur_id := i)
type frozen_state = state
type proof_part =
@@ -1518,7 +1517,7 @@ end = struct (* {{{ *)
let e, etac, time, fail =
let rec find time fail = function
| VernacSolve(_,_,re,b) -> re, b, time, fail
- | VernacTime [_,e] | VernacRedirect (_,[_,e]) -> find true fail e
+ | VernacTime (_,e) | VernacRedirect (_,(_,e)) -> find true fail e
| VernacFail e -> find time true e
| _ -> errorlabstrm "Stm" (str"unsupported") in find false false e in
Hooks.call Hooks.with_fail fail (fun () ->
@@ -1633,7 +1632,7 @@ end = struct (* {{{ *)
let vernac_interp switch prev id q =
assert(TaskQueue.n_workers (Option.get !queue) > 0);
TaskQueue.enqueue_task (Option.get !queue)
- QueryTask.({ QueryTask.t_where = prev; t_for = id; t_what = q }, switch)
+ QueryTask.({ t_where = prev; t_for = id; t_what = q }, switch)
let init () = queue := Some (TaskQueue.create
(if !Flags.async_proofs_full then 1 else 0))
diff --git a/stm/stm.mli b/stm/stm.mli
index ad89eb71f..4279921b3 100644
--- a/stm/stm.mli
+++ b/stm/stm.mli
@@ -9,6 +9,7 @@
open Vernacexpr
open Names
open Feedback
+open Loc
(** state-transaction-machine interface *)
@@ -19,7 +20,7 @@ open Feedback
The sentence [s] is parsed in the state [ontop].
If [newtip] is provided, then the returned state id is guaranteed to be
[newtip] *)
-val add : ontop:Stateid.t -> ?newtip:Stateid.t -> ?check:(located_vernac_expr -> unit) ->
+val add : ontop:Stateid.t -> ?newtip:Stateid.t -> ?check:(vernac_expr located -> unit) ->
bool -> edit_id -> string ->
Stateid.t * [ `NewTip | `Unfocus of Stateid.t ]
@@ -126,7 +127,7 @@ val state_of_id : Stateid.t -> [ `Valid of state option | `Expired ]
(* Adds a new line to the document. It replaces the core of Vernac.interp.
[finish] is called as the last bit of this function is the system
is running interactively (-emacs or coqtop). *)
-val interp : bool -> located_vernac_expr -> unit
+val interp : bool -> vernac_expr located -> unit
(* Queries for backward compatibility *)
val current_proof_depth : unit -> int
diff --git a/stm/texmacspp.ml b/stm/texmacspp.ml
index 85cb45708..5bd1569ce 100644
--- a/stm/texmacspp.ml
+++ b/stm/texmacspp.ml
@@ -20,9 +20,6 @@ let unlock loc =
let start, stop = Loc.unloc loc in
(string_of_int start, string_of_int stop)
-let xmlNoop = (* almost noop *)
- PCData ""
-
let xmlWithLoc loc ename attr xml =
let start, stop = unlock loc in
Element(ename, [ "begin", start; "end", stop ] @ attr, xml)
@@ -347,7 +344,7 @@ and pp_cases_pattern_expr cpe =
xmlApply loc
(xmlOperator "delimiter" ~attr:["name", delim] loc ::
[pp_cases_pattern_expr cpe])
-and pp_case_expr (e, (name, pat)) =
+and pp_case_expr (e, name, pat) =
match name, pat with
| None, None -> xmlScrutinee [pp_expr e]
| Some (loc, name), None ->
@@ -460,7 +457,7 @@ and pp_expr ?(attr=[]) e =
(return @
[Element ("scrutinees", [], List.map pp_case_expr cel)] @
[pp_branch_expr_list bel]))
- | CRecord (_, _, _) -> assert false
+ | CRecord (_, _) -> assert false
| CLetIn (loc, (varloc, var), value, body) ->
xmlApply loc
(xmlOperator "let" loc ::
@@ -487,12 +484,12 @@ let rec tmpp v loc =
(* Control *)
| VernacLoad (verbose,f) ->
xmlWithLoc loc "load" ["verbose",string_of_bool verbose;"file",f] []
- | VernacTime l ->
+ | VernacTime (loc,e) ->
xmlApply loc (Element("time",[],[]) ::
- List.map (fun(loc,e) ->tmpp e loc) l)
- | VernacRedirect (s, l) ->
+ [tmpp e loc])
+ | VernacRedirect (s, (loc,e)) ->
xmlApply loc (Element("redirect",["path", s],[]) ::
- List.map (fun(loc,e) ->tmpp e loc) l)
+ [tmpp e loc])
| VernacTimeout (s,e) ->
xmlApply loc (Element("timeout",["val",string_of_int s],[]) ::
[tmpp e loc])
@@ -724,7 +721,6 @@ let rec tmpp v loc =
| VernacRegister _ as x -> xmlTODO loc x
| VernacComments (cl) ->
xmlComment loc (List.flatten (List.map pp_comment cl))
- | VernacNop as x -> xmlTODO loc x
(* Stm backdoor *)
| VernacStm _ as x -> xmlTODO loc x
diff --git a/stm/vernac_classifier.ml b/stm/vernac_classifier.ml
index edb54ece4..f9f08f7af 100644
--- a/stm/vernac_classifier.ml
+++ b/stm/vernac_classifier.ml
@@ -60,7 +60,7 @@ let undo_classifier = ref (fun _ -> assert false)
let set_undo_classifier f = undo_classifier := f
let rec classify_vernac e =
- let rec static_classifier e = match e with
+ let static_classifier e = match e with
(* PG compatibility *)
| VernacUnsetOption (["Silent"]|["Undo"]|["Printing";"Depth"])
| VernacSetOption ((["Silent"]|["Undo"]|["Printing";"Depth"]),_)
@@ -86,7 +86,7 @@ let rec classify_vernac e =
make_polymorphic (classify_vernac e)
else classify_vernac e
| VernacTimeout (_,e) -> classify_vernac e
- | VernacTime e | VernacRedirect (_, e) -> classify_vernac_list e
+ | VernacTime (_,e) | VernacRedirect (_, (_,e)) -> classify_vernac e
| VernacFail e -> (* Fail Qed or Fail Lemma must not join/fork the DAG *)
(match classify_vernac e with
| ( VtQuery _ | VtProofStep _ | VtSideff _
@@ -175,11 +175,13 @@ let rec classify_vernac e =
| VernacRegister _
| VernacNameSectionHypSet _
| VernacComments _ -> VtSideff [], VtLater
- | VernacDeclareTacticDefinition (_,l) ->
+ | VernacDeclareTacticDefinition l ->
let open Libnames in
+ let open Vernacexpr in
VtSideff (List.map (function
- | (Ident (_,r),_,_) -> r
- | (Qualid (_,q),_,_) -> snd(repr_qualid q)) l), VtLater
+ | TacticDefinition ((_,r),_) -> r
+ | TacticRedefinition (Ident (_,r),_) -> r
+ | TacticRedefinition (Qualid (_,q),_) -> snd(repr_qualid q)) l), VtLater
(* Who knows *)
| VernacLoad _ -> VtSideff [], VtNow
(* (Local) Notations have to disappear *)
@@ -208,7 +210,6 @@ let rec classify_vernac e =
| VernacResetName _ | VernacResetInitial
| VernacBacktrack _ | VernacBackTo _ | VernacRestart -> !undo_classifier e
(* What are these? *)
- | VernacNop
| VernacToplevelControl _
| VernacRestoreState _
| VernacWriteState _ -> VtUnknown, VtNow
@@ -217,13 +218,6 @@ let rec classify_vernac e =
| VernacExtend (s,l) ->
try List.assoc s !classifiers l ()
with Not_found -> anomaly(str"No classifier for"++spc()++str (fst s))
- and classify_vernac_list = function
- (* spiwack: It would be better to define a monoid on classifiers.
- So that the classifier of the list would be the composition of
- the classifier of the individual commands. Currently: special
- case for singleton lists.*)
- | [_,c] -> static_classifier c
- | l -> VtUnknown,VtNow
in
let res = static_classifier e in
if Flags.is_universe_polymorphism () then
diff --git a/tactics/auto.ml b/tactics/auto.ml
index 2d92387c0..f9b180de6 100644
--- a/tactics/auto.ml
+++ b/tactics/auto.ml
@@ -67,16 +67,13 @@ let auto_unif_flags_of st1 st2 useeager =
let auto_unif_flags =
auto_unif_flags_of full_transparent_state empty_transparent_state false
-let auto_flags_of_state st =
- auto_unif_flags_of full_transparent_state st false
-
(* Try unification with the precompiled clause, then use registered Apply *)
let connect_hint_clenv poly (c, _, ctx) clenv gl =
(** [clenv] has been generated by a hint-making function, so the only relevant
data in its evarmap is the set of metas. The [evar_reset_evd] function
below just replaces the metas of sigma by those coming from the clenv. *)
- let sigma = Proofview.Goal.sigma gl in
+ let sigma = Tacmach.New.project gl in
let evd = Evd.evars_reset_evd ~with_conv_pbs:true ~with_univs:false sigma clenv.evd in
(** Still, we need to update the universes *)
let clenv, c =
@@ -96,11 +93,11 @@ let connect_hint_clenv poly (c, _, ctx) clenv gl =
in clenv, c
let unify_resolve poly flags ((c : raw_hint), clenv) =
- Proofview.Goal.nf_enter begin fun gl ->
+ Proofview.Goal.nf_enter { enter = begin fun gl ->
let clenv, c = connect_hint_clenv poly c clenv gl in
let clenv = Tacmach.New.of_old (fun gl -> clenv_unique_resolver ~flags clenv gl) gl in
Clenvtac.clenv_refine false clenv
- end
+ end }
let unify_resolve_nodelta poly h = unify_resolve poly auto_unif_flags h
@@ -119,10 +116,12 @@ let exact poly (c,clenv) =
let ctx = Evd.evar_universe_context clenv.evd in
ctx, c
in
- Proofview.Goal.enter begin fun gl ->
- let sigma = Evd.merge_universe_context (Proofview.Goal.sigma gl) ctx in
- Tacticals.New.tclTHEN (Proofview.Unsafe.tclEVARS sigma) (exact_check c')
- end
+ Proofview.Goal.s_enter { s_enter = begin fun gl ->
+ let sigma = Proofview.Goal.sigma gl in
+ let sigma = Sigma.to_evar_map sigma in
+ let sigma = Evd.merge_universe_context sigma ctx in
+ Sigma.Unsafe.of_pair (exact_check c', sigma)
+ end }
(* Util *)
@@ -150,11 +149,12 @@ let conclPattern concl pat tac =
with Constr_matching.PatternMatchingFailure ->
Tacticals.New.tclZEROMSG (str "conclPattern")
in
- Proofview.Goal.enter (fun gl ->
+ Proofview.Goal.enter { enter = begin fun gl ->
let env = Proofview.Goal.env gl in
- let sigma = Proofview.Goal.sigma gl in
+ let sigma = Tacmach.New.project gl in
constr_bindings env sigma >>= fun constr_bindings ->
- Hook.get forward_interp_tactic constr_bindings tac)
+ Hook.get forward_interp_tactic constr_bindings tac
+ end }
(***********************************************************)
(** A debugging / verbosity framework for trivial and auto *)
@@ -293,9 +293,6 @@ let tclTRY_dbg d tac =
(* Papageno : cette fonction a été pas mal simplifiée depuis que la base
de Hint impérative a été remplacée par plusieurs bases fonctionnelles *)
-let auto_unif_flags =
- auto_unif_flags_of full_transparent_state empty_transparent_state false
-
let flags_of_state st =
auto_unif_flags_of st st false
@@ -319,24 +316,24 @@ let dbg_assumption dbg = tclLOG dbg (fun () -> str "assumption") assumption
let rec trivial_fail_db dbg mod_delta db_list local_db =
let intro_tac =
Tacticals.New.tclTHEN (dbg_intro dbg)
- ( Proofview.Goal.enter begin fun gl ->
- let sigma = Proofview.Goal.sigma gl in
+ ( Proofview.Goal.enter { enter = begin fun gl ->
+ let sigma = Tacmach.New.project gl in
let env = Proofview.Goal.env gl in
let nf c = Evarutil.nf_evar sigma c in
let decl = Tacmach.New.pf_last_hyp (Proofview.Goal.assume gl) in
- let hyp = Context.map_named_declaration nf decl in
+ let hyp = Context.Named.Declaration.map nf decl in
let hintl = make_resolve_hyp env sigma hyp
in trivial_fail_db dbg mod_delta db_list
(Hint_db.add_list env sigma hintl local_db)
- end)
+ end })
in
- Proofview.Goal.enter begin fun gl ->
+ Proofview.Goal.enter { enter = begin fun gl ->
let concl = Tacmach.New.pf_nf_concl gl in
Tacticals.New.tclFIRST
((dbg_assumption dbg)::intro_tac::
(List.map Tacticals.New.tclCOMPLETE
(trivial_resolve dbg mod_delta db_list local_db concl)))
- end
+ end }
and my_find_search_nodelta db_list local_db hdc concl =
List.map (fun hint -> (None,hint))
@@ -413,26 +410,26 @@ and trivial_resolve dbg mod_delta db_list local_db cl =
"nocore" amongst the databases. *)
let trivial ?(debug=Off) lems dbnames =
- Proofview.Goal.nf_enter begin fun gl ->
+ Proofview.Goal.nf_enter { enter = begin fun gl ->
let env = Proofview.Goal.env gl in
- let sigma = Proofview.Goal.sigma gl in
+ let sigma = Tacmach.New.project gl in
let db_list = make_db_list dbnames in
let d = mk_trivial_dbg debug in
let hints = make_local_hint_db env sigma false lems in
tclTRY_dbg d
(trivial_fail_db d false db_list hints)
- end
+ end }
let full_trivial ?(debug=Off) lems =
- Proofview.Goal.nf_enter begin fun gl ->
+ Proofview.Goal.nf_enter { enter = begin fun gl ->
let env = Proofview.Goal.env gl in
- let sigma = Proofview.Goal.sigma gl in
+ let sigma = Tacmach.New.project gl in
let db_list = current_pure_db () in
let d = mk_trivial_dbg debug in
let hints = make_local_hint_db env sigma false lems in
tclTRY_dbg d
(trivial_fail_db d false db_list hints)
- end
+ end }
let gen_trivial ?(debug=Off) lems = function
| None -> full_trivial ~debug lems
@@ -457,7 +454,7 @@ let possible_resolve dbg mod_delta db_list local_db cl =
let extend_local_db decl db gl =
let env = Tacmach.New.pf_env gl in
- let sigma = Proofview.Goal.sigma gl in
+ let sigma = Tacmach.New.project gl in
Hint_db.add_list env sigma (make_resolve_hyp env sigma decl) db
(* Introduce an hypothesis, then call the continuation tactic [kont]
@@ -465,10 +462,10 @@ let extend_local_db decl db gl =
let intro_register dbg kont db =
Tacticals.New.tclTHEN (dbg_intro dbg)
- (Proofview.Goal.enter begin fun gl ->
+ (Proofview.Goal.enter { enter = begin fun gl ->
let extend_local_db decl db = extend_local_db decl db gl in
Tacticals.New.onLastDecl (fun decl -> kont (extend_local_db decl db))
- end)
+ end })
(* n is the max depth of search *)
(* local_db contains the local Hypotheses *)
@@ -481,14 +478,14 @@ let search d n mod_delta db_list local_db =
if Int.equal n 0 then Tacticals.New.tclZEROMSG (str"BOUND 2") else
Tacticals.New.tclORELSE0 (dbg_assumption d)
(Tacticals.New.tclORELSE0 (intro_register d (search d n) local_db)
- ( Proofview.Goal.enter begin fun gl ->
+ ( Proofview.Goal.enter { enter = begin fun gl ->
let concl = Tacmach.New.pf_nf_concl gl in
let d' = incr_dbg d in
Tacticals.New.tclFIRST
(List.map
(fun ntac -> Tacticals.New.tclTHEN ntac (search d' (n-1) local_db))
(possible_resolve d mod_delta db_list local_db concl))
- end))
+ end }))
end []
in
search d n local_db
@@ -496,15 +493,15 @@ let search d n mod_delta db_list local_db =
let default_search_depth = ref 5
let delta_auto debug mod_delta n lems dbnames =
- Proofview.Goal.nf_enter begin fun gl ->
+ Proofview.Goal.nf_enter { enter = begin fun gl ->
let env = Proofview.Goal.env gl in
- let sigma = Proofview.Goal.sigma gl in
+ let sigma = Tacmach.New.project gl in
let db_list = make_db_list dbnames in
let d = mk_auto_dbg debug in
let hints = make_local_hint_db env sigma false lems in
tclTRY_dbg d
(search d n mod_delta db_list hints)
- end
+ end }
let delta_auto =
if Flags.profile then
@@ -519,15 +516,15 @@ let new_auto ?(debug=Off) n = delta_auto debug true n
let default_auto = auto !default_search_depth [] []
let delta_full_auto ?(debug=Off) mod_delta n lems =
- Proofview.Goal.nf_enter begin fun gl ->
+ Proofview.Goal.nf_enter { enter = begin fun gl ->
let env = Proofview.Goal.env gl in
- let sigma = Proofview.Goal.sigma gl in
+ let sigma = Tacmach.New.project gl in
let db_list = current_pure_db () in
let d = mk_auto_dbg debug in
let hints = make_local_hint_db env sigma false lems in
tclTRY_dbg d
(search d n mod_delta db_list hints)
- end
+ end }
let full_auto ?(debug=Off) n = delta_full_auto ~debug false n
let new_full_auto ?(debug=Off) n = delta_full_auto ~debug true n
diff --git a/tactics/auto.mli b/tactics/auto.mli
index 2e5647f87..cd2de99be 100644
--- a/tactics/auto.mli
+++ b/tactics/auto.mli
@@ -10,7 +10,6 @@ open Names
open Term
open Clenv
open Pattern
-open Evd
open Decl_kinds
open Hints
@@ -26,11 +25,9 @@ val default_search_depth : int ref
val auto_flags_of_state : transparent_state -> Unification.unify_flags
val connect_hint_clenv : polymorphic -> raw_hint -> clausenv ->
- [ `NF ] Proofview.Goal.t -> clausenv * constr
+ ([ `NF ], 'r) Proofview.Goal.t -> clausenv * constr
(** Try unification with the precompiled clause, then use registered Apply *)
-val unify_resolve_nodelta : polymorphic -> (raw_hint * clausenv) -> unit Proofview.tactic
-
val unify_resolve : polymorphic -> Unification.unify_flags -> (raw_hint * clausenv) -> unit Proofview.tactic
(** [ConclPattern concl pat tacast]:
@@ -46,24 +43,24 @@ val conclPattern : constr -> constr_pattern option -> Tacexpr.glob_tactic_expr -
"nocore" amongst the databases. *)
val auto : ?debug:Tacexpr.debug ->
- int -> open_constr list -> hint_db_name list -> unit Proofview.tactic
+ int -> Tacexpr.delayed_open_constr list -> hint_db_name list -> unit Proofview.tactic
(** Auto with more delta. *)
val new_auto : ?debug:Tacexpr.debug ->
- int -> open_constr list -> hint_db_name list -> unit Proofview.tactic
+ int -> Tacexpr.delayed_open_constr list -> hint_db_name list -> unit Proofview.tactic
(** auto with default search depth and with the hint database "core" *)
val default_auto : unit Proofview.tactic
(** auto with all hint databases except the "v62" compatibility database *)
val full_auto : ?debug:Tacexpr.debug ->
- int -> open_constr list -> unit Proofview.tactic
+ int -> Tacexpr.delayed_open_constr list -> unit Proofview.tactic
(** auto with all hint databases except the "v62" compatibility database
and doing delta *)
val new_full_auto : ?debug:Tacexpr.debug ->
- int -> open_constr list -> unit Proofview.tactic
+ int -> Tacexpr.delayed_open_constr list -> unit Proofview.tactic
(** auto with default search depth and with all hint databases
except the "v62" compatibility database *)
@@ -71,19 +68,19 @@ val default_full_auto : unit Proofview.tactic
(** The generic form of auto (second arg [None] means all bases) *)
val gen_auto : ?debug:Tacexpr.debug ->
- int option -> open_constr list -> hint_db_name list option -> unit Proofview.tactic
+ int option -> Tacexpr.delayed_open_constr list -> hint_db_name list option -> unit Proofview.tactic
(** The hidden version of auto *)
val h_auto : ?debug:Tacexpr.debug ->
- int option -> open_constr list -> hint_db_name list option -> unit Proofview.tactic
+ int option -> Tacexpr.delayed_open_constr list -> hint_db_name list option -> unit Proofview.tactic
(** Trivial *)
val trivial : ?debug:Tacexpr.debug ->
- open_constr list -> hint_db_name list -> unit Proofview.tactic
+ Tacexpr.delayed_open_constr list -> hint_db_name list -> unit Proofview.tactic
val gen_trivial : ?debug:Tacexpr.debug ->
- open_constr list -> hint_db_name list option -> unit Proofview.tactic
+ Tacexpr.delayed_open_constr list -> hint_db_name list option -> unit Proofview.tactic
val full_trivial : ?debug:Tacexpr.debug ->
- open_constr list -> unit Proofview.tactic
+ Tacexpr.delayed_open_constr list -> unit Proofview.tactic
val h_trivial : ?debug:Tacexpr.debug ->
- open_constr list -> hint_db_name list option -> unit Proofview.tactic
+ Tacexpr.delayed_open_constr list -> hint_db_name list option -> unit Proofview.tactic
diff --git a/tactics/autorewrite.ml b/tactics/autorewrite.ml
index 49e5c6204..40c0f7f9b 100644
--- a/tactics/autorewrite.ml
+++ b/tactics/autorewrite.ml
@@ -18,6 +18,8 @@ open Util
open Tacexpr
open Mod_subst
open Locus
+open Sigma.Notations
+open Proofview.Notations
(* Rewriting rules *)
type rew_rule = { rew_lemma: constr;
@@ -91,14 +93,16 @@ type raw_rew_rule = Loc.t * constr Univ.in_universe_context_set * bool * raw_tac
(* Applies all the rules of one base *)
let one_base general_rewrite_maybe_in tac_main bas =
let lrul = find_rewrites bas in
- let try_rewrite dir ctx c tc = Proofview.Goal.nf_enter (fun gl ->
+ let try_rewrite dir ctx c tc =
+ Proofview.Goal.nf_s_enter { s_enter = begin fun gl ->
+ let sigma = Proofview.Goal.sigma gl in
let subst, ctx' = Universes.fresh_universe_context_set_instance ctx in
let c' = Vars.subst_univs_level_constr subst c in
- let sigma = Proofview.Goal.sigma gl in
+ let sigma = Sigma.to_evar_map sigma in
let sigma = Evd.merge_context_set Evd.univ_flexible sigma ctx' in
- Tacticals.New.tclTHEN (Proofview.Unsafe.tclEVARS sigma)
- (general_rewrite_maybe_in dir c' tc)
- ) in
+ let tac = general_rewrite_maybe_in dir c' tc in
+ Sigma.Unsafe.of_pair (tac, sigma)
+ end } in
let lrul = List.map (fun h ->
let tac = match h.rew_tac with None -> Proofview.tclUNIT () | Some t -> Tacinterp.eval_tactic t in
(h.rew_ctx,h.rew_lemma,h.rew_l2r,tac)) lrul in
@@ -120,7 +124,7 @@ let autorewrite ?(conds=Naive) tac_main lbas =
(Proofview.tclUNIT()) lbas))
let autorewrite_multi_in ?(conds=Naive) idl tac_main lbas =
- Proofview.Goal.nf_enter begin fun gl ->
+ Proofview.Goal.nf_enter { enter = begin fun gl ->
(* let's check at once if id exists (to raise the appropriate error) *)
let _ = List.map (fun id -> Tacmach.New.pf_get_hyp id gl) idl in
let general_rewrite_in id =
@@ -163,7 +167,7 @@ let autorewrite_multi_in ?(conds=Naive) idl tac_main lbas =
(List.fold_left (fun tac bas ->
Tacticals.New.tclTHEN tac (one_base (general_rewrite_in id) tac_main bas)) (Proofview.tclUNIT()) lbas)))
idl
- end
+ end }
let autorewrite_in ?(conds=Naive) id = autorewrite_multi_in ~conds [id]
@@ -188,12 +192,13 @@ let gen_auto_multi_rewrite conds tac_main lbas cl =
| None ->
(* try to rewrite in all hypothesis
(except maybe the rewritten one) *)
- Proofview.Goal.nf_enter begin fun gl ->
+ Proofview.Goal.nf_enter { enter = begin fun gl ->
let ids = Tacmach.New.pf_ids_of_hyps gl in
try_do_hyps (fun id -> id) ids
- end)
+ end })
-let auto_multi_rewrite ?(conds=Naive) = gen_auto_multi_rewrite conds (Proofview.tclUNIT())
+let auto_multi_rewrite ?(conds=Naive) lems cl =
+ Proofview.V82.wrap_exceptions (fun () -> gen_auto_multi_rewrite conds (Proofview.tclUNIT()) lems cl)
let auto_multi_rewrite_with ?(conds=Naive) tac_main lbas cl =
let onconcl = match cl.Locus.concl_occs with NoOccurrences -> false | _ -> true in
@@ -202,7 +207,7 @@ let auto_multi_rewrite_with ?(conds=Naive) tac_main lbas cl =
(* autorewrite with .... in clause using tac n'est sur que
si clause represente soit le but soit UNE hypothese
*)
- gen_auto_multi_rewrite conds tac_main lbas cl
+ Proofview.V82.wrap_exceptions (fun () -> gen_auto_multi_rewrite conds tac_main lbas cl)
| _ ->
Tacticals.New.tclZEROMSG (strbrk "autorewrite .. in .. using can only be used either with a unique hypothesis or on the conclusion.")
diff --git a/tactics/class_tactics.ml b/tactics/class_tactics.ml
index 5b3231dea..c9b2c7cfd 100644
--- a/tactics/class_tactics.ml
+++ b/tactics/class_tactics.ml
@@ -39,6 +39,10 @@ let typeclasses_dependency_order = ref false
let set_typeclasses_dependency_order d = (:=) typeclasses_dependency_order d
let get_typeclasses_dependency_order () = !typeclasses_dependency_order
+let typeclasses_iterative_deepening = ref false
+let set_typeclasses_iterative_deepening d = (:=) typeclasses_iterative_deepening d
+let get_typeclasses_iterative_deepening () = !typeclasses_iterative_deepening
+
open Goptions
let _ =
@@ -59,6 +63,15 @@ let _ =
optread = get_typeclasses_dependency_order;
optwrite = set_typeclasses_dependency_order; }
+let _ =
+ declare_bool_option
+ { optsync = true;
+ optdepr = false;
+ optname = "use iterative deepening strategy";
+ optkey = ["Typeclasses";"Iterative";"Deepening"];
+ optread = get_typeclasses_iterative_deepening;
+ optwrite = set_typeclasses_iterative_deepening; }
+
(** We transform the evars that are concerned by this resolution
(according to predicate p) into goals.
Invariant: function p only manipulates and returns undefined evars *)
@@ -127,17 +140,17 @@ let rec eq_constr_mod_evars x y =
| _, _ -> compare_constr eq_constr_mod_evars x y
let progress_evars t =
- Proofview.Goal.nf_enter begin fun gl ->
+ Proofview.Goal.nf_enter { enter = begin fun gl ->
let concl = Proofview.Goal.concl gl in
let check =
- Proofview.Goal.nf_enter begin fun gl' ->
+ Proofview.Goal.nf_enter { enter = begin fun gl' ->
let newconcl = Proofview.Goal.concl gl' in
if eq_constr_mod_evars concl newconcl
then Tacticals.New.tclFAIL 0 (str"No progress made (modulo evars)")
else Proofview.tclUNIT ()
- end
+ end }
in t <*> check
- end
+ end }
let e_give_exact flags poly (c,clenv) gl =
@@ -145,23 +158,25 @@ let e_give_exact flags poly (c,clenv) gl =
let c, gl =
if poly then
let clenv', subst = Clenv.refresh_undefined_univs clenv in
- let clenv' = connect_clenv gl clenv' in
+ let evd = evars_reset_evd ~with_conv_pbs:true gl.sigma clenv'.evd in
let c = Vars.subst_univs_level_constr subst c in
- c, {gl with sigma = clenv'.evd}
+ c, {gl with sigma = evd}
else c, gl
in
let t1 = pf_unsafe_type_of gl c in
tclTHEN (Proofview.V82.of_tactic (Clenvtac.unify ~flags t1)) (exact_no_check c) gl
-let unify_e_resolve poly flags (c,clenv) gls =
+let unify_e_resolve poly flags = { enter = begin fun gls (c,clenv) ->
let clenv', c = connect_hint_clenv poly c clenv gls in
let clenv' = Tacmach.New.of_old (clenv_unique_resolver ~flags clenv') gls in
Clenvtac.clenv_refine true ~with_classes:false clenv'
+ end }
-let unify_resolve poly flags (c,clenv) gls =
+let unify_resolve poly flags = { enter = begin fun gls (c,clenv) ->
let clenv', _ = connect_hint_clenv poly c clenv gls in
let clenv' = Tacmach.New.of_old (clenv_unique_resolver ~flags clenv') gls in
Clenvtac.clenv_refine false ~with_classes:false clenv'
+ end }
let clenv_of_prods poly nprods (c, clenv) gl =
let (c, _, _) = c in
@@ -175,16 +190,17 @@ let clenv_of_prods poly nprods (c, clenv) gl =
else None
let with_prods nprods poly (c, clenv) f =
- Proofview.Goal.nf_enter (fun gl ->
+ Proofview.Goal.nf_enter { enter = begin fun gl ->
match clenv_of_prods poly nprods (c, clenv) gl with
| None -> Tacticals.New.tclZEROMSG (str"Not enough premisses")
- | Some clenv' -> f (c, clenv') gl)
+ | Some clenv' -> f.enter gl (c, clenv')
+ end }
(** Hack to properly solve dependent evars that are typeclasses *)
let rec e_trivial_fail_db db_list local_db goal =
let tacl =
- Eauto.registered_e_assumption ::
+ Proofview.V82.of_tactic Eauto.registered_e_assumption ::
(tclTHEN (Proofview.V82.of_tactic Tactics.intro)
(function g'->
let d = pf_last_hyp g' in
@@ -267,7 +283,8 @@ type autoinfo = { hints : hint_db; is_evar: existential_key option;
auto_path : global_reference option list;
auto_cut : hints_path }
type autogoal = goal * autoinfo
-type 'ans fk = unit -> 'ans
+type failure = NotApplicable | ReachedLimit
+type 'ans fk = failure -> 'ans
type ('a,'ans) sk = 'a -> 'ans fk -> 'ans
type 'a tac = { skft : 'ans. ('a,'ans) sk -> 'ans fk -> autogoal sigma -> 'ans }
@@ -282,7 +299,7 @@ type 'a optionk =
| Somek of 'a * 'a optionk fk
type ('a,'b) optionk2 =
- | Nonek2
+ | Nonek2 of failure
| Somek2 of 'a * 'b * ('a,'b) optionk2 fk
let make_resolve_hyp env sigma st flags only_classes pri (id, _, cty) =
@@ -364,7 +381,7 @@ let lift_tactic tac (f : goal list sigma -> autoinfo -> autogoal list sigma) : '
with e when catchable e -> None in
match res with
| Some gls -> sk (f gls hints) fk
- | None -> fk () }
+ | None -> fk NotApplicable }
let intro_tac : atac =
lift_tactic (Proofview.V82.of_tactic Tactics.intro)
@@ -385,8 +402,19 @@ let normevars_tac : atac =
let info' = { info with auto_last_tac = lazy (str"normevars") } in
sk {it = [gl', info']; sigma = sigma';} fk }
+let merge_failures x y =
+ match x, y with
+ | _, ReachedLimit
+ | ReachedLimit, _ -> ReachedLimit
+ | NotApplicable, NotApplicable -> NotApplicable
+
let or_tac (x : 'a tac) (y : 'a tac) : 'a tac =
- { skft = fun sk fk gls -> x.skft sk (fun () -> y.skft sk fk gls) gls }
+ { skft = fun sk fk gls -> x.skft sk
+ (fun f -> y.skft sk (fun f' -> fk (merge_failures f f')) gls) gls }
+
+let or_else_tac (x : 'a tac) (y : failure -> 'a tac) : 'a tac =
+ { skft = fun sk fk gls -> x.skft sk
+ (fun f -> (y f).skft sk fk gls) gls }
let is_Prop env sigma concl =
let ty = Retyping.get_type_of env sigma concl in
@@ -463,7 +491,7 @@ let hints_tac hints =
in g, info) 1 newgls in
let glsv = {it = gls'; sigma = s';} in
let fk' =
- (fun () ->
+ (fun e ->
let do_backtrack =
if unique then occur_existential concl
else if info.unique then true
@@ -471,22 +499,25 @@ let hints_tac hints =
needs_backtrack env s' info.is_evar concl
else true
in
+ let e' = match foundone with None -> e | Some e' -> merge_failures e e' in
if !typeclasses_debug then
msg_debug
((if do_backtrack then str"Backtracking after "
else str "Not backtracking after ")
++ Lazy.force pp);
- if do_backtrack then aux (succ i) true tl
- else fk ())
+ if do_backtrack then aux (succ i) (Some e') tl
+ else fk e')
in
sk glsv fk')
| [] ->
- if not foundone && !typeclasses_debug then
+ if foundone == None && !typeclasses_debug then
msg_debug (pr_depth info.auto_depth ++ str": no match for " ++
Printer.pr_constr_env (Goal.V82.env s gl) s concl ++
spc () ++ str ", " ++ int (List.length poss) ++ str" possibilities");
- fk ()
- in aux 1 false poss }
+ match foundone with
+ | Some e -> fk e
+ | None -> fk NotApplicable
+ in aux 1 None poss }
let then_list (second : atac) (sk : (auto_result, 'a) sk) : (auto_result, 'a) sk =
let rec aux s (acc : autogoal list list) fk = function
@@ -509,11 +540,11 @@ let then_list (second : atac) (sk : (auto_result, 'a) sk) : (auto_result, 'a) sk
| [] -> Somek2 (List.rev acc, s, fk)
in fun {it = gls; sigma = s; } fk ->
let rec aux' = function
- | Nonek2 -> fk ()
+ | Nonek2 e -> fk e
| Somek2 (res, s', fk') ->
let goals' = List.concat res in
- sk {it = goals'; sigma = s'; } (fun () -> aux' (fk' ()))
- in aux' (aux s [] (fun () -> Nonek2) gls)
+ sk {it = goals'; sigma = s'; } (fun e -> aux' (fk' e))
+ in aux' (aux s [] (fun e -> Nonek2 e) gls)
let then_tac (first : atac) (second : atac) : atac =
{ skft = fun sk fk -> first.skft (then_list second sk) fk }
@@ -528,16 +559,30 @@ let run_list_tac (t : 'a tac) p goals (gl : autogoal list sigma) : run_list_res
gl
(fun _ -> Nonek)
-let fail_tac : atac =
- { skft = fun sk fk _ -> fk () }
+let fail_tac reason : atac =
+ { skft = fun sk fk _ -> fk reason }
let rec fix (t : 'a tac) : 'a tac =
then_tac t { skft = fun sk fk -> (fix t).skft sk fk }
let rec fix_limit limit (t : 'a tac) : 'a tac =
- if Int.equal limit 0 then fail_tac
+ if Int.equal limit 0 then fail_tac ReachedLimit
else then_tac t { skft = fun sk fk -> (fix_limit (pred limit) t).skft sk fk }
+let fix_iterative t =
+ let rec aux depth =
+ or_else_tac (fix_limit depth t)
+ (function
+ | NotApplicable as e -> fail_tac e
+ | ReachedLimit -> aux (succ depth))
+ in aux 1
+
+let fix_iterative_limit limit (t : 'a tac) : 'a tac =
+ let rec aux depth =
+ if Int.equal depth limit then fail_tac ReachedLimit
+ else or_tac (fix_limit depth t) { skft = fun sk fk -> (aux (succ depth)).skft sk fk }
+ in aux 1
+
let make_autogoal ?(only_classes=true) ?(unique=false) ?(st=full_transparent_state) cut ev g =
let hints = make_autogoal_hints only_classes ~st g in
(g.it, { hints = hints ; is_evar = ev; unique = unique;
@@ -581,16 +626,14 @@ let eauto_tac hints =
then_tac normevars_tac (or_tac (hints_tac hints) intro_tac)
let eauto_tac ?limit hints =
- match limit with
- | None -> fix (eauto_tac hints)
- | Some limit -> fix_limit limit (eauto_tac hints)
-
-let eauto ?(only_classes=true) ?st ?limit hints g =
- let gl = { it = make_autogoal ~only_classes ?st (cut_of_hints hints) None g; sigma = project g; } in
- match run_tac (eauto_tac ?limit hints) gl with
- | None -> raise Not_found
- | Some {it = goals; sigma = s; } ->
- {it = List.map fst goals; sigma = s;}
+ if get_typeclasses_iterative_deepening () then
+ match limit with
+ | None -> fix_iterative (eauto_tac hints)
+ | Some limit -> fix_iterative_limit limit (eauto_tac hints)
+ else
+ match limit with
+ | None -> fix (eauto_tac hints)
+ | Some limit -> fix_limit limit (eauto_tac hints)
let real_eauto ?limit unique st hints p evd =
let res =
@@ -600,7 +643,7 @@ let real_eauto ?limit unique st hints p evd =
| None -> evd
| Some (evd', fk) ->
if unique then
- (match get_result (fk ()) with
+ (match get_result (fk NotApplicable) with
| Some (evd'', fk') -> error "Typeclass resolution gives multiple solutions"
| None -> evd')
else evd'
@@ -609,6 +652,13 @@ let resolve_all_evars_once debug limit unique p evd =
let db = searchtable_map typeclasses_db in
real_eauto ?limit unique (Hint_db.transparent_state db) [db] p evd
+let eauto ?(only_classes=true) ?st ?limit hints g =
+ let gl = { it = make_autogoal ~only_classes ?st (cut_of_hints hints) None g; sigma = project g; } in
+ match run_tac (eauto_tac ?limit hints) gl with
+ | None -> raise Not_found
+ | Some {it = goals; sigma = s; } ->
+ {it = List.map fst goals; sigma = s;}
+
(** We compute dependencies via a union-find algorithm.
Beware of the imperative effects on the partition structure,
it should not be shared, but only used locally. *)
@@ -846,5 +896,5 @@ let autoapply c i gl =
(Hints.Hint_db.transparent_state (Hints.searchtable_map i)) in
let cty = pf_unsafe_type_of gl c in
let ce = mk_clenv_from gl (c,cty) in
- let tac = unify_e_resolve false flags ((c,cty,Univ.ContextSet.empty),ce) in
+ let tac = { enter = fun gl -> (unify_e_resolve false flags).enter gl ((c,cty,Univ.ContextSet.empty),ce) } in
Proofview.V82.of_tactic (Proofview.Goal.nf_enter tac) gl
diff --git a/tactics/contradiction.ml b/tactics/contradiction.ml
index 6eebf4941..c4a23f686 100644
--- a/tactics/contradiction.ml
+++ b/tactics/contradiction.ml
@@ -13,6 +13,8 @@ open Tactics
open Coqlib
open Reductionops
open Misctypes
+open Sigma.Notations
+open Proofview.Notations
(* Absurd *)
@@ -22,18 +24,20 @@ let mk_absurd_proof t =
mkLambda (Names.Name id,t,mkApp (mkRel 2,[|mkRel 1|])))
let absurd c =
- Proofview.Goal.enter begin fun gl ->
- let env = Proofview.Goal.env gl in
+ Proofview.Goal.s_enter { s_enter = begin fun gl ->
let sigma = Proofview.Goal.sigma gl in
+ let env = Proofview.Goal.env gl in
+ let sigma = Sigma.to_evar_map sigma in
let j = Retyping.get_judgment_of env sigma c in
let sigma, j = Coercion.inh_coerce_to_sort Loc.ghost env sigma j in
let t = j.Environ.utj_val in
+ let tac =
Tacticals.New.tclTHENLIST [
- Proofview.Unsafe.tclEVARS sigma;
elim_type (build_coq_False ());
Simple.apply (mk_absurd_proof t)
- ]
- end
+ ] in
+ Sigma.Unsafe.of_pair (tac, sigma)
+ end }
let absurd c = absurd c
@@ -45,14 +49,14 @@ let filter_hyp f tac =
| [] -> Proofview.tclZERO Not_found
| (id,_,t)::rest when f t -> tac id
| _::rest -> seek rest in
- Proofview.Goal.enter begin fun gl ->
+ Proofview.Goal.enter { enter = begin fun gl ->
let hyps = Proofview.Goal.hyps (Proofview.Goal.assume gl) in
seek hyps
- end
+ end }
let contradiction_context =
- Proofview.Goal.enter begin fun gl ->
- let sigma = Proofview.Goal.sigma gl in
+ Proofview.Goal.enter { enter = begin fun gl ->
+ let sigma = Tacmach.New.project gl in
let env = Proofview.Goal.env gl in
let rec seek_neg l = match l with
| [] -> Tacticals.New.tclZEROMSG (Pp.str"No such contradiction")
@@ -64,11 +68,11 @@ let contradiction_context =
else match kind_of_term typ with
| Prod (na,t,u) when is_empty_type u ->
(Proofview.tclORELSE
- (Proofview.Goal.enter begin fun gl ->
+ (Proofview.Goal.enter { enter = begin fun gl ->
let is_conv_leq = Tacmach.New.pf_apply is_conv_leq gl in
filter_hyp (fun typ -> is_conv_leq typ t)
(fun id' -> simplest_elim (mkApp (mkVar id,[|mkVar id'|])))
- end)
+ end })
begin function (e, info) -> match e with
| Not_found -> seek_neg rest
| e -> Proofview.tclZERO ~info e
@@ -77,7 +81,7 @@ let contradiction_context =
in
let hyps = Proofview.Goal.hyps (Proofview.Goal.assume gl) in
seek_neg hyps
- end
+ end }
let is_negation_of env sigma typ t =
match kind_of_term (whd_betadeltaiota env sigma t) with
@@ -87,8 +91,8 @@ let is_negation_of env sigma typ t =
| _ -> false
let contradiction_term (c,lbind as cl) =
- Proofview.Goal.nf_enter begin fun gl ->
- let sigma = Proofview.Goal.sigma gl in
+ Proofview.Goal.nf_enter { enter = begin fun gl ->
+ let sigma = Tacmach.New.project gl in
let env = Proofview.Goal.env gl in
let type_of = Tacmach.New.pf_unsafe_type_of gl in
let typ = type_of c in
@@ -110,7 +114,7 @@ let contradiction_term (c,lbind as cl) =
| Not_found -> Tacticals.New.tclZEROMSG (Pp.str"Not a contradiction.")
| e -> Proofview.tclZERO ~info e
end
- end
+ end }
let contradiction = function
| None -> Tacticals.New.tclTHEN intros contradiction_context
diff --git a/tactics/coretactics.ml4 b/tactics/coretactics.ml4
index 3efa65eb5..63fb67e14 100644
--- a/tactics/coretactics.ml4
+++ b/tactics/coretactics.ml4
@@ -74,15 +74,13 @@ END
TACTIC EXTEND left_with
[ "left" "with" bindings(bl) ] -> [
- let { Evd.sigma = sigma ; it = bl } = bl in
- Tacticals.New.tclWITHHOLES false (Tactics.left_with_bindings false bl) sigma
+ Tacticals.New.tclDELAYEDWITHHOLES false bl (fun bl -> Tactics.left_with_bindings false bl)
]
END
TACTIC EXTEND eleft_with
[ "eleft" "with" bindings(bl) ] -> [
- let { Evd.sigma = sigma ; it = bl } = bl in
- Tacticals.New.tclWITHHOLES true (Tactics.left_with_bindings true bl) sigma
+ Tacticals.New.tclDELAYEDWITHHOLES true bl (fun bl -> Tactics.left_with_bindings true bl)
]
END
@@ -98,15 +96,13 @@ END
TACTIC EXTEND right_with
[ "right" "with" bindings(bl) ] -> [
- let { Evd.sigma = sigma ; it = bl } = bl in
- Tacticals.New.tclWITHHOLES false (Tactics.right_with_bindings false bl) sigma
+ Tacticals.New.tclDELAYEDWITHHOLES false bl (fun bl -> Tactics.right_with_bindings false bl)
]
END
TACTIC EXTEND eright_with
[ "eright" "with" bindings(bl) ] -> [
- let { Evd.sigma = sigma ; it = bl } = bl in
- Tacticals.New.tclWITHHOLES true (Tactics.right_with_bindings true bl) sigma
+ Tacticals.New.tclDELAYEDWITHHOLES true bl (fun bl -> Tactics.right_with_bindings true bl)
]
END
@@ -115,28 +111,22 @@ END
TACTIC EXTEND constructor
[ "constructor" ] -> [ Tactics.any_constructor false None ]
| [ "constructor" int_or_var(i) ] -> [
- let i = Tacinterp.interp_int_or_var ist i in
Tactics.constructor_tac false None i NoBindings
]
| [ "constructor" int_or_var(i) "with" bindings(bl) ] -> [
- let { Evd.sigma = sigma; it = bl } = bl in
- let i = Tacinterp.interp_int_or_var ist i in
- let tac = Tactics.constructor_tac false None i bl in
- Tacticals.New.tclWITHHOLES false tac sigma
+ let tac bl = Tactics.constructor_tac false None i bl in
+ Tacticals.New.tclDELAYEDWITHHOLES false bl tac
]
END
TACTIC EXTEND econstructor
[ "econstructor" ] -> [ Tactics.any_constructor true None ]
| [ "econstructor" int_or_var(i) ] -> [
- let i = Tacinterp.interp_int_or_var ist i in
Tactics.constructor_tac true None i NoBindings
]
| [ "econstructor" int_or_var(i) "with" bindings(bl) ] -> [
- let { Evd.sigma = sigma; it = bl } = bl in
- let i = Tacinterp.interp_int_or_var ist i in
- let tac = Tactics.constructor_tac true None i bl in
- Tacticals.New.tclWITHHOLES true tac sigma
+ let tac bl = Tactics.constructor_tac true None i bl in
+ Tacticals.New.tclDELAYEDWITHHOLES true bl tac
]
END
@@ -144,9 +134,7 @@ END
TACTIC EXTEND specialize
[ "specialize" constr_with_bindings(c) ] -> [
- let { Evd.sigma = sigma; it = c } = c in
- let specialize = Proofview.V82.tactic (Tactics.specialize c) in
- Tacticals.New.tclWITHHOLES false specialize sigma
+ Tacticals.New.tclDELAYEDWITHHOLES false c Tactics.specialize
]
END
@@ -166,15 +154,13 @@ END
TACTIC EXTEND split_with
[ "split" "with" bindings(bl) ] -> [
- let { Evd.sigma = sigma ; it = bl } = bl in
- Tacticals.New.tclWITHHOLES false (Tactics.split_with_bindings false [bl]) sigma
+ Tacticals.New.tclDELAYEDWITHHOLES false bl (fun bl -> Tactics.split_with_bindings false [bl])
]
END
TACTIC EXTEND esplit_with
[ "esplit" "with" bindings(bl) ] -> [
- let { Evd.sigma = sigma ; it = bl } = bl in
- Tacticals.New.tclWITHHOLES true (Tactics.split_with_bindings true [bl]) sigma
+ Tacticals.New.tclDELAYEDWITHHOLES true bl (fun bl -> Tactics.split_with_bindings true [bl])
]
END
@@ -225,8 +211,6 @@ let initial_atomic () =
"intro", TacIntroMove(None,MoveLast);
"intros", TacIntroPattern [];
"cofix", TacCofix None;
- "trivial", TacTrivial (Off,[],None);
- "auto", TacAuto(Off,None,[],None);
]
in
let iter (s, t) = Tacenv.register_ltac false false (Id.of_string s) t in
diff --git a/tactics/eauto.ml4 b/tactics/eauto.ml4
index 568b1d17c..6117c8b43 100644
--- a/tactics/eauto.ml4
+++ b/tactics/eauto.ml4
@@ -28,33 +28,51 @@ open Misctypes
open Locus
open Locusops
open Hints
+open Proofview.Notations
DECLARE PLUGIN "eauto"
let eauto_unif_flags = auto_flags_of_state full_transparent_state
-let e_give_exact ?(flags=eauto_unif_flags) c gl =
- let t1 = (pf_unsafe_type_of gl c) and t2 = pf_concl gl in
+let e_give_exact ?(flags=eauto_unif_flags) c =
+ Proofview.Goal.nf_enter { enter = begin fun gl ->
+ let t1 = Tacmach.New.pf_unsafe_type_of gl c in
+ let t2 = Tacmach.New.pf_concl gl in
if occur_existential t1 || occur_existential t2 then
- tclTHEN (Proofview.V82.of_tactic (Clenvtac.unify ~flags t1)) (exact_no_check c) gl
- else Proofview.V82.of_tactic (exact_check c) gl
+ Tacticals.New.tclTHEN (Clenvtac.unify ~flags t1) (Proofview.V82.tactic (exact_no_check c))
+ else exact_check c
+ end }
let assumption id = e_give_exact (mkVar id)
-let e_assumption gl =
- tclFIRST (List.map assumption (pf_ids_of_hyps gl)) gl
+let e_assumption =
+ Proofview.Goal.enter { enter = begin fun gl ->
+ Tacticals.New.tclFIRST (List.map assumption (Tacmach.New.pf_ids_of_hyps gl))
+ end }
TACTIC EXTEND eassumption
-| [ "eassumption" ] -> [ Proofview.V82.tactic e_assumption ]
+| [ "eassumption" ] -> [ e_assumption ]
END
TACTIC EXTEND eexact
-| [ "eexact" constr(c) ] -> [ Proofview.V82.tactic (e_give_exact c) ]
+| [ "eexact" constr(c) ] -> [ e_give_exact c ]
END
-let registered_e_assumption gl =
- tclFIRST (List.map (fun id gl -> e_give_exact (mkVar id) gl)
- (pf_ids_of_hyps gl)) gl
+let registered_e_assumption =
+ Proofview.Goal.enter { enter = begin fun gl ->
+ Tacticals.New.tclFIRST (List.map (fun id -> e_give_exact (mkVar id))
+ (Tacmach.New.pf_ids_of_hyps gl))
+ end }
+
+let eval_uconstrs ist cs =
+ let flags = {
+ Pretyping.use_typeclasses = false;
+ use_unif_heuristics = true;
+ use_hook = Some Pfedit.solve_by_implicit_tactic;
+ fail_evar = false;
+ expand_evars = true
+ } in
+ List.map (fun c -> Tacinterp.type_uconstr ~flags ist c) cs
(************************************************************************)
(* PROLOG tactic *)
@@ -83,7 +101,7 @@ let one_step l gl =
[Proofview.V82.of_tactic Tactics.intro]
@ (List.map (fun c -> Proofview.V82.of_tactic (Tactics.Simple.eapply c)) (List.map mkVar (pf_ids_of_hyps gl)))
@ (List.map (fun c -> Proofview.V82.of_tactic (Tactics.Simple.eapply c)) l)
- @ (List.map assumption (pf_ids_of_hyps gl))
+ @ (List.map (fun c -> Proofview.V82.of_tactic (assumption c)) (pf_ids_of_hyps gl))
let rec prolog l n gl =
if n <= 0 then error "prolog - failure";
@@ -95,18 +113,19 @@ let out_term = function
| IsGlobRef gr -> fst (Universes.fresh_global_instance (Global.env ()) gr)
let prolog_tac l n gl =
- let l = List.map (fun x -> out_term (pf_apply (prepare_hint false (false,true)) gl x)) l in
- let n =
- match n with
- | ArgArg n -> n
- | _ -> error "Prolog called with a non closed argument."
+ let map c =
+ let (c, sigma) = Tactics.run_delayed (pf_env gl) (project gl) c in
+ let c = pf_apply (prepare_hint false (false,true)) gl (sigma, c) in
+ out_term c
in
+ let l = List.map map l in
try (prolog l n gl)
with UserError ("Refiner.tclFIRST",_) ->
errorlabstrm "Prolog.prolog" (str "Prolog failed.")
TACTIC EXTEND prolog
-| [ "prolog" "[" open_constr_list(l) "]" int_or_var(n) ] -> [ Proofview.V82.tactic (prolog_tac l n) ]
+| [ "prolog" "[" uconstr_list(l) "]" int_or_var(n) ] ->
+ [ Proofview.V82.tactic (prolog_tac (eval_uconstrs ist l) n) ]
END
open Auto
@@ -119,15 +138,14 @@ open Unification
let priority l = List.map snd (List.filter (fun (pr,_) -> Int.equal pr 0) l)
let unify_e_resolve poly flags (c,clenv) =
- Proofview.Goal.nf_enter begin
- fun gl ->
+ Proofview.Goal.nf_enter { enter = begin fun gl ->
let clenv', c = connect_hint_clenv poly c clenv gl in
Proofview.V82.tactic
(fun gls ->
let clenv' = clenv_unique_resolver ~flags clenv' gls in
tclTHEN (Refiner.tclEVARUNIVCONTEXT (Evd.evar_universe_context clenv'.evd))
(Proofview.V82.of_tactic (Tactics.Simple.eapply c)) gls)
- end
+ end }
let hintmap_of hdc concl =
match hdc with
@@ -143,19 +161,21 @@ let e_exact poly flags (c,clenv) =
if poly then Clenv.refresh_undefined_univs clenv
else clenv, Univ.empty_level_subst
in e_give_exact (* ~flags *) (Vars.subst_univs_level_constr subst c)
-
-let rec e_trivial_fail_db db_list local_db goal =
+
+let rec e_trivial_fail_db db_list local_db =
+ let next = Proofview.Goal.nf_enter { enter = begin fun gl ->
+ let d = Tacmach.New.pf_last_hyp gl in
+ let hintl = make_resolve_hyp (Tacmach.New.pf_env gl) (Tacmach.New.project gl) d in
+ e_trivial_fail_db db_list (Hint_db.add_list (Tacmach.New.pf_env gl) (Tacmach.New.project gl) hintl local_db)
+ end } in
+ Proofview.Goal.enter { enter = begin fun gl ->
let tacl =
registered_e_assumption ::
- (tclTHEN (Proofview.V82.of_tactic Tactics.intro)
- (function g'->
- let d = pf_last_hyp g' in
- let hintl = make_resolve_hyp (pf_env g') (project g') d in
- (e_trivial_fail_db db_list
- (Hint_db.add_list (pf_env g') (project g') hintl local_db) g'))) ::
- (List.map fst (e_trivial_resolve db_list local_db (pf_concl goal)) )
+ (Tacticals.New.tclTHEN Tactics.intro next) ::
+ (List.map fst (e_trivial_resolve db_list local_db (Tacmach.New.pf_nf_concl gl)))
in
- tclFIRST (List.map tclCOMPLETE tacl) goal
+ Tacticals.New.tclFIRST (List.map Tacticals.New.tclCOMPLETE tacl)
+ end }
and e_my_find_search db_list local_db hdc concl =
let hint_of_db = hintmap_of hdc concl in
@@ -174,14 +194,14 @@ and e_my_find_search db_list local_db hdc concl =
let tac = function
| Res_pf (term,cl) -> unify_resolve poly st (term,cl)
| ERes_pf (term,cl) -> unify_e_resolve poly st (term,cl)
- | Give_exact (c,cl) -> Proofview.V82.tactic (e_exact poly st (c,cl))
+ | Give_exact (c,cl) -> e_exact poly st (c,cl)
| Res_pf_THEN_trivial_fail (term,cl) ->
- Proofview.V82.tactic (tclTHEN (Proofview.V82.of_tactic (unify_e_resolve poly st (term,cl)))
- (e_trivial_fail_db db_list local_db))
+ Tacticals.New.tclTHEN (unify_e_resolve poly st (term,cl))
+ (e_trivial_fail_db db_list local_db)
| Unfold_nth c -> Proofview.V82.tactic (reduce (Unfold [AllOccurrences,c]) onConcl)
| Extern tacast -> conclPattern concl p tacast
in
- let tac = Proofview.V82.of_tactic (run_hint t tac) in
+ let tac = run_hint t tac in
(tac, lazy (pr_hint t)))
in
List.map tac_of_hint hintl
@@ -210,7 +230,7 @@ type search_state = {
dblist : hint_db list;
localdb : hint_db list;
prev : prev_search_state;
- local_lemmas : Evd.open_constr list;
+ local_lemmas : Tacexpr.delayed_open_constr list;
}
and prev_search_state = (* for info eauto *)
@@ -234,7 +254,7 @@ module SearchProblem = struct
| [] -> []
| (tac, cost, pptac) :: tacl ->
try
- let lgls = apply_tac_list tac glls in
+ let lgls = apply_tac_list (Proofview.V82.of_tactic tac) glls in
(* let gl = Proof_trees.db_pr_goal (List.hd (sig_it glls)) in *)
(* msg (hov 1 (pptac ++ str" gives: \n" ++ pr_goals lgls ++ str"\n")); *)
(lgls, cost, pptac) :: aux tacl
@@ -272,7 +292,7 @@ module SearchProblem = struct
prev = ps; local_lemmas = s.local_lemmas}) l
in
let intro_tac =
- let l = filter_tactics s.tacres [Proofview.V82.of_tactic Tactics.intro, (-1), lazy (str "intro")] in
+ let l = filter_tactics s.tacres [Tactics.intro, (-1), lazy (str "intro")] in
List.map
(fun (lgls, cost, pp) ->
let g' = first_goal lgls in
@@ -427,77 +447,48 @@ let gen_eauto ?(debug=Off) np lems = function
let make_depth = function
| None -> !default_search_depth
- | Some (ArgArg d) -> d
- | _ -> error "eauto called with a non closed argument."
+ | Some d -> d
let make_dimension n = function
| None -> (true,make_depth n)
- | Some (ArgArg d) -> (false,d)
- | _ -> error "eauto called with a non closed argument."
+ | Some d -> (false,d)
open Genarg
+open G_auto
-(* Hint bases *)
-
-let pr_hintbases _prc _prlc _prt = Pptactic.pr_hintbases
-
-ARGUMENT EXTEND hintbases
- TYPED AS preident_list_opt
- PRINTED BY pr_hintbases
-| [ "with" "*" ] -> [ None ]
-| [ "with" ne_preident_list(l) ] -> [ Some l ]
-| [ ] -> [ Some [] ]
-END
-
-let pr_constr_coma_sequence prc _ _ =
- prlist_with_sep pr_comma (fun (_,c) -> prc c)
-
-ARGUMENT EXTEND constr_coma_sequence
- TYPED AS open_constr_list
- PRINTED BY pr_constr_coma_sequence
-| [ open_constr(c) "," constr_coma_sequence(l) ] -> [ c::l ]
-| [ open_constr(c) ] -> [ [c] ]
-END
-
-let pr_auto_using prc _prlc _prt = Pptactic.pr_auto_using (fun (_,c) -> prc c)
-
-ARGUMENT EXTEND auto_using
- TYPED AS open_constr_list
- PRINTED BY pr_auto_using
-| [ "using" constr_coma_sequence(l) ] -> [ l ]
-| [ ] -> [ [] ]
-END
+let hintbases = G_auto.hintbases
+let wit_hintbases = G_auto.wit_hintbases
TACTIC EXTEND eauto
| [ "eauto" int_or_var_opt(n) int_or_var_opt(p) auto_using(lems)
hintbases(db) ] ->
- [ Proofview.V82.tactic (gen_eauto (make_dimension n p) lems db) ]
+ [ Proofview.V82.tactic (gen_eauto (make_dimension n p) (eval_uconstrs ist lems) db) ]
END
TACTIC EXTEND new_eauto
| [ "new" "auto" int_or_var_opt(n) auto_using(lems)
hintbases(db) ] ->
[ match db with
- | None -> new_full_auto (make_depth n) lems
- | Some l -> new_auto (make_depth n) lems l ]
+ | None -> new_full_auto (make_depth n) (eval_uconstrs ist lems)
+ | Some l -> new_auto (make_depth n) (eval_uconstrs ist lems) l ]
END
TACTIC EXTEND debug_eauto
| [ "debug" "eauto" int_or_var_opt(n) int_or_var_opt(p) auto_using(lems)
hintbases(db) ] ->
- [ Proofview.V82.tactic (gen_eauto ~debug:Debug (make_dimension n p) lems db) ]
+ [ Proofview.V82.tactic (gen_eauto ~debug:Debug (make_dimension n p) (eval_uconstrs ist lems) db) ]
END
TACTIC EXTEND info_eauto
| [ "info_eauto" int_or_var_opt(n) int_or_var_opt(p) auto_using(lems)
hintbases(db) ] ->
- [ Proofview.V82.tactic (gen_eauto ~debug:Info (make_dimension n p) lems db) ]
+ [ Proofview.V82.tactic (gen_eauto ~debug:Info (make_dimension n p) (eval_uconstrs ist lems) db) ]
END
TACTIC EXTEND dfs_eauto
| [ "dfs" "eauto" int_or_var_opt(p) auto_using(lems)
hintbases(db) ] ->
- [ Proofview.V82.tactic (gen_eauto (true, make_depth p) lems db) ]
+ [ Proofview.V82.tactic (gen_eauto (true, make_depth p) (eval_uconstrs ist lems) db) ]
END
let cons a l = a :: l
@@ -567,7 +558,7 @@ let unfold_head env (ids, csts) c =
in aux c
let autounfold_one db cl =
- Proofview.Goal.nf_enter begin fun gl ->
+ Proofview.Goal.nf_enter { enter = begin fun gl ->
let env = Proofview.Goal.env gl in
let concl = Proofview.Goal.concl gl in
let st =
@@ -586,7 +577,7 @@ let autounfold_one db cl =
| Some hyp -> change_in_hyp None (make_change_arg c') hyp
| None -> convert_concl_no_check c' DEFAULTcast
else Tacticals.New.tclFAIL 0 (str "Nothing to unfold")
- end
+ end }
(* Cset.fold (fun cst -> cons (all_occurrences, EvalConstRef cst)) csts *)
(* (Id.Set.fold (fun id -> cons (all_occurrences, EvalVarRef id)) ids [])) db) *)
diff --git a/tactics/eauto.mli b/tactics/eauto.mli
index 1bb15d6cb..0a490c65d 100644
--- a/tactics/eauto.mli
+++ b/tactics/eauto.mli
@@ -8,31 +8,24 @@
open Term
open Proof_type
-open Evd
open Hints
val hintbases : hint_db_name list option Pcoq.Gram.entry
val wit_hintbases : hint_db_name list option Genarg.uniform_genarg_type
-val wit_auto_using :
- (Tacexpr.open_constr_expr list,
- Tacexpr.open_glob_constr list, Evd.open_constr list)
- Genarg.genarg_type
+val e_assumption : unit Proofview.tactic
+val registered_e_assumption : unit Proofview.tactic
-val e_assumption : tactic
+val e_give_exact : ?flags:Unification.unify_flags -> constr -> unit Proofview.tactic
-val registered_e_assumption : tactic
-
-val e_give_exact : ?flags:Unification.unify_flags -> constr -> tactic
-
-val gen_eauto : ?debug:Tacexpr.debug -> bool * int -> open_constr list ->
+val gen_eauto : ?debug:Tacexpr.debug -> bool * int -> Tacexpr.delayed_open_constr list ->
hint_db_name list option -> tactic
val eauto_with_bases :
?debug:Tacexpr.debug ->
bool * int ->
- open_constr list -> hint_db list -> Proof_type.tactic
+ Tacexpr.delayed_open_constr list -> hint_db list -> Proof_type.tactic
val autounfold : hint_db_name list -> Locus.clause -> tactic
diff --git a/tactics/elim.ml b/tactics/elim.ml
index 1c7e1f0d5..7767affcc 100644
--- a/tactics/elim.ml
+++ b/tactics/elim.ml
@@ -17,28 +17,19 @@ open Tacticals.New
open Tactics
open Proofview.Notations
+(* Supposed to be called without as clause *)
let introElimAssumsThen tac ba =
- let nassums =
- List.fold_left
- (fun acc b -> if b then acc+2 else acc+1)
- 0 ba.Tacticals.branchsign
- in
- let introElimAssums = tclDO nassums intro in
+ assert (ba.Tacticals.branchnames == []);
+ let introElimAssums = tclDO ba.Tacticals.nassums intro in
(tclTHEN introElimAssums (elim_on_ba tac ba))
+(* Supposed to be called with a non-recursive scheme *)
let introCaseAssumsThen tac ba =
- let case_thin_sign =
- List.flatten
- (List.map (function b -> if b then [false;true] else [false])
- ba.Tacticals.branchsign)
- in
- let n1 = List.length case_thin_sign in
+ let n1 = List.length ba.Tacticals.branchsign in
let n2 = List.length ba.Tacticals.branchnames in
let (l1,l2),l3 =
if n1 < n2 then List.chop n1 ba.Tacticals.branchnames, []
- else
- (ba.Tacticals.branchnames, []),
- if n1 > n2 then snd (List.chop n2 case_thin_sign) else [] in
+ else (ba.Tacticals.branchnames, []), List.make (n1-n2) false in
let introCaseAssums =
tclTHEN (intro_patterns l1) (intros_clearing l3) in
(tclTHEN introCaseAssums (case_on_ba (tac l2) ba))
@@ -84,7 +75,7 @@ let tmphyp_name = Id.of_string "_TmpHyp"
let up_to_delta = ref false (* true *)
let general_decompose recognizer c =
- Proofview.Goal.enter begin fun gl ->
+ Proofview.Goal.enter { enter = begin fun gl ->
let type_of = pf_unsafe_type_of gl in
let typc = type_of c in
tclTHENS (cut typc)
@@ -93,11 +84,11 @@ let general_decompose recognizer c =
(ifOnHyp recognizer (general_decompose_aux recognizer)
(fun id -> Proofview.V82.tactic (clear [id]))));
Proofview.V82.tactic (exact_no_check c) ]
- end
+ end }
let head_in indl t gl =
let env = Proofview.Goal.env gl in
- let sigma = Proofview.Goal.sigma gl in
+ let sigma = Tacmach.New.project gl in
try
let ity,_ =
if !up_to_delta
@@ -107,10 +98,10 @@ let head_in indl t gl =
with Not_found -> false
let decompose_these c l =
- Proofview.Goal.enter begin fun gl ->
+ Proofview.Goal.enter { enter = begin fun gl ->
let indl = List.map (fun x -> x, Univ.Instance.empty) l in
general_decompose (fun (_,t) -> head_in indl t gl) c
- end
+ end }
let decompose_and c =
general_decompose
@@ -138,7 +129,7 @@ let induction_trailer abs_i abs_j bargs =
(tclDO (abs_j - abs_i) intro)
(onLastHypId
(fun id ->
- Proofview.Goal.nf_enter begin fun gl ->
+ Proofview.Goal.nf_enter { enter = begin fun gl ->
let idty = pf_unsafe_type_of gl (mkVar id) in
let fvty = global_vars (pf_env gl) idty in
let possible_bring_hyps =
@@ -154,15 +145,14 @@ let induction_trailer abs_i abs_j bargs =
in
let ids = List.rev (ids_of_named_context hyps) in
(tclTHENLIST
- [bring_hyps hyps; tclTRY (Proofview.V82.tactic (clear ids));
- simple_elimination (mkVar id)])
- end
+ [revert ids; simple_elimination (mkVar id)])
+ end }
))
let double_ind h1 h2 =
- Proofview.Goal.nf_enter begin fun gl ->
- let abs_i = of_old (depth_of_quantified_hypothesis true h1) gl in
- let abs_j = of_old (depth_of_quantified_hypothesis true h2) gl in
+ Proofview.Goal.nf_enter { enter = begin fun gl ->
+ let abs_i = depth_of_quantified_hypothesis true h1 gl in
+ let abs_j = depth_of_quantified_hypothesis true h2 gl in
let abs =
if abs_i < abs_j then Proofview.tclUNIT (abs_i,abs_j) else
if abs_i > abs_j then Proofview.tclUNIT (abs_j,abs_i) else
@@ -173,7 +163,7 @@ let double_ind h1 h2 =
(fun id ->
elimination_then
(introElimAssumsThen (induction_trailer abs_i abs_j)) (mkVar id))))
- end
+ end }
let h_double_induction = double_ind
diff --git a/tactics/elimschemes.ml b/tactics/elimschemes.ml
index 4ff774b8e..de2818902 100644
--- a/tactics/elimschemes.ml
+++ b/tactics/elimschemes.ml
@@ -18,6 +18,7 @@ open Indrec
open Declarations
open Typeops
open Ind_tables
+open Sigma.Notations
(* Induction/recursion schemes *)
@@ -102,10 +103,10 @@ let rec_dep_scheme_kind_from_type =
let build_case_analysis_scheme_in_type dep sort ind =
let env = Global.env () in
- let sigma = Evd.from_env env in
- let sigma, indu = Evd.fresh_inductive_instance env sigma ind in
- let sigma, c = build_case_analysis_scheme env sigma indu dep sort in
- c, Evd.evar_universe_context sigma
+ let sigma = Sigma.Unsafe.of_evar_map (Evd.from_env env) in
+ let Sigma (indu, sigma, _) = Sigma.fresh_inductive_instance env sigma ind in
+ let Sigma (c, sigma, _) = build_case_analysis_scheme env sigma indu dep sort in
+ c, Evd.evar_universe_context (Sigma.to_evar_map sigma)
let case_scheme_kind_from_type =
declare_individual_scheme_object "_case_nodep"
diff --git a/tactics/eqdecide.ml b/tactics/eqdecide.ml
index 8ba8f7b6d..be4b13597 100644
--- a/tactics/eqdecide.ml
+++ b/tactics/eqdecide.ml
@@ -27,6 +27,7 @@ open Constr_matching
open Hipattern
open Tacmach.New
open Coqlib
+open Proofview.Notations
(* This file containts the implementation of the tactics ``Decide
Equality'' and ``Compare''. They can be used to decide the
@@ -146,7 +147,7 @@ let rec solveArg hyps eqonleft op largs rargs = match largs, rargs with
intros_reflexivity;
]
| a1 :: largs, a2 :: rargs ->
- Proofview.Goal.enter begin fun gl ->
+ Proofview.Goal.enter { enter = begin fun gl ->
let rectype = pf_unsafe_type_of gl a1 in
let decide = mkDecideEqGoal eqonleft op rectype a1 a2 in
let tac hyp = solveArg (hyp :: hyps) eqonleft op largs rargs in
@@ -154,13 +155,13 @@ let rec solveArg hyps eqonleft op largs rargs = match largs, rargs with
if eqonleft then [eqCase tac;diseqCase hyps eqonleft;default_auto]
else [diseqCase hyps eqonleft;eqCase tac;default_auto] in
(tclTHENS (elim_type decide) subtacs)
- end
+ end }
| _ -> invalid_arg "List.fold_right2"
let solveEqBranch rectype =
Proofview.tclORELSE
begin
- Proofview.Goal.enter begin fun gl ->
+ Proofview.Goal.enter { enter = begin fun gl ->
let concl = pf_nf_concl gl in
match_eqdec concl >>= fun (eqonleft,op,lhs,rhs,_) ->
let (mib,mip) = Global.lookup_inductive rectype in
@@ -169,7 +170,7 @@ let solveEqBranch rectype =
let rargs = getargs rhs
and largs = getargs lhs in
solveArg [] eqonleft op largs rargs
- end
+ end }
end
begin function (e, info) -> match e with
| PatternMatchingFailure -> Tacticals.New.tclZEROMSG (Pp.str"Unexpected conclusion!")
@@ -185,7 +186,7 @@ let hd_app c = match kind_of_term c with
let decideGralEquality =
Proofview.tclORELSE
begin
- Proofview.Goal.enter begin fun gl ->
+ Proofview.Goal.enter { enter = begin fun gl ->
let concl = pf_nf_concl gl in
match_eqdec concl >>= fun (eqonleft,_,c1,c2,typ) ->
let headtyp = hd_app (pf_compute gl typ) in
@@ -196,7 +197,7 @@ let decideGralEquality =
(tclTHEN
(mkBranches c1 c2)
(tclORELSE (solveNoteqBranch eqonleft) (solveEqBranch rectype)))
- end
+ end }
end
begin function (e, info) -> match e with
| PatternMatchingFailure ->
@@ -207,20 +208,20 @@ let decideGralEquality =
let decideEqualityGoal = tclTHEN intros decideGralEquality
let decideEquality rectype =
- Proofview.Goal.enter begin fun gl ->
+ Proofview.Goal.enter { enter = begin fun gl ->
let decide = mkGenDecideEqGoal rectype gl in
(tclTHENS (cut decide) [default_auto;decideEqualityGoal])
- end
+ end }
(* The tactic Compare *)
let compare c1 c2 =
- Proofview.Goal.enter begin fun gl ->
+ Proofview.Goal.enter { enter = begin fun gl ->
let rectype = pf_unsafe_type_of gl c1 in
let decide = mkDecideEqGoal true (build_coq_sumbool ()) rectype c1 c2 in
(tclTHENS (cut decide)
[(tclTHEN intro
(tclTHEN (onLastHyp simplest_case) clear_last));
decideEquality rectype])
- end
+ end }
diff --git a/tactics/eqschemes.ml b/tactics/eqschemes.ml
index c9764af1c..e0bea7770 100644
--- a/tactics/eqschemes.ml
+++ b/tactics/eqschemes.ml
@@ -49,7 +49,6 @@ open Util
open Names
open Term
open Vars
-open Context
open Declarations
open Environ
open Inductive
@@ -58,6 +57,7 @@ open Namegen
open Inductiveops
open Ind_tables
open Indrec
+open Sigma.Notations
let hid = Id.of_string "H"
let xid = Id.of_string "X"
@@ -70,8 +70,8 @@ let build_dependent_inductive ind (mib,mip) =
let realargs,_ = List.chop mip.mind_nrealdecls mip.mind_arity_ctxt in
applist
(mkIndU ind,
- extended_rel_list mip.mind_nrealdecls mib.mind_params_ctxt
- @ extended_rel_list 0 realargs)
+ Context.Rel.to_extended_list mip.mind_nrealdecls mib.mind_params_ctxt
+ @ Context.Rel.to_extended_list 0 realargs)
let my_it_mkLambda_or_LetIn s c = it_mkLambda_or_LetIn c s
let my_it_mkProd_or_LetIn s c = it_mkProd_or_LetIn c s
@@ -108,7 +108,7 @@ let get_sym_eq_data env (ind,u) =
error "Inductive equalities with local definitions in arity not supported.";
let constrsign,ccl = decompose_prod_assum mip.mind_nf_lc.(0) in
let _,constrargs = decompose_app ccl in
- if not (Int.equal (rel_context_length constrsign) (rel_context_length mib.mind_params_ctxt)) then
+ if not (Int.equal (Context.Rel.length constrsign) (Context.Rel.length mib.mind_params_ctxt)) then
error "Constructor must have no arguments"; (* This can be relaxed... *)
let params,constrargs = List.chop mib.mind_nparams constrargs in
if mip.mind_nrealargs > mib.mind_nparams then
@@ -143,7 +143,7 @@ let get_non_sym_eq_data env (ind,u) =
error "Inductive equalities with local definitions in arity not supported";
let constrsign,ccl = decompose_prod_assum mip.mind_nf_lc.(0) in
let _,constrargs = decompose_app ccl in
- if not (Int.equal (rel_context_length constrsign) (rel_context_length mib.mind_params_ctxt)) then
+ if not (Int.equal (Context.Rel.length constrsign) (Context.Rel.length mib.mind_params_ctxt)) then
error "Constructor must have no arguments";
let _,constrargs = List.chop mib.mind_nparams constrargs in
let constrargs = List.map (Vars.subst_instance_constr u) constrargs in
@@ -169,7 +169,7 @@ let build_sym_scheme env ind =
let (mib,mip as specif),nrealargs,realsign,paramsctxt,paramsctxt1 =
get_sym_eq_data env indu in
let cstr n =
- mkApp (mkConstructUi(indu,1),extended_rel_vect n mib.mind_params_ctxt) in
+ mkApp (mkConstructUi(indu,1),Context.Rel.to_extended_vect n mib.mind_params_ctxt) in
let varH = fresh env (default_id_of_sort (snd (mind_arity mip))) in
let applied_ind = build_dependent_inductive indu specif in
let realsign_ind =
@@ -182,7 +182,7 @@ let build_sym_scheme env ind =
my_it_mkLambda_or_LetIn_name
(lift_rel_context (nrealargs+1) realsign_ind)
(mkApp (mkIndU indu,Array.concat
- [extended_rel_vect (3*nrealargs+2) paramsctxt1;
+ [Context.Rel.to_extended_vect (3*nrealargs+2) paramsctxt1;
rel_vect 1 nrealargs;
rel_vect (2*nrealargs+2) nrealargs])),
mkRel 1 (* varH *),
@@ -223,13 +223,13 @@ let build_sym_involutive_scheme env ind =
get_sym_eq_data env indu in
let eq,eqrefl,ctx = get_coq_eq ctx in
let sym, ctx, eff = const_of_scheme sym_scheme_kind env ind ctx in
- let cstr n = mkApp (mkConstructUi (indu,1),extended_rel_vect n paramsctxt) in
+ let cstr n = mkApp (mkConstructUi (indu,1),Context.Rel.to_extended_vect n paramsctxt) in
let varH = fresh env (default_id_of_sort (snd (mind_arity mip))) in
let applied_ind = build_dependent_inductive indu specif in
let applied_ind_C =
mkApp
(mkIndU indu, Array.append
- (extended_rel_vect (nrealargs+1) mib.mind_params_ctxt)
+ (Context.Rel.to_extended_vect (nrealargs+1) mib.mind_params_ctxt)
(rel_vect (nrealargs+1) nrealargs)) in
let realsign_ind =
name_context env ((Name varH,None,applied_ind)::realsign) in
@@ -243,15 +243,15 @@ let build_sym_involutive_scheme env ind =
(mkApp (eq,[|
mkApp
(mkIndU indu, Array.concat
- [extended_rel_vect (3*nrealargs+2) paramsctxt1;
+ [Context.Rel.to_extended_vect (3*nrealargs+2) paramsctxt1;
rel_vect (2*nrealargs+2) nrealargs;
rel_vect 1 nrealargs]);
mkApp (sym,Array.concat
- [extended_rel_vect (3*nrealargs+2) paramsctxt1;
+ [Context.Rel.to_extended_vect (3*nrealargs+2) paramsctxt1;
rel_vect 1 nrealargs;
rel_vect (2*nrealargs+2) nrealargs;
[|mkApp (sym,Array.concat
- [extended_rel_vect (3*nrealargs+2) paramsctxt1;
+ [Context.Rel.to_extended_vect (3*nrealargs+2) paramsctxt1;
rel_vect (2*nrealargs+2) nrealargs;
rel_vect 1 nrealargs;
[|mkRel 1|]])|]]);
@@ -334,7 +334,7 @@ let build_l2r_rew_scheme dep env ind kind =
let eq,eqrefl,ctx = get_coq_eq ctx in
let cstr n p =
mkApp (mkConstructUi(indu,1),
- Array.concat [extended_rel_vect n paramsctxt1;
+ Array.concat [Context.Rel.to_extended_vect n paramsctxt1;
rel_vect p nrealargs]) in
let varH = fresh env (default_id_of_sort (snd (mind_arity mip))) in
let varHC = fresh env (Id.of_string "HC") in
@@ -342,12 +342,12 @@ let build_l2r_rew_scheme dep env ind kind =
let applied_ind = build_dependent_inductive indu specif in
let applied_ind_P =
mkApp (mkIndU indu, Array.concat
- [extended_rel_vect (3*nrealargs) paramsctxt1;
+ [Context.Rel.to_extended_vect (3*nrealargs) paramsctxt1;
rel_vect 0 nrealargs;
rel_vect nrealargs nrealargs]) in
let applied_ind_G =
mkApp (mkIndU indu, Array.concat
- [extended_rel_vect (3*nrealargs+3) paramsctxt1;
+ [Context.Rel.to_extended_vect (3*nrealargs+3) paramsctxt1;
rel_vect (nrealargs+3) nrealargs;
rel_vect 0 nrealargs]) in
let realsign_P = lift_rel_context nrealargs realsign in
@@ -358,10 +358,10 @@ let build_l2r_rew_scheme dep env ind kind =
lift_rel_context (nrealargs+3) realsign) in
let applied_sym_C n =
mkApp(sym,
- Array.append (extended_rel_vect n mip.mind_arity_ctxt) [|mkVar varH|]) in
+ Array.append (Context.Rel.to_extended_vect n mip.mind_arity_ctxt) [|mkVar varH|]) in
let applied_sym_G =
mkApp(sym,
- Array.concat [extended_rel_vect (nrealargs*3+4) paramsctxt1;
+ Array.concat [Context.Rel.to_extended_vect (nrealargs*3+4) paramsctxt1;
rel_vect (nrealargs+4) nrealargs;
rel_vect 1 nrealargs;
[|mkRel 1|]]) in
@@ -371,7 +371,7 @@ let build_l2r_rew_scheme dep env ind kind =
let ci = make_case_info (Global.env()) ind RegularStyle in
let cieq = make_case_info (Global.env()) (fst (destInd eq)) RegularStyle in
let applied_PC =
- mkApp (mkVar varP,Array.append (extended_rel_vect 1 realsign)
+ mkApp (mkVar varP,Array.append (Context.Rel.to_extended_vect 1 realsign)
(if dep then [|cstr (2*nrealargs+1) 1|] else [||])) in
let applied_PG =
mkApp (mkVar varP,Array.append (rel_vect 1 nrealargs)
@@ -381,11 +381,11 @@ let build_l2r_rew_scheme dep env ind kind =
(if dep then [|mkRel 2|] else [||])) in
let applied_sym_sym =
mkApp (sym,Array.concat
- [extended_rel_vect (2*nrealargs+4) paramsctxt1;
+ [Context.Rel.to_extended_vect (2*nrealargs+4) paramsctxt1;
rel_vect 4 nrealargs;
rel_vect (nrealargs+4) nrealargs;
[|mkApp (sym,Array.concat
- [extended_rel_vect (2*nrealargs+4) paramsctxt1;
+ [Context.Rel.to_extended_vect (2*nrealargs+4) paramsctxt1;
rel_vect (nrealargs+4) nrealargs;
rel_vect 4 nrealargs;
[|mkRel 2|]])|]]) in
@@ -408,7 +408,7 @@ let build_l2r_rew_scheme dep env ind kind =
mkApp (eq,[|lift 4 applied_ind;applied_sym_sym;mkRel 1|]),
applied_PR)),
mkApp (sym_involutive,
- Array.append (extended_rel_vect 3 mip.mind_arity_ctxt) [|mkVar varH|]),
+ Array.append (Context.Rel.to_extended_vect 3 mip.mind_arity_ctxt) [|mkVar varH|]),
[|main_body|])
else
main_body))))))
@@ -447,7 +447,7 @@ let build_l2r_forward_rew_scheme dep env ind kind =
get_sym_eq_data env indu in
let cstr n p =
mkApp (mkConstructUi(indu,1),
- Array.concat [extended_rel_vect n paramsctxt1;
+ Array.concat [Context.Rel.to_extended_vect n paramsctxt1;
rel_vect p nrealargs]) in
let varH = fresh env (default_id_of_sort (snd (mind_arity mip))) in
let varHC = fresh env (Id.of_string "HC") in
@@ -455,12 +455,12 @@ let build_l2r_forward_rew_scheme dep env ind kind =
let applied_ind = build_dependent_inductive indu specif in
let applied_ind_P =
mkApp (mkIndU indu, Array.concat
- [extended_rel_vect (4*nrealargs+2) paramsctxt1;
+ [Context.Rel.to_extended_vect (4*nrealargs+2) paramsctxt1;
rel_vect 0 nrealargs;
rel_vect (nrealargs+1) nrealargs]) in
let applied_ind_P' =
mkApp (mkIndU indu, Array.concat
- [extended_rel_vect (3*nrealargs+1) paramsctxt1;
+ [Context.Rel.to_extended_vect (3*nrealargs+1) paramsctxt1;
rel_vect 0 nrealargs;
rel_vect (2*nrealargs+1) nrealargs]) in
let realsign_P n = lift_rel_context (nrealargs*n+n) realsign in
@@ -538,7 +538,7 @@ let build_r2l_forward_rew_scheme dep env ind kind =
let ((mib,mip as specif),constrargs,realsign,paramsctxt,nrealargs) =
get_non_sym_eq_data env indu in
let cstr n =
- mkApp (mkConstructUi(indu,1),extended_rel_vect n mib.mind_params_ctxt) in
+ mkApp (mkConstructUi(indu,1),Context.Rel.to_extended_vect n mib.mind_params_ctxt) in
let constrargs_cstr = constrargs@[cstr 0] in
let varH = fresh env (default_id_of_sort (snd (mind_arity mip))) in
let varHC = fresh env (Id.of_string "HC") in
@@ -554,8 +554,8 @@ let build_r2l_forward_rew_scheme dep env ind kind =
applist (mkVar varP,if dep then constrargs_cstr else constrargs) in
let applied_PG =
mkApp (mkVar varP,
- if dep then extended_rel_vect 0 realsign_ind
- else extended_rel_vect 1 realsign) in
+ if dep then Context.Rel.to_extended_vect 0 realsign_ind
+ else Context.Rel.to_extended_vect 1 realsign) in
let c =
(my_it_mkLambda_or_LetIn paramsctxt
(my_it_mkLambda_or_LetIn_name realsign_ind
@@ -599,12 +599,12 @@ let fix_r2l_forward_rew_scheme (c, ctx') =
| hp :: p :: ind :: indargs ->
let c' =
my_it_mkLambda_or_LetIn indargs
- (mkLambda_or_LetIn (map_rel_declaration (liftn (-1) 1) p)
- (mkLambda_or_LetIn (map_rel_declaration (liftn (-1) 2) hp)
- (mkLambda_or_LetIn (map_rel_declaration (lift 2) ind)
+ (mkLambda_or_LetIn (Context.Rel.Declaration.map (liftn (-1) 1) p)
+ (mkLambda_or_LetIn (Context.Rel.Declaration.map (liftn (-1) 2) hp)
+ (mkLambda_or_LetIn (Context.Rel.Declaration.map (lift 2) ind)
(Reductionops.whd_beta Evd.empty
(applist (c,
- extended_rel_list 3 indargs @ [mkRel 1;mkRel 3;mkRel 2]))))))
+ Context.Rel.to_extended_list 3 indargs @ [mkRel 1;mkRel 3;mkRel 2]))))))
in c', ctx'
| _ -> anomaly (Pp.str "Ill-formed non-dependent left-to-right rewriting scheme")
@@ -630,9 +630,10 @@ let fix_r2l_forward_rew_scheme (c, ctx') =
(**********************************************************************)
let build_r2l_rew_scheme dep env ind k =
- let sigma, indu = Evd.fresh_inductive_instance env (Evd.from_env env) ind in
- let sigma', c = build_case_analysis_scheme env sigma indu dep k in
- c, Evd.evar_universe_context sigma'
+ let sigma = Sigma.Unsafe.of_evar_map (Evd.from_env env) in
+ let Sigma (indu, sigma, _) = Sigma.fresh_inductive_instance env sigma ind in
+ let Sigma (c, sigma, _) = build_case_analysis_scheme env sigma indu dep k in
+ c, Evd.evar_universe_context (Sigma.to_evar_map sigma)
let build_l2r_rew_scheme = build_l2r_rew_scheme
let build_l2r_forward_rew_scheme = build_l2r_forward_rew_scheme
@@ -742,7 +743,7 @@ let build_congr env (eq,refl,ctx) ind =
let (_,_,ty) = lookup_rel (mip.mind_nrealargs - i + 1) env_with_arity in
let constrsign,ccl = decompose_prod_assum mip.mind_nf_lc.(0) in
let _,constrargs = decompose_app ccl in
- if Int.equal (rel_context_length constrsign) (rel_context_length mib.mind_params_ctxt) then
+ if Int.equal (Context.Rel.length constrsign) (Context.Rel.length mib.mind_params_ctxt) then
error "Constructor must have no arguments";
let b = List.nth constrargs (i + mib.mind_nparams - 1) in
let varB = fresh env (Id.of_string "B") in
@@ -758,8 +759,8 @@ let build_congr env (eq,refl,ctx) ind =
(mkNamedLambda varH
(applist
(mkIndU indu,
- extended_rel_list (mip.mind_nrealargs+2) paramsctxt @
- extended_rel_list 0 realsign))
+ Context.Rel.to_extended_list (mip.mind_nrealargs+2) paramsctxt @
+ Context.Rel.to_extended_list 0 realsign))
(mkCase (ci,
my_it_mkLambda_or_LetIn_name
(lift_rel_context (mip.mind_nrealargs+3) realsign)
@@ -767,9 +768,9 @@ let build_congr env (eq,refl,ctx) ind =
(Anonymous,
applist
(mkIndU indu,
- extended_rel_list (2*mip.mind_nrealdecls+3)
+ Context.Rel.to_extended_list (2*mip.mind_nrealdecls+3)
paramsctxt
- @ extended_rel_list 0 realsign),
+ @ Context.Rel.to_extended_list 0 realsign),
mkApp (eq,
[|mkVar varB;
mkApp (mkVar varf, [|lift (2*mip.mind_nrealdecls+4) b|]);
diff --git a/tactics/equality.ml b/tactics/equality.ml
index ef1ec13ba..1e814e861 100644
--- a/tactics/equality.ml
+++ b/tactics/equality.ml
@@ -40,6 +40,7 @@ open Eqschemes
open Locus
open Locusops
open Misctypes
+open Sigma.Notations
open Proofview.Notations
open Unification
@@ -158,7 +159,7 @@ let instantiate_lemma_all frzevars gl c ty l l2r concl =
let try_occ (evd', c') =
Clenvtac.clenv_pose_dependent_evars true {eqclause with evd = evd'}
in
- let flags = make_flags frzevars (Proofview.Goal.sigma gl) rewrite_unif_flags eqclause in
+ let flags = make_flags frzevars (Tacmach.New.project gl) rewrite_unif_flags eqclause in
let occs =
w_unify_to_subterm_all ~flags env eqclause.evd
((if l2r then c1 else c2),concl)
@@ -242,12 +243,12 @@ let rewrite_keyed_unif_flags = {
}
let rewrite_elim with_evars frzevars cls c e =
- Proofview.Goal.enter begin fun gl ->
+ Proofview.Goal.enter { enter = begin fun gl ->
let flags = if Unification.is_keyed_unification ()
then rewrite_keyed_unif_flags else rewrite_conv_closed_unif_flags in
- let flags = make_flags frzevars (Proofview.Goal.sigma gl) flags c in
+ let flags = make_flags frzevars (Tacmach.New.project gl) flags c in
general_elim_clause with_evars flags cls c e
- end
+ end }
(* Ad hoc asymmetric general_elim_clause *)
let general_elim_clause with_evars frzevars cls rew elim =
@@ -282,7 +283,7 @@ let general_elim_clause with_evars frzevars tac cls c t l l2r elim =
(general_elim_clause with_evars frzevars cls c elim))
tac
in
- Proofview.Goal.enter begin fun gl ->
+ Proofview.Goal.enter { enter = begin fun gl ->
let instantiate_lemma concl =
if not all then instantiate_lemma gl c t l l2r concl
else instantiate_lemma_all frzevars gl c t l l2r concl
@@ -294,7 +295,7 @@ let general_elim_clause with_evars frzevars tac cls c t l l2r elim =
let cs = instantiate_lemma typ in
if firstonly then tclFIRST (List.map try_clause cs)
else tclMAP try_clause cs
- end
+ end }
(* The next function decides in particular whether to try a regular
rewrite or a generalized rewrite.
@@ -313,7 +314,7 @@ let jmeq_same_dom gl = function
let rels, t = decompose_prod_assum t in
let env = Environ.push_rel_context rels (Proofview.Goal.env gl) in
match decompose_app t with
- | _, [dom1; _; dom2;_] -> is_conv env (Proofview.Goal.sigma gl) dom1 dom2
+ | _, [dom1; _; dom2;_] -> is_conv env (Tacmach.New.project gl) dom1 dom2
| _ -> false
(* find_elim determines which elimination principle is necessary to
@@ -354,8 +355,8 @@ let find_elim hdcncl lft2rgt dep cls ot gl =
Logic.eq or Jmeq just before *)
assert false
in
- let sigma, elim = Evd.fresh_global (Global.env ()) (Proofview.Goal.sigma gl) (ConstRef c) in
- sigma, elim, Safe_typing.empty_private_constants
+ let Sigma (elim, sigma, p) = Sigma.fresh_global (Global.env ()) (Proofview.Goal.sigma gl) (ConstRef c) in
+ Sigma ((elim, Safe_typing.empty_private_constants), sigma, p)
else
let scheme_name = match dep, lft2rgt, inccl with
(* Non dependent case *)
@@ -373,10 +374,10 @@ let find_elim hdcncl lft2rgt dep cls ot gl =
| Ind (ind,u) ->
let c, eff = find_scheme scheme_name ind in
(* MS: cannot use pf_constr_of_global as the eliminator might be generated by side-effect *)
- let sigma, elim =
- Evd.fresh_global (Global.env ()) (Proofview.Goal.sigma gl) (ConstRef c)
+ let Sigma (elim, sigma, p) =
+ Sigma.fresh_global (Global.env ()) (Proofview.Goal.sigma gl) (ConstRef c)
in
- sigma, elim, eff
+ Sigma ((elim, eff), sigma, p)
| _ -> assert false
let type_of_clause cls gl = match cls with
@@ -384,17 +385,20 @@ let type_of_clause cls gl = match cls with
| Some id -> pf_get_hyp_typ id gl
let leibniz_rewrite_ebindings_clause cls lft2rgt tac c t l with_evars frzevars dep_proof_ok hdcncl =
- Proofview.Goal.nf_enter begin fun gl ->
+ Proofview.Goal.nf_s_enter { s_enter = begin fun gl ->
let isatomic = isProd (whd_zeta hdcncl) in
let dep_fun = if isatomic then dependent else dependent_no_evar in
let type_of_cls = type_of_clause cls gl in
let dep = dep_proof_ok && dep_fun c type_of_cls in
- let (sigma,elim,effs) = find_elim hdcncl lft2rgt dep cls (Some t) gl in
- Proofview.Unsafe.tclEVARS sigma <*> Proofview.tclEFFECTS effs <*>
+ let Sigma ((elim, effs), sigma, p) = find_elim hdcncl lft2rgt dep cls (Some t) gl in
+ let tac =
+ Proofview.tclEFFECTS effs <*>
general_elim_clause with_evars frzevars tac cls c t l
(match lft2rgt with None -> false | Some b -> b)
{elimindex = None; elimbody = (elim,NoBindings); elimrename = None}
- end
+ in
+ Sigma (tac, sigma, p)
+ end }
let adjust_rewriting_direction args lft2rgt =
match args with
@@ -417,8 +421,8 @@ let general_rewrite_ebindings_clause cls lft2rgt occs frzevars dep_proof_ok ?tac
if occs != AllOccurrences then (
rewrite_side_tac (Hook.get forward_general_setoid_rewrite_clause cls lft2rgt occs (c,l) ~new_goals:[]) tac)
else
- Proofview.Goal.enter begin fun gl ->
- let sigma = Proofview.Goal.sigma gl in
+ Proofview.Goal.enter { enter = begin fun gl ->
+ let sigma = Tacmach.New.project gl in
let env = Proofview.Goal.env gl in
let ctype = get_type_of env sigma c in
let rels, t = decompose_prod_assum (whd_betaiotazeta sigma ctype) in
@@ -445,7 +449,7 @@ let general_rewrite_ebindings_clause cls lft2rgt occs frzevars dep_proof_ok ?tac
| None -> Proofview.tclZERO ~info e
(* error "The provided term does not end with an equality or a declared rewrite relation." *)
end
- end
+ end }
let general_rewrite_ebindings =
general_rewrite_ebindings_clause None
@@ -507,9 +511,9 @@ let general_rewrite_clause l2r with_evars ?tac c cl =
let ids_of_hyps = pf_ids_of_hyps gl in
Id.Set.fold (fun id l -> List.remove Id.equal id l) ids_in_c ids_of_hyps
in
- Proofview.Goal.enter begin fun gl ->
+ Proofview.Goal.enter { enter = begin fun gl ->
do_hyps_atleastonce (ids gl)
- end
+ end }
in
if cl.concl_occs == NoOccurrences then do_hyps else
tclIFTHENTRYELSEMUST
@@ -517,25 +521,25 @@ let general_rewrite_clause l2r with_evars ?tac c cl =
do_hyps
let apply_special_clear_request clear_flag f =
- Proofview.Goal.enter begin fun gl ->
- let sigma = Proofview.Goal.sigma gl in
+ Proofview.Goal.enter { enter = begin fun gl ->
+ let sigma = Tacmach.New.project gl in
let env = Proofview.Goal.env gl in
try
- let sigma,(c,bl) = f env sigma in
+ let ((c, bl), sigma) = run_delayed env sigma f in
apply_clear_request clear_flag (use_clear_hyp_by_default ()) c
with
e when catchable_exception e -> tclIDTAC
- end
+ end }
let general_multi_rewrite with_evars l cl tac =
let do1 l2r f =
- Proofview.Goal.enter begin fun gl ->
- let sigma = Proofview.Goal.sigma gl in
+ Proofview.Goal.enter { enter = begin fun gl ->
+ let sigma = Tacmach.New.project gl in
let env = Proofview.Goal.env gl in
- let sigma,c = f env sigma in
+ let (c, sigma) = run_delayed env sigma f in
tclWITHHOLES with_evars
(general_rewrite_clause l2r with_evars ?tac c cl) sigma
- end
+ end }
in
let rec doN l2r c = function
| Precisely n when n <= 0 -> Proofview.tclUNIT ()
@@ -598,14 +602,14 @@ let replace_using_leibniz clause c1 c2 l2r unsafe try_prove_eq_opt =
| None -> Proofview.tclUNIT ()
| Some tac -> tclCOMPLETE tac
in
- Proofview.Goal.enter begin fun gl ->
+ Proofview.Goal.enter { enter = begin fun gl ->
let get_type_of = pf_apply get_type_of gl in
let t1 = get_type_of c1
and t2 = get_type_of c2 in
let evd =
- if unsafe then Some (Proofview.Goal.sigma gl)
+ if unsafe then Some (Tacmach.New.project gl)
else
- try Some (Evarconv.the_conv_x (Proofview.Goal.env gl) t1 t2 (Proofview.Goal.sigma gl))
+ try Some (Evarconv.the_conv_x (Proofview.Goal.env gl) t1 t2 (Tacmach.New.project gl))
with Evarconv.UnableToUnify _ -> None
in
match evd with
@@ -624,7 +628,7 @@ let replace_using_leibniz clause c1 c2 l2r unsafe try_prove_eq_opt =
tclTHEN (apply sym) assumption;
try_prove_eq
])))
- end
+ end }
let replace c1 c2 =
replace_using_leibniz onConcl c2 c1 false false None
@@ -907,7 +911,7 @@ let rec build_discriminator env sigma dirn c sort = function
*)
let gen_absurdity id =
- Proofview.Goal.enter begin fun gl ->
+ Proofview.Goal.enter { enter = begin fun gl ->
let hyp_typ = pf_get_hyp_typ id (Proofview.Goal.assume gl) in
let hyp_typ = pf_nf_evar gl hyp_typ in
if is_empty_type hyp_typ
@@ -915,7 +919,7 @@ let gen_absurdity id =
simplest_elim (mkVar id)
else
tclZEROMSG (str "Not the negation of an equality.")
- end
+ end }
(* Precondition: eq is leibniz equality
@@ -971,7 +975,7 @@ let discr_positions env sigma (lbeq,eqn,(t,t1,t2)) eq_clause cpath dirn sort =
let discrEq (lbeq,_,(t,t1,t2) as u) eq_clause =
let sigma = eq_clause.evd in
- Proofview.Goal.nf_enter begin fun gl ->
+ Proofview.Goal.nf_enter { enter = begin fun gl ->
let env = Proofview.Goal.env gl in
let concl = Proofview.Goal.concl gl in
match find_positions env sigma t1 t2 with
@@ -980,10 +984,10 @@ let discrEq (lbeq,_,(t,t1,t2) as u) eq_clause =
| Inl (cpath, (_,dirn), _) ->
let sort = pf_apply get_type_of gl concl in
discr_positions env sigma u eq_clause cpath dirn sort
- end
+ end }
let onEquality with_evars tac (c,lbindc) =
- Proofview.Goal.nf_enter begin fun gl ->
+ Proofview.Goal.nf_enter { enter = begin fun gl ->
let type_of = pf_unsafe_type_of gl in
let reduce_to_quantified_ind = pf_apply Tacred.reduce_to_quantified_ind gl in
let t = type_of c in
@@ -995,11 +999,11 @@ let onEquality with_evars tac (c,lbindc) =
tclTHEN
(Proofview.Unsafe.tclEVARS eq_clause'.evd)
(tac (eq,eqn,eq_args) eq_clause')
- end
+ end }
let onNegatedEquality with_evars tac =
- Proofview.Goal.nf_enter begin fun gl ->
- let sigma = Proofview.Goal.sigma gl in
+ Proofview.Goal.nf_enter { enter = begin fun gl ->
+ let sigma = Tacmach.New.project gl in
let ccl = Proofview.Goal.concl gl in
let env = Proofview.Goal.env gl in
match kind_of_term (hnf_constr env sigma ccl) with
@@ -1009,7 +1013,7 @@ let onNegatedEquality with_evars tac =
onEquality with_evars tac (mkVar id,NoBindings)))
| _ ->
tclZEROMSG (str "Not a negated primitive equality.")
- end
+ end }
let discrSimpleClause with_evars = function
| None -> onNegatedEquality with_evars discrEq
@@ -1135,7 +1139,7 @@ let minimal_free_rels_rec env sigma =
let sig_clausal_form env sigma sort_of_ty siglen ty dflt =
let sigdata = find_sigma_data env sort_of_ty in
- let evdref = ref (Evd.create_goal_evar_defs sigma) in
+ let evdref = ref (Evd.clear_metas sigma) in
let rec sigrec_clausal_form siglen p_i =
if Int.equal siglen 0 then
(* is the default value typable with the expected type *)
@@ -1278,7 +1282,7 @@ let eq_dec_scheme_kind_name = ref (fun _ -> failwith "eq_dec_scheme undefined")
let set_eq_dec_scheme_kind k = eq_dec_scheme_kind_name := (fun _ -> k)
let inject_if_homogenous_dependent_pair ty =
- Proofview.Goal.nf_enter begin fun gl ->
+ Proofview.Goal.nf_enter { enter = begin fun gl ->
try
let eq,u,(t,t1,t2) = find_this_eq_data_decompose gl ty in
(* fetch the informations of the pair *)
@@ -1316,7 +1320,7 @@ let inject_if_homogenous_dependent_pair ty =
])]
with Exit ->
Proofview.tclUNIT ()
- end
+ end }
(* Given t1=t2 Inj calculates the whd normal forms of t1 and t2 and it
expands then only when the whdnf has a constructor of an inductive type
@@ -1353,13 +1357,13 @@ let inject_at_positions env sigma l2r (eq,_,(t,t1,t2)) eq_clause posns tac =
tclZEROMSG (str "Failed to decompose the equality.")
else
Proofview.tclTHEN (Proofview.Unsafe.tclEVARS !evdref)
- (Proofview.tclBIND
- (Proofview.Monad.List.map
+ (Tacticals.New.tclTHENFIRST
+ (Proofview.tclIGNORE (Proofview.Monad.List.map
(fun (pf,ty) -> tclTHENS (cut ty)
[inject_if_homogenous_dependent_pair ty;
Proofview.V82.tactic (refine pf)])
- (if l2r then List.rev injectors else injectors))
- (fun _ -> tac (List.length injectors)))
+ (if l2r then List.rev injectors else injectors)))
+ (tac (List.length injectors)))
let injEqThen tac l2r (eq,_,(t,t1,t2) as u) eq_clause =
let sigma = eq_clause.evd in
@@ -1390,7 +1394,7 @@ let postInjEqTac clear_flag ipats c n =
then intro_patterns_bound_to n MoveLast ipats
else intro_patterns_to MoveLast ipats in
tclTHEN clear_tac intro_tac
- | None -> tclIDTAC
+ | None -> apply_clear_request clear_flag false c
let injEq clear_flag ipats =
let l2r =
@@ -1408,7 +1412,7 @@ let injConcl = injClause None false None
let injHyp clear_flag id = injClause None false (Some (clear_flag,ElimOnIdent (Loc.ghost,id)))
let decompEqThen ntac (lbeq,_,(t,t1,t2) as u) clause =
- Proofview.Goal.nf_enter begin fun gl ->
+ Proofview.Goal.nf_enter { enter = begin fun gl ->
let sort = pf_apply get_type_of gl (Proofview.Goal.concl gl) in
let sigma = clause.evd in
let env = Proofview.Goal.env gl in
@@ -1420,7 +1424,7 @@ let decompEqThen ntac (lbeq,_,(t,t1,t2) as u) clause =
| Inr posns ->
inject_at_positions env sigma true u clause posns
(ntac (clenv_value clause))
- end
+ end }
let dEqThen with_evars ntac = function
| None -> onNegatedEquality with_evars (decompEqThen (ntac None))
@@ -1431,10 +1435,10 @@ let dEq with_evars =
(apply_clear_request clear_flag (use_clear_hyp_by_default ()) c))
let intro_decompe_eq tac data cl =
- Proofview.Goal.enter begin fun gl ->
+ Proofview.Goal.enter { enter = begin fun gl ->
let cl = pf_apply make_clenv_binding gl cl NoBindings in
decompEqThen (fun _ -> tac) data cl
- end
+ end }
let _ = declare_intro_decomp_eq intro_decompe_eq
@@ -1485,6 +1489,7 @@ let decomp_tuple_term env c t =
in decomprec (mkRel 1) c t
let subst_tuple_term env sigma dep_pair1 dep_pair2 b =
+ let sigma = Sigma.to_evar_map sigma in
let typ = get_type_of env sigma dep_pair1 in
(* We find all possible decompositions *)
let decomps1 = decomp_tuple_term env dep_pair1 typ in
@@ -1509,7 +1514,7 @@ let subst_tuple_term env sigma dep_pair1 dep_pair2 b =
(* 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
- sigma,body,expected_goal
+ Sigma.Unsafe.of_pair ((body, expected_goal), sigma)
(* Like "replace" but decompose dependent equalities *)
(* i.e. if equality is "exists t v = exists u w", and goal is "phi(t,u)", *)
@@ -1517,34 +1522,42 @@ let subst_tuple_term env sigma dep_pair1 dep_pair2 b =
(* on for further iterated sigma-tuples *)
let cutSubstInConcl l2r eqn =
- Proofview.Goal.nf_enter begin fun gl ->
+ Proofview.Goal.nf_s_enter { s_enter = begin fun gl ->
+ let env = Proofview.Goal.env gl in
+ let sigma = Proofview.Goal.sigma gl in
let (lbeq,u,(t,e1,e2)) = find_eq_data_decompose gl eqn in
let typ = pf_concl gl in
let (e1,e2) = if l2r then (e1,e2) else (e2,e1) in
- let sigma,typ,expected = pf_apply subst_tuple_term gl e1 e2 typ in
+ let Sigma ((typ, expected), sigma, p) = subst_tuple_term env sigma e1 e2 typ in
+ let tac =
tclTHENFIRST
(tclTHENLIST [
- (Proofview.Unsafe.tclEVARS sigma);
(change_concl typ); (* Put in pattern form *)
(replace_core onConcl l2r eqn)
])
(change_concl expected) (* Put in normalized form *)
- end
+ in
+ Sigma (tac, sigma, p)
+ end }
let cutSubstInHyp l2r eqn id =
- Proofview.Goal.nf_enter begin fun gl ->
+ Proofview.Goal.nf_s_enter { s_enter = begin fun gl ->
+ let env = Proofview.Goal.env gl in
+ let sigma = Proofview.Goal.sigma gl in
let (lbeq,u,(t,e1,e2)) = find_eq_data_decompose gl eqn in
let typ = pf_get_hyp_typ id gl in
let (e1,e2) = if l2r then (e1,e2) else (e2,e1) in
- let sigma,typ,expected = pf_apply subst_tuple_term gl e1 e2 typ in
- tclTHENFIRST
+ let Sigma ((typ, expected), sigma, p) = subst_tuple_term env sigma e1 e2 typ in
+ let tac =
+ tclTHENFIRST
(tclTHENLIST [
- (Proofview.Unsafe.tclEVARS sigma);
(change_in_hyp None (make_change_arg typ) (id,InHypTypeOnly));
(replace_core (onHyp id) l2r eqn)
])
(change_in_hyp None (make_change_arg expected) (id,InHypTypeOnly))
- end
+ in
+ Sigma (tac, sigma, p)
+ end }
let try_rewrite tac =
Proofview.tclORELSE tac begin function (e, info) -> match e with
@@ -1566,11 +1579,11 @@ let cutRewriteInHyp l2r eqn id = cutRewriteClause l2r eqn (Some id)
let cutRewriteInConcl l2r eqn = cutRewriteClause l2r eqn None
let substClause l2r c cls =
- Proofview.Goal.enter begin fun gl ->
+ Proofview.Goal.enter { enter = begin fun gl ->
let eq = pf_apply get_type_of gl c in
tclTHENS (cutSubstClause l2r eq cls)
[Proofview.tclUNIT (); Proofview.V82.tactic (exact_no_check c)]
- end
+ end }
let rewriteClause l2r c cls = try_rewrite (substClause l2r c cls)
let rewriteInHyp l2r c id = rewriteClause l2r c (Some id)
@@ -1596,10 +1609,10 @@ user = raise user error specific to rewrite
(* Substitutions tactics (JCF) *)
let unfold_body x =
- Proofview.Goal.enter begin fun gl ->
+ Proofview.Goal.enter { enter = begin fun gl ->
(** We normalize the given hypothesis immediately. *)
let hyps = Proofview.Goal.hyps (Proofview.Goal.assume gl) in
- let (_, xval, _) = Context.lookup_named x hyps in
+ let (_, xval, _) = Context.Named.lookup x hyps in
let xval = match xval with
| None -> errorlabstrm "unfold_body"
(pr_id x ++ str" is not a defined hypothesis.")
@@ -1613,7 +1626,7 @@ let unfold_body x =
let reductc = Proofview.V82.tactic (fun gl -> reduct_in_concl (rfun, DEFAULTcast) gl) in
tclTHENLIST [tclMAP reducth hl; reductc]
end
- end
+ end }
let restrict_to_eq_and_identity eq = (* compatibility *)
if not (is_global glob_eq eq) &&
@@ -1636,7 +1649,7 @@ let is_eq_x gl x (id,_,c) =
erase hyp and x; proceed by generalizing all dep hyps *)
let subst_one dep_proof_ok x (hyp,rhs,dir) =
- Proofview.Goal.enter begin fun gl ->
+ Proofview.Goal.enter { enter = begin fun gl ->
let env = Proofview.Goal.env gl in
let hyps = Proofview.Goal.hyps (Proofview.Goal.assume gl) in
let concl = Proofview.Goal.concl (Proofview.Goal.assume gl) in
@@ -1662,13 +1675,13 @@ let subst_one dep_proof_ok x (hyp,rhs,dir) =
else
[Proofview.tclUNIT ()]) @
[tclTRY (clear [x; hyp])])
- end
+ end }
(* Look for an hypothesis hyp of the form "x=rhs" or "rhs=x", rewrite
it everywhere, and erase hyp and x; proceed by generalizing all dep hyps *)
let subst_one_var dep_proof_ok x =
- Proofview.Goal.enter begin fun gl ->
+ Proofview.Goal.enter { enter = begin fun gl ->
let gl = Proofview.Goal.assume gl in
let (_,xval,_) = pf_get_hyp x gl in
(* If x has a body, simply replace x with body and clear x *)
@@ -1681,13 +1694,13 @@ let subst_one_var dep_proof_ok x =
(** [is_eq_x] ensures nf_evar on its side *)
let hyps = Proofview.Goal.hyps gl in
let test hyp _ = is_eq_x gl varx hyp in
- Context.fold_named_context test ~init:() hyps;
+ Context.Named.fold_outside test ~init:() hyps;
errorlabstrm "Subst"
(str "Cannot find any non-recursive equality over " ++ pr_id x ++
str".")
with FoundHyp res -> res in
subst_one dep_proof_ok x res
- end
+ end }
let subst_gen dep_proof_ok ids =
tclTHEN Proofview.V82.nf_evar_goals (tclMAP (subst_one_var dep_proof_ok) ids)
@@ -1709,7 +1722,7 @@ let default_subst_tactic_flags () =
else
{ only_leibniz = true; rewrite_dependent_proof = false }
-let regular_subst_tactic = ref false
+let regular_subst_tactic = ref true
let _ =
declare_bool_option
@@ -1747,7 +1760,7 @@ let subst_all ?(flags=default_subst_tactic_flags ()) () =
(* Second step: treat equations *)
let process hyp =
- Proofview.Goal.enter begin fun gl ->
+ Proofview.Goal.enter { enter = begin fun gl ->
let gl = Proofview.Goal.assume gl in
let find_eq_data_decompose = find_eq_data_decompose gl in
let (_,_,c) = pf_get_hyp hyp gl in
@@ -1761,19 +1774,19 @@ let subst_all ?(flags=default_subst_tactic_flags ()) () =
subst_one flags.rewrite_dependent_proof y' (hyp,x,false)
| _ ->
Proofview.tclUNIT ()
- end
+ end }
in
- Proofview.Goal.nf_enter begin fun gl ->
+ Proofview.Goal.nf_enter { enter = begin fun gl ->
let ids = find_equations gl in
tclMAP process ids
- end
+ end }
else
(* Old implementation, not able to manage configurations like a=b, a=t,
or situations like "a = S b, b = S a", or also accidentally unfolding
let-ins *)
- Proofview.Goal.nf_enter begin fun gl ->
+ Proofview.Goal.nf_enter { enter = begin fun gl ->
let find_eq_data_decompose = find_eq_data_decompose gl in
let test (_,c) =
try
@@ -1790,7 +1803,7 @@ let subst_all ?(flags=default_subst_tactic_flags ()) () =
let ids = List.map_filter test hyps in
let ids = List.uniquize ids in
subst_gen flags.rewrite_dependent_proof ids
- end
+ end }
(* Rewrite the first assumption for which a condition holds
and gives the direction of the rewrite *)
@@ -1826,10 +1839,11 @@ let rewrite_assumption_cond cond_eq_term cl =
with | Failure _ | UserError _ -> arec rest gl
end
in
- Proofview.Goal.nf_enter begin fun gl ->
+ Proofview.Goal.nf_enter { enter = begin fun gl ->
+ let gl = Proofview.Goal.lift gl Sigma.Unsafe.le in
let hyps = Proofview.Goal.hyps gl in
arec hyps gl
- end
+ end }
(* Generalize "subst x" to substitution of subterm appearing as an
equation in the context, but not clearing the hypothesis *)
diff --git a/tactics/evar_tactics.ml b/tactics/evar_tactics.ml
index 202aca0de..48b9006cd 100644
--- a/tactics/evar_tactics.ml
+++ b/tactics/evar_tactics.ml
@@ -14,6 +14,8 @@ open Tacexpr
open Refiner
open Evd
open Locus
+open Sigma.Notations
+open Proofview.Notations
(* The instantiate tactic *)
@@ -68,15 +70,18 @@ let instantiate_tac_by_name id c =
let let_evar name typ =
let src = (Loc.ghost,Evar_kinds.GoalEvar) in
- Proofview.Goal.enter begin fun gl ->
+ Proofview.Goal.s_enter { s_enter = begin fun gl ->
let sigma = Proofview.Goal.sigma gl in
let env = Proofview.Goal.env gl in
let id = match name with
| Names.Anonymous ->
let id = Namegen.id_of_name_using_hdchar env typ name in
Namegen.next_ident_away_in_goal id (Termops.ids_of_named_context (Environ.named_context env))
- | Names.Name id -> id in
- let sigma',evar = Evarutil.new_evar env sigma ~src ~naming:(Misctypes.IntroFresh id) typ in
- Tacticals.New.tclTHEN (Proofview.V82.tactic (Refiner.tclEVARS sigma'))
+ | Names.Name id -> id
+ in
+ let Sigma (evar, sigma, p) = Evarutil.new_evar env sigma ~src ~naming:(Misctypes.IntroFresh id) typ in
+ let tac =
(Tactics.letin_tac None (Names.Name id) evar None Locusops.nowhere)
- end
+ in
+ Sigma (tac, sigma, p)
+ end }
diff --git a/tactics/extratactics.ml4 b/tactics/extratactics.ml4
index 15613c7ec..930cfebf4 100644
--- a/tactics/extratactics.ml4
+++ b/tactics/extratactics.ml4
@@ -19,8 +19,10 @@ open Tactics
open Errors
open Util
open Evd
+open Termops
open Equality
open Misctypes
+open Sigma.Notations
open Proofview.Notations
DECLARE PLUGIN "extratactics"
@@ -29,34 +31,42 @@ DECLARE PLUGIN "extratactics"
(* replace, discriminate, injection, simplify_eq *)
(* cutrewrite, dependent rewrite *)
-let replace_in_clause_maybe_by (sigma1,c1) c2 cl tac =
- Tacticals.New.tclWITHHOLES false
- (replace_in_clause_maybe_by c1 c2 cl (Option.map Tacinterp.eval_tactic tac))
- sigma1
+let with_delayed_uconstr ist c tac =
+ let flags = {
+ Pretyping.use_typeclasses = false;
+ use_unif_heuristics = true;
+ use_hook = Some Pfedit.solve_by_implicit_tactic;
+ fail_evar = false;
+ expand_evars = true
+ } in
+ let c = Tacinterp.type_uconstr ~flags ist c in
+ Tacticals.New.tclDELAYEDWITHHOLES false c tac
-let replace_term dir_opt (sigma,c) cl =
- Tacticals.New.tclWITHHOLES false
- (replace_term dir_opt c cl)
- sigma
+let replace_in_clause_maybe_by ist c1 c2 cl tac =
+ with_delayed_uconstr ist c1
+ (fun c1 -> replace_in_clause_maybe_by c1 c2 cl (Option.map Tacinterp.eval_tactic tac))
+
+let replace_term ist dir_opt c cl =
+ with_delayed_uconstr ist c (fun c -> replace_term dir_opt c cl)
TACTIC EXTEND replace
- ["replace" open_constr(c1) "with" constr(c2) clause(cl) by_arg_tac(tac) ]
--> [ replace_in_clause_maybe_by c1 c2 cl tac ]
+ ["replace" uconstr(c1) "with" constr(c2) clause(cl) by_arg_tac(tac) ]
+-> [ replace_in_clause_maybe_by ist c1 c2 cl tac ]
END
TACTIC EXTEND replace_term_left
- [ "replace" "->" open_constr(c) clause(cl) ]
- -> [ replace_term (Some true) c cl ]
+ [ "replace" "->" uconstr(c) clause(cl) ]
+ -> [ replace_term ist (Some true) c cl ]
END
TACTIC EXTEND replace_term_right
- [ "replace" "<-" open_constr(c) clause(cl) ]
- -> [ replace_term (Some false) c cl ]
+ [ "replace" "<-" uconstr(c) clause(cl) ]
+ -> [ replace_term ist (Some false) c cl ]
END
TACTIC EXTEND replace_term
- [ "replace" open_constr(c) clause(cl) ]
- -> [ replace_term None c cl ]
+ [ "replace" uconstr(c) clause(cl) ]
+ -> [ replace_term ist None c cl ]
END
let induction_arg_of_quantified_hyp = function
@@ -68,8 +78,8 @@ let induction_arg_of_quantified_hyp = function
ElimOnIdent and not as "constr" *)
let elimOnConstrWithHoles tac with_evars c =
- Tacticals.New.tclWITHHOLES with_evars
- (tac with_evars (Some (None,ElimOnConstr c.it))) c.sigma
+ Tacticals.New.tclDELAYEDWITHHOLES with_evars c
+ (fun c -> tac with_evars (Some (None,ElimOnConstr c)))
TACTIC EXTEND simplify_eq_main
| [ "simplify_eq" constr_with_bindings(c) ] ->
@@ -114,7 +124,7 @@ END
open Proofview.Notations
let discrHyp id =
Proofview.tclEVARMAP >>= fun sigma ->
- discr_main {it = Term.mkVar id,NoBindings; sigma = sigma;}
+ discr_main { delayed = fun env sigma -> Sigma.here (Term.mkVar id, NoBindings) sigma }
let injection_main c =
elimOnConstrWithHoles (injClause None) false c
@@ -159,7 +169,7 @@ END
let injHyp id =
Proofview.tclEVARMAP >>= fun sigma ->
- injection_main { it = Term.mkVar id,NoBindings; sigma = sigma; }
+ injection_main { delayed = fun env sigma -> Sigma.here (Term.mkVar id, NoBindings) sigma }
TACTIC EXTEND dependent_rewrite
| [ "dependent" "rewrite" orient(b) constr(c) ] -> [ rewriteInConcl b c ]
@@ -199,7 +209,7 @@ END
let onSomeWithHoles tac = function
| None -> tac None
- | Some c -> Tacticals.New.tclWITHHOLES false (tac (Some c.it)) c.sigma
+ | Some c -> Tacticals.New.tclDELAYEDWITHHOLES false c (fun c -> tac (Some c))
TACTIC EXTEND contradiction
[ "contradiction" constr_with_bindings_opt(c) ] ->
@@ -241,22 +251,22 @@ END
(**********************************************************************)
(* Rewrite star *)
-let rewrite_star clause orient occs (sigma,c) (tac : glob_tactic_expr option) =
+let rewrite_star ist clause orient occs c (tac : glob_tactic_expr option) =
let tac' = Option.map (fun t -> Tacinterp.eval_tactic t, FirstSolved) tac in
- Tacticals.New.tclWITHHOLES false
- (general_rewrite_ebindings_clause clause orient occs ?tac:tac' true true (c,NoBindings) true) sigma
+ with_delayed_uconstr ist c
+ (fun c -> general_rewrite_ebindings_clause clause orient occs ?tac:tac' true true (c,NoBindings) true)
TACTIC EXTEND rewrite_star
-| [ "rewrite" "*" orient(o) open_constr(c) "in" hyp(id) "at" occurrences(occ) by_arg_tac(tac) ] ->
- [ rewrite_star (Some id) o (occurrences_of occ) c tac ]
-| [ "rewrite" "*" orient(o) open_constr(c) "at" occurrences(occ) "in" hyp(id) by_arg_tac(tac) ] ->
- [ rewrite_star (Some id) o (occurrences_of occ) c tac ]
-| [ "rewrite" "*" orient(o) open_constr(c) "in" hyp(id) by_arg_tac(tac) ] ->
- [ rewrite_star (Some id) o Locus.AllOccurrences c tac ]
-| [ "rewrite" "*" orient(o) open_constr(c) "at" occurrences(occ) by_arg_tac(tac) ] ->
- [ rewrite_star None o (occurrences_of occ) c tac ]
-| [ "rewrite" "*" orient(o) open_constr(c) by_arg_tac(tac) ] ->
- [ rewrite_star None o Locus.AllOccurrences c tac ]
+| [ "rewrite" "*" orient(o) uconstr(c) "in" hyp(id) "at" occurrences(occ) by_arg_tac(tac) ] ->
+ [ rewrite_star ist (Some id) o (occurrences_of occ) c tac ]
+| [ "rewrite" "*" orient(o) uconstr(c) "at" occurrences(occ) "in" hyp(id) by_arg_tac(tac) ] ->
+ [ rewrite_star ist (Some id) o (occurrences_of occ) c tac ]
+| [ "rewrite" "*" orient(o) uconstr(c) "in" hyp(id) by_arg_tac(tac) ] ->
+ [ rewrite_star ist (Some id) o Locus.AllOccurrences c tac ]
+| [ "rewrite" "*" orient(o) uconstr(c) "at" occurrences(occ) by_arg_tac(tac) ] ->
+ [ rewrite_star ist None o (occurrences_of occ) c tac ]
+| [ "rewrite" "*" orient(o) uconstr(c) by_arg_tac(tac) ] ->
+ [ rewrite_star ist None o Locus.AllOccurrences c tac ]
END
(**********************************************************************)
@@ -269,7 +279,7 @@ let add_rewrite_hint bases ort t lcsr =
let f ce =
let c, ctx = Constrintern.interp_constr env sigma ce in
let ctx =
- let ctx = Evd.evar_universe_context_set Univ.UContext.empty ctx in
+ let ctx = UState.context_set ctx in
if poly then ctx
else (Global.push_context_set false ctx; Univ.ContextSet.empty)
in
@@ -313,7 +323,7 @@ let project_hint pri l2r r =
| _ -> assert false in
let p =
if l2r then build_coq_iff_left_proj () else build_coq_iff_right_proj () in
- let c = Reductionops.whd_beta Evd.empty (mkApp (c,Termops.extended_rel_vect 0 sign)) in
+ let c = Reductionops.whd_beta Evd.empty (mkApp (c, Context.Rel.to_extended_vect 0 sign)) in
let c = it_mkLambda_or_LetIn
(mkApp (p,[|mkArrow a (lift 1 b);mkArrow b (lift 1 a);c|])) sign in
let id =
@@ -345,31 +355,27 @@ END
(**********************************************************************)
(* Refine *)
-let refine_tac simple {Glob_term.closure=closure;term=term} =
- Proofview.Goal.nf_enter begin fun gl ->
+let refine_tac ist simple c =
+ Proofview.Goal.nf_enter { enter = begin fun gl ->
let concl = Proofview.Goal.concl gl in
let env = Proofview.Goal.env gl in
let flags = Pretyping.all_no_fail_flags in
- let tycon = Pretyping.OfType concl in
- let lvar = { Pretyping.empty_lvar with
- Pretyping.ltac_constrs = closure.Glob_term.typed;
- Pretyping.ltac_uconstrs = closure.Glob_term.untyped;
- Pretyping.ltac_idents = closure.Glob_term.idents;
- } in
- let update evd = Pretyping.understand_ltac flags env evd lvar tycon term in
+ let expected_type = Pretyping.OfType concl in
+ let c = Tacinterp.type_uconstr ~flags ~expected_type ist c in
+ let update = { run = fun sigma -> c.delayed env sigma } in
let refine = Proofview.Refine.refine ~unsafe:false update in
if simple then refine
else refine <*>
Tactics.New.reduce_after_refine <*>
Proofview.shelve_unifiable
- end
+ end }
TACTIC EXTEND refine
-| [ "refine" uconstr(c) ] -> [ refine_tac false c ]
+| [ "refine" uconstr(c) ] -> [ refine_tac ist false c ]
END
TACTIC EXTEND simple_refine
-| [ "simple" "refine" uconstr(c) ] -> [ refine_tac true c ]
+| [ "simple" "refine" uconstr(c) ] -> [ refine_tac ist true c ]
END
(**********************************************************************)
@@ -616,13 +622,10 @@ let subst_hole_with_term occ tc t =
open Tacmach
-let out_arg = function
- | ArgVar _ -> anomaly (Pp.str "Unevaluated or_var variable")
- | ArgArg x -> x
-
let hResolve id c occ t =
- Proofview.Goal.nf_enter begin fun gl ->
+ Proofview.Goal.nf_s_enter { s_enter = begin fun gl ->
let sigma = Proofview.Goal.sigma gl in
+ let sigma = Sigma.to_evar_map sigma in
let env = Termops.clear_named_body id (Proofview.Goal.env gl) in
let concl = Proofview.Goal.concl gl in
let env_ids = Termops.ids_of_context env in
@@ -640,10 +643,11 @@ let hResolve id c occ t =
let t_constr,ctx = resolve_hole (subst_var_with_hole occ id t_raw) in
let sigma = Evd.merge_universe_context sigma ctx in
let t_constr_type = Retyping.get_type_of env sigma t_constr in
- Tacticals.New.tclTHEN
- (Proofview.Unsafe.tclEVARS sigma)
+ let tac =
(change_concl (mkLetIn (Anonymous,t_constr,t_constr_type,concl)))
- end
+ in
+ Sigma.Unsafe.of_pair (tac, sigma)
+ end }
let hResolve_auto id c t =
let rec resolve_auto n =
@@ -656,7 +660,7 @@ let hResolve_auto id c t =
resolve_auto 1
TACTIC EXTEND hresolve_core
-| [ "hresolve_core" "(" ident(id) ":=" constr(c) ")" "at" int_or_var(occ) "in" constr(t) ] -> [ hResolve id c (out_arg occ) t ]
+| [ "hresolve_core" "(" ident(id) ":=" constr(c) ")" "at" int_or_var(occ) "in" constr(t) ] -> [ hResolve id c occ t ]
| [ "hresolve_core" "(" ident(id) ":=" constr(c) ")" "in" constr(t) ] -> [ hResolve_auto id c t ]
END
@@ -665,8 +669,8 @@ END
*)
let hget_evar n =
- Proofview.Goal.nf_enter begin fun gl ->
- let sigma = Proofview.Goal.sigma gl in
+ Proofview.Goal.nf_enter { enter = begin fun gl ->
+ let sigma = Tacmach.New.project gl in
let concl = Proofview.Goal.concl gl in
let evl = evar_list concl in
if List.length evl < n then
@@ -675,10 +679,10 @@ let hget_evar n =
let ev = List.nth evl (n-1) in
let ev_type = existential_type sigma ev in
change_concl (mkLetIn (Anonymous,mkEvar ev,ev_type,concl))
- end
+ end }
TACTIC EXTEND hget_evar
-| [ "hget_evar" int_or_var(n) ] -> [ hget_evar (out_arg n) ]
+| [ "hget_evar" int_or_var(n) ] -> [ hget_evar n ]
END
(**********************************************************************)
@@ -694,12 +698,12 @@ END
exception Found of unit Proofview.tactic
let rewrite_except h =
- Proofview.Goal.nf_enter begin fun gl ->
+ Proofview.Goal.nf_enter { enter = begin fun gl ->
let hyps = Tacmach.New.pf_ids_of_hyps gl in
Tacticals.New.tclMAP (fun id -> if Id.equal id h then Proofview.tclUNIT () else
Tacticals.New.tclTRY (Equality.general_rewrite_in true Locus.AllOccurrences true true id (mkVar h) false))
hyps
- end
+ end }
let refl_equal =
@@ -713,27 +717,27 @@ let refl_equal =
should be replaced by a call to the tactic but I don't know how to
call it before it is defined. *)
let mkCaseEq a : unit Proofview.tactic =
- Proofview.Goal.nf_enter begin fun gl ->
+ Proofview.Goal.nf_enter { enter = begin fun gl ->
let type_of_a = Tacmach.New.of_old (fun g -> Tacmach.pf_unsafe_type_of g a) gl in
Tacticals.New.tclTHENLIST
- [Proofview.V82.tactic (Tactics.Simple.generalize [mkApp(delayed_force refl_equal, [| type_of_a; a|])]);
- Proofview.Goal.nf_enter begin fun gl ->
+ [Proofview.V82.tactic (Tactics.generalize [mkApp(delayed_force refl_equal, [| type_of_a; a|])]);
+ Proofview.Goal.nf_enter { enter = begin fun gl ->
let concl = Proofview.Goal.concl gl in
let env = Proofview.Goal.env gl in
change_concl
(snd (Tacred.pattern_occs [Locus.OnlyOccurrences [1], a] env Evd.empty concl))
- end;
+ end };
simplest_case a]
- end
+ end }
let case_eq_intros_rewrite x =
- Proofview.Goal.nf_enter begin fun gl ->
+ Proofview.Goal.nf_enter { enter = begin fun gl ->
let n = nb_prod (Proofview.Goal.concl gl) in
(* Pp.msgnl (Printer.pr_lconstr x); *)
Tacticals.New.tclTHENLIST [
mkCaseEq x;
- Proofview.Goal.nf_enter begin fun gl ->
+ Proofview.Goal.nf_enter { enter = begin fun gl ->
let concl = Proofview.Goal.concl gl in
let hyps = Tacmach.New.pf_ids_of_hyps gl in
let n' = nb_prod concl in
@@ -742,9 +746,9 @@ let case_eq_intros_rewrite x =
Tacticals.New.tclDO (n'-n-1) intro;
introduction h;
rewrite_except h]
- end
+ end }
]
- end
+ end }
let rec find_a_destructable_match t =
match kind_of_term t with
@@ -764,15 +768,15 @@ let destauto t =
with Found tac -> tac
let destauto_in id =
- Proofview.Goal.nf_enter begin fun gl ->
+ Proofview.Goal.nf_enter { enter = begin fun gl ->
let ctype = Tacmach.New.of_old (fun g -> Tacmach.pf_unsafe_type_of g (mkVar id)) gl in
(* Pp.msgnl (Printer.pr_lconstr (mkVar id)); *)
(* Pp.msgnl (Printer.pr_lconstr (ctype)); *)
destauto ctype
- end
+ end }
TACTIC EXTEND destauto
-| [ "destauto" ] -> [ Proofview.Goal.nf_enter (fun gl -> destauto (Proofview.Goal.concl gl)) ]
+| [ "destauto" ] -> [ Proofview.Goal.nf_enter { enter = begin fun gl -> destauto (Proofview.Goal.concl gl) end } ]
| [ "destauto" "in" hyp(id) ] -> [ destauto_in id ]
END
@@ -780,10 +784,11 @@ END
(* ********************************************************************* *)
let eq_constr x y =
- Proofview.Goal.enter (fun gl ->
- let evd = Proofview.Goal.sigma gl in
+ Proofview.Goal.enter { enter = begin fun gl ->
+ let evd = Tacmach.New.project gl in
if Evarutil.eq_constr_univs_test evd evd x y then Proofview.tclUNIT ()
- else Tacticals.New.tclFAIL 0 (str "Not equal"))
+ else Tacticals.New.tclFAIL 0 (str "Not equal")
+ end }
TACTIC EXTEND constr_eq
| [ "constr_eq" constr(x) constr(y) ] -> [ eq_constr x y ]
@@ -900,12 +905,12 @@ END
(* cycles [n] goals *)
TACTIC EXTEND cycle
-| [ "cycle" int_or_var(n) ] -> [ Proofview.cycle (out_arg n) ]
+| [ "cycle" int_or_var(n) ] -> [ Proofview.cycle n ]
END
(* swaps goals number [i] and [j] *)
TACTIC EXTEND swap
-| [ "swap" int_or_var(i) int_or_var(j) ] -> [ Proofview.swap (out_arg i) (out_arg j) ]
+| [ "swap" int_or_var(i) int_or_var(j) ] -> [ Proofview.swap i j ]
END
(* reverses the list of focused goals *)
@@ -994,14 +999,14 @@ TACTIC EXTEND guard
END
let decompose l c =
- Proofview.Goal.enter begin fun gl ->
+ Proofview.Goal.enter { enter = begin fun gl ->
let to_ind c =
if isInd c then Univ.out_punivs (destInd c)
else error "not an inductive type"
in
let l = List.map to_ind l in
Elim.h_decompose l c
- end
+ end }
TACTIC EXTEND decompose
| [ "decompose" "[" ne_constr_list(l) "]" constr(c) ] -> [ decompose l c ]
diff --git a/tactics/extratactics.mli b/tactics/extratactics.mli
index e0e9f3770..18334dafe 100644
--- a/tactics/extratactics.mli
+++ b/tactics/extratactics.mli
@@ -11,4 +11,4 @@ val injHyp : Names.Id.t -> unit Proofview.tactic
(* val refine_tac : Evd.open_constr -> unit Proofview.tactic *)
-val onSomeWithHoles : ('a option -> unit Proofview.tactic) -> 'a Evd.sigma option -> unit Proofview.tactic
+val onSomeWithHoles : ('a option -> unit Proofview.tactic) -> 'a Tacexpr.delayed_open option -> unit Proofview.tactic
diff --git a/tactics/ftactic.ml b/tactics/ftactic.ml
index 8e42dcba7..55463afd0 100644
--- a/tactics/ftactic.ml
+++ b/tactics/ftactic.ml
@@ -37,16 +37,32 @@ let bind (type a) (type b) (m : a t) (f : a -> b t) : b t = m >>= function
Proofview.tclDISPATCHL (List.map f l) >>= fun l ->
Proofview.tclUNIT (Depends (List.concat l))
+let goals = Proofview.Goal.goals >>= fun l -> Proofview.tclUNIT (Depends l)
+let set_sigma r =
+ let Sigma.Sigma (ans, sigma, _) = r in
+ Proofview.Unsafe.tclEVARS (Sigma.to_evar_map sigma) >>= fun () -> ans
+
let nf_enter f =
- bind (Proofview.Goal.goals >>= fun l -> Proofview.tclUNIT (Depends l))
+ bind goals
+ (fun gl ->
+ gl >>= fun gl ->
+ Proofview.Goal.normalize gl >>= fun nfgl ->
+ Proofview.V82.wrap_exceptions (fun () -> f.enter nfgl))
+
+let nf_s_enter f =
+ bind goals
(fun gl ->
gl >>= fun gl ->
Proofview.Goal.normalize gl >>= fun nfgl ->
- Proofview.V82.wrap_exceptions (fun () -> f nfgl))
+ Proofview.V82.wrap_exceptions (fun () -> set_sigma (f.s_enter nfgl)))
let enter f =
- bind (Proofview.Goal.goals >>= fun l -> Proofview.tclUNIT (Depends l))
- (fun gl -> gl >>= fun gl -> Proofview.V82.wrap_exceptions (fun () -> f gl))
+ bind goals
+ (fun gl -> gl >>= fun gl -> Proofview.V82.wrap_exceptions (fun () -> f.enter gl))
+
+let s_enter f =
+ bind goals
+ (fun gl -> gl >>= fun gl -> Proofview.V82.wrap_exceptions (fun () -> set_sigma (f.s_enter gl)))
let with_env t =
t >>= function
@@ -84,3 +100,9 @@ module Ftac = Monad.Make(Self)
module List = Ftac.List
let debug_prompt = Tactic_debug.debug_prompt
+
+module Notations =
+struct
+ let (>>=) = bind
+ let (<*>) = fun m n -> bind m (fun () -> n)
+end
diff --git a/tactics/ftactic.mli b/tactics/ftactic.mli
index 3f4da2a83..fd05a4469 100644
--- a/tactics/ftactic.mli
+++ b/tactics/ftactic.mli
@@ -6,6 +6,8 @@
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
+open Proofview.Notations
+
(** Potentially focussing tactics *)
type +'a focus
@@ -37,13 +39,20 @@ val run : 'a t -> ('a -> unit Proofview.tactic) -> unit Proofview.tactic
(** {5 Focussing} *)
-val nf_enter : ([ `NF ] Proofview.Goal.t -> 'a t) -> 'a t
+val nf_enter : ([ `NF ], 'a t) enter -> 'a t
(** Enter a goal. The resulting tactic is focussed. *)
-val enter : ([ `LZ ] Proofview.Goal.t -> 'a t) -> 'a t
+val enter : ([ `LZ ], 'a t) enter -> 'a t
(** Enter a goal, without evar normalization. The resulting tactic is
focussed. *)
+val s_enter : ([ `LZ ], 'a t) s_enter -> 'a t
+(** Enter a goal and put back an evarmap. The resulting tactic is focussed. *)
+
+val nf_s_enter : ([ `NF ], 'a t) s_enter -> 'a t
+(** Enter a goal, without evar normalization and put back an evarmap. The
+ resulting tactic is focussed. *)
+
val with_env : 'a t -> (Environ.env*'a) t
(** [with_env t] returns, in addition to the return type of [t], an
environment, which is the global environment if [t] does not focus on
@@ -65,3 +74,11 @@ module List : Monad.ListS with type 'a t := 'a t
val debug_prompt :
int -> Tacexpr.glob_tactic_expr -> (Tactic_debug.debug_info -> 'a t) -> 'a t
+
+(** {5 Notations} *)
+
+module Notations :
+sig
+ val (>>=) : 'a t -> ('a -> 'b t) -> 'b t
+ val (<*>) : unit t -> 'a t -> 'a t
+end
diff --git a/tactics/g_auto.ml4 b/tactics/g_auto.ml4
new file mode 100644
index 000000000..3a2cee9f7
--- /dev/null
+++ b/tactics/g_auto.ml4
@@ -0,0 +1,76 @@
+(************************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2015 *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(************************************************************************)
+
+(*i camlp4deps: "grammar/grammar.cma" i*)
+
+open Pp
+open Genarg
+open Tacexpr
+
+DECLARE PLUGIN "g_auto"
+
+(* Hint bases *)
+
+let pr_hintbases _prc _prlc _prt = Pptactic.pr_hintbases
+
+ARGUMENT EXTEND hintbases
+ TYPED AS preident_list_opt
+ PRINTED BY pr_hintbases
+| [ "with" "*" ] -> [ None ]
+| [ "with" ne_preident_list(l) ] -> [ Some l ]
+| [ ] -> [ Some [] ]
+END
+
+let eval_uconstrs ist cs =
+ let flags = {
+ Pretyping.use_typeclasses = false;
+ use_unif_heuristics = true;
+ use_hook = Some Pfedit.solve_by_implicit_tactic;
+ fail_evar = false;
+ expand_evars = true
+ } in
+ List.map (fun c -> Tacinterp.type_uconstr ~flags ist c) cs
+
+let pr_auto_using _ _ _ = Pptactic.pr_auto_using (fun _ -> mt ())
+
+ARGUMENT EXTEND auto_using
+ TYPED AS uconstr_list
+ PRINTED BY pr_auto_using
+| [ "using" ne_uconstr_list_sep(l, ",") ] -> [ l ]
+| [ ] -> [ [] ]
+END
+
+TACTIC EXTEND trivial
+| [ "trivial" auto_using(lems) hintbases(db) ] ->
+ [ Auto.h_trivial (eval_uconstrs ist lems) db ]
+END
+
+TACTIC EXTEND info_trivial
+| [ "info_trivial" auto_using(lems) hintbases(db) ] ->
+ [ Auto.h_trivial ~debug:Info (eval_uconstrs ist lems) db ]
+END
+
+TACTIC EXTEND debug_trivial
+| [ "debug" "trivial" auto_using(lems) hintbases(db) ] ->
+ [ Auto.h_trivial ~debug:Debug (eval_uconstrs ist lems) db ]
+END
+
+TACTIC EXTEND auto
+| [ "auto" int_or_var_opt(n) auto_using(lems) hintbases(db) ] ->
+ [ Auto.h_auto n (eval_uconstrs ist lems) db ]
+END
+
+TACTIC EXTEND info_auto
+| [ "info_auto" int_or_var_opt(n) auto_using(lems) hintbases(db) ] ->
+ [ Auto.h_auto ~debug:Info n (eval_uconstrs ist lems) db ]
+END
+
+TACTIC EXTEND debug_auto
+| [ "debug" "auto" int_or_var_opt(n) auto_using(lems) hintbases(db) ] ->
+ [ Auto.h_auto ~debug:Debug n (eval_uconstrs ist lems) db ]
+END
diff --git a/tactics/geninterp.ml b/tactics/geninterp.ml
index 0ad3abb53..008075800 100644
--- a/tactics/geninterp.ml
+++ b/tactics/geninterp.ml
@@ -12,11 +12,10 @@ open Genarg
module TacStore = Store.Make(struct end)
type interp_sign = {
- lfun : tlevel generic_argument Id.Map.t;
+ lfun : Val.t Id.Map.t;
extra : TacStore.t }
-type ('glb, 'top) interp_fun = interp_sign ->
- Goal.goal Evd.sigma -> 'glb -> Evd.evar_map * 'top
+type ('glb, 'top) interp_fun = interp_sign -> 'glb -> 'top Ftactic.t
module InterpObj =
struct
@@ -30,9 +29,7 @@ module Interp = Register(InterpObj)
let interp = Interp.obj
let register_interp0 = Interp.register0
-let generic_interp ist gl v =
- let unpacker wit v =
- let (sigma, ans) = interp wit ist gl (glb v) in
- (sigma, in_gen (topwit wit) ans)
- in
- unpack { unpacker; } v
+let generic_interp ist (GenArg (Glbwit wit, v)) =
+ let open Ftactic.Notations in
+ interp wit ist v >>= fun ans ->
+ Ftactic.return (Val.Dyn (val_tag (topwit wit), ans))
diff --git a/tactics/geninterp.mli b/tactics/geninterp.mli
index 7f25a022c..0992db7a2 100644
--- a/tactics/geninterp.mli
+++ b/tactics/geninterp.mli
@@ -14,15 +14,14 @@ open Genarg
module TacStore : Store.S
type interp_sign = {
- lfun : tlevel generic_argument Id.Map.t;
+ lfun : Val.t Id.Map.t;
extra : TacStore.t }
-type ('glb, 'top) interp_fun = interp_sign ->
- Goal.goal Evd.sigma -> 'glb -> Evd.evar_map * 'top
+type ('glb, 'top) interp_fun = interp_sign -> 'glb -> 'top Ftactic.t
val interp : ('raw, 'glb, 'top) genarg_type -> ('glb, 'top) interp_fun
-val generic_interp : (glob_generic_argument, typed_generic_argument) interp_fun
+val generic_interp : (glob_generic_argument, Val.t) interp_fun
val register_interp0 :
('raw, 'glb, 'top) genarg_type -> ('glb, 'top) interp_fun -> unit
diff --git a/tactics/hightactics.mllib b/tactics/hightactics.mllib
index ff2e1ff6a..30e97f62d 100644
--- a/tactics/hightactics.mllib
+++ b/tactics/hightactics.mllib
@@ -1,6 +1,7 @@
Extraargs
Coretactics
Extratactics
+G_auto
Eauto
Class_tactics
G_class
diff --git a/tactics/hints.ml b/tactics/hints.ml
index 42e5067c9..c99e591fe 100644
--- a/tactics/hints.ml
+++ b/tactics/hints.ml
@@ -33,6 +33,7 @@ open Pfedit
open Tacred
open Printer
open Vernacexpr
+open Sigma.Notations
(****************************************)
(* General functions *)
@@ -153,27 +154,6 @@ let fresh_key =
in
KerName.make mp dir (Label.of_id lbl)
-let eq_hints_path_atom p1 p2 = match p1, p2 with
-| PathHints gr1, PathHints gr2 -> List.equal eq_gr gr1 gr2
-| PathAny, PathAny -> true
-| (PathHints _ | PathAny), _ -> false
-
-let eq_auto_tactic t1 t2 = match t1, t2 with
-| Res_pf (c1, _), Res_pf (c2, _) -> Constr.equal c1 c2
-| ERes_pf (c1, _), ERes_pf (c2, _) -> Constr.equal c1 c2
-| Give_exact (c1, _), Give_exact (c2, _) -> Constr.equal c1 c2
-| Res_pf_THEN_trivial_fail (c1, _), Res_pf_THEN_trivial_fail (c2, _) -> Constr.equal c1 c2
-| Unfold_nth gr1, Unfold_nth gr2 -> eq_egr gr1 gr2
-| Extern tac1, Extern tac2 -> tac1 == tac2 (** May cause redundancy in addkv *)
-| (Res_pf _ | ERes_pf _ | Give_exact _ | Res_pf_THEN_trivial_fail _
- | Unfold_nth _ | Extern _), _ -> false
-
-let eq_hint_metadata t1 t2 =
- Int.equal t1.pri t2.pri &&
- Option.equal constr_pattern_eq t1.pat t2.pat &&
- eq_hints_path_atom t1.name t2.name &&
- eq_auto_tactic t1.code t2.code
-
let pri_order_int (id1, {pri=pri1}) (id2, {pri=pri2}) =
let d = pri1 - pri2 in
if Int.equal d 0 then id2 - id1
@@ -1184,6 +1164,12 @@ let add_hint_lemmas env sigma eapply lems hint_db =
Hint_db.add_list env sigma hintlist' hint_db
let make_local_hint_db env sigma ts eapply lems =
+ let map c =
+ let sigma = Sigma.Unsafe.of_evar_map sigma in
+ let Sigma (c, sigma, _) = c.delayed env sigma in
+ (Sigma.to_evar_map sigma, c)
+ in
+ let lems = List.map map lems in
let sign = Environ.named_context env in
let ts = match ts with
| None -> Hint_db.transparent_state (searchtable_map "core")
diff --git a/tactics/hints.mli b/tactics/hints.mli
index 08ea71bb1..3e08060f8 100644
--- a/tactics/hints.mli
+++ b/tactics/hints.mli
@@ -10,7 +10,6 @@ open Pp
open Util
open Names
open Term
-open Context
open Environ
open Globnames
open Decl_kinds
@@ -192,7 +191,7 @@ val make_resolves :
If the hyp cannot be used as a Hint, the empty list is returned. *)
val make_resolve_hyp :
- env -> evar_map -> named_declaration -> hint_entry list
+ env -> evar_map -> Context.Named.Declaration.t -> hint_entry list
(** [make_extern pri pattern tactic_expr] *)
@@ -214,7 +213,7 @@ val extern_intern_tac :
Useful to take the current goal hypotheses as hints;
Boolean tells if lemmas with evars are allowed *)
-val make_local_hint_db : env -> evar_map -> ?ts:transparent_state -> bool -> open_constr list -> hint_db
+val make_local_hint_db : env -> evar_map -> ?ts:transparent_state -> bool -> Tacexpr.delayed_open_constr list -> hint_db
val make_db_list : hint_db_name list -> hint_db list
diff --git a/tactics/hipattern.mli b/tactics/hipattern.mli
index 32938ce50..7cc41f1b9 100644
--- a/tactics/hipattern.mli
+++ b/tactics/hipattern.mli
@@ -119,11 +119,11 @@ val match_with_equation:
(** Match terms [eq A t u], [identity A t u] or [JMeq A t A u]
Returns associated lemmas and [A,t,u] or fails PatternMatchingFailure *)
-val find_eq_data_decompose : [ `NF ] Proofview.Goal.t -> constr ->
+val find_eq_data_decompose : ([ `NF ], 'r) Proofview.Goal.t -> constr ->
coq_eq_data * Univ.universe_instance * (types * constr * constr)
(** Idem but fails with an error message instead of PatternMatchingFailure *)
-val find_this_eq_data_decompose : [ `NF ] Proofview.Goal.t -> constr ->
+val find_this_eq_data_decompose : ([ `NF ], 'r) Proofview.Goal.t -> constr ->
coq_eq_data * Univ.universe_instance * (types * constr * constr)
(** A variant that returns more informative structure on the equality found *)
@@ -144,7 +144,7 @@ val is_matching_sigma : constr -> bool
val match_eqdec : constr -> bool * constr * constr * constr * constr
(** Match an equality up to conversion; returns [(eq,t1,t2)] in normal form *)
-val dest_nf_eq : [ `NF ] Proofview.Goal.t -> constr -> (constr * constr * constr)
+val dest_nf_eq : ([ `NF ], 'r) Proofview.Goal.t -> constr -> (constr * constr * constr)
(** Match a negation *)
val is_matching_not : constr -> bool
diff --git a/tactics/inv.ml b/tactics/inv.ml
index 22bacdfc2..8030fc32e 100644
--- a/tactics/inv.ml
+++ b/tactics/inv.ml
@@ -13,7 +13,6 @@ open Names
open Nameops
open Term
open Vars
-open Context
open Termops
open Namegen
open Environ
@@ -27,6 +26,7 @@ open Elim
open Equality
open Misctypes
open Tacexpr
+open Sigma.Notations
open Proofview.Notations
let clear hyps = Proofview.V82.tactic (clear hyps)
@@ -96,7 +96,7 @@ let make_inv_predicate env evd indf realargs id status concl =
(* We lift to make room for the equations *)
(hyps,lift nrealargs bodypred)
in
- let nhyps = rel_context_length hyps in
+ let nhyps = Context.Rel.length hyps in
let env' = push_rel_context hyps env in
(* Now the arity is pushed, and we need to construct the pairs
* ai,mkRel(n-i+1) *)
@@ -269,14 +269,14 @@ Nota: with Inversion_clear, only four useless hypotheses
let generalizeRewriteIntros as_mode tac depids id =
Proofview.tclENV >>= fun env ->
- Proofview.Goal.nf_enter begin fun gl ->
+ Proofview.Goal.nf_enter { enter = begin fun gl ->
let dids = dependent_hyps env id depids gl in
let reintros = if as_mode then intros_replacing else intros_possibly_replacing in
(tclTHENLIST
[bring_hyps dids; tac;
(* may actually fail to replace if dependent in a previous eq *)
reintros (ids_of_named_context dids)])
- end
+ end }
let error_too_many_names pats =
let loc = Loc.join_loc (fst (List.hd pats)) (fst (List.last pats)) in
@@ -284,10 +284,10 @@ let error_too_many_names pats =
tclZEROMSG ~loc (
str "Unexpected " ++
str (String.plural (List.length pats) "introduction pattern") ++
- str ": " ++ pr_enum (Miscprint.pr_intro_pattern (fun c -> Printer.pr_constr (snd (c env Evd.empty)))) pats ++
+ str ": " ++ pr_enum (Miscprint.pr_intro_pattern (fun c -> Printer.pr_constr (fst (run_delayed env Evd.empty c)))) pats ++
str ".")
-let rec get_names (allow_conj,issimple) (loc,pat as x) = match pat with
+let get_names (allow_conj,issimple) (loc, pat as x) = match pat with
| IntroNaming IntroAnonymous | IntroForthcoming _ ->
error "Anonymous pattern not allowed for inversion equations."
| IntroNaming (IntroFresh _) ->
@@ -296,17 +296,17 @@ let rec get_names (allow_conj,issimple) (loc,pat as x) = match pat with
error "Discarding pattern not allowed for inversion equations."
| IntroAction (IntroRewrite _) ->
error "Rewriting pattern not allowed for inversion equations."
- | IntroAction (IntroOrAndPattern [[]]) when allow_conj -> (None, [])
- | IntroAction (IntroOrAndPattern [(_,IntroNaming (IntroIdentifier id)) :: _ as l])
+ | IntroAction (IntroOrAndPattern (IntroAndPattern [])) when allow_conj -> (None, [])
+ | IntroAction (IntroOrAndPattern (IntroAndPattern ((_,IntroNaming (IntroIdentifier id)) :: _ as l)))
when allow_conj -> (Some id,l)
- | IntroAction (IntroOrAndPattern [_]) ->
+ | IntroAction (IntroOrAndPattern (IntroAndPattern _)) ->
if issimple then
error"Conjunctive patterns not allowed for simple inversion equations."
else
error"Nested conjunctive patterns not allowed for inversion equations."
| IntroAction (IntroInjection l) ->
error "Injection patterns not allowed for inversion equations."
- | IntroAction (IntroOrAndPattern l) ->
+ | IntroAction (IntroOrAndPattern (IntroOrPattern _)) ->
error "Disjunctive patterns not allowed for inversion equations."
| IntroAction (IntroApplyOn (c,pat)) ->
error "Apply patterns not allowed for inversion equations."
@@ -338,7 +338,7 @@ let projectAndApply as_mode thin avoid id eqname names depids =
(if thin then clear [id] else (remember_first_eq id eqname; tclIDTAC))
in
let substHypIfVariable tac id =
- Proofview.Goal.nf_enter begin fun gl ->
+ Proofview.Goal.nf_enter { enter = begin fun gl ->
(** We only look at the type of hypothesis "id" *)
let hyp = pf_nf_evar gl (pf_get_hyp_typ id (Proofview.Goal.assume gl)) in
let (t,t1,t2) = Hipattern.dest_nf_eq gl hyp in
@@ -346,7 +346,7 @@ let projectAndApply as_mode thin avoid id eqname names depids =
| Var id1, _ -> generalizeRewriteIntros as_mode (subst_hyp true id) depids id1
| _, Var id2 -> generalizeRewriteIntros as_mode (subst_hyp false id) depids id2
| _ -> tac id
- end
+ end }
in
let deq_trailer id clear_flag _ neqns =
assert (clear_flag == None);
@@ -373,7 +373,7 @@ let projectAndApply as_mode thin avoid id eqname names depids =
id
let nLastDecls i tac =
- Proofview.Goal.nf_enter (fun gl -> tac (nLastDecls gl i))
+ Proofview.Goal.nf_enter { enter = begin fun gl -> tac (nLastDecls gl i) end }
(* Introduction of the equations on arguments
othin: discriminates Simple Inversion, Inversion and Inversion_clear
@@ -381,7 +381,7 @@ let nLastDecls i tac =
Some thin: the equations are rewritten, and cleared if thin is true *)
let rewrite_equations as_mode othin neqns names ba =
- Proofview.Goal.nf_enter begin fun gl ->
+ Proofview.Goal.nf_enter { enter = begin fun gl ->
let (depids,nodepids) = split_dep_and_nodep ba.Tacticals.assums gl in
let first_eq = ref MoveLast in
let avoid = if as_mode then List.map pi1 nodepids else [] in
@@ -414,7 +414,7 @@ let rewrite_equations as_mode othin neqns names ba =
[tclDO neqns intro;
bring_hyps nodepids;
clear (ids_of_named_context nodepids)])
- end
+ end }
let interp_inversion_kind = function
| SimpleInversion -> None
@@ -431,8 +431,9 @@ let rewrite_equations_tac as_mode othin id neqns names ba =
tac
let raw_inversion inv_kind id status names =
- Proofview.Goal.nf_enter begin fun gl ->
+ Proofview.Goal.nf_s_enter { s_enter = begin fun gl ->
let sigma = Proofview.Goal.sigma gl in
+ let sigma = Sigma.to_evar_map sigma in
let env = Proofview.Goal.env gl in
let concl = Proofview.Goal.concl gl in
let c = mkVar id in
@@ -457,11 +458,11 @@ let raw_inversion inv_kind id status names =
in
let refined id =
let prf = mkApp (mkVar id, args) in
- Proofview.Refine.refine (fun h -> h, prf)
+ Proofview.Refine.refine { run = fun h -> Sigma (prf, h, Sigma.refl) }
in
let neqns = List.length realargs in
let as_mode = names != None in
- tclTHEN (Proofview.Unsafe.tclEVARS sigma)
+ let tac =
(tclTHENS
(assert_before Anonymous cut_concl)
[case_tac names
@@ -469,7 +470,9 @@ let raw_inversion inv_kind id status names =
(rewrite_equations_tac as_mode inv_kind id neqns))
(Some elim_predicate) ind (c, t);
onLastHypId (fun id -> tclTHEN (refined id) reflexivity)])
- end
+ in
+ Sigma.Unsafe.of_pair (tac, sigma)
+ end }
(* Error messages of the inversion tactics *)
let wrap_inv_error id = function (e, info) -> match e with
@@ -511,12 +514,12 @@ let dinv_clear_tac id = dinv FullInversionClear None None (NamedHyp id)
* back to their places in the hyp-list. *)
let invIn k names ids id =
- Proofview.Goal.nf_enter begin fun gl ->
+ Proofview.Goal.nf_enter { enter = begin fun gl ->
let hyps = List.map (fun id -> pf_get_hyp id gl) ids in
let concl = Proofview.Goal.concl gl in
let nb_prod_init = nb_prod concl in
let intros_replace_ids =
- Proofview.Goal.enter begin fun gl ->
+ Proofview.Goal.enter { enter = begin fun gl ->
let concl = pf_nf_concl gl in
let nb_of_new_hyp =
nb_prod concl - (List.length hyps + nb_prod_init)
@@ -525,7 +528,7 @@ let invIn k names ids id =
intros_replacing ids
else
tclTHEN (tclDO nb_of_new_hyp intro) (intros_replacing ids)
- end
+ end }
in
Proofview.tclORELSE
(tclTHENLIST
@@ -533,7 +536,7 @@ let invIn k names ids id =
inversion k NoDep names id;
intros_replace_ids])
(wrap_inv_error id)
- end
+ end }
let invIn_gen k names idl = try_intros_until (invIn k names idl)
diff --git a/tactics/leminv.ml b/tactics/leminv.ml
index 894d44744..cdf38ae46 100644
--- a/tactics/leminv.ml
+++ b/tactics/leminv.ml
@@ -14,7 +14,6 @@ open Term
open Vars
open Termops
open Namegen
-open Context
open Evd
open Printer
open Reductionops
@@ -27,6 +26,7 @@ open Declare
open Tacticals.New
open Tactics
open Decl_kinds
+open Proofview.Notations
let no_inductive_inconstr env sigma constr =
(str "Cannot recognize an inductive predicate in " ++
@@ -156,7 +156,7 @@ let compute_first_inversion_scheme env sigma ind sort dep_option =
fold_named_context
(fun env (id,_,_ as d) (revargs,hyps) ->
if Id.List.mem id ivars then
- ((mkVar id)::revargs,add_named_decl d hyps)
+ ((mkVar id)::revargs, Context.Named.add d hyps)
else
(revargs,hyps))
env ~init:([],[])
@@ -205,8 +205,8 @@ let inversion_scheme env sigma t sort dep_option inv_op =
fold_named_context
(fun env (id,_,_ as d) sign ->
if mem_named_context id global_named_context then sign
- else add_named_decl d sign)
- invEnv ~init:empty_named_context
+ else Context.Named.add d sign)
+ invEnv ~init:Context.Named.empty
end in
let avoid = ref [] in
let { sigma=sigma } = Proof.V82.subgoals pf in
@@ -217,7 +217,7 @@ let inversion_scheme env sigma t sort dep_option inv_op =
let h = next_ident_away (Id.of_string "H") !avoid in
let ty,inst = Evarutil.generalize_evar_over_rels sigma (e,args) in
avoid := h::!avoid;
- ownSign := add_named_decl (h,None,ty) !ownSign;
+ ownSign := Context.Named.add (h,None,ty) !ownSign;
applist (mkVar h, inst)
| _ -> map_constr fill_holes c
in
@@ -269,7 +269,7 @@ let lemInv id c gls =
let lemInv_gen id c = try_intros_until (fun id -> Proofview.V82.tactic (lemInv id c)) id
let lemInvIn id c ids =
- Proofview.Goal.nf_enter begin fun gl ->
+ Proofview.Goal.nf_enter { enter = begin fun gl ->
let hyps = List.map (fun id -> pf_get_hyp id gl) ids in
let intros_replace_ids =
let concl = Proofview.Goal.concl gl in
@@ -281,7 +281,7 @@ let lemInvIn id c ids =
in
((tclTHEN (tclTHEN (bring_hyps hyps) (Proofview.V82.tactic (lemInv id c)))
(intros_replace_ids)))
- end
+ end }
let lemInvIn_gen id c l = try_intros_until (fun id -> lemInvIn id c l) id
diff --git a/tactics/rewrite.ml b/tactics/rewrite.ml
index 74bb6d597..d14e7deff 100644
--- a/tactics/rewrite.ml
+++ b/tactics/rewrite.ml
@@ -34,6 +34,8 @@ open Elimschemes
open Environ
open Termops
open Libnames
+open Sigma.Notations
+open Proofview.Notations
(** Typeclass-based generalized rewriting. *)
@@ -84,7 +86,9 @@ let cstrevars evars = snd evars
let new_cstr_evar (evd,cstrs) env t =
let s = Typeclasses.set_resolvable Evd.Store.empty false in
- let evd', t = Evarutil.new_evar ~store:s env evd t in
+ let evd = Sigma.Unsafe.of_evar_map evd in
+ let Sigma (t, evd', _) = Evarutil.new_evar ~store:s env evd t in
+ let evd' = Sigma.to_evar_map evd' in
let ev, _ = destEvar t in
(evd', Evar.Set.add ev cstrs), t
@@ -1498,7 +1502,7 @@ let rec insert_dependent env decl accu hyps = match hyps with
insert_dependent env decl (ndecl :: accu) rem
let assert_replacing id newt tac =
- let prf = Proofview.Goal.nf_enter begin fun gl ->
+ let prf = Proofview.Goal.nf_enter { enter = begin fun gl ->
let concl = Proofview.Goal.concl gl in
let env = Proofview.Goal.env gl in
let ctx = Environ.named_context env in
@@ -1508,14 +1512,14 @@ let assert_replacing id newt tac =
| (id, b, _) :: rem -> insert_dependent env (id, None, newt) [] after @ rem
in
let env' = Environ.reset_with_named_context (val_of_named_context nc) env in
- Proofview.Refine.refine ~unsafe:false begin fun sigma ->
- let sigma, ev = Evarutil.new_evar env' sigma concl in
- let sigma, ev' = Evarutil.new_evar env sigma newt in
+ Proofview.Refine.refine ~unsafe:false { run = begin fun sigma ->
+ let Sigma (ev, sigma, p) = Evarutil.new_evar env' sigma concl in
+ let Sigma (ev', sigma, q) = Evarutil.new_evar env sigma newt in
let map (n, _, _) = if Id.equal n id then ev' else mkVar n in
let (e, _) = destEvar ev in
- sigma, mkEvar (e, Array.map_of_list map nc)
- end
- end in
+ Sigma (mkEvar (e, Array.map_of_list map nc), sigma, p +> q)
+ end }
+ end } in
Proofview.tclTHEN prf (Proofview.tclFOCUS 2 2 tac)
let newfail n s =
@@ -1534,7 +1538,7 @@ let cl_rewrite_clause_newtac ?abs ?origsigma ~progress strat clause =
let gls = List.rev (Evd.fold_undefined fold undef []) in
match clause, prf with
| Some id, Some p ->
- let tac = Proofview.Refine.refine ~unsafe:false (fun h -> (h, p)) <*> Proofview.Unsafe.tclNEWGOALS gls in
+ let tac = Proofview.Refine.refine ~unsafe:false { run = fun h -> Sigma (p, h, Sigma.refl) } <*> Proofview.Unsafe.tclNEWGOALS gls in
Proofview.Unsafe.tclEVARS undef <*>
assert_replacing id newt tac
| Some id, None ->
@@ -1542,14 +1546,14 @@ let cl_rewrite_clause_newtac ?abs ?origsigma ~progress strat clause =
convert_hyp_no_check (id, None, newt)
| None, Some p ->
Proofview.Unsafe.tclEVARS undef <*>
- Proofview.Goal.enter begin fun gl ->
+ Proofview.Goal.enter { enter = begin fun gl ->
let env = Proofview.Goal.env gl in
- let make sigma =
- let (sigma, ev) = Evarutil.new_evar env sigma newt in
- sigma, mkApp (p, [| ev |])
- in
+ let make = { run = begin fun sigma ->
+ let Sigma (ev, sigma, q) = Evarutil.new_evar env sigma newt in
+ Sigma (mkApp (p, [| ev |]), sigma, q)
+ end } in
Proofview.Refine.refine ~unsafe:false make <*> Proofview.Unsafe.tclNEWGOALS gls
- end
+ end }
| None, None ->
Proofview.Unsafe.tclEVARS undef <*>
convert_concl_no_check newt DEFAULTcast
@@ -1560,10 +1564,10 @@ let cl_rewrite_clause_newtac ?abs ?origsigma ~progress strat clause =
| None -> Proofview.tclUNIT ()
| Some id -> Proofview.V82.tactic (Tactics.reduct_in_hyp beta_red (id, InHyp))
in
- Proofview.Goal.nf_enter begin fun gl ->
+ Proofview.Goal.nf_enter { enter = begin fun gl ->
let concl = Proofview.Goal.concl gl in
let env = Proofview.Goal.env gl in
- let sigma = Proofview.Goal.sigma gl in
+ let sigma = Tacmach.New.project gl in
let ty = match clause with
| None -> concl
| Some id -> Environ.named_type id env
@@ -1588,7 +1592,7 @@ let cl_rewrite_clause_newtac ?abs ?origsigma ~progress strat clause =
with
| PretypeError (env, evd, (UnsatisfiableConstraints _ as e)) ->
raise (RewriteFailure (Himsg.explain_pretype_error env evd e))
- end
+ end }
let tactic_init_setoid () =
try init_setoid (); tclIDTAC
@@ -1711,7 +1715,7 @@ let declare_instance a aeq n s = declare_an_instance n s [a;aeq]
let anew_instance global binders instance fields =
new_instance (Flags.is_universe_polymorphism ())
- binders instance (Some (true, CRecord (Loc.ghost,None,fields)))
+ binders instance (Some (true, CRecord (Loc.ghost,fields)))
~global ~generalize:false None
let declare_instance_refl global binders a aeq n lemma =
@@ -1926,7 +1930,7 @@ let add_morphism glob binders m s n =
in
let tac = Tacinterp.interp (make_tactic "add_morphism_tactic") in
ignore(new_instance ~global:glob poly binders instance
- (Some (true, CRecord (Loc.ghost,None,[])))
+ (Some (true, CRecord (Loc.ghost,[])))
~generalize:false ~tac ~hook:(declare_projection n instance_id) None)
(** Bind to "rewrite" too *)
@@ -2040,9 +2044,9 @@ let not_declared env ty rel =
str ty ++ str" relation. Maybe you need to require the Setoid library")
let setoid_proof ty fn fallback =
- Proofview.Goal.nf_enter begin fun gl ->
+ Proofview.Goal.nf_enter { enter = begin fun gl ->
let env = Proofview.Goal.env gl in
- let sigma = Proofview.Goal.sigma gl in
+ let sigma = Tacmach.New.project gl in
let concl = Proofview.Goal.concl gl in
Proofview.tclORELSE
begin
@@ -2069,7 +2073,7 @@ let setoid_proof ty fn fallback =
| e' -> Proofview.tclZERO ~info e'
end
end
- end
+ end }
let tac_open ((evm,_), c) tac =
Proofview.V82.tactic
diff --git a/tactics/rewrite.mli b/tactics/rewrite.mli
index b4d47d62d..01709f29f 100644
--- a/tactics/rewrite.mli
+++ b/tactics/rewrite.mli
@@ -71,7 +71,7 @@ val cl_rewrite_clause :
bool -> Locus.occurrences -> Id.t option -> tactic
val is_applied_rewrite_relation :
- env -> evar_map -> Context.rel_context -> constr -> types option
+ env -> evar_map -> Context.Rel.t -> constr -> types option
val declare_relation :
?binders:local_binder list -> constr_expr -> constr_expr -> Id.t ->
diff --git a/tactics/taccoerce.ml b/tactics/taccoerce.ml
index 25f5c8e9f..0cd3e0944 100644
--- a/tactics/taccoerce.ml
+++ b/tactics/taccoerce.ml
@@ -24,15 +24,27 @@ let (wit_constr_context : (Empty.t, Empty.t, constr) Genarg.genarg_type) =
let (wit_constr_under_binders : (Empty.t, Empty.t, constr_under_binders) Genarg.genarg_type) =
Genarg.create_arg None "constr_under_binders"
+let has_type : type a. Val.t -> a typed_abstract_argument_type -> bool = fun v wit ->
+ let Val.Dyn (t, _) = v in
+ match Val.eq t (val_tag wit) with
+ | None -> false
+ | Some Refl -> true
+
+let prj : type a. a Val.tag -> Val.t -> a option = fun t v ->
+ let Val.Dyn (t', x) = v in
+ match Val.eq t t' with
+ | None -> None
+ | Some Refl -> Some x
+
+let in_gen wit v = Val.Dyn (val_tag wit, v)
+let out_gen wit v = match prj (val_tag wit) v with None -> assert false | Some x -> x
+
module Value =
struct
-type t = tlevel generic_argument
+type t = Val.t
-let rec normalize v =
- if has_type v (topwit wit_genarg) then
- normalize (out_gen (topwit wit_genarg) v)
- else v
+let normalize v = v
let of_constr c = in_gen (topwit wit_constr) c
@@ -64,9 +76,21 @@ let to_int v =
let to_list v =
let v = normalize v in
- let list_unpacker wit l = List.map (fun v -> in_gen (topwit wit) v) (top l) in
- try Some (list_unpack { list_unpacker } v)
- with Failure _ -> None
+ let Val.Dyn (tag, v) = v in
+ match tag with
+ | Val.List t -> Some (List.map (fun x -> Val.Dyn (t, x)) v)
+ | _ -> None
+
+let of_list t v = Val.Dyn (Val.List t, v)
+
+let to_option v =
+ let v = normalize v in
+ let Val.Dyn (tag, v) = v in
+ match tag with
+ | Val.Opt t -> Some (Option.map (fun x -> Val.Dyn (t, x)) v)
+ | _ -> None
+
+let of_option t v = Val.Dyn (Val.Opt t, v)
end
diff --git a/tactics/taccoerce.mli b/tactics/taccoerce.mli
index d26a477ee..87137fd2e 100644
--- a/tactics/taccoerce.mli
+++ b/tactics/taccoerce.mli
@@ -29,8 +29,7 @@ exception CannotCoerceTo of string
module Value :
sig
- type t = tlevel generic_argument
- (** Tactics manipulate [tlevel generic_argument]. *)
+ type t = Val.t
val normalize : t -> t
(** Eliminated the leading dynamic type casts. *)
@@ -42,6 +41,9 @@ sig
val of_int : int -> t
val to_int : t -> int option
val to_list : t -> t list option
+ val of_list : 'a Val.tag -> 'a list -> t
+ val to_option : t -> t option option
+ val of_option : 'a Val.tag -> 'a option -> t
end
(** {5 Coercion functions} *)
@@ -55,9 +57,6 @@ val coerce_to_intro_pattern : Environ.env -> Value.t -> Tacexpr.delayed_open_con
val coerce_to_intro_pattern_naming :
Environ.env -> Value.t -> intro_pattern_naming_expr
-val coerce_to_intro_pattern_naming :
- Environ.env -> Value.t -> intro_pattern_naming_expr
-
val coerce_to_hint_base : Value.t -> string
val coerce_to_int : Value.t -> int
diff --git a/tactics/tacenv.ml b/tactics/tacenv.ml
index dc89a71ef..d2d3f3117 100644
--- a/tactics/tacenv.ml
+++ b/tactics/tacenv.ml
@@ -15,9 +15,10 @@ open Tacexpr
(** Tactic notations (TacAlias) *)
type alias = KerName.t
+type alias_tactic = Id.t list * glob_tactic_expr
let alias_map = Summary.ref ~name:"tactic-alias"
- (KNmap.empty : glob_tactic_expr KNmap.t)
+ (KNmap.empty : alias_tactic KNmap.t)
let register_alias key tac =
alias_map := KNmap.add key tac !alias_map
@@ -31,7 +32,7 @@ let check_alias key = KNmap.mem key !alias_map
(** ML tactic extensions (TacML) *)
type ml_tactic =
- typed_generic_argument list -> Geninterp.interp_sign -> unit Proofview.tactic
+ Val.t list -> Geninterp.interp_sign -> unit Proofview.tactic
module MLName =
struct
@@ -49,7 +50,7 @@ let pr_tacname t =
let tac_tab = ref MLTacMap.empty
-let register_ml_tactic ?(overwrite = false) s (t : ml_tactic) =
+let register_ml_tactic ?(overwrite = false) s (t : ml_tactic array) =
let () =
if MLTacMap.mem s !tac_tab then
if overwrite then
@@ -60,9 +61,11 @@ let register_ml_tactic ?(overwrite = false) s (t : ml_tactic) =
in
tac_tab := MLTacMap.add s t !tac_tab
-let interp_ml_tactic s =
+let interp_ml_tactic { mltac_name = s; mltac_index = i } =
try
- MLTacMap.find s !tac_tab
+ let tacs = MLTacMap.find s !tac_tab in
+ let () = if Array.length tacs <= i then raise Not_found in
+ tacs.(i)
with Not_found ->
Errors.errorlabstrm ""
(str "The tactic " ++ pr_tacname s ++ str " is not installed.")
diff --git a/tactics/tacenv.mli b/tactics/tacenv.mli
index 87cdce652..88b54993b 100644
--- a/tactics/tacenv.mli
+++ b/tactics/tacenv.mli
@@ -17,10 +17,13 @@ open Tacexpr
type alias = KerName.t
(** Type of tactic alias, used in the [TacAlias] node. *)
-val register_alias : alias -> glob_tactic_expr -> unit
+type alias_tactic = Id.t list * glob_tactic_expr
+(** Contents of a tactic notation *)
+
+val register_alias : alias -> alias_tactic -> unit
(** Register a tactic alias. *)
-val interp_alias : alias -> glob_tactic_expr
+val interp_alias : alias -> alias_tactic
(** Recover the the body of an alias. Raises an anomaly if it does not exist. *)
val check_alias : alias -> bool
@@ -61,11 +64,11 @@ val ltac_entries : unit -> ltac_entry KNmap.t
(** {5 ML tactic extensions} *)
type ml_tactic =
- typed_generic_argument list -> Geninterp.interp_sign -> unit Proofview.tactic
+ Val.t list -> Geninterp.interp_sign -> unit Proofview.tactic
(** Type of external tactics, used by [TacML]. *)
-val register_ml_tactic : ?overwrite:bool -> ml_tactic_name -> ml_tactic -> unit
+val register_ml_tactic : ?overwrite:bool -> ml_tactic_name -> ml_tactic array -> unit
(** Register an external tactic. *)
-val interp_ml_tactic : ml_tactic_name -> ml_tactic
+val interp_ml_tactic : ml_tactic_entry -> ml_tactic
(** Get the named tactic. Raises a user error if it does not exist. *)
diff --git a/tactics/tacintern.ml b/tactics/tacintern.ml
index 11f2c5943..4ef1beb03 100644
--- a/tactics/tacintern.ml
+++ b/tactics/tacintern.ml
@@ -97,7 +97,6 @@ let intern_or_var f ist = function
| ArgArg x -> ArgArg (f x)
let intern_int_or_var = intern_or_var (fun (n : int) -> n)
-let intern_id_or_var = intern_or_var (fun (id : Id.t) -> id)
let intern_string_or_var = intern_or_var (fun (s : string) -> s)
let intern_global_reference ist = function
@@ -259,8 +258,11 @@ and intern_intro_pattern_action lf ist = function
| IntroApplyOn (c,pat) ->
IntroApplyOn (intern_constr ist c, intern_intro_pattern lf ist pat)
-and intern_or_and_intro_pattern lf ist =
- List.map (List.map (intern_intro_pattern lf ist))
+and intern_or_and_intro_pattern lf ist = function
+ | IntroAndPattern l ->
+ IntroAndPattern (List.map (intern_intro_pattern lf ist) l)
+ | IntroOrPattern ll ->
+ IntroOrPattern (List.map (List.map (intern_intro_pattern lf ist)) ll)
let intern_or_and_intro_pattern_loc lf ist = function
| ArgVar (_,id) as x ->
@@ -339,7 +341,7 @@ let intern_typed_pattern ist p =
(* type it, so we remember the pattern as a glob_constr only *)
(intern_constr_gen true false ist p,dummy_pat)
-let rec intern_typed_pattern_or_ref_with_occurrences ist (l,p) =
+let intern_typed_pattern_or_ref_with_occurrences ist (l,p) =
let interp_ref r =
try Inl (intern_evaluable ist r)
with e when Logic.catchable_exception e ->
@@ -517,12 +519,6 @@ let rec intern_atomic lf ist x =
(clause_app (intern_hyp_location ist) cls),b,
(Option.map (intern_intro_pattern_naming_loc lf ist) eqpat))
- (* Automation tactics *)
- | TacTrivial (d,lems,l) -> TacTrivial (d,List.map (intern_constr ist) lems,l)
- | TacAuto (d,n,lems,l) ->
- TacAuto (d,Option.map (intern_int_or_var ist) n,
- List.map (intern_constr ist) lems,l)
-
(* Derived basic tactics *)
| TacInductionDestruct (ev,isrec,(l,el)) ->
TacInductionDestruct (ev,isrec,(List.map (fun (c,(ipato,ipats),cls) ->
@@ -663,16 +659,16 @@ and intern_tactic_seq onlytac ist = function
(* For extensions *)
| TacAlias (loc,s,l) ->
- let l = List.map (fun (id,a) -> (id,intern_genarg ist a)) l in
+ let l = List.map (intern_tacarg !strict_check false ist) l in
ist.ltacvars, TacAlias (loc,s,l)
| TacML (loc,opn,l) ->
let _ignore = Tacenv.interp_ml_tactic opn in
- ist.ltacvars, TacML (adjust_loc loc,opn,List.map (intern_genarg ist) l)
+ ist.ltacvars, TacML (adjust_loc loc,opn,List.map (intern_tacarg !strict_check false ist) l)
and intern_tactic_as_arg loc onlytac ist a =
match intern_tacarg !strict_check onlytac ist a with
| TacCall _ | Reference _
- | TacDynamic _ | TacGeneric _ as a -> TacArg (loc,a)
+ | TacGeneric _ as a -> TacArg (loc,a)
| Tacexp a -> a
| ConstrMayEval _ | UConstr _ | TacFreshId _ | TacPretype _ | TacNumgoals as a ->
if onlytac then error_tactic_expected loc else TacArg (loc,a)
@@ -707,15 +703,8 @@ and intern_tacarg strict onlytac ist = function
| TacNumgoals -> TacNumgoals
| Tacexp t -> Tacexp (intern_tactic onlytac ist t)
| TacGeneric arg ->
- let (_, arg) = Genintern.generic_intern ist arg in
+ let arg = intern_genarg ist arg in
TacGeneric arg
- | TacDynamic(loc,t) as x ->
- if Dyn.has_tag t "tactic" || Dyn.has_tag t "value" then x
- else if Dyn.has_tag t "constr" then
- if onlytac then error_tactic_expected loc else x
- else
- let tag = Dyn.tag t in
- anomaly ~loc (str "Unknown dynamic: <" ++ str tag ++ str ">")
(* Reads the rules of a Match Context or a Match *)
and intern_match_rule onlytac ist = function
@@ -732,57 +721,29 @@ and intern_match_rule onlytac ist = function
Pat (hyps,pat,intern_tactic onlytac ist' tc) :: (intern_match_rule onlytac ist tl)
| [] -> []
-and intern_genarg ist x =
- match genarg_tag x with
- | IntOrVarArgType -> map_raw wit_int_or_var intern_int_or_var ist x
- | IdentArgType ->
- let lf = ref Id.Set.empty in
- map_raw wit_ident (intern_ident lf) ist x
- | VarArgType ->
- map_raw wit_var intern_hyp ist x
- | GenArgType ->
- map_raw wit_genarg intern_genarg ist x
- | ConstrArgType ->
- map_raw wit_constr intern_constr ist x
- | ConstrMayEvalArgType ->
- map_raw wit_constr_may_eval intern_constr_may_eval ist x
- | QuantHypArgType ->
- map_raw wit_quant_hyp intern_quantified_hypothesis ist x
- | RedExprArgType ->
- map_raw wit_red_expr intern_red_expr ist x
- | OpenConstrArgType ->
- map_raw wit_open_constr (fun ist -> on_snd (intern_constr ist)) ist x
- | ConstrWithBindingsArgType ->
- map_raw wit_constr_with_bindings intern_constr_with_bindings ist x
- | BindingsArgType ->
- map_raw wit_bindings intern_bindings ist x
- | ListArgType _ ->
- let list_unpacker wit l =
- let map x =
- let ans = intern_genarg ist (in_gen (rawwit wit) x) in
- out_gen (glbwit wit) ans
- in
- in_gen (glbwit (wit_list wit)) (List.map map (raw l))
+and intern_genarg ist (GenArg (Rawwit wit, x)) =
+ match wit with
+ | ListArg wit ->
+ let map x =
+ let ans = intern_genarg ist (in_gen (rawwit wit) x) in
+ out_gen (glbwit wit) ans
in
- list_unpack { list_unpacker } x
- | OptArgType _ ->
- let opt_unpacker wit o = match raw o with
+ in_gen (glbwit (wit_list wit)) (List.map map x)
+ | OptArg wit ->
+ let ans = match x with
| None -> in_gen (glbwit (wit_opt wit)) None
| Some x ->
let s = out_gen (glbwit wit) (intern_genarg ist (in_gen (rawwit wit) x)) in
in_gen (glbwit (wit_opt wit)) (Some s)
in
- opt_unpack { opt_unpacker } x
- | PairArgType _ ->
- let pair_unpacker wit1 wit2 o =
- let p, q = raw o in
- let p = out_gen (glbwit wit1) (intern_genarg ist (in_gen (rawwit wit1) p)) in
- let q = out_gen (glbwit wit2) (intern_genarg ist (in_gen (rawwit wit2) q)) in
- in_gen (glbwit (wit_pair wit1 wit2)) (p, q)
- in
- pair_unpack { pair_unpacker } x
- | ExtraArgType s ->
- snd (Genintern.generic_intern ist x)
+ ans
+ | PairArg (wit1, wit2) ->
+ let p, q = x in
+ let p = out_gen (glbwit wit1) (intern_genarg ist (in_gen (rawwit wit1) p)) in
+ let q = out_gen (glbwit wit2) (intern_genarg ist (in_gen (rawwit wit2) q)) in
+ in_gen (glbwit (wit_pair wit1 wit2)) (p, q)
+ | ExtraArg s ->
+ snd (Genintern.generic_intern ist (in_gen (rawwit wit) x))
(** Other entry points *)
@@ -852,13 +813,26 @@ let () =
in
Genintern.register_intern0 wit_clause_dft_concl intern_clause
+let intern_ident' ist id =
+ let lf = ref Id.Set.empty in
+ (ist, intern_ident lf ist id)
+
let () =
+ Genintern.register_intern0 wit_int_or_var (lift intern_int_or_var);
Genintern.register_intern0 wit_ref (lift intern_global_reference);
+ Genintern.register_intern0 wit_ident intern_ident';
+ Genintern.register_intern0 wit_var (lift intern_hyp);
Genintern.register_intern0 wit_tactic (lift intern_tactic_or_tacarg);
- Genintern.register_intern0 wit_sort (fun ist s -> (ist, s))
-
-let () =
- Genintern.register_intern0 wit_uconstr (fun ist c -> (ist,intern_constr ist c))
+ Genintern.register_intern0 wit_sort (fun ist s -> (ist, s));
+ Genintern.register_intern0 wit_quant_hyp (lift intern_quantified_hypothesis);
+ Genintern.register_intern0 wit_constr (fun ist c -> (ist,intern_constr ist c));
+ Genintern.register_intern0 wit_uconstr (fun ist c -> (ist,intern_constr ist c));
+ Genintern.register_intern0 wit_open_constr (fun ist c -> (ist,intern_constr ist c));
+ Genintern.register_intern0 wit_red_expr (lift intern_red_expr);
+ Genintern.register_intern0 wit_bindings (lift intern_bindings);
+ Genintern.register_intern0 wit_constr_with_bindings (lift intern_constr_with_bindings);
+ Genintern.register_intern0 wit_constr_may_eval (lift intern_constr_may_eval);
+ ()
(***************************************************************************)
(* Backwarding recursive needs of tactic glob/interp/eval functions *)
diff --git a/tactics/tacintern.mli b/tactics/tacintern.mli
index 7901cfeb4..71ca354fa 100644
--- a/tactics/tacintern.mli
+++ b/tactics/tacintern.mli
@@ -12,7 +12,6 @@ open Tacexpr
open Genarg
open Constrexpr
open Misctypes
-open Nametab
(** Globalization of tactic expressions :
Conversion from [raw_tactic_expr] to [glob_tactic_expr] *)
diff --git a/tactics/tacinterp.ml b/tactics/tacinterp.ml
index 54adbd937..1112da4a0 100644
--- a/tactics/tacinterp.ml
+++ b/tactics/tacinterp.ml
@@ -40,29 +40,49 @@ open Misctypes
open Locus
open Tacintern
open Taccoerce
+open Sigma.Notations
open Proofview.Notations
+let has_type : type a. Val.t -> a typed_abstract_argument_type -> bool = fun v wit ->
+ let Val.Dyn (t, _) = v in
+ match Val.eq t (val_tag wit) with
+ | None -> false
+ | Some Refl -> true
+
+let prj : type a. a Val.tag -> Val.t -> a option = fun t v ->
+ let Val.Dyn (t', x) = v in
+ match Val.eq t t' with
+ | None -> None
+ | Some Refl -> Some x
+
+let in_gen wit v = Val.Dyn (val_tag wit, v)
+let out_gen wit v = match prj (val_tag wit) v with None -> assert false | Some x -> x
+
+let val_tag wit = val_tag (topwit wit)
+
+let pr_argument_type arg =
+ let Val.Dyn (tag, _) = arg in
+ Val.repr tag
+
let safe_msgnl s =
Proofview.NonLogical.catch
(Proofview.NonLogical.print_debug (s++fnl()))
(fun _ -> Proofview.NonLogical.print_warning (str "bug in the debugger: an exception is raised while printing debug information"++fnl()))
-type value = tlevel generic_argument
+type value = Val.t
(** Abstract application, to print ltac functions *)
type appl =
| UnnamedAppl (** For generic applications: nothing is printed *)
- | GlbAppl of (Names.kernel_name * typed_generic_argument list) list
+ | GlbAppl of (Names.kernel_name * Val.t list) list
(** For calls to global constants, some may alias other. *)
let push_appl appl args =
match appl with
| UnnamedAppl -> UnnamedAppl
| GlbAppl l -> GlbAppl (List.map (fun (h,vs) -> (h,vs@args)) l)
-let pr_generic arg =
- let pr_gtac _ x = Pptactic.pr_glob_tactic (Global.env()) x in
- try
- Pptactic.pr_top_generic pr_constr pr_lconstr pr_gtac pr_constr_pattern arg
- with e when Errors.noncritical e -> str"<generic>"
+let pr_generic arg = (** FIXME *)
+ let Val.Dyn (tag, _) = arg in
+ str"<" ++ Val.repr tag ++ str ">"
let pr_appl h vs =
Pptactic.pr_ltac_constant h ++ spc () ++
Pp.prlist_with_sep spc pr_generic vs
@@ -85,7 +105,7 @@ type tacvalue =
Id.t option list * glob_tactic_expr
| VRec of value Id.Map.t ref * glob_tactic_expr
-let (wit_tacvalue : (Empty.t, Empty.t, tacvalue) Genarg.genarg_type) =
+let (wit_tacvalue : (Empty.t, tacvalue, tacvalue) Genarg.genarg_type) =
Genarg.create_arg None "tacvalue"
let of_tacvalue v = in_gen (topwit wit_tacvalue) v
@@ -124,8 +144,59 @@ module Value = struct
let closure = VFun (UnnamedAppl,extract_trace ist, ist.lfun, [], tac) in
of_tacvalue closure
+ let cast_error wit v =
+ let pr_v = mt () in (** FIXME *)
+ let Val.Dyn (tag, _) = v in
+ let tag = Val.repr tag in
+ errorlabstrm "" (str "Type error: value " ++ pr_v ++ str "is a " ++ tag
+ ++ str " while type " ++ Genarg.pr_argument_type (unquote (rawwit wit)) ++ str " was expected.")
+
+ let prj : type a. a Val.tag -> Val.t -> a option = fun t v ->
+ let Val.Dyn (t', x) = v in
+ match Val.eq t t' with
+ | None -> None
+ | Some Refl -> Some x
+
+ let try_prj wit v = match prj (val_tag wit) v with
+ | None -> cast_error wit v
+ | Some x -> x
+
+ let rec val_cast : type a b c. (a, b, c) genarg_type -> Val.t -> c =
+ fun wit v -> match wit with
+ | ExtraArg _ -> try_prj wit v
+ | ListArg t ->
+ let Val.Dyn (tag, v) = v in
+ begin match tag with
+ | Val.List tag ->
+ let map x = val_cast t (Val.Dyn (tag, x)) in
+ List.map map v
+ | _ -> cast_error wit (Val.Dyn (tag, v))
+ end
+ | OptArg t ->
+ let Val.Dyn (tag, v) = v in
+ begin match tag with
+ | Val.Opt tag ->
+ let map x = val_cast t (Val.Dyn (tag, x)) in
+ Option.map map v
+ | _ -> cast_error wit (Val.Dyn (tag, v))
+ end
+ | PairArg (t1, t2) ->
+ let Val.Dyn (tag, v) = v in
+ begin match tag with
+ | Val.Pair (tag1, tag2) ->
+ let (v1, v2) = v in
+ let v1 = Val.Dyn (tag1, v1) in
+ let v2 = Val.Dyn (tag2, v2) in
+ (val_cast t1 v1, val_cast t2 v2)
+ | _ -> cast_error wit (Val.Dyn (tag, v))
+ end
+
+ let cast (Topwit wit) v = val_cast wit v
+
end
+let print_top_val env v = mt () (** FIXME *)
+
let dloc = Loc.ghost
let catching_error call_trace fail (e, info) =
@@ -177,13 +248,13 @@ let pr_value env v =
| Some (env,sigma) -> pr_lconstr_under_binders_env env sigma c
| _ -> str "a term"
else
- str "a value of type" ++ spc () ++ pr_argument_type (genarg_tag v)
+ str "a value of type" ++ spc () ++ pr_argument_type v
let pr_closure env ist body =
let pp_body = Pptactic.pr_glob_tactic env body in
let pr_sep () = fnl () in
let pr_iarg (id, arg) =
- let arg = pr_argument_type (genarg_tag arg) in
+ let arg = pr_argument_type arg in
hov 0 (pr_id id ++ spc () ++ str ":" ++ spc () ++ arg)
in
let pp_iargs = v 0 (prlist_with_sep pr_sep pr_iarg (Id.Map.bindings ist)) in
@@ -200,7 +271,7 @@ let pr_inspect env expr result =
| VRec (ist, body) ->
str "a recursive closure" ++ fnl () ++ pr_closure env !ist body
else
- let pp_type = pr_argument_type (genarg_tag result) in
+ let pp_type = pr_argument_type result in
str "an object of type" ++ spc () ++ pp_type
in
pp_expr ++ fnl() ++ str "this is " ++ pp_result
@@ -209,17 +280,6 @@ let pr_inspect env expr result =
let constr_of_id env id =
Term.mkVar (let _ = Environ.lookup_named id env in id)
-(* To embed tactics *)
-
-let ((tactic_in : (interp_sign -> glob_tactic_expr) -> Dyn.t),
- (tactic_out : Dyn.t -> (interp_sign -> glob_tactic_expr))) =
- Dyn.create "tactic"
-
-let ((value_in : value -> Dyn.t),
- (value_out : Dyn.t -> value)) = Dyn.create "value"
-
-let valueIn t = TacDynamic (Loc.ghost, value_in t)
-
(** Generic arguments : table of interpretation functions *)
let push_trace call ist = match TacStore.get ist.extra f_trace with
@@ -260,9 +320,9 @@ let coerce_to_tactic loc id v =
| _ -> fail ()
else fail ()
+let intro_pattern_of_ident id = (Loc.ghost, IntroNaming (IntroIdentifier id))
let value_of_ident id =
- in_gen (topwit wit_intro_pattern)
- (Loc.ghost, IntroNaming (IntroIdentifier id))
+ in_gen (topwit wit_intro_pattern) (intro_pattern_of_ident id)
let (+++) lfun1 lfun2 = Id.Map.fold Id.Map.add lfun1 lfun2
@@ -337,10 +397,6 @@ let interp_intro_pattern_naming_var loc ist env sigma id =
try try_interp_ltac_var (coerce_to_intro_pattern_naming env) ist (Some (env,sigma)) (loc,id)
with Not_found -> IntroIdentifier id
-let interp_hint_base ist s =
- try try_interp_ltac_var coerce_to_hint_base ist None (dloc,Id.of_string s)
- with Not_found -> s
-
let interp_int ist locid =
try try_interp_ltac_var coerce_to_int ist None locid
with Not_found ->
@@ -455,7 +511,9 @@ let extract_ltac_constr_values ist env =
(* Extract the identifier list from lfun: join all branches (what to do else?)*)
let rec intropattern_ids (loc,pat) = match pat with
| IntroNaming (IntroIdentifier id) -> [id]
- | IntroAction (IntroOrAndPattern ll) ->
+ | IntroAction (IntroOrAndPattern (IntroAndPattern l)) ->
+ List.flatten (List.map intropattern_ids l)
+ | IntroAction (IntroOrAndPattern (IntroOrPattern ll)) ->
List.flatten (List.map intropattern_ids (List.flatten ll))
| IntroAction (IntroInjection l) ->
List.flatten (List.map intropattern_ids l)
@@ -633,10 +691,10 @@ let pf_interp_constr ist gl =
let new_interp_constr ist c k =
let open Proofview in
- Proofview.Goal.enter begin fun gl ->
- let (sigma, c) = interp_constr ist (Goal.env gl) (Goal.sigma gl) c in
- Proofview.tclTHEN (Proofview.Unsafe.tclEVARS sigma) (k c)
- end
+ Proofview.Goal.s_enter { s_enter = begin fun gl ->
+ let (sigma, c) = interp_constr ist (Goal.env gl) (Tacmach.New.project gl) c in
+ Sigma.Unsafe.of_pair (k c, sigma)
+ end }
let interp_constr_in_compound_list inj_fun dest_fun interp_fun ist env sigma l =
let try_expand_ltac_var sigma x =
@@ -659,14 +717,28 @@ let interp_constr_list ist env sigma c =
let interp_open_constr_list =
interp_constr_in_compound_list (fun x -> x) (fun x -> x) interp_open_constr
-let interp_auto_lemmas ist env sigma lems =
- let local_sigma, lems = interp_open_constr_list ist env sigma lems in
- List.map (fun lem -> (local_sigma,lem)) lems
-
(* Interprets a type expression *)
let pf_interp_type ist gl =
interp_type ist (pf_env gl) (project gl)
+(* Fully evaluate an untyped constr *)
+let type_uconstr ?(flags = constr_flags)
+ ?(expected_type = WithoutTypeConstraint) ist c =
+ { delayed = begin fun env sigma ->
+ let open Pretyping in
+ let { closure; term } = c in
+ let vars = {
+ ltac_constrs = closure.typed;
+ ltac_uconstrs = closure.untyped;
+ ltac_idents = closure.idents;
+ ltac_genargs = ist.lfun;
+ } in
+ let sigma = Sigma.to_evar_map sigma in
+ let (sigma, c) = understand_ltac flags env sigma vars expected_type term in
+ Sigma.Unsafe.of_pair (c, sigma)
+ end }
+
+
(* Interprets a reduction expression *)
let interp_unfold ist env sigma (occs,qid) =
(interp_occurrences ist occs,interp_evaluable ist env sigma qid)
@@ -791,37 +863,37 @@ let rec message_of_value v =
Ftactic.return (str "<tactic>")
else if has_type v (topwit wit_constr) then
let v = out_gen (topwit wit_constr) v in
- Ftactic.nf_enter begin fun gl -> Ftactic.return (pr_constr_env (pf_env gl) (Proofview.Goal.sigma gl) v) end
+ Ftactic.nf_enter {enter = begin fun gl -> Ftactic.return (pr_constr_env (pf_env gl) (Tacmach.New.project gl) v) end }
else if has_type v (topwit wit_constr_under_binders) then
let c = out_gen (topwit wit_constr_under_binders) v in
- Ftactic.nf_enter begin fun gl ->
- Ftactic.return (pr_constr_under_binders_env (pf_env gl) (Proofview.Goal.sigma gl) c)
- end
+ Ftactic.nf_enter { enter = begin fun gl ->
+ Ftactic.return (pr_constr_under_binders_env (pf_env gl) (Tacmach.New.project gl) c)
+ end }
else if has_type v (topwit wit_unit) then
Ftactic.return (str "()")
else if has_type v (topwit wit_int) then
Ftactic.return (int (out_gen (topwit wit_int) v))
else if has_type v (topwit wit_intro_pattern) then
let p = out_gen (topwit wit_intro_pattern) v in
- let print env sigma c = pr_constr_env env sigma (snd (c env Evd.empty)) in
- Ftactic.nf_enter begin fun gl ->
- Ftactic.return (Miscprint.pr_intro_pattern (fun c -> print (pf_env gl) (Proofview.Goal.sigma gl) c) p)
- end
+ let print env sigma c = pr_constr_env env sigma (fst (Tactics.run_delayed env Evd.empty c)) in
+ Ftactic.nf_enter { enter = begin fun gl ->
+ Ftactic.return (Miscprint.pr_intro_pattern (fun c -> print (pf_env gl) (Tacmach.New.project gl) c) p)
+ end }
else if has_type v (topwit wit_constr_context) then
let c = out_gen (topwit wit_constr_context) v in
- Ftactic.nf_enter begin fun gl -> Ftactic.return (pr_constr_env (pf_env gl) (Proofview.Goal.sigma gl) c) end
+ Ftactic.nf_enter { enter = begin fun gl -> Ftactic.return (pr_constr_env (pf_env gl) (Tacmach.New.project gl) c) end }
else if has_type v (topwit wit_uconstr) then
let c = out_gen (topwit wit_uconstr) v in
- Ftactic.nf_enter begin fun gl ->
+ Ftactic.nf_enter { enter = begin fun gl ->
Ftactic.return (pr_closed_glob_env (pf_env gl)
- (Proofview.Goal.sigma gl) c)
- end
+ (Tacmach.New.project gl) c)
+ end }
else match Value.to_list v with
| Some l ->
Ftactic.List.map message_of_value l >>= fun l ->
Ftactic.return (prlist_with_sep spc (fun x -> x) l)
| None ->
- let tag = pr_argument_type (genarg_tag v) in
+ let tag = pr_argument_type v in
Ftactic.return (str "<" ++ tag ++ str ">") (** TODO *)
let interp_message_token ist = function
@@ -838,11 +910,6 @@ let interp_message ist l =
Ftactic.List.map (interp_message_token ist) l >>= fun l ->
Ftactic.return (prlist_with_sep spc (fun x -> x) l)
-let interp_message ist l =
- let open Ftactic in
- Ftactic.List.map (interp_message_token ist) l >>= fun l ->
- Ftactic.return (prlist_with_sep spc (fun x -> x) l)
-
let rec interp_intro_pattern ist env sigma = function
| loc, IntroAction pat ->
let (sigma,pat) = interp_intro_pattern_action ist env sigma pat in
@@ -866,13 +933,22 @@ and interp_intro_pattern_action ist env sigma = function
let sigma,l = interp_intro_pattern_list_as_list ist env sigma l in
sigma, IntroInjection l
| IntroApplyOn (c,ipat) ->
- let c = fun env sigma -> interp_open_constr ist env sigma c in
+ let c = { delayed = fun env sigma ->
+ let sigma = Sigma.to_evar_map sigma in
+ let (sigma, c) = interp_open_constr ist env sigma c in
+ Sigma.Unsafe.of_pair (c, sigma)
+ } in
let sigma,ipat = interp_intro_pattern ist env sigma ipat in
sigma, IntroApplyOn (c,ipat)
| IntroWildcard | IntroRewrite _ as x -> sigma, x
-and interp_or_and_intro_pattern ist env sigma =
- List.fold_map (interp_intro_pattern_list_as_list ist env) sigma
+and interp_or_and_intro_pattern ist env sigma = function
+ | IntroAndPattern l ->
+ let sigma, l = List.fold_map (interp_intro_pattern ist env) sigma l in
+ sigma, IntroAndPattern l
+ | IntroOrPattern ll ->
+ let sigma, ll = List.fold_map (interp_intro_pattern_list_as_list ist env) sigma ll in
+ sigma, IntroOrPattern ll
and interp_intro_pattern_list_as_list ist env sigma = function
| [loc,IntroNaming (IntroIdentifier id)] as l ->
@@ -947,19 +1023,11 @@ let interp_constr_with_bindings ist env sigma (c,bl) =
let sigma, c = interp_open_constr ist env sigma c in
sigma, (c,bl)
-let interp_constr_with_bindings_arg ist env sigma (keep,c) =
- let sigma, c = interp_constr_with_bindings ist env sigma c in
- sigma, (keep,c)
-
let interp_open_constr_with_bindings ist env sigma (c,bl) =
let sigma, bl = interp_bindings ist env sigma bl in
let sigma, c = interp_open_constr ist env sigma c in
sigma, (c, bl)
-let interp_open_constr_with_bindings_arg ist env sigma (keep,c) =
- let sigma, c = interp_open_constr_with_bindings ist env sigma c in
- sigma,(keep,c)
-
let loc_of_bindings = function
| NoBindings -> Loc.ghost
| ImplicitBindings l -> loc_of_glob_constr (fst (List.last l))
@@ -969,13 +1037,21 @@ let interp_open_constr_with_bindings_loc ist ((c,_),bl as cb) =
let loc1 = loc_of_glob_constr c in
let loc2 = loc_of_bindings bl in
let loc = if Loc.is_ghost loc2 then loc1 else Loc.merge loc1 loc2 in
- let f env sigma = interp_open_constr_with_bindings ist env sigma cb in
+ let f = { delayed = fun env sigma ->
+ let sigma = Sigma.to_evar_map sigma in
+ let (sigma, c) = interp_open_constr_with_bindings ist env sigma cb in
+ Sigma.Unsafe.of_pair (c, sigma)
+ } in
(loc,f)
let interp_induction_arg ist gl arg =
match arg with
| keep,ElimOnConstr c ->
- keep,ElimOnConstr (fun env sigma -> interp_constr_with_bindings ist env sigma c)
+ keep,ElimOnConstr { delayed = fun env sigma ->
+ let sigma = Sigma.to_evar_map sigma in
+ let (sigma, c) = interp_constr_with_bindings ist env sigma c in
+ Sigma.Unsafe.of_pair (c, sigma)
+ }
| keep,ElimOnAnonHyp n as x -> x
| keep,ElimOnIdent (loc,id) ->
let error () = user_err_loc (loc, "",
@@ -985,11 +1061,13 @@ let interp_induction_arg ist gl arg =
let try_cast_id id' =
if Tactics.is_quantified_hypothesis id' gl
then keep,ElimOnIdent (loc,id')
- else keep, ElimOnConstr (fun env sigma ->
- try sigma, (constr_of_id env id', NoBindings)
+ else
+ (keep, ElimOnConstr { delayed = begin fun env sigma ->
+ try Sigma.here (constr_of_id env id', NoBindings) sigma
with Not_found ->
user_err_loc (loc, "interp_induction_arg",
- pr_id id ++ strbrk " binds to " ++ pr_id id' ++ strbrk " which is neither a declared nor a quantified hypothesis."))
+ pr_id id ++ strbrk " binds to " ++ pr_id id' ++ strbrk " which is neither a declared nor a quantified hypothesis.")
+ end })
in
try
(** FIXME: should be moved to taccoerce *)
@@ -1007,16 +1085,18 @@ let interp_induction_arg ist gl arg =
keep,ElimOnAnonHyp (out_gen (topwit wit_int) v)
else match Value.to_constr v with
| None -> error ()
- | Some c -> keep,ElimOnConstr (fun env sigma -> sigma,(c,NoBindings))
+ | Some c -> keep,ElimOnConstr { delayed = fun env sigma -> Sigma ((c,NoBindings), sigma, Sigma.refl) }
with Not_found ->
(* We were in non strict (interactive) mode *)
if Tactics.is_quantified_hypothesis id gl then
keep,ElimOnIdent (loc,id)
else
let c = (GVar (loc,id),Some (CRef (Ident (loc,id),None))) in
- let f env sigma =
+ let f = { delayed = fun env sigma ->
+ let sigma = Sigma.to_evar_map sigma in
let (sigma,c) = interp_open_constr ist env sigma c in
- sigma,(c,NoBindings) in
+ Sigma.Unsafe.of_pair ((c,NoBindings), sigma)
+ } in
keep,ElimOnConstr f
(* Associates variables with values and gives the remaining variables and
@@ -1081,20 +1161,17 @@ let rec read_match_rule lfun ist env sigma = function
(* misc *)
-let mk_constr_value ist gl c =
- let (sigma,c_interp) = pf_interp_constr ist gl c in
- sigma, Value.of_constr c_interp
-let mk_open_constr_value ist gl c =
- let (sigma,c_interp) = pf_apply (interp_open_constr ist) gl c in
- sigma, Value.of_constr c_interp
-let mk_hyp_value ist env sigma c =
- Value.of_constr (mkVar (interp_hyp ist env sigma c))
-let mk_int_or_var_value ist c = in_gen (topwit wit_int) (interp_int_or_var ist c)
-
-let pack_sigma (sigma,c) = {it=c;sigma=sigma;}
+let interp_focussed wit f v =
+ Ftactic.nf_enter { enter = begin fun gl ->
+ let v = Genarg.out_gen (glbwit wit) v in
+ let env = Proofview.Goal.env gl in
+ let sigma = Sigma.to_evar_map (Proofview.Goal.sigma gl) in
+ let v = in_gen (topwit wit) (f env sigma v) in
+ Ftactic.return v
+ end }
(* Interprets an l-tac expression into a value *)
-let rec val_interp ist ?(appl=UnnamedAppl) (tac:glob_tactic_expr) : typed_generic_argument Ftactic.t =
+let rec val_interp ist ?(appl=UnnamedAppl) (tac:glob_tactic_expr) : Val.t Ftactic.t =
(* The name [appl] of applied top-level Ltac names is ignored in
[value_interp]. It is installed in the second step by a call to
[name_vfun], because it gives more opportunities to detect a
@@ -1159,9 +1236,9 @@ and eval_tactic ist tac : unit Proofview.tactic = match tac with
tclSHOWHYPS (Proofview.V82.of_tactic (interp_tactic ist tac))
end
| TacAbstract (tac,ido) ->
- Proofview.Goal.nf_enter begin fun gl -> Tactics.tclABSTRACT
+ Proofview.Goal.nf_enter { enter = begin fun gl -> Tactics.tclABSTRACT
(Option.map (Tacmach.New.of_old (pf_interp_ident ist) gl) ido) (interp_tactic ist tac)
- end
+ end }
| TacThen (t1,t) ->
Tacticals.New.tclTHEN (interp_tactic ist t1) (interp_tactic ist t)
| TacDispatch tl ->
@@ -1204,102 +1281,12 @@ and eval_tactic ist tac : unit Proofview.tactic = match tac with
eval_tactic ist tac
(* For extensions *)
| TacAlias (loc,s,l) ->
- let body = Tacenv.interp_alias s in
- let rec f x = match genarg_tag x with
- | QuantHypArgType | RedExprArgType
- | ConstrWithBindingsArgType
- | BindingsArgType
- | OptArgType _ | PairArgType _ -> (** generic handler *)
- Ftactic.nf_enter begin fun gl ->
- let sigma = Proofview.Goal.sigma gl in
- let env = Proofview.Goal.env gl in
- let concl = Proofview.Goal.concl gl in
- let goal = Proofview.Goal.goal gl in
- let (sigma, arg) = interp_genarg ist env sigma concl goal x in
- Ftactic.(lift (Proofview.Unsafe.tclEVARS sigma) <*> return arg)
- end
- | _ as tag -> (** Special treatment. TODO: use generic handler *)
- Ftactic.nf_enter begin fun gl ->
- let sigma = Proofview.Goal.sigma gl in
- let env = Proofview.Goal.env gl in
- match tag with
- | IntOrVarArgType ->
- Ftactic.return (mk_int_or_var_value ist (out_gen (glbwit wit_int_or_var) x))
- | IdentArgType ->
- Ftactic.return (value_of_ident (interp_ident ist env sigma
- (out_gen (glbwit wit_ident) x)))
- | VarArgType ->
- Ftactic.return (mk_hyp_value ist env sigma (out_gen (glbwit wit_var) x))
- | GenArgType -> f (out_gen (glbwit wit_genarg) x)
- | ConstrArgType ->
- let (sigma,v) =
- Tacmach.New.of_old (fun gl -> mk_constr_value ist gl (out_gen (glbwit wit_constr) x)) gl
- in
- Ftactic.(lift (Proofview.Unsafe.tclEVARS sigma) <*> return v)
- | OpenConstrArgType ->
- let (sigma,v) =
- Tacmach.New.of_old (fun gl -> mk_open_constr_value ist gl (snd (out_gen (glbwit wit_open_constr) x))) gl in
- Ftactic.(lift (Proofview.Unsafe.tclEVARS sigma) <*> return v)
- | ConstrMayEvalArgType ->
- let (sigma,c_interp) =
- interp_constr_may_eval ist env sigma
- (out_gen (glbwit wit_constr_may_eval) x)
- in
- Ftactic.(lift (Proofview.Unsafe.tclEVARS sigma) <*> return (Value.of_constr c_interp))
- | ListArgType ConstrArgType ->
- let wit = glbwit (wit_list wit_constr) in
- let (sigma,l_interp) = Tacmach.New.of_old begin fun gl ->
- Evd.MonadR.List.map_right
- (fun c sigma -> mk_constr_value ist { gl with sigma=sigma } c)
- (out_gen wit x)
- (project gl)
- end gl in
- Ftactic.(lift (Proofview.Unsafe.tclEVARS sigma) <*> return (in_gen (topwit (wit_list wit_genarg)) l_interp))
- | ListArgType VarArgType ->
- let wit = glbwit (wit_list wit_var) in
- Ftactic.return (
- let ans = List.map (mk_hyp_value ist env sigma) (out_gen wit x) in
- in_gen (topwit (wit_list wit_genarg)) ans
- )
- | ListArgType IntOrVarArgType ->
- let wit = glbwit (wit_list wit_int_or_var) in
- let ans = List.map (mk_int_or_var_value ist) (out_gen wit x) in
- Ftactic.return (in_gen (topwit (wit_list wit_genarg)) ans)
- | ListArgType IdentArgType ->
- let wit = glbwit (wit_list wit_ident) in
- let mk_ident x = value_of_ident (interp_ident ist env sigma x) in
- let ans = List.map mk_ident (out_gen wit x) in
- Ftactic.return (in_gen (topwit (wit_list wit_genarg)) ans)
- | ListArgType t ->
- let open Ftactic in
- let list_unpacker wit l =
- let map x =
- f (in_gen (glbwit wit) x) >>= fun v ->
- Ftactic.return (out_gen (topwit wit) v)
- in
- Ftactic.List.map map (glb l) >>= fun l ->
- Ftactic.return (in_gen (topwit (wit_list wit)) l)
- in
- list_unpack { list_unpacker } x
- | ExtraArgType _ ->
- (** Special treatment of tactics *)
- if has_type x (glbwit wit_tactic) then
- let tac = out_gen (glbwit wit_tactic) x in
- val_interp ist tac
- else
- let goal = Proofview.Goal.goal gl in
- let (newsigma,v) = Geninterp.generic_interp ist {Evd.it=goal;sigma} x in
- Ftactic.(lift (Proofview.Unsafe.tclEVARS newsigma) <*> return v)
- | _ -> assert false
- end
- in
+ let (ids, body) = Tacenv.interp_alias s in
let (>>=) = Ftactic.bind in
- let interp_vars =
- Ftactic.List.map (fun (x,v) -> f v >>= fun v -> Ftactic.return (x,v)) l
- in
- let addvar (x, v) accu = Id.Map.add x v accu in
+ let interp_vars = Ftactic.List.map (fun v -> interp_tacarg ist v) l in
let tac l =
- let lfun = List.fold_right addvar l ist.lfun in
+ let addvar x v accu = Id.Map.add x v accu in
+ let lfun = List.fold_right2 addvar ids l ist.lfun in
let trace = push_trace (loc,LtacNotationCall s) ist in
let ist = {
lfun = lfun;
@@ -1308,52 +1295,35 @@ and eval_tactic ist tac : unit Proofview.tactic = match tac with
Ftactic.lift (tactic_of_value ist v)
in
let tac =
- Ftactic.with_env interp_vars >>= fun (env,l) ->
- let name () = Pptactic.pr_tactic env (TacAlias(loc,s,l)) in
- Proofview.Trace.name_tactic name (tac l)
+ Ftactic.with_env interp_vars >>= fun (env, lr) ->
+ let name () = Pptactic.pr_alias (fun v -> print_top_val env v) 0 s lr in
+ Proofview.Trace.name_tactic name (tac lr)
(* spiwack: this use of name_tactic is not robust to a
change of implementation of [Ftactic]. In such a situation,
some more elaborate solution will have to be used. *)
in
+ let tac =
+ let len1 = List.length ids in
+ let len2 = List.length l in
+ if len1 = len2 then tac
+ else Tacticals.New.tclZEROMSG (str "Arguments length mismatch: \
+ expected " ++ int len1 ++ str ", found " ++ int len2)
+ in
Ftactic.run tac (fun () -> Proofview.tclUNIT ())
- | TacML (loc,opn,l) when List.for_all global_genarg l ->
- let trace = push_trace (loc,LtacMLCall tac) ist in
- let ist = { ist with extra = TacStore.set ist.extra f_trace trace; } in
- (* spiwack: a special case for tactics (from TACTIC EXTEND) when
- every argument can be interpreted without a
- [Proofview.Goal.nf_enter]. *)
- let tac = Tacenv.interp_ml_tactic opn in
- (* dummy values, will be ignored *)
- let env = Environ.empty_env in
- let sigma = Evd.empty in
- let concl = Term.mkRel (-1) in
- let goal = Evar.unsafe_of_int (-1) in
- (* /dummy values *)
- let args = List.map (fun a -> snd(interp_genarg ist env sigma concl goal a)) l in
- let name () = Pptactic.pr_tactic env (TacML(loc,opn,args)) in
- Proofview.Trace.name_tactic name
- (catch_error_tac trace (tac args ist))
| TacML (loc,opn,l) ->
+ let open Ftactic.Notations in
let trace = push_trace (loc,LtacMLCall tac) ist in
let ist = { ist with extra = TacStore.set ist.extra f_trace trace; } in
- Proofview.Goal.nf_enter begin fun gl ->
- let env = Proofview.Goal.env gl in
- let goal_sigma = Proofview.Goal.sigma gl in
- let concl = Proofview.Goal.concl gl in
- let goal = Proofview.Goal.goal gl in
- let tac = Tacenv.interp_ml_tactic opn in
- let (sigma,args) =
- Evd.MonadR.List.map_right
- (fun a sigma -> interp_genarg ist env sigma concl goal a) l goal_sigma
- in
- Proofview.Unsafe.tclEVARS sigma <*>
- let name () = Pptactic.pr_tactic env (TacML(loc,opn,args)) in
- Proofview.Trace.name_tactic name
- (catch_error_tac trace (tac args ist))
- end
+ let tac = Tacenv.interp_ml_tactic opn in
+ let args = Ftactic.List.map_right (fun a -> interp_tacarg ist a) l in
+ let tac args =
+ let name () = Pptactic.pr_extend (fun v -> print_top_val () v) 0 opn args in
+ Proofview.Trace.name_tactic name (catch_error_tac trace (tac args ist))
+ in
+ Ftactic.run args tac
-and force_vrec ist v : typed_generic_argument Ftactic.t =
+and force_vrec ist v : Val.t Ftactic.t =
let v = Value.normalize v in
if has_type v (topwit wit_tacvalue) then
let v = to_tacvalue v in
@@ -1362,7 +1332,7 @@ and force_vrec ist v : typed_generic_argument Ftactic.t =
| v -> Ftactic.return (of_tacvalue v)
else Ftactic.return v
-and interp_ltac_reference loc' mustbetac ist r : typed_generic_argument Ftactic.t =
+and interp_ltac_reference loc' mustbetac ist r : Val.t Ftactic.t =
match r with
| ArgVar (loc,id) ->
let v =
@@ -1382,28 +1352,22 @@ and interp_ltac_reference loc' mustbetac ist r : typed_generic_argument Ftactic.
let appl = GlbAppl[r,[]] in
val_interp ~appl ist (Tacenv.interp_ltac r)
-and interp_tacarg ist arg : typed_generic_argument Ftactic.t =
+and interp_tacarg ist arg : Val.t Ftactic.t =
match arg with
- | TacGeneric arg ->
- Ftactic.nf_enter begin fun gl ->
- let sigma = Proofview.Goal.sigma gl in
- let goal = Proofview.Goal.goal gl in
- let (sigma,v) = Geninterp.generic_interp ist {Evd.it=goal;sigma} arg in
- Ftactic.(lift (Proofview.Unsafe.tclEVARS sigma) <*> return v)
- end
+ | TacGeneric arg -> interp_genarg ist arg
| Reference r -> interp_ltac_reference dloc false ist r
| ConstrMayEval c ->
- Ftactic.enter begin fun gl ->
- let sigma = Proofview.Goal.sigma gl in
+ Ftactic.s_enter { s_enter = begin fun gl ->
+ let sigma = Tacmach.New.project gl in
let env = Proofview.Goal.env gl in
let (sigma,c_interp) = interp_constr_may_eval ist env sigma c in
- Ftactic.(lift (Proofview.Unsafe.tclEVARS sigma) <*> return (Value.of_constr c_interp))
- end
+ Sigma.Unsafe.of_pair (Ftactic.return (Value.of_constr c_interp), sigma)
+ end }
| UConstr c ->
- Ftactic.enter begin fun gl ->
+ Ftactic.enter { enter = begin fun gl ->
let env = Proofview.Goal.env gl in
Ftactic.return (Value.of_uconstr (interp_uconstr ist env c))
- end
+ end }
| MetaIdArg (loc,_,id) -> assert false
| TacCall (loc,r,[]) ->
interp_ltac_reference loc true ist r
@@ -1413,26 +1377,18 @@ and interp_tacarg ist arg : typed_generic_argument Ftactic.t =
Ftactic.List.map (fun a -> interp_tacarg ist a) l >>= fun largs ->
interp_app loc ist fv largs
| TacFreshId l ->
- Ftactic.enter begin fun gl ->
- let id = interp_fresh_id ist (Tacmach.New.pf_env gl) (Proofview.Goal.sigma gl) l in
+ Ftactic.enter { enter = begin fun gl ->
+ let id = interp_fresh_id ist (Tacmach.New.pf_env gl) (Tacmach.New.project gl) l in
Ftactic.return (in_gen (topwit wit_intro_pattern) (dloc, IntroNaming (IntroIdentifier id)))
- end
+ end }
| TacPretype c ->
- Ftactic.enter begin fun gl ->
+ Ftactic.s_enter { s_enter = begin fun gl ->
let sigma = Proofview.Goal.sigma gl in
let env = Proofview.Goal.env gl in
- let {closure;term} = interp_uconstr ist env c in
- let vars = {
- Pretyping.ltac_constrs = closure.typed;
- Pretyping.ltac_uconstrs = closure.untyped;
- Pretyping.ltac_idents = closure.idents;
- Pretyping.ltac_genargs = ist.lfun;
- } in
- let (sigma,c_interp) =
- Pretyping.understand_ltac constr_flags env sigma vars WithoutTypeConstraint term
- in
- Ftactic.(lift (Proofview.Unsafe.tclEVARS sigma) <*> return (Value.of_constr c_interp))
- end
+ let c = interp_uconstr ist env c in
+ let Sigma (c, sigma, p) = (type_uconstr ist c).delayed env sigma in
+ Sigma (Ftactic.return (Value.of_constr c), sigma, p)
+ end }
| TacNumgoals ->
Ftactic.lift begin
let open Proofview.Notations in
@@ -1440,20 +1396,9 @@ and interp_tacarg ist arg : typed_generic_argument Ftactic.t =
Proofview.tclUNIT (Value.of_int i)
end
| Tacexp t -> val_interp ist t
- | TacDynamic(_,t) ->
- let tg = (Dyn.tag t) in
- if String.equal tg "tactic" then
- val_interp ist (tactic_out t ist)
- else if String.equal tg "value" then
- Ftactic.return (value_out t)
- else if String.equal tg "constr" then
- Ftactic.return (Value.of_constr (constr_out t))
- else
- Errors.anomaly ~loc:dloc ~label:"Tacinterp.val_interp"
- (str "Unknown dynamic: <" ++ str (Dyn.tag t) ++ str ">")
(* Interprets an application node *)
-and interp_app loc ist fv largs : typed_generic_argument Ftactic.t =
+and interp_app loc ist fv largs : Val.t Ftactic.t =
let (>>=) = Ftactic.bind in
let fail = Tacticals.New.tclZEROMSG (str "Illegal tactic application.") in
let fv = Value.normalize fv in
@@ -1597,141 +1542,84 @@ and interp_match ist lz constr lmr =
Proofview.tclZERO ~info e
end
end >>= fun constr ->
- Ftactic.enter begin fun gl ->
- let sigma = Proofview.Goal.sigma gl in
+ Ftactic.enter { enter = begin fun gl ->
+ let sigma = Tacmach.New.project gl in
let env = Proofview.Goal.env gl in
let ilr = read_match_rule (extract_ltac_constr_values ist env) ist env sigma lmr in
interp_match_successes lz ist (Tactic_matching.match_term env sigma constr ilr)
- end
+ end }
(* Interprets the Match Context expressions *)
and interp_match_goal ist lz lr lmr =
- Ftactic.nf_enter begin fun gl ->
- let sigma = Proofview.Goal.sigma gl in
+ Ftactic.nf_enter { enter = begin fun gl ->
+ let sigma = Tacmach.New.project gl in
let env = Proofview.Goal.env gl in
let hyps = Proofview.Goal.hyps gl in
let hyps = if lr then List.rev hyps else hyps in
let concl = Proofview.Goal.concl gl in
let ilr = read_match_rule (extract_ltac_constr_values ist env) ist env sigma lmr in
interp_match_successes lz ist (Tactic_matching.match_goal env sigma hyps concl ilr)
- end
+ end }
(* Interprets extended tactic generic arguments *)
-(* spiwack: interp_genarg has an argument [concl] for the case of
- "casted open constr". And [gl] for [Geninterp]. I haven't changed
- the interface for geninterp yet as it is used by ARGUMENT EXTEND
- (in turn used by plugins). At the time I'm writing this comment
- though, the only concerned plugins are the declarative mode (which
- needs the [extra] field of goals to interprete rules) and ssreflect
- (a handful of time). I believe we'd need to address "casted open
- constr" and the declarative mode rules to provide a reasonable
- interface. *)
-and interp_genarg ist env sigma concl gl x =
- let evdref = ref sigma in
- let rec interp_genarg x =
- match genarg_tag x with
- | IntOrVarArgType ->
- in_gen (topwit wit_int_or_var)
- (ArgArg (interp_int_or_var ist (out_gen (glbwit wit_int_or_var) x)))
- | IdentArgType ->
- in_gen (topwit wit_ident)
- (interp_ident ist env sigma (out_gen (glbwit wit_ident) x))
- | VarArgType ->
- in_gen (topwit wit_var) (interp_hyp ist env sigma (out_gen (glbwit wit_var) x))
- | GenArgType ->
- in_gen (topwit wit_genarg) (interp_genarg (out_gen (glbwit wit_genarg) x))
- | ConstrArgType ->
- let (sigma,c_interp) =
- interp_constr ist env !evdref (out_gen (glbwit wit_constr) x)
- in
- evdref := sigma;
- in_gen (topwit wit_constr) c_interp
- | ConstrMayEvalArgType ->
- let (sigma,c_interp) = interp_constr_may_eval ist env !evdref (out_gen (glbwit wit_constr_may_eval) x) in
- evdref := sigma;
- in_gen (topwit wit_constr_may_eval) c_interp
- | QuantHypArgType ->
- in_gen (topwit wit_quant_hyp)
- (interp_declared_or_quantified_hypothesis ist env sigma
- (out_gen (glbwit wit_quant_hyp) x))
- | RedExprArgType ->
- let (sigma,r_interp) =
- interp_red_expr ist env !evdref (out_gen (glbwit wit_red_expr) x)
- in
- evdref := sigma;
- in_gen (topwit wit_red_expr) r_interp
- | OpenConstrArgType ->
- let expected_type = WithoutTypeConstraint in
- in_gen (topwit wit_open_constr)
- (interp_open_constr ~expected_type
- ist env !evdref
- (snd (out_gen (glbwit wit_open_constr) x)))
- | ConstrWithBindingsArgType ->
- in_gen (topwit wit_constr_with_bindings)
- (pack_sigma (interp_constr_with_bindings ist env !evdref
- (out_gen (glbwit wit_constr_with_bindings) x)))
- | BindingsArgType ->
- in_gen (topwit wit_bindings)
- (pack_sigma (interp_bindings ist env !evdref (out_gen (glbwit wit_bindings) x)))
- | ListArgType ConstrArgType ->
- let (sigma,v) = interp_genarg_constr_list ist env !evdref x in
- evdref := sigma;
- v
- | ListArgType VarArgType -> interp_genarg_var_list ist env sigma x
- | ListArgType _ ->
- let list_unpacker wit l =
- let map x =
- out_gen (topwit wit) (interp_genarg (in_gen (glbwit wit) x))
- in
- in_gen (topwit (wit_list wit)) (List.map map (glb l))
+and interp_genarg ist x : Val.t Ftactic.t =
+ let open Ftactic.Notations in
+ (** Ad-hoc handling of some types. *)
+ let tag = genarg_tag x in
+ if argument_type_eq tag (unquote (topwit (wit_list wit_var))) then
+ interp_genarg_var_list ist x
+ else if argument_type_eq tag (unquote (topwit (wit_list wit_constr))) then
+ interp_genarg_constr_list ist x
+ else
+ let GenArg (Glbwit wit, x) = x in
+ match wit with
+ | ListArg wit ->
+ let map x =
+ interp_genarg ist (Genarg.in_gen (glbwit wit) x) >>= fun x ->
+ Ftactic.return (Value.cast (topwit wit) x)
in
- list_unpack { list_unpacker } x
- | OptArgType _ ->
- let opt_unpacker wit o = match glb o with
- | None -> in_gen (topwit (wit_opt wit)) None
+ Ftactic.List.map map x >>= fun l ->
+ Ftactic.return (Value.of_list (val_tag wit) l)
+ | OptArg wit ->
+ let ans = match x with
+ | None -> Ftactic.return (Value.of_option (val_tag wit) None)
| Some x ->
- let x = out_gen (topwit wit) (interp_genarg (in_gen (glbwit wit) x)) in
- in_gen (topwit (wit_opt wit)) (Some x)
+ interp_genarg ist (Genarg.in_gen (glbwit wit) x) >>= fun x ->
+ let x = Value.cast (topwit wit) x in
+ Ftactic.return (Value.of_option (val_tag wit) (Some x))
in
- opt_unpack { opt_unpacker } x
- | PairArgType _ ->
- let pair_unpacker wit1 wit2 o =
- let (p, q) = glb o in
- let p = out_gen (topwit wit1) (interp_genarg (in_gen (glbwit wit1) p)) in
- let q = out_gen (topwit wit2) (interp_genarg (in_gen (glbwit wit2) q)) in
- in_gen (topwit (wit_pair wit1 wit2)) (p, q)
- in
- pair_unpack { pair_unpacker } x
- | ExtraArgType s ->
- let (sigma,v) = Geninterp.generic_interp ist { Evd.it=gl;sigma=(!evdref) } x in
- evdref:=sigma;
- v
- in
- let v = interp_genarg x in
- !evdref , v
-
+ ans
+ | PairArg (wit1, wit2) ->
+ let (p, q) = x in
+ interp_genarg ist (Genarg.in_gen (glbwit wit1) p) >>= fun p ->
+ interp_genarg ist (Genarg.in_gen (glbwit wit2) q) >>= fun q ->
+ let p = Value.cast (topwit wit1) p in
+ let q = Value.cast (topwit wit2) q in
+ Ftactic.return (Val.Dyn (Val.Pair (val_tag wit1, val_tag wit2), (p, q)))
+ | ExtraArg s ->
+ Geninterp.generic_interp ist (Genarg.in_gen (glbwit wit) x)
(** returns [true] for genargs which have the same meaning
independently of goals. *)
-and global_genarg =
- let rec global_tag = function
- | IntOrVarArgType | GenArgType -> true
- | ListArgType t | OptArgType t -> global_tag t
- | PairArgType (t1,t2) -> global_tag t1 && global_tag t2
- | _ -> false
- in
- fun x -> global_tag (genarg_tag x)
-
-and interp_genarg_constr_list ist env sigma x =
- let lc = out_gen (glbwit (wit_list wit_constr)) x in
+and interp_genarg_constr_list ist x =
+ Ftactic.nf_s_enter { s_enter = begin fun gl ->
+ let env = Proofview.Goal.env gl in
+ let sigma = Sigma.to_evar_map (Proofview.Goal.sigma gl) in
+ let lc = Genarg.out_gen (glbwit (wit_list wit_constr)) x in
let (sigma,lc) = interp_constr_list ist env sigma lc in
- sigma , in_gen (topwit (wit_list wit_constr)) lc
+ let lc = Value.of_list (val_tag wit_constr) lc in
+ Sigma.Unsafe.of_pair (Ftactic.return lc, sigma)
+ end }
-and interp_genarg_var_list ist env sigma x =
- let lc = out_gen (glbwit (wit_list wit_var)) x in
+and interp_genarg_var_list ist x =
+ Ftactic.nf_enter { enter = begin fun gl ->
+ let env = Proofview.Goal.env gl in
+ let sigma = Sigma.to_evar_map (Proofview.Goal.sigma gl) in
+ let lc = Genarg.out_gen (glbwit (wit_list wit_var)) x in
let lc = interp_hyp_list ist env sigma lc in
- in_gen (topwit (wit_list wit_var)) lc
+ Ftactic.return (Value.of_list (val_tag wit_var) lc)
+ end }
(* Interprets tactic expressions : returns a "constr" *)
and interp_ltac_constr ist e : constr Ftactic.t =
@@ -1740,7 +1628,7 @@ and interp_ltac_constr ist e : constr Ftactic.t =
(val_interp ist e)
begin function (err, info) -> match err with
| Not_found ->
- Ftactic.enter begin fun gl ->
+ Ftactic.enter { enter = begin fun gl ->
let env = Proofview.Goal.env gl in
Proofview.tclLIFT begin
debugging_step ist (fun () ->
@@ -1748,13 +1636,13 @@ and interp_ltac_constr ist e : constr Ftactic.t =
Pptactic.pr_glob_tactic env e)
end
<*> Proofview.tclZERO Not_found
- end
+ end }
| err -> Proofview.tclZERO ~info err
end
end >>= fun result ->
- Ftactic.enter begin fun gl ->
+ Ftactic.enter { enter = begin fun gl ->
let env = Proofview.Goal.env gl in
- let sigma = Proofview.Goal.sigma gl in
+ let sigma = Tacmach.New.project gl in
let result = Value.normalize result in
try
let cresult = coerce_to_closed_constr env result in
@@ -1769,7 +1657,7 @@ and interp_ltac_constr ist e : constr Ftactic.t =
let env = Proofview.Goal.env gl in
Tacticals.New.tclZEROMSG (str "Must evaluate to a closed term" ++ fnl() ++
str "offending expression: " ++ fnl() ++ pr_inspect env e result)
- end
+ end }
(* Interprets tactic expressions : returns a "tactic" *)
@@ -1790,27 +1678,27 @@ and interp_atomic ist tac : unit Proofview.tactic =
match tac with
(* Basic tactics *)
| TacIntroPattern l ->
- Proofview.Goal.enter begin fun gl ->
+ Proofview.Goal.enter { enter = begin fun gl ->
let env = Proofview.Goal.env gl in
- let sigma = Proofview.Goal.sigma gl in
+ let sigma = Tacmach.New.project gl in
let sigma,l' = interp_intro_pattern_list_as_list ist env sigma l in
Tacticals.New.tclWITHHOLES false
(name_atomic ~env
(TacIntroPattern l)
(* spiwack: print uninterpreted, not sure if it is the
expected behaviour. *)
- (Tactics.intros_patterns l')) sigma
- end
+ (Tactics.intro_patterns l')) sigma
+ end }
| TacIntroMove (ido,hto) ->
- Proofview.Goal.enter begin fun gl ->
+ Proofview.Goal.enter { enter = begin fun gl ->
let env = Proofview.Goal.env gl in
- let sigma = Proofview.Goal.sigma gl in
+ let sigma = Tacmach.New.project gl in
let mloc = interp_move_location ist env sigma hto in
let ido = Option.map (interp_ident ist env sigma) ido in
name_atomic ~env
(TacIntroMove(ido,mloc))
(Tactics.intro_move ido mloc)
- end
+ end }
| TacExact c ->
(* spiwack: until the tactic is in the monad *)
Proofview.Trace.name_tactic (fun () -> Pp.str"<exact>") begin
@@ -1825,9 +1713,9 @@ and interp_atomic ist tac : unit Proofview.tactic =
| TacApply (a,ev,cb,cl) ->
(* spiwack: until the tactic is in the monad *)
Proofview.Trace.name_tactic (fun () -> Pp.str"<apply>") begin
- Proofview.Goal.enter begin fun gl ->
+ Proofview.Goal.enter { enter = begin fun gl ->
let env = Proofview.Goal.env gl in
- let sigma = Proofview.Goal.sigma gl in
+ let sigma = Tacmach.New.project gl in
let l = List.map (fun (k,c) ->
let loc, f = interp_open_constr_with_bindings_loc ist c in
(k,(loc,f))) cb
@@ -1838,12 +1726,12 @@ and interp_atomic ist tac : unit Proofview.tactic =
let sigma,(id,cl) = interp_in_hyp_as ist env sigma cl in
sigma, Tactics.apply_delayed_in a ev id l cl in
Tacticals.New.tclWITHHOLES ev tac sigma
- end
+ end }
end
| TacElim (ev,(keep,cb),cbo) ->
- Proofview.Goal.enter begin fun gl ->
+ Proofview.Goal.enter { enter = begin fun gl ->
let env = Proofview.Goal.env gl in
- let sigma = Proofview.Goal.sigma gl in
+ let sigma = Tacmach.New.project gl in
let sigma, cb = interp_constr_with_bindings ist env sigma cb in
let sigma, cbo = Option.fold_map (interp_constr_with_bindings ist env) sigma cbo in
let named_tac =
@@ -1851,10 +1739,10 @@ and interp_atomic ist tac : unit Proofview.tactic =
name_atomic ~env (TacElim (ev,(keep,cb),cbo)) tac
in
Tacticals.New.tclWITHHOLES ev named_tac sigma
- end
+ end }
| TacCase (ev,(keep,cb)) ->
- Proofview.Goal.enter begin fun gl ->
- let sigma = Proofview.Goal.sigma gl in
+ Proofview.Goal.enter { enter = begin fun gl ->
+ let sigma = Tacmach.New.project gl in
let env = Proofview.Goal.env gl in
let sigma, cb = interp_constr_with_bindings ist env sigma cb in
let named_tac =
@@ -1862,16 +1750,16 @@ and interp_atomic ist tac : unit Proofview.tactic =
name_atomic ~env (TacCase(ev,(keep,cb))) tac
in
Tacticals.New.tclWITHHOLES ev named_tac sigma
- end
+ end }
| TacFix (idopt,n) ->
- Proofview.Goal.enter begin fun gl ->
+ Proofview.Goal.enter { enter = begin fun gl ->
let env = Proofview.Goal.env gl in
- let sigma = Proofview.Goal.sigma gl in
+ let sigma = Tacmach.New.project gl in
let idopt = Option.map (interp_ident ist env sigma) idopt in
name_atomic ~env
(TacFix(idopt,n))
(Proofview.V82.tactic (Tactics.fix idopt n))
- end
+ end }
| TacMutualFix (id,n,l) ->
(* spiwack: until the tactic is in the monad *)
Proofview.Trace.name_tactic (fun () -> Pp.str"<mutual fix>") begin
@@ -1890,14 +1778,14 @@ and interp_atomic ist tac : unit Proofview.tactic =
end
end
| TacCofix idopt ->
- Proofview.Goal.enter begin fun gl ->
+ Proofview.Goal.enter { enter = begin fun gl ->
let env = Proofview.Goal.env gl in
- let sigma = Proofview.Goal.sigma gl in
+ let sigma = Tacmach.New.project gl in
let idopt = Option.map (interp_ident ist env sigma) idopt in
name_atomic ~env
(TacCofix (idopt))
(Proofview.V82.tactic (Tactics.cofix idopt))
- end
+ end }
| TacMutualCofix (id,l) ->
(* spiwack: until the tactic is in the monad *)
Proofview.Trace.name_tactic (fun () -> Pp.str"<mutual cofix>") begin
@@ -1916,9 +1804,9 @@ and interp_atomic ist tac : unit Proofview.tactic =
end
end
| TacAssert (b,t,ipat,c) ->
- Proofview.Goal.enter begin fun gl ->
+ Proofview.Goal.enter { enter = begin fun gl ->
let env = Proofview.Goal.env gl in
- let sigma = Proofview.Goal.sigma gl in
+ let sigma = Tacmach.New.project gl in
let (sigma,c) =
(if Option.is_empty t then interp_constr else interp_type) ist env sigma c
in
@@ -1928,17 +1816,17 @@ and interp_atomic ist tac : unit Proofview.tactic =
(name_atomic ~env
(TacAssert(b,t,ipat,c))
(Tactics.forward b tac ipat' c)) sigma
- end
+ end }
| TacGeneralize cl ->
- Proofview.Goal.enter begin fun gl ->
- let sigma = Proofview.Goal.sigma gl in
+ Proofview.Goal.enter { enter = begin fun gl ->
+ let sigma = Tacmach.New.project gl in
let env = Proofview.Goal.env gl in
let sigma, cl = interp_constr_with_occurrences_and_name_as_list ist env sigma cl in
Tacticals.New.tclWITHHOLES false
(name_atomic ~env
(TacGeneralize cl)
- (Proofview.V82.tactic (Tactics.Simple.generalize_gen cl))) sigma
- end
+ (Proofview.V82.tactic (Tactics.generalize_gen cl))) sigma
+ end }
| TacGeneralizeDep c ->
(new_interp_constr ist c) (fun c ->
name_atomic (* spiwack: probably needs a goal environment *)
@@ -1947,9 +1835,9 @@ and interp_atomic ist tac : unit Proofview.tactic =
)
| TacLetTac (na,c,clp,b,eqpat) ->
Proofview.V82.nf_evar_goals <*>
- Proofview.Goal.nf_enter begin fun gl ->
+ Proofview.Goal.nf_enter { enter = begin fun gl ->
let env = Proofview.Goal.env gl in
- let sigma = Proofview.Goal.sigma gl in
+ let sigma = Tacmach.New.project gl in
let clp = interp_clause ist env sigma clp in
let eqpat = interp_intro_pattern_naming_option ist env sigma eqpat in
if Locusops.is_nowhere clp then
@@ -1980,58 +1868,22 @@ and interp_atomic ist tac : unit Proofview.tactic =
(Tacticals.New.tclWITHHOLES false (*in hope of a future "eset/epose"*)
(let_pat_tac b (interp_name ist env sigma na)
((sigma,sigma'),c) clp eqpat) sigma')
- end
-
- (* Automation tactics *)
- | TacTrivial (debug,lems,l) ->
- begin if debug == Tacexpr.Info then
- msg_warning
- (strbrk"The \"info_trivial\" tactic" ++ spc ()
- ++strbrk"does not print traces anymore." ++ spc()
- ++strbrk"Use \"Info 1 trivial\", instead.")
- end;
- Proofview.Goal.enter begin fun gl ->
- let env = Proofview.Goal.env gl in
- let sigma = Proofview.Goal.sigma gl in
- let lems = interp_auto_lemmas ist env sigma lems in
- name_atomic ~env
- (TacTrivial(debug,List.map snd lems,l))
- (Auto.h_trivial ~debug
- lems
- (Option.map (List.map (interp_hint_base ist)) l))
- end
- | TacAuto (debug,n,lems,l) ->
- begin if debug == Tacexpr.Info then
- msg_warning
- (strbrk"The \"info_auto\" tactic" ++ spc ()
- ++strbrk"does not print traces anymore." ++ spc()
- ++strbrk"Use \"Info 1 auto\", instead.")
- end;
- Proofview.Goal.enter begin fun gl ->
- let env = Proofview.Goal.env gl in
- let sigma = Proofview.Goal.sigma gl in
- let lems = interp_auto_lemmas ist env sigma lems in
- name_atomic ~env
- (TacAuto(debug,n,List.map snd lems,l))
- (Auto.h_auto ~debug (Option.map (interp_int_or_var ist) n)
- lems
- (Option.map (List.map (interp_hint_base ist)) l))
- end
+ end }
(* Derived basic tactics *)
| TacInductionDestruct (isrec,ev,(l,el)) ->
(* spiwack: some unknown part of destruct needs the goal to be
prenormalised. *)
Proofview.V82.nf_evar_goals <*>
- Proofview.Goal.nf_enter begin fun gl ->
+ Proofview.Goal.nf_s_enter { s_enter = begin fun gl ->
let env = Proofview.Goal.env gl in
- let sigma = Proofview.Goal.sigma gl in
+ let sigma = Tacmach.New.project gl in
let sigma,l =
List.fold_map begin fun sigma (c,(ipato,ipats),cls) ->
(* TODO: move sigma as a side-effect *)
(* spiwack: the [*p] variants are for printing *)
let cp = c in
- let c = Tacmach.New.of_old (fun gl -> interp_induction_arg ist gl c) gl in
+ let c = interp_induction_arg ist gl c in
let ipato = interp_intro_pattern_naming_option ist env sigma ipato in
let ipatsp = ipats in
let sigma,ipats = interp_or_and_intro_pattern_option ist env sigma ipats in
@@ -2042,12 +1894,12 @@ and interp_atomic ist tac : unit Proofview.tactic =
let l,lp = List.split l in
let sigma,el =
Option.fold_map (interp_constr_with_bindings ist env) sigma el in
- name_atomic ~env
+ let tac = name_atomic ~env
(TacInductionDestruct(isrec,ev,(lp,el)))
- (Tacticals.New.tclTHEN
- (Proofview.Unsafe.tclEVARS sigma)
- (Tactics.induction_destruct isrec ev (l,el)))
- end
+ (Tactics.induction_destruct isrec ev (l,el))
+ in
+ Sigma.Unsafe.of_pair (tac, sigma)
+ end }
| TacDoubleInduction (h1,h2) ->
let h1 = interp_quantified_hypothesis ist h1 in
let h2 = interp_quantified_hypothesis ist h2 in
@@ -2056,25 +1908,25 @@ and interp_atomic ist tac : unit Proofview.tactic =
(Elim.h_double_induction h1 h2)
(* Context management *)
| TacClear (b,l) ->
- Proofview.Goal.enter begin fun gl ->
+ Proofview.Goal.enter { enter = begin fun gl ->
let env = Tacmach.New.pf_env gl in
- let sigma = Proofview.Goal.sigma gl in
+ let sigma = Tacmach.New.project gl in
let l = interp_hyp_list ist env sigma l in
if b then name_atomic ~env (TacClear (b, l)) (Tactics.keep l)
else
(* spiwack: until the tactic is in the monad *)
let tac = Proofview.V82.tactic (fun gl -> Tactics.clear l gl) in
Proofview.Trace.name_tactic (fun () -> Pp.str"<clear>") tac
- end
+ end }
| TacClearBody l ->
- Proofview.Goal.enter begin fun gl ->
+ Proofview.Goal.enter { enter = begin fun gl ->
let env = Tacmach.New.pf_env gl in
- let sigma = Proofview.Goal.sigma gl in
+ let sigma = Tacmach.New.project gl in
let l = interp_hyp_list ist env sigma l in
name_atomic ~env
(TacClearBody l)
(Tactics.clear_body l)
- end
+ end }
| TacMove (id1,id2) ->
Proofview.V82.tactic begin fun gl ->
Tactics.move_hyp (interp_hyp ist (pf_env gl) (project gl) id1)
@@ -2082,9 +1934,9 @@ and interp_atomic ist tac : unit Proofview.tactic =
gl
end
| TacRename l ->
- Proofview.Goal.enter begin fun gl ->
+ Proofview.Goal.enter { enter = begin fun gl ->
let env = Tacmach.New.pf_env gl in
- let sigma = Proofview.Goal.sigma gl in
+ let sigma = Tacmach.New.project gl in
let l =
List.map (fun (id1,id2) ->
interp_hyp ist env sigma id1,
@@ -2093,20 +1945,20 @@ and interp_atomic ist tac : unit Proofview.tactic =
name_atomic ~env
(TacRename l)
(Tactics.rename_hyp l)
- end
+ end }
(* Constructors *)
| TacSplit (ev,bll) ->
- Proofview.Goal.enter begin fun gl ->
+ Proofview.Goal.enter { enter = begin fun gl ->
let env = Proofview.Goal.env gl in
- let sigma = Proofview.Goal.sigma gl in
+ let sigma = Tacmach.New.project gl in
let sigma, bll = List.fold_map (interp_bindings ist env) sigma bll in
let named_tac =
let tac = Tactics.split_with_bindings ev bll in
name_atomic ~env (TacSplit (ev, bll)) tac
in
Tacticals.New.tclWITHHOLES ev named_tac sigma
- end
+ end }
(* Conversion *)
| TacReduce (r,cl) ->
(* spiwack: until the tactic is in the monad *)
@@ -2132,16 +1984,20 @@ and interp_atomic ist tac : unit Proofview.tactic =
| AllOccurrences | NoOccurrences -> true
| _ -> false
in
- let c_interp patvars sigma =
+ let c_interp patvars = { Sigma.run = begin fun sigma ->
let lfun' = Id.Map.fold (fun id c lfun ->
Id.Map.add id (Value.of_constr c) lfun)
patvars ist.lfun
in
+ let sigma = Sigma.to_evar_map sigma in
let ist = { ist with lfun = lfun' } in
- if is_onhyps && is_onconcl
- then interp_type ist (pf_env gl) sigma c
- else interp_constr ist (pf_env gl) sigma c
- in
+ let (sigma, c) =
+ if is_onhyps && is_onconcl
+ then interp_type ist (pf_env gl) sigma c
+ else interp_constr ist (pf_env gl) sigma c
+ in
+ Sigma.Unsafe.of_pair (c, sigma)
+ end } in
(Tactics.change None c_interp (interp_clause ist (pf_env gl) (project gl) cl))
gl
end
@@ -2150,47 +2006,54 @@ and interp_atomic ist tac : unit Proofview.tactic =
(* spiwack: until the tactic is in the monad *)
Proofview.Trace.name_tactic (fun () -> Pp.str"<change>") begin
Proofview.V82.nf_evar_goals <*>
- Proofview.Goal.enter begin fun gl ->
+ Proofview.Goal.enter { enter = begin fun gl ->
let env = Proofview.Goal.env gl in
- let sigma = Proofview.Goal.sigma gl in
+ let sigma = Tacmach.New.project gl in
Proofview.V82.tactic begin fun gl ->
let op = interp_typed_pattern ist env sigma op in
let to_catch = function Not_found -> true | e -> Errors.is_anomaly e in
- let c_interp patvars sigma =
+ let c_interp patvars = { Sigma.run = begin fun sigma ->
let lfun' = Id.Map.fold (fun id c lfun ->
Id.Map.add id (Value.of_constr c) lfun)
patvars ist.lfun
in
let ist = { ist with lfun = lfun' } in
- try interp_constr ist env sigma c
+ try
+ let sigma = Sigma.to_evar_map sigma in
+ let (sigma, c) = interp_constr ist env sigma c in
+ Sigma.Unsafe.of_pair (c, sigma)
with e when to_catch e (* Hack *) ->
errorlabstrm "" (strbrk "Failed to get enough information from the left-hand side to type the right-hand side.")
- in
+ end } in
(Tactics.change (Some op) c_interp (interp_clause ist env sigma cl))
gl
end
- end
+ end }
end
(* Equivalence relations *)
| TacSymmetry c ->
- Proofview.Goal.enter begin fun gl ->
+ Proofview.Goal.enter { enter = begin fun gl ->
let env = Proofview.Goal.env gl in
- let sigma = Proofview.Goal.sigma gl in
+ let sigma = Tacmach.New.project gl in
let cl = interp_clause ist env sigma c in
name_atomic ~env
(TacSymmetry cl)
(Tactics.intros_symmetry cl)
- end
+ end }
(* Equality and inversion *)
| TacRewrite (ev,l,cl,by) ->
- Proofview.Goal.enter begin fun gl ->
+ Proofview.Goal.enter { enter = begin fun gl ->
let l' = List.map (fun (b,m,(keep,c)) ->
- let f env sigma = interp_open_constr_with_bindings ist env sigma c in
+ let f = { delayed = fun env sigma ->
+ let sigma = Sigma.to_evar_map sigma in
+ let (sigma, c) = interp_open_constr_with_bindings ist env sigma c in
+ Sigma.Unsafe.of_pair (c, sigma)
+ } in
(b,m,keep,f)) l in
let env = Proofview.Goal.env gl in
- let sigma = Proofview.Goal.sigma gl in
+ let sigma = Tacmach.New.project gl in
let cl = interp_clause ist env sigma cl in
name_atomic ~env
(TacRewrite (ev,l,cl,by))
@@ -2198,11 +2061,11 @@ and interp_atomic ist tac : unit Proofview.tactic =
(Option.map (fun by -> Tacticals.New.tclCOMPLETE (interp_tactic ist by),
Equality.Naive)
by))
- end
+ end }
| TacInversion (DepInversion (k,c,ids),hyp) ->
- Proofview.Goal.nf_enter begin fun gl ->
+ Proofview.Goal.nf_enter { enter = begin fun gl ->
let env = Proofview.Goal.env gl in
- let sigma = Proofview.Goal.sigma gl in
+ let sigma = Tacmach.New.project gl in
let (sigma,c_interp) =
match c with
| None -> sigma , None
@@ -2218,11 +2081,11 @@ and interp_atomic ist tac : unit Proofview.tactic =
(name_atomic ~env
(TacInversion(DepInversion(k,c_interp,ids),dqhyps))
(Inv.dinv k c_interp ids_interp dqhyps)) sigma
- end
+ end }
| TacInversion (NonDepInversion (k,idl,ids),hyp) ->
- Proofview.Goal.enter begin fun gl ->
+ Proofview.Goal.enter { enter = begin fun gl ->
let env = Proofview.Goal.env gl in
- let sigma = Proofview.Goal.sigma gl in
+ let sigma = Tacmach.New.project gl in
let hyps = interp_hyp_list ist env sigma idl in
let dqhyps = interp_declared_or_quantified_hypothesis ist env sigma hyp in
let sigma, ids_interp = interp_or_and_intro_pattern_option ist env sigma ids in
@@ -2230,19 +2093,20 @@ and interp_atomic ist tac : unit Proofview.tactic =
(name_atomic ~env
(TacInversion (NonDepInversion (k,hyps,ids),dqhyps))
(Inv.inv_clause k ids_interp hyps dqhyps)) sigma
- end
+ end }
| TacInversion (InversionUsing (c,idl),hyp) ->
- Proofview.Goal.enter begin fun gl ->
+ Proofview.Goal.s_enter { s_enter = begin fun gl ->
let env = Proofview.Goal.env gl in
- let sigma = Proofview.Goal.sigma gl in
+ let sigma = Tacmach.New.project gl in
let (sigma,c_interp) = interp_constr ist env sigma c in
let dqhyps = interp_declared_or_quantified_hypothesis ist env sigma hyp in
let hyps = interp_hyp_list ist env sigma idl in
- Proofview.Unsafe.tclEVARS sigma <*>
- name_atomic ~env
+ let tac = name_atomic ~env
(TacInversion (InversionUsing (c_interp,hyps),dqhyps))
(Leminv.lemInv_clause dqhyps c_interp hyps)
- end
+ in
+ Sigma.Unsafe.of_pair (tac, sigma)
+ end }
(* Initial call for interpretation *)
@@ -2263,7 +2127,7 @@ let eval_tactic_ist ist t =
let interp_tac_gen lfun avoid_ids debug t =
- Proofview.Goal.enter begin fun gl ->
+ Proofview.Goal.enter { enter = begin fun gl ->
let env = Proofview.Goal.env gl in
let extra = TacStore.set TacStore.empty f_debug debug in
let extra = TacStore.set extra f_avoid_ids avoid_ids in
@@ -2272,7 +2136,7 @@ let interp_tac_gen lfun avoid_ids debug t =
interp_tactic ist
(intern_pure_tactic {
ltacvars; genv = env } t)
- end
+ end }
let interp t = interp_tac_gen Id.Map.empty [] (get_debug()) t
let _ = Proof_global.set_interp_tac interp
@@ -2292,16 +2156,16 @@ let hide_interp global t ot =
Proofview.tclENV >>= fun env ->
hide_interp env
else
- Proofview.Goal.enter begin fun gl ->
+ Proofview.Goal.enter { enter = begin fun gl ->
hide_interp (Proofview.Goal.env gl)
- end
+ end }
(***************************************************************************)
(** Register standard arguments *)
let def_intern ist x = (ist, x)
let def_subst _ x = x
-let def_interp ist gl x = (project gl, x)
+let def_interp ist x = Ftactic.return x
let declare_uniform t =
Genintern.register_intern0 t def_intern;
@@ -2323,27 +2187,58 @@ let () =
let () =
declare_uniform wit_pre_ident
+let lift f = (); fun ist x -> Ftactic.nf_enter { enter = begin fun gl ->
+ let env = Proofview.Goal.env gl in
+ let sigma = Sigma.to_evar_map (Proofview.Goal.sigma gl) in
+ Ftactic.return (f ist env sigma x)
+end }
+
+let lifts f = (); fun ist x -> Ftactic.nf_s_enter { s_enter = begin fun gl ->
+ let env = Proofview.Goal.env gl in
+ let sigma = Sigma.to_evar_map (Proofview.Goal.sigma gl) in
+ let (sigma, v) = f ist env sigma x in
+ Sigma.Unsafe.of_pair (Ftactic.return v, sigma)
+end }
+
+let interp_bindings' ist bl = Ftactic.return { delayed = fun env sigma ->
+ let (sigma, bl) = interp_bindings ist env (Sigma.to_evar_map sigma) bl in
+ Sigma.Unsafe.of_pair (bl, sigma)
+ }
+
+let interp_constr_with_bindings' ist c = Ftactic.return { delayed = fun env sigma ->
+ let (sigma, c) = interp_constr_with_bindings ist env (Sigma.to_evar_map sigma) c in
+ Sigma.Unsafe.of_pair (c, sigma)
+ }
+
let () =
- let interp ist gl ref = (project gl, interp_reference ist (pf_env gl) (project gl) ref) in
- Geninterp.register_interp0 wit_ref interp;
- let interp ist gl pat = interp_intro_pattern ist (pf_env gl) (project gl) pat in
- Geninterp.register_interp0 wit_intro_pattern interp;
- let interp ist gl pat = (project gl, interp_clause ist (pf_env gl) (project gl) pat) in
- Geninterp.register_interp0 wit_clause_dft_concl interp;
- let interp ist gl s = interp_sort (project gl) s in
- Geninterp.register_interp0 wit_sort interp
+ Geninterp.register_interp0 wit_int_or_var (fun ist n -> Ftactic.return (interp_int_or_var ist n));
+ Geninterp.register_interp0 wit_ref (lift interp_reference);
+ Geninterp.register_interp0 wit_ident (lift interp_ident);
+ Geninterp.register_interp0 wit_var (lift interp_hyp);
+ Geninterp.register_interp0 wit_intro_pattern (lifts interp_intro_pattern);
+ Geninterp.register_interp0 wit_clause_dft_concl (lift interp_clause);
+ Geninterp.register_interp0 wit_constr (lifts interp_constr);
+ Geninterp.register_interp0 wit_sort (lifts (fun _ _ evd s -> interp_sort evd s));
+ Geninterp.register_interp0 wit_tacvalue (fun ist v -> Ftactic.return v);
+ Geninterp.register_interp0 wit_red_expr (lifts interp_red_expr);
+ Geninterp.register_interp0 wit_quant_hyp (lift interp_declared_or_quantified_hypothesis);
+ Geninterp.register_interp0 wit_open_constr (lifts interp_open_constr);
+ Geninterp.register_interp0 wit_bindings interp_bindings';
+ Geninterp.register_interp0 wit_constr_with_bindings interp_constr_with_bindings';
+ Geninterp.register_interp0 wit_constr_may_eval (lifts interp_constr_may_eval);
+ ()
let () =
- let interp ist gl tac =
+ let interp ist tac =
let f = VFun (UnnamedAppl,extract_trace ist, ist.lfun, [], tac) in
- (project gl, TacArg (dloc, valueIn (of_tacvalue f)))
+ Ftactic.return (TacArg (dloc, TacGeneric (Genarg.in_gen (glbwit wit_tacvalue) f)))
in
Geninterp.register_interp0 wit_tactic interp
let () =
- Geninterp.register_interp0 wit_uconstr (fun ist gl c ->
- project gl , interp_uconstr ist (pf_env gl) c
- )
+ Geninterp.register_interp0 wit_uconstr (fun ist c -> Ftactic.nf_enter { enter = begin fun gl ->
+ Ftactic.return (interp_uconstr ist (Proofview.Goal.env gl) c)
+ end })
(***************************************************************************)
(* Other entry points *)
@@ -2358,24 +2253,13 @@ let interp_redexp env sigma r =
interp_red_expr ist env sigma (intern_red_expr gist r)
(***************************************************************************)
-(* Embed tactics in raw or glob tactic expr *)
-
-let globTacticIn t = TacArg (dloc,TacDynamic (dloc,tactic_in t))
-let tacticIn t =
- globTacticIn (fun ist ->
- try glob_tactic (t ist)
- with e when Errors.noncritical e -> anomaly ~label:"tacticIn"
- (str "Incorrect tactic expression. Received exception is:" ++
- Errors.print e))
-
-(***************************************************************************)
(* Backwarding recursive needs of tactic glob/interp/eval functions *)
let _ =
let eval ty env sigma lfun arg =
let ist = { lfun = lfun; extra = TacStore.empty; } in
- if has_type arg (glbwit wit_tactic) then
- let tac = out_gen (glbwit wit_tactic) arg in
+ if Genarg.has_type arg (glbwit wit_tactic) then
+ let tac = Genarg.out_gen (glbwit wit_tactic) arg in
let tac = interp_tactic ist tac in
Pfedit.refine_by_tactic env sigma ty tac
else
@@ -2394,9 +2278,9 @@ let _ = Hook.set Auto.extern_interp
let dummy_id = Id.of_string "_"
let lift_constr_tac_to_ml_tac vars tac =
- let tac _ ist = Proofview.Goal.enter begin fun gl ->
+ let tac _ ist = Proofview.Goal.enter { enter = begin fun gl ->
let env = Proofview.Goal.env gl in
- let sigma = Proofview.Goal.sigma gl in
+ let sigma = Tacmach.New.project gl in
let map = function
| None -> None
| Some id ->
@@ -2407,5 +2291,5 @@ let lift_constr_tac_to_ml_tac vars tac =
in
let args = List.map_filter map vars in
tac args ist
- end in
+ end } in
tac
diff --git a/tactics/tacinterp.mli b/tactics/tacinterp.mli
index ac7e2149e..89d34231b 100644
--- a/tactics/tacinterp.mli
+++ b/tactics/tacinterp.mli
@@ -16,13 +16,14 @@ open Misctypes
module Value :
sig
- type t = tlevel generic_argument
+ type t = Val.t
val of_constr : constr -> t
val to_constr : t -> constr option
val of_int : int -> t
val to_int : t -> int option
val to_list : t -> t list option
val of_closure : Geninterp.interp_sign -> glob_tactic_expr -> t
+ val cast : 'a typed_abstract_argument_type -> Val.t -> 'a
end
(** Values for interpretation *)
@@ -45,14 +46,6 @@ val extract_ltac_constr_values : interp_sign -> Environ.env ->
(** Given an interpretation signature, extract all values which are coercible to
a [constr]. *)
-(** To embed several objects in Coqast.t *)
-val tactic_in : (interp_sign -> glob_tactic_expr) -> Dyn.t
-val tactic_out : Dyn.t -> (interp_sign -> glob_tactic_expr)
-
-val tacticIn : (interp_sign -> raw_tactic_expr) -> raw_tactic_expr
-val globTacticIn : (interp_sign -> glob_tactic_expr) -> raw_tactic_expr
-val valueIn : value -> raw_tactic_arg
-
(** Sets the debugger mode *)
val set_debug : debug_info -> unit
@@ -61,10 +54,7 @@ val get_debug : unit -> debug_info
(** Adds an interpretation function for extra generic arguments *)
-(* spiwack: the [Term.constr] argument is the conclusion of the goal,
- for "casted open constr" *)
-val interp_genarg : interp_sign -> Environ.env -> Evd.evar_map -> Term.constr -> Goal.goal ->
- glob_generic_argument -> Evd.evar_map * typed_generic_argument
+val interp_genarg : interp_sign -> glob_generic_argument -> Value.t Ftactic.t
(** Interprets any expression *)
val val_interp : interp_sign -> glob_tactic_expr -> (value -> unit Proofview.tactic) -> unit Proofview.tactic
@@ -72,6 +62,11 @@ val val_interp : interp_sign -> glob_tactic_expr -> (value -> unit Proofview.tac
(** Interprets an expression that evaluates to a constr *)
val interp_ltac_constr : interp_sign -> glob_tactic_expr -> (constr -> unit Proofview.tactic) -> unit Proofview.tactic
+val type_uconstr :
+ ?flags:Pretyping.inference_flags ->
+ ?expected_type:Pretyping.typing_constraint ->
+ interp_sign -> Glob_term.closed_glob_constr -> constr delayed_open
+
(** Interprets redexp arguments *)
val interp_redexp : Environ.env -> Evd.evar_map -> raw_red_expr -> Evd.evar_map * red_expr
diff --git a/tactics/tacsubst.ml b/tactics/tacsubst.ml
index cef630da3..dd851b5c0 100644
--- a/tactics/tacsubst.ml
+++ b/tactics/tacsubst.ml
@@ -54,10 +54,16 @@ and subst_intro_pattern_action subst = function
| IntroApplyOn (t,pat) ->
IntroApplyOn (subst_glob_constr subst t,subst_intro_pattern subst pat)
| IntroOrAndPattern l ->
- IntroOrAndPattern (List.map (List.map (subst_intro_pattern subst)) l)
+ IntroOrAndPattern (subst_intro_or_and_pattern subst l)
| IntroInjection l -> IntroInjection (List.map (subst_intro_pattern subst) l)
| IntroWildcard | IntroRewrite _ as x -> x
+and subst_intro_or_and_pattern subst = function
+ | IntroAndPattern l ->
+ IntroAndPattern (List.map (subst_intro_pattern subst) l)
+ | IntroOrPattern ll ->
+ IntroOrPattern (List.map (List.map (subst_intro_pattern subst)) ll)
+
let subst_induction_arg subst = function
| clear,ElimOnConstr c -> clear,ElimOnConstr (subst_glob_with_bindings subst c)
| clear,ElimOnAnonHyp n as x -> x
@@ -154,10 +160,6 @@ let rec subst_atomic subst (t:glob_atomic_tactic_expr) = match t with
| TacLetTac (id,c,clp,b,eqpat) ->
TacLetTac (id,subst_glob_constr subst c,clp,b,eqpat)
- (* Automation tactics *)
- | TacTrivial (d,lems,l) -> TacTrivial (d,List.map (subst_glob_constr subst) lems,l)
- | TacAuto (d,n,lems,l) -> TacAuto (d,n,List.map (subst_glob_constr subst) lems,l)
-
(* Derived basic tactics *)
| TacInductionDestruct (isrec,ev,(l,el)) ->
let l' = List.map (fun (c,ids,cls) ->
@@ -249,8 +251,8 @@ and subst_tactic subst (t:glob_tactic_expr) = match t with
(* For extensions *)
| TacAlias (_,s,l) ->
let s = subst_kn subst s in
- TacAlias (dloc,s,List.map (fun (id,a) -> (id,subst_genarg subst a)) l)
- | TacML (_loc,opn,l) -> TacML (dloc,opn,List.map (subst_genarg subst) l)
+ TacAlias (dloc,s,List.map (subst_tacarg subst) l)
+ | TacML (_loc,opn,l) -> TacML (dloc,opn,List.map (subst_tacarg subst) l)
and subst_tactic_fun subst (var,body) = (var,subst_tactic subst body)
@@ -265,14 +267,7 @@ and subst_tacarg subst = function
| TacPretype c -> TacPretype (subst_glob_constr subst c)
| TacNumgoals -> TacNumgoals
| Tacexp t -> Tacexp (subst_tactic subst t)
- | TacGeneric arg -> TacGeneric (Genintern.generic_substitute subst arg)
- | TacDynamic(the_loc,t) as x ->
- (match Dyn.tag t with
- | "tactic" | "value" -> x
- | "constr" ->
- TacDynamic(the_loc, constr_in (subst_mps subst (constr_out t)))
- | s -> Errors.anomaly ~loc:dloc ~label:"Tacinterp.val_interp"
- (str "Unknown dynamic: <" ++ str s ++ str ">"))
+ | TacGeneric arg -> TacGeneric (subst_genarg subst arg)
(* Reads the rules of a Match Context or a Match *)
and subst_match_rule subst = function
@@ -285,66 +280,47 @@ and subst_match_rule subst = function
::(subst_match_rule subst tl)
| [] -> []
-and subst_genarg subst (x:glob_generic_argument) =
- match genarg_tag x with
- | IntOrVarArgType -> in_gen (glbwit wit_int_or_var) (out_gen (glbwit wit_int_or_var) x)
- | IdentArgType ->
- in_gen (glbwit wit_ident) (out_gen (glbwit wit_ident) x)
- | VarArgType -> in_gen (glbwit wit_var) (out_gen (glbwit wit_var) x)
- | GenArgType -> in_gen (glbwit wit_genarg) (subst_genarg subst (out_gen (glbwit wit_genarg) x))
- | ConstrArgType ->
- in_gen (glbwit wit_constr) (subst_glob_constr subst (out_gen (glbwit wit_constr) x))
- | ConstrMayEvalArgType ->
- in_gen (glbwit wit_constr_may_eval) (subst_raw_may_eval subst (out_gen (glbwit wit_constr_may_eval) x))
- | QuantHypArgType ->
- in_gen (glbwit wit_quant_hyp)
- (subst_declared_or_quantified_hypothesis subst
- (out_gen (glbwit wit_quant_hyp) x))
- | RedExprArgType ->
- in_gen (glbwit wit_red_expr) (subst_redexp subst (out_gen (glbwit wit_red_expr) x))
- | OpenConstrArgType ->
- in_gen (glbwit wit_open_constr)
- ((),subst_glob_constr subst (snd (out_gen (glbwit wit_open_constr) x)))
- | ConstrWithBindingsArgType ->
- in_gen (glbwit wit_constr_with_bindings)
- (subst_glob_with_bindings subst (out_gen (glbwit wit_constr_with_bindings) x))
- | BindingsArgType ->
- in_gen (glbwit wit_bindings)
- (subst_bindings subst (out_gen (glbwit wit_bindings) x))
- | ListArgType _ ->
- let list_unpacker wit l =
- let map x =
- let ans = subst_genarg subst (in_gen (glbwit wit) x) in
- out_gen (glbwit wit) ans
- in
- in_gen (glbwit (wit_list wit)) (List.map map (glb l))
+and subst_genarg subst (GenArg (Glbwit wit, x)) =
+ match wit with
+ | ListArg wit ->
+ let map x =
+ let ans = subst_genarg subst (in_gen (glbwit wit) x) in
+ out_gen (glbwit wit) ans
in
- list_unpack { list_unpacker } x
- | OptArgType _ ->
- let opt_unpacker wit o = match glb o with
+ in_gen (glbwit (wit_list wit)) (List.map map x)
+ | OptArg wit ->
+ let ans = match x with
| None -> in_gen (glbwit (wit_opt wit)) None
| Some x ->
let s = out_gen (glbwit wit) (subst_genarg subst (in_gen (glbwit wit) x)) in
in_gen (glbwit (wit_opt wit)) (Some s)
in
- opt_unpack { opt_unpacker } x
- | PairArgType _ ->
- let pair_unpacker wit1 wit2 o =
- let p, q = glb o in
- let p = out_gen (glbwit wit1) (subst_genarg subst (in_gen (glbwit wit1) p)) in
- let q = out_gen (glbwit wit2) (subst_genarg subst (in_gen (glbwit wit2) q)) in
- in_gen (glbwit (wit_pair wit1 wit2)) (p, q)
- in
- pair_unpack { pair_unpacker } x
- | ExtraArgType s ->
- Genintern.generic_substitute subst x
+ ans
+ | PairArg (wit1, wit2) ->
+ let p, q = x in
+ let p = out_gen (glbwit wit1) (subst_genarg subst (in_gen (glbwit wit1) p)) in
+ let q = out_gen (glbwit wit2) (subst_genarg subst (in_gen (glbwit wit2) q)) in
+ in_gen (glbwit (wit_pair wit1 wit2)) (p, q)
+ | ExtraArg s ->
+ Genintern.generic_substitute subst (in_gen (glbwit wit) x)
(** Registering *)
let () =
+ Genintern.register_subst0 wit_int_or_var (fun _ v -> v);
Genintern.register_subst0 wit_ref subst_global_reference;
+ Genintern.register_subst0 wit_ident (fun _ v -> v);
+ Genintern.register_subst0 wit_var (fun _ v -> v);
Genintern.register_subst0 wit_intro_pattern (fun _ v -> v);
Genintern.register_subst0 wit_tactic subst_tactic;
+ Genintern.register_subst0 wit_constr subst_glob_constr;
Genintern.register_subst0 wit_sort (fun _ v -> v);
Genintern.register_subst0 wit_clause_dft_concl (fun _ v -> v);
- Genintern.register_subst0 wit_uconstr (fun subst c -> subst_glob_constr subst c)
+ Genintern.register_subst0 wit_uconstr (fun subst c -> subst_glob_constr subst c);
+ Genintern.register_subst0 wit_open_constr (fun subst c -> subst_glob_constr subst c);
+ Genintern.register_subst0 wit_red_expr subst_redexp;
+ Genintern.register_subst0 wit_quant_hyp subst_declared_or_quantified_hypothesis;
+ Genintern.register_subst0 wit_bindings subst_bindings;
+ Genintern.register_subst0 wit_constr_with_bindings subst_glob_with_bindings;
+ Genintern.register_subst0 wit_constr_may_eval subst_raw_may_eval;
+ ()
diff --git a/tactics/tactic_matching.mli b/tactics/tactic_matching.mli
index d8e6dd0ae..090207bcc 100644
--- a/tactics/tactic_matching.mli
+++ b/tactics/tactic_matching.mli
@@ -43,7 +43,7 @@ val match_term :
val match_goal:
Environ.env ->
Evd.evar_map ->
- Context.named_context ->
+ Context.Named.t ->
Term.constr ->
(Tacexpr.binding_bound_vars * Pattern.constr_pattern, Tacexpr.glob_tactic_expr) Tacexpr.match_rule list ->
Tacexpr.glob_tactic_expr t Proofview.tactic
diff --git a/tactics/tacticals.ml b/tactics/tacticals.ml
index f59224111..bacd8a607 100644
--- a/tactics/tacticals.ml
+++ b/tactics/tacticals.ml
@@ -12,10 +12,10 @@ open Util
open Names
open Term
open Termops
-open Context
open Declarations
open Tacmach
open Clenv
+open Sigma.Notations
(************************************************************************)
(* Tacticals re-exported from the Refiner module *)
@@ -147,14 +147,16 @@ type branch_args = {
largs : constr list; (* its arguments *)
branchnum : int; (* the branch number *)
pred : constr; (* the predicate we used *)
- nassums : int; (* the number of assumptions to be introduced *)
+ nassums : int; (* number of assumptions/letin to be introduced *)
branchsign : bool list; (* the signature of the branch.
- true=recursive argument, false=constant *)
+ true=assumption, false=let-in *)
branchnames : Tacexpr.intro_patterns}
type branch_assumptions = {
- ba : branch_args; (* the branch args *)
- assums : named_context} (* the list of assumptions introduced *)
+ ba : branch_args; (* the branch args *)
+ assums : Context.Named.t} (* the list of assumptions introduced *)
+
+open Misctypes
let fix_empty_or_and_pattern nv l =
(* 1- The syntax does not distinguish between "[ ]" for one clause with no
@@ -162,36 +164,68 @@ let fix_empty_or_and_pattern nv l =
(* 2- More generally, we admit "[ ]" for any disjunctive pattern of
arbitrary length *)
match l with
- | [[]] -> List.make nv []
+ | IntroOrPattern [[]] -> IntroOrPattern (List.make nv [])
| _ -> l
-let check_or_and_pattern_size loc names n =
- if not (Int.equal (List.length names) n) then
- if Int.equal n 1 then
- user_err_loc (loc,"",str "Expects a conjunctive pattern.")
- else
- user_err_loc (loc,"",str "Expects a disjunctive pattern with " ++ int n
- ++ str " branches.")
-
-let compute_induction_names n = function
+let check_or_and_pattern_size loc names branchsigns =
+ let n = Array.length branchsigns in
+ let msg p1 p2 = strbrk "a conjunctive pattern made of " ++ int p1 ++ (if p1 == p2 then mt () else str " or " ++ int p2) ++ str " patterns" in
+ let err1 p1 p2 =
+ user_err_loc (loc,"",str "Expects " ++ msg p1 p2 ++ str ".") in
+ let errn n =
+ user_err_loc (loc,"",str "Expects a disjunctive pattern with " ++ int n
+ ++ str " branches.") in
+ let err1' p1 p2 =
+ user_err_loc (loc,"",strbrk "Expects a disjunctive pattern with 1 branch or " ++ msg p1 p2 ++ str ".") in
+ match names with
+ | IntroAndPattern l ->
+ if not (Int.equal n 1) then errn n;
+ let p1 = List.count (fun x -> x) branchsigns.(0) in
+ let p2 = List.length branchsigns.(0) in
+ let p = List.length l in
+ if not (Int.equal p p1 || Int.equal p p2) ||
+ not (List.for_all (function _,IntroNaming _ | _,IntroAction _ -> true | _,IntroForthcoming _ -> false) l) then err1 p1 p2;
+ if Int.equal p p1 then
+ IntroAndPattern
+ (List.extend branchsigns.(0) (Loc.ghost,IntroNaming IntroAnonymous) l)
+ else
+ names
+ | IntroOrPattern ll ->
+ if not (Int.equal n (List.length ll)) then
+ if Int.equal n 1 then
+ let p1 = List.count (fun x -> x) branchsigns.(0) in
+ let p2 = List.length branchsigns.(0) in
+ err1' p1 p2 else errn n;
+ names
+
+let get_and_check_or_and_pattern loc names branchsigns =
+ let names = check_or_and_pattern_size loc names branchsigns in
+ match names with
+ | IntroAndPattern l -> [|l|]
+ | IntroOrPattern l -> Array.of_list l
+
+let compute_induction_names branchletsigns = function
| None ->
- Array.make n []
+ Array.make (Array.length branchletsigns) []
| Some (loc,names) ->
- let names = fix_empty_or_and_pattern n names in
- check_or_and_pattern_size loc names n;
- Array.of_list names
+ let names = fix_empty_or_and_pattern (Array.length branchletsigns) names in
+ get_and_check_or_and_pattern loc names branchletsigns
-let compute_construtor_signatures isrec ((_,k as ity),u) =
+(* Compute the let-in signature of case analysis or standard induction scheme *)
+let compute_constructor_signatures isrec ((_,k as ity),u) =
let rec analrec c recargs =
match kind_of_term c, recargs with
| Prod (_,_,c), recarg::rest ->
- let b = match Declareops.dest_recarg recarg with
- | Norec | Imbr _ -> false
- | Mrec (_,j) -> isrec && Int.equal j k
- in b :: (analrec c rest)
- | LetIn (_,_,_,c), rest -> false :: (analrec c rest)
+ let rest = analrec c rest in
+ begin match Declareops.dest_recarg recarg with
+ | Norec | Imbr _ -> true :: rest
+ | Mrec (_,j) ->
+ if isrec && Int.equal j k then true :: true :: rest
+ else true :: rest
+ end
+ | LetIn (_,_,_,c), rest -> false :: analrec c rest
| _, [] -> []
- | _ -> anomaly (Pp.str "compute_construtor_signatures")
+ | _ -> anomaly (Pp.str "compute_constructor_signatures")
in
let (mib,mip) = Global.lookup_inductive ity in
let n = mib.mind_nparams in
@@ -225,60 +259,28 @@ let gl_make_elim ind gl =
pf_apply Evd.fresh_global gl gr
let gl_make_case_dep ind gl =
- pf_apply Indrec.build_case_analysis_scheme gl ind true
+ let sigma = Sigma.Unsafe.of_evar_map (Tacmach.project gl) in
+ let Sigma (r, sigma, _) = Indrec.build_case_analysis_scheme (pf_env gl) sigma ind true
(elimination_sort_of_goal gl)
+ in
+ (Sigma.to_evar_map sigma, r)
let gl_make_case_nodep ind gl =
- pf_apply Indrec.build_case_analysis_scheme gl ind false
+ let sigma = Sigma.Unsafe.of_evar_map (Tacmach.project gl) in
+ let Sigma (r, sigma, _) = Indrec.build_case_analysis_scheme (pf_env gl) sigma ind false
(elimination_sort_of_goal gl)
+ in
+ (Sigma.to_evar_map sigma, r)
let make_elim_branch_assumptions ba gl =
- let rec makerec (assums,cargs,constargs,recargs,indargs) lb lc =
- match lb,lc with
- | ([], _) ->
- { ba = ba;
- assums = assums}
- | ((true::tl), ((idrec,_,_ as recarg)::(idind,_,_ as indarg)::idtl)) ->
- makerec (recarg::indarg::assums,
- idrec::cargs,
- idrec::recargs,
- constargs,
- idind::indargs) tl idtl
- | ((false::tl), ((id,_,_ as constarg)::idtl)) ->
- makerec (constarg::assums,
- id::cargs,
- id::constargs,
- recargs,
- indargs) tl idtl
- | (_, _) -> anomaly (Pp.str "make_elim_branch_assumptions")
- in
- makerec ([],[],[],[],[]) ba.branchsign
- (try List.firstn ba.nassums (pf_hyps gl)
- with Failure _ -> anomaly (Pp.str "make_elim_branch_assumptions"))
+ let assums =
+ try List.rev (List.firstn ba.nassums (pf_hyps gl))
+ with Failure _ -> anomaly (Pp.str "make_elim_branch_assumptions") in
+ { ba = ba; assums = assums }
let elim_on_ba tac ba gl = tac (make_elim_branch_assumptions ba gl) gl
-let make_case_branch_assumptions ba gl =
- let rec makerec (assums,cargs,constargs,recargs) p_0 p_1 =
- match p_0,p_1 with
- | ([], _) ->
- { ba = ba;
- assums = assums}
- | ((true::tl), ((idrec,_,_ as recarg)::idtl)) ->
- makerec (recarg::assums,
- idrec::cargs,
- idrec::recargs,
- constargs) tl idtl
- | ((false::tl), ((id,_,_ as constarg)::idtl)) ->
- makerec (constarg::assums,
- id::cargs,
- recargs,
- id::constargs) tl idtl
- | (_, _) -> anomaly (Pp.str "make_case_branch_assumptions")
- in
- makerec ([],[],[],[]) ba.branchsign
- (try List.firstn ba.nassums (pf_hyps gl)
- with Failure _ -> anomaly (Pp.str "make_case_branch_assumptions"))
+let make_case_branch_assumptions = make_elim_branch_assumptions
let case_on_ba tac ba gl = tac (make_case_branch_assumptions ba gl) gl
@@ -508,6 +510,14 @@ module New = struct
in
Proofview.Unsafe.tclEVARS sigma <*> tac >>= check_evars_if
+ let tclDELAYEDWITHHOLES check x tac =
+ Proofview.Goal.nf_enter { enter = begin fun gl ->
+ let env = Proofview.Goal.env gl in
+ let sigma = Proofview.Goal.sigma gl in
+ let Sigma (x, sigma, _) = x.Tacexpr.delayed env sigma in
+ tclWITHHOLES check (tac x) (Sigma.to_evar_map sigma)
+ end }
+
let tclTIMEOUT n t =
Proofview.tclOR
(Proofview.tclTIMEOUT n t)
@@ -538,66 +548,65 @@ module New = struct
mkVar (nthHypId m gl)
let onNthHypId m tac =
- Proofview.Goal.enter begin fun gl -> tac (nthHypId m gl) end
+ Proofview.Goal.enter { enter = begin fun gl -> tac (nthHypId m gl) end }
let onNthHyp m tac =
- Proofview.Goal.enter begin fun gl -> tac (nthHyp m gl) end
+ Proofview.Goal.enter { enter = begin fun gl -> tac (nthHyp m gl) end }
let onLastHypId = onNthHypId 1
let onLastHyp = onNthHyp 1
let onNthDecl m tac =
- Proofview.Goal.nf_enter begin fun gl ->
+ Proofview.Goal.nf_enter { enter = begin fun gl ->
Proofview.tclUNIT (nthDecl m gl) >>= tac
- end
+ end }
let onLastDecl = onNthDecl 1
let ifOnHyp pred tac1 tac2 id =
- Proofview.Goal.nf_enter begin fun gl ->
+ Proofview.Goal.nf_enter { enter = begin fun gl ->
let typ = Tacmach.New.pf_get_hyp_typ id gl in
if pred (id,typ) then
tac1 id
else
tac2 id
- end
+ end }
- let onHyps find tac = Proofview.Goal.nf_enter (fun gl -> tac (find gl))
+ let onHyps find tac = Proofview.Goal.nf_enter { enter = begin fun gl -> tac (find.enter gl) end }
let afterHyp id tac =
- Proofview.Goal.nf_enter begin fun gl ->
+ Proofview.Goal.nf_enter { enter = begin fun gl ->
let hyps = Proofview.Goal.hyps gl in
let rem, _ = List.split_when (fun (hyp,_,_) -> Id.equal hyp id) hyps in
tac rem
- end
+ end }
let fullGoal gl =
let hyps = Tacmach.New.pf_ids_of_hyps gl in
None :: List.map Option.make hyps
let tryAllHyps tac =
- Proofview.Goal.enter begin fun gl ->
+ Proofview.Goal.enter { enter = begin fun gl ->
let hyps = Tacmach.New.pf_ids_of_hyps gl in
tclFIRST_PROGRESS_ON tac hyps
- end
+ end }
let tryAllHypsAndConcl tac =
- Proofview.Goal.enter begin fun gl ->
+ Proofview.Goal.enter { enter = begin fun gl ->
tclFIRST_PROGRESS_ON tac (fullGoal gl)
- end
+ end }
let onClause tac cl =
- Proofview.Goal.enter begin fun gl ->
+ Proofview.Goal.enter { enter = begin fun gl ->
let hyps = Tacmach.New.pf_ids_of_hyps gl in
tclMAP tac (Locusops.simple_clause_of (fun () -> hyps) cl)
- end
+ end }
(* Find the right elimination suffix corresponding to the sort of the goal *)
(* c should be of type A1->.. An->B with B an inductive definition *)
let general_elim_then_using mk_elim
isrec allnames tac predicate ind (c, t) =
- Proofview.Goal.nf_enter
- begin fun gl ->
+ Proofview.Goal.nf_enter { enter = begin fun gl ->
let sigma, elim = Tacmach.New.of_old (mk_elim ind) gl in
Proofview.tclTHEN (Proofview.Unsafe.tclEVARS sigma)
- (Proofview.Goal.nf_enter begin fun gl ->
+ (Proofview.Goal.nf_enter { enter = begin fun gl ->
let indclause = Tacmach.New.of_old (fun gl -> mk_clenv_from gl (c, t)) gl in
(* applying elimination_scheme just a little modified *)
let elimclause = Tacmach.New.of_old (fun gls -> mk_clenv_from gls (elim,Tacmach.New.pf_unsafe_type_of gl elim)) gl in
@@ -621,8 +630,8 @@ module New = struct
(str "The elimination combinator " ++ str name_elim ++ str " is unknown.")
in
let elimclause' = clenv_fchain ~with_univs:false indmv elimclause indclause in
- let branchsigns = compute_construtor_signatures isrec ind in
- let brnames = compute_induction_names (Array.length branchsigns) allnames in
+ let branchsigns = compute_constructor_signatures isrec ind in
+ let brnames = compute_induction_names branchsigns allnames in
let flags = Unification.elim_flags () in
let elimclause' =
match predicate with
@@ -634,10 +643,7 @@ module New = struct
let (hd,largs) = decompose_app clenv'.templtyp.Evd.rebus in
let ba = { branchsign = branchsigns.(i);
branchnames = brnames.(i);
- nassums =
- List.fold_left
- (fun acc b -> if b then acc+2 else acc+1)
- 0 branchsigns.(i);
+ nassums = List.length branchsigns.(i);
branchnum = i+1;
ity = ind;
largs = List.map (clenv_nf_meta clenv') largs;
@@ -649,10 +655,10 @@ module New = struct
Proofview.tclTHEN
(Clenvtac.clenv_refine false clenv')
(Proofview.tclEXTEND [] tclIDTAC branchtacs)
- end) end
+ end }) end }
let elimination_then tac c =
- Proofview.Goal.nf_enter begin fun gl ->
+ Proofview.Goal.nf_enter { enter = begin fun gl ->
let (ind,t) = pf_reduce_to_quantified_ind gl (pf_unsafe_type_of gl c) in
let isrec,mkelim =
match (Global.lookup_mind (fst (fst ind))).mind_record with
@@ -660,7 +666,7 @@ module New = struct
| Some _ -> false,gl_make_case_dep
in
general_elim_then_using mkelim isrec None tac None ind (c, t)
- end
+ end }
let case_then_using =
general_elim_then_using gl_make_case_dep false
@@ -669,16 +675,16 @@ module New = struct
general_elim_then_using gl_make_case_nodep false
let elim_on_ba tac ba =
- Proofview.Goal.nf_enter begin fun gl ->
+ Proofview.Goal.nf_enter { enter = begin fun gl ->
let branches = Tacmach.New.of_old (make_elim_branch_assumptions ba) gl in
tac branches
- end
+ end }
let case_on_ba tac ba =
- Proofview.Goal.nf_enter begin fun gl ->
+ Proofview.Goal.nf_enter { enter = begin fun gl ->
let branches = Tacmach.New.of_old (make_case_branch_assumptions ba) gl in
tac branches
- end
+ end }
let elimination_sort_of_goal gl =
(** Retyping will expand evars anyway. *)
@@ -695,11 +701,11 @@ module New = struct
| Some id -> elimination_sort_of_hyp id gl
let pf_constr_of_global ref tac =
- Proofview.Goal.nf_enter begin fun gl ->
+ Proofview.Goal.nf_enter { enter = begin fun gl ->
let env = Proofview.Goal.env gl in
- let sigma = Proofview.Goal.sigma gl in
+ let sigma = Tacmach.New.project gl in
let (sigma, c) = Evd.fresh_global env sigma ref in
Proofview.Unsafe.tclEVARS sigma <*> (tac c)
- end
+ end }
end
diff --git a/tactics/tacticals.mli b/tactics/tacticals.mli
index 1b3b04d9f..4b7053611 100644
--- a/tactics/tacticals.mli
+++ b/tactics/tacticals.mli
@@ -9,7 +9,6 @@
open Pp
open Names
open Term
-open Context
open Tacmach
open Proof_type
open Tacexpr
@@ -60,29 +59,29 @@ val tclIFTHENTRYELSEMUST : tactic -> tactic -> tactic
val onNthHypId : int -> (Id.t -> tactic) -> tactic
val onNthHyp : int -> (constr -> tactic) -> tactic
-val onNthDecl : int -> (named_declaration -> tactic) -> tactic
+val onNthDecl : int -> (Context.Named.Declaration.t -> tactic) -> tactic
val onLastHypId : (Id.t -> tactic) -> tactic
val onLastHyp : (constr -> tactic) -> tactic
-val onLastDecl : (named_declaration -> tactic) -> tactic
+val onLastDecl : (Context.Named.Declaration.t -> tactic) -> tactic
val onNLastHypsId : int -> (Id.t list -> tactic) -> tactic
val onNLastHyps : int -> (constr list -> tactic) -> tactic
-val onNLastDecls : int -> (named_context -> tactic) -> tactic
+val onNLastDecls : int -> (Context.Named.t -> tactic) -> tactic
val lastHypId : goal sigma -> Id.t
val lastHyp : goal sigma -> constr
-val lastDecl : goal sigma -> named_declaration
+val lastDecl : goal sigma -> Context.Named.Declaration.t
val nLastHypsId : int -> goal sigma -> Id.t list
val nLastHyps : int -> goal sigma -> constr list
-val nLastDecls : int -> goal sigma -> named_context
+val nLastDecls : int -> goal sigma -> Context.Named.t
-val afterHyp : Id.t -> goal sigma -> named_context
+val afterHyp : Id.t -> goal sigma -> Context.Named.t
val ifOnHyp : (Id.t * types -> bool) ->
(Id.t -> tactic) -> (Id.t -> tactic) ->
Id.t -> tactic
-val onHyps : (goal sigma -> named_context) ->
- (named_context -> tactic) -> tactic
+val onHyps : (goal sigma -> Context.Named.t) ->
+ (Context.Named.t -> tactic) -> tactic
(** {6 Tacticals applying to goal components } *)
@@ -99,32 +98,36 @@ val onClauseLR : (Id.t option -> tactic) -> clause -> tactic
(** {6 Elimination tacticals. } *)
type branch_args = {
- ity : pinductive; (** the type we were eliminating on *)
+ ity : pinductive; (** the type we were eliminating on *)
largs : constr list; (** its arguments *)
branchnum : int; (** the branch number *)
pred : constr; (** the predicate we used *)
- nassums : int; (** the number of assumptions to be introduced *)
+ nassums : int; (** number of assumptions/letin to be introduced *)
branchsign : bool list; (** the signature of the branch.
- true=recursive argument, false=constant *)
+ true=assumption, false=let-in *)
branchnames : intro_patterns}
type branch_assumptions = {
- ba : branch_args; (** the branch args *)
- assums : named_context} (** the list of assumptions introduced *)
+ ba : branch_args; (** the branch args *)
+ assums : Context.Named.t} (** the list of assumptions introduced *)
-(** [check_disjunctive_pattern_size loc pats n] returns an appropriate
- error message if |pats| <> n *)
-val check_or_and_pattern_size :
- Loc.t -> delayed_open_constr or_and_intro_pattern_expr -> int -> unit
+(** [check_disjunctive_pattern_size loc pats n] returns an appropriate
+ error message if |pats| <> n; extends them if no pattern is given
+ for let-ins in the case of a conjunctive pattern *)
+val get_and_check_or_and_pattern :
+ Loc.t -> delayed_open_constr or_and_intro_pattern_expr ->
+ bool list array -> intro_patterns array
(** Tolerate "[]" to mean a disjunctive pattern of any length *)
val fix_empty_or_and_pattern : int ->
delayed_open_constr or_and_intro_pattern_expr ->
delayed_open_constr or_and_intro_pattern_expr
+val compute_constructor_signatures : rec_flag -> pinductive -> bool list array
+
(** Useful for [as intro_pattern] modifier *)
val compute_induction_names :
- int -> or_and_intro_pattern option -> intro_patterns array
+ bool list array -> or_and_intro_pattern option -> intro_patterns array
val elimination_sort_of_goal : goal sigma -> sorts_family
val elimination_sort_of_hyp : Id.t -> goal sigma -> sorts_family
@@ -219,11 +222,12 @@ module New : sig
val tclSOLVE : unit tactic list -> unit tactic
val tclPROGRESS : unit tactic -> unit tactic
val tclWITHHOLES : bool -> 'a tactic -> Evd.evar_map -> 'a tactic
+ val tclDELAYEDWITHHOLES : bool -> 'a delayed_open -> ('a -> unit tactic) -> unit tactic
val tclTIMEOUT : int -> unit tactic -> unit tactic
val tclTIME : string option -> 'a tactic -> 'a tactic
- val nLastDecls : [ `NF ] Proofview.Goal.t -> int -> named_context
+ val nLastDecls : ([ `NF ], 'r) Proofview.Goal.t -> int -> Context.Named.t
val ifOnHyp : (identifier * types -> bool) ->
(identifier -> unit Proofview.tactic) -> (identifier -> unit Proofview.tactic) ->
@@ -232,19 +236,19 @@ module New : sig
val onNthHypId : int -> (identifier -> unit tactic) -> unit tactic
val onLastHypId : (identifier -> unit tactic) -> unit tactic
val onLastHyp : (constr -> unit tactic) -> unit tactic
- val onLastDecl : (named_declaration -> unit tactic) -> unit tactic
+ val onLastDecl : (Context.Named.Declaration.t -> unit tactic) -> unit tactic
- val onHyps : ([ `NF ] Proofview.Goal.t -> named_context) ->
- (named_context -> unit tactic) -> unit tactic
- val afterHyp : Id.t -> (named_context -> unit tactic) -> unit tactic
+ val onHyps : ([ `NF ], Context.Named.t) Proofview.Goal.enter ->
+ (Context.Named.t -> unit tactic) -> unit tactic
+ val afterHyp : Id.t -> (Context.Named.t -> unit tactic) -> unit tactic
val tryAllHyps : (identifier -> unit tactic) -> unit tactic
val tryAllHypsAndConcl : (identifier option -> unit tactic) -> unit tactic
val onClause : (identifier option -> unit tactic) -> clause -> unit tactic
- val elimination_sort_of_goal : 'a Proofview.Goal.t -> sorts_family
- val elimination_sort_of_hyp : Id.t -> 'a Proofview.Goal.t -> sorts_family
- val elimination_sort_of_clause : Id.t option -> 'a Proofview.Goal.t -> sorts_family
+ val elimination_sort_of_goal : ('a, 'r) Proofview.Goal.t -> sorts_family
+ val elimination_sort_of_hyp : Id.t -> ('a, 'r) Proofview.Goal.t -> sorts_family
+ val elimination_sort_of_clause : Id.t option -> ('a, 'r) Proofview.Goal.t -> sorts_family
val elimination_then :
(branch_args -> unit Proofview.tactic) ->
diff --git a/tactics/tactics.ml b/tactics/tactics.ml
index f23808f6f..b88ec69e6 100644
--- a/tactics/tactics.ml
+++ b/tactics/tactics.ml
@@ -13,7 +13,6 @@ open Names
open Nameops
open Term
open Vars
-open Context
open Termops
open Find_subterm
open Namegen
@@ -26,7 +25,7 @@ open Evd
open Pfedit
open Tacred
open Genredexpr
-open Tacmach
+open Tacmach.New
open Logic
open Clenv
open Refiner
@@ -43,21 +42,13 @@ open Locus
open Locusops
open Misctypes
open Proofview.Notations
-
-let nb_prod x =
- let rec count n c =
- match kind_of_term c with
- Prod(_,_,t) -> count (n+1) t
- | LetIn(_,a,_,t) -> count n (subst1 a t)
- | Cast(c,_,_) -> count n c
- | _ -> n
- in count 0 x
+open Sigma.Notations
let inj_with_occurrences e = (AllOccurrences,e)
let dloc = Loc.ghost
-let typ_of = Retyping.get_type_of
+let typ_of env sigma c = Retyping.get_type_of env (Sigma.to_evar_map sigma) c
open Goptions
@@ -126,13 +117,26 @@ let _ =
optread = (fun () -> !universal_lemma_under_conjunctions) ;
optwrite = (fun b -> universal_lemma_under_conjunctions := b) }
+(* Shrinking of abstract proofs. *)
+
+let shrink_abstract = ref false
+
+let _ =
+ declare_bool_option
+ { optsync = true;
+ optdepr = false;
+ optname = "shrinking of abstracted proofs";
+ optkey = ["Shrink"; "Abstract"];
+ optread = (fun () -> !shrink_abstract) ;
+ optwrite = (fun b -> shrink_abstract := b) }
+
(* The following boolean governs what "intros []" do on examples such
as "forall x:nat*nat, x=x"; if true, it behaves as "intros [? ?]";
if false, it behaves as "intro H; case H; clear H" for fresh H.
Kept as false for compatibility.
*)
-let bracketing_last_or_and_intro_pattern = ref false
+let bracketing_last_or_and_intro_pattern = ref true
let use_bracketing_last_or_and_intro_pattern () =
!bracketing_last_or_and_intro_pattern
@@ -144,7 +148,7 @@ let _ =
optdepr = false;
optname = "bracketing last or-and introduction pattern";
optkey = ["Bracketing";"Last";"Introduction";"Pattern"];
- optread = (fun () -> !bracketing_last_or_and_intro_pattern) ;
+ optread = (fun () -> !bracketing_last_or_and_intro_pattern);
optwrite = (fun b -> bracketing_last_or_and_intro_pattern := b) }
(*********************************************)
@@ -158,21 +162,22 @@ let _ =
(** This tactic creates a partial proof realizing the introduction rule, but
does not check anything. *)
let unsafe_intro env store (id, c, t) b =
- Proofview.Refine.refine ~unsafe:true begin fun sigma ->
+ Proofview.Refine.refine ~unsafe:true { run = begin fun sigma ->
+ let sigma = Sigma.to_evar_map sigma in
let ctx = named_context_val env in
let nctx = push_named_context_val (id, c, t) ctx in
let inst = List.map (fun (id, _, _) -> mkVar id) (named_context env) in
let ninst = mkRel 1 :: inst in
let nb = subst1 (mkVar id) b in
let sigma, ev = new_evar_instance nctx sigma nb ~principal:true ~store ninst in
- sigma, mkNamedLambda_or_LetIn (id, c, t) ev
- end
+ Sigma.Unsafe.of_pair (mkNamedLambda_or_LetIn (id, c, t) ev, sigma)
+ end }
let introduction ?(check=true) id =
- Proofview.Goal.enter begin fun gl ->
+ Proofview.Goal.enter { enter = begin fun gl ->
let gl = Proofview.Goal.assume gl in
let concl = Proofview.Goal.concl gl in
- let sigma = Proofview.Goal.sigma gl in
+ let sigma = Tacmach.New.project gl in
let hyps = Proofview.Goal.hyps gl in
let store = Proofview.Goal.extra gl in
let env = Proofview.Goal.env gl in
@@ -184,44 +189,48 @@ let introduction ?(check=true) id =
| Prod (_, t, b) -> unsafe_intro env store (id, None, t) b
| LetIn (_, c, t, b) -> unsafe_intro env store (id, Some c, t) b
| _ -> raise (RefinerError IntroNeedsProduct)
- end
+ end }
let refine = Tacmach.refine
let convert_concl ?(check=true) ty k =
- Proofview.Goal.enter begin fun gl ->
+ Proofview.Goal.enter { enter = begin fun gl ->
let env = Proofview.Goal.env gl in
let store = Proofview.Goal.extra gl in
let conclty = Proofview.Goal.raw_concl gl in
- Proofview.Refine.refine ~unsafe:true begin fun sigma ->
- let sigma =
+ Proofview.Refine.refine ~unsafe:true { run = begin fun sigma ->
+ let Sigma ((), sigma, p) =
if check then begin
+ let sigma = Sigma.to_evar_map sigma in
ignore (Typing.unsafe_type_of env sigma ty);
let sigma,b = Reductionops.infer_conv env sigma ty conclty in
if not b then error "Not convertible.";
- sigma
- end else sigma in
- let (sigma,x) = Evarutil.new_evar env sigma ~principal:true ~store ty in
- (sigma, if k == DEFAULTcast then x else mkCast(x,k,conclty))
- end
- end
+ Sigma.Unsafe.of_pair ((), sigma)
+ end else Sigma.here () sigma in
+ let Sigma (x, sigma, q) = Evarutil.new_evar env sigma ~principal:true ~store ty in
+ let ans = if k == DEFAULTcast then x else mkCast(x,k,conclty) in
+ Sigma (ans, sigma, p +> q)
+ end }
+ end }
let convert_hyp ?(check=true) d =
- Proofview.Goal.enter begin fun gl ->
+ Proofview.Goal.enter { enter = begin fun gl ->
let env = Proofview.Goal.env gl in
- let sigma = Proofview.Goal.sigma gl in
+ let sigma = Tacmach.New.project gl in
let ty = Proofview.Goal.raw_concl gl in
let store = Proofview.Goal.extra gl in
let sign = convert_hyp check (named_context_val env) sigma d in
let env = reset_with_named_context sign env in
- Proofview.Refine.refine ~unsafe:true (fun sigma -> Evarutil.new_evar env sigma ~principal:true ~store ty)
- end
+ Proofview.Refine.refine ~unsafe:true { run = begin fun sigma ->
+ Evarutil.new_evar env sigma ~principal:true ~store ty
+ end }
+ end }
let convert_concl_no_check = convert_concl ~check:false
let convert_hyp_no_check = convert_hyp ~check:false
let convert_gen pb x y =
- Proofview.Goal.enter begin fun gl ->
+ Proofview.Goal.enter { enter = begin fun gl ->
try
let sigma, b = Tacmach.New.pf_apply (Reductionops.infer_conv ~pb) gl x y in
if b then Proofview.Unsafe.tclEVARS sigma
@@ -229,7 +238,7 @@ let convert_gen pb x y =
with (* Reduction.NotConvertible *) _ ->
(** FIXME: Sometimes an anomaly is raised from conversion *)
Tacticals.New.tclFAIL 0 (str "Not convertible")
-end
+end }
let convert x y = convert_gen Reduction.CONV x y
let convert_leq x y = convert_gen Reduction.CUMUL x y
@@ -262,7 +271,7 @@ let error_replacing_dependency env sigma id err =
errorlabstrm "" (replacing_dependency_msg env sigma id err)
let thin l gl =
- try thin l gl
+ try Tacmach.thin l gl
with Evarutil.ClearDependencyError (id,err) ->
error_clear_dependency (pf_env gl) (project gl) id err
@@ -302,7 +311,7 @@ let rename_hyp repl =
match dom with
| None -> Tacticals.New.tclZEROMSG (str "Not a one-to-one name mapping")
| Some (src, dst) ->
- Proofview.Goal.enter begin fun gl ->
+ Proofview.Goal.enter { enter = begin fun gl ->
let gl = Proofview.Goal.assume gl in
let hyps = Proofview.Goal.hyps gl in
let concl = Proofview.Goal.concl gl in
@@ -334,10 +343,12 @@ let rename_hyp repl =
let nconcl = subst concl in
let nctx = Environ.val_of_named_context nhyps in
let instance = List.map (fun (id, _, _) -> mkVar id) hyps in
- Proofview.Refine.refine ~unsafe:true begin fun sigma ->
- Evarutil.new_evar_instance nctx sigma nconcl ~store instance
- end
- end
+ Proofview.Refine.refine ~unsafe:true { run = begin fun sigma ->
+ let sigma = Sigma.to_evar_map sigma in
+ let (sigma, c) = Evarutil.new_evar_instance nctx sigma nconcl ~store instance in
+ Sigma.Unsafe.of_pair (c, sigma)
+ end }
+ end }
(**************************************************************)
(* Fresh names *)
@@ -382,7 +393,7 @@ let find_name mayrepl decl naming gl = match naming with
| NamingAvoid idl ->
(* this case must be compatible with [find_intro_names] below. *)
let env = Proofview.Goal.env gl in
- let sigma = Proofview.Goal.sigma gl in
+ let sigma = Tacmach.New.project gl in
new_fresh_id idl (default_id env sigma decl) gl
| NamingBasedOn (id,idl) -> new_fresh_id idl id gl
| NamingMustBe (loc,id) ->
@@ -398,16 +409,16 @@ let find_name mayrepl decl naming gl = match naming with
(**************************************************************)
let assert_before_then_gen b naming t tac =
- Proofview.Goal.enter begin fun gl ->
+ Proofview.Goal.enter { enter = begin fun gl ->
let id = find_name b (Anonymous,None,t) naming gl in
Tacticals.New.tclTHENLAST
(Proofview.V82.tactic
(fun gl ->
- try internal_cut b id t gl
+ try Tacmach.internal_cut b id t gl
with Evarutil.ClearDependencyError (id,err) ->
error_replacing_dependency (pf_env gl) (project gl) id err))
(tac id)
- end
+ end }
let assert_before_gen b naming t =
assert_before_then_gen b naming t (fun _ -> Proofview.tclUNIT ())
@@ -416,16 +427,16 @@ let assert_before na = assert_before_gen false (naming_of_name na)
let assert_before_replacing id = assert_before_gen true (NamingMustBe (dloc,id))
let assert_after_then_gen b naming t tac =
- Proofview.Goal.enter begin fun gl ->
+ Proofview.Goal.enter { enter = begin fun gl ->
let id = find_name b (Anonymous,None,t) naming gl in
Tacticals.New.tclTHENFIRST
(Proofview.V82.tactic
(fun gl ->
- try internal_cut_rev b id t gl
+ try Tacmach.internal_cut_rev b id t gl
with Evarutil.ClearDependencyError (id,err) ->
error_replacing_dependency (pf_env gl) (project gl) id err))
(tac id)
- end
+ end }
let assert_after_gen b naming t =
assert_after_then_gen b naming t (fun _ -> (Proofview.tclUNIT ()))
@@ -462,7 +473,7 @@ let cofix ido gl = match ido with
type tactic_reduction = env -> evar_map -> constr -> constr
let pf_reduce_decl redfun where (id,c,ty) gl =
- let redfun' = pf_reduce redfun gl in
+ let redfun' = Tacmach.pf_reduce redfun gl in
match c with
| None ->
if where == InHypValueOnly then
@@ -542,11 +553,11 @@ let bind_red_expr_occurrences occs nbcl redexp =
certain hypothesis *)
let reduct_in_concl (redfun,sty) gl =
- Proofview.V82.of_tactic (convert_concl_no_check (pf_reduce redfun gl (pf_concl gl)) sty) gl
+ Proofview.V82.of_tactic (convert_concl_no_check (Tacmach.pf_reduce redfun gl (Tacmach.pf_concl gl)) sty) gl
let reduct_in_hyp ?(check=false) redfun (id,where) gl =
Proofview.V82.of_tactic (convert_hyp ~check
- (pf_reduce_decl redfun where (pf_get_hyp gl id) gl)) gl
+ (pf_reduce_decl redfun where (Tacmach.pf_get_hyp gl id) gl)) gl
let revert_cast (redfun,kind as r) =
if kind == DEFAULTcast then (redfun,REVERTcast) else r
@@ -573,13 +584,13 @@ let pf_e_reduce_decl redfun where (id,c,ty) gl =
let e_reduct_in_concl (redfun,sty) gl =
Proofview.V82.of_tactic
- (let sigma, c' = (pf_apply redfun gl (pf_concl gl)) in
+ (let sigma, c' = (Tacmach.pf_apply redfun gl (Tacmach.pf_concl gl)) in
Proofview.Unsafe.tclEVARS sigma <*>
convert_concl_no_check c' sty) gl
let e_reduct_in_hyp ?(check=false) redfun (id,where) gl =
Proofview.V82.of_tactic
- (let sigma, decl' = pf_e_reduce_decl redfun where (pf_get_hyp gl id) gl in
+ (let sigma, decl' = pf_e_reduce_decl redfun where (Tacmach.pf_get_hyp gl id) gl in
Proofview.Unsafe.tclEVARS sigma <*>
convert_hyp ~check decl') gl
@@ -590,17 +601,13 @@ let e_reduct_option ?(check=false) redfun = function
(** Versions with evars to maintain the unification of universes resulting
from conversions. *)
-let tclWITHEVARS f k =
- Proofview.Goal.enter begin fun gl ->
- let evm, c' = f gl in
- Tacticals.New.tclTHEN (Proofview.Unsafe.tclEVARS evm) (k c')
- end
-
let e_change_in_concl (redfun,sty) =
- tclWITHEVARS
- (fun gl -> redfun (Proofview.Goal.env gl) (Proofview.Goal.sigma gl)
- (Proofview.Goal.raw_concl gl))
- (fun c -> convert_concl_no_check c sty)
+ Proofview.Goal.s_enter { s_enter = begin fun gl ->
+ let sigma = Proofview.Goal.sigma gl in
+ let sigma = Sigma.to_evar_map sigma in
+ let (sigma, c) = redfun (Proofview.Goal.env gl) sigma (Proofview.Goal.raw_concl gl) in
+ Sigma.Unsafe.of_pair (convert_concl_no_check c sty, sigma)
+ end }
let e_pf_change_decl (redfun : bool -> e_reduction_function) where (id,c,ty) env sigma =
match c with
@@ -619,16 +626,18 @@ let e_pf_change_decl (redfun : bool -> e_reduction_function) where (id,c,ty) env
sigma', (id,Some b',ty')
let e_change_in_hyp redfun (id,where) =
- tclWITHEVARS
- (fun gl -> e_pf_change_decl redfun where
- (Tacmach.New.pf_get_hyp id (Proofview.Goal.assume gl))
- (Proofview.Goal.env gl) (Proofview.Goal.sigma gl))
- convert_hyp
+ Proofview.Goal.s_enter { s_enter = begin fun gl ->
+ let sigma = Proofview.Goal.sigma gl in
+ let sigma = Sigma.to_evar_map sigma in
+ let hyp = Tacmach.New.pf_get_hyp id (Proofview.Goal.assume gl) in
+ let sigma, c = e_pf_change_decl redfun where hyp (Proofview.Goal.env gl) sigma in
+ Sigma.Unsafe.of_pair (convert_hyp c, sigma)
+ end }
-type change_arg = Pattern.patvar_map -> evar_map -> evar_map * constr
+type change_arg = Pattern.patvar_map -> constr Sigma.run
-let make_change_arg c =
- fun pats sigma -> (sigma, replace_vars (Id.Map.bindings pats) c)
+let make_change_arg c pats =
+ { run = fun sigma -> Sigma.here (replace_vars (Id.Map.bindings pats) c) sigma }
let check_types env sigma mayneedglobalcheck deep newc origc =
let t1 = Retyping.get_type_of env sigma newc in
@@ -653,7 +662,9 @@ let check_types env sigma mayneedglobalcheck deep newc origc =
(* Now we introduce different instances of the previous tacticals *)
let change_and_check cv_pb mayneedglobalcheck deep t env sigma c =
- let sigma, t' = t sigma in
+ let sigma = Sigma.Unsafe.of_evar_map sigma in
+ let Sigma (t', sigma, p) = t.run sigma in
+ let sigma = Sigma.to_evar_map sigma in
let sigma = check_types env sigma mayneedglobalcheck deep t' c in
let sigma, b = infer_conv ~pb:cv_pb env sigma t' c in
if not b then errorlabstrm "convert-check-hyp" (str "Not convertible.");
@@ -688,7 +699,7 @@ let change_option occl t = function
| None -> change_in_concl occl t
let change chg c cls gl =
- let cls = concrete_clause_of (fun () -> pf_ids_of_hyps gl) cls in
+ let cls = concrete_clause_of (fun () -> Tacmach.pf_ids_of_hyps gl) cls in
Proofview.V82.of_tactic (Tacticals.New.tclMAP (function
| OnHyp (id,occs,where) ->
change_option (bind_change_occurrences occs chg) c (Some (id,where))
@@ -729,12 +740,12 @@ let reduction_clause redexp cl =
(None, bind_red_expr_occurrences occs nbcl redexp)) cl
let reduce redexp cl goal =
- let cl = concrete_clause_of (fun () -> pf_ids_of_hyps goal) cl in
+ let cl = concrete_clause_of (fun () -> Tacmach.pf_ids_of_hyps goal) cl in
let redexps = reduction_clause redexp cl in
let check = match redexp with Fold _ | Pattern _ -> true | _ -> false in
let tac = tclMAP (fun (where,redexp) ->
e_reduct_option ~check
- (Redexpr.reduction_of_red_expr (pf_env goal) redexp) where) redexps in
+ (Redexpr.reduction_of_red_expr (Tacmach.pf_env goal) redexp) where) redexps in
if check then with_check tac goal else tac goal
(* Unfolding occurrences of a constant *)
@@ -771,9 +782,9 @@ let build_intro_tac id dest tac = match dest with
Proofview.V82.tactic (move_hyp id dest); tac id]
let rec intro_then_gen name_flag move_flag force_flag dep_flag tac =
- Proofview.Goal.enter begin fun gl ->
+ Proofview.Goal.enter { enter = begin fun gl ->
let concl = Proofview.Goal.concl (Proofview.Goal.assume gl) in
- let concl = nf_evar (Proofview.Goal.sigma gl) concl in
+ let concl = nf_evar (Tacmach.New.project gl) concl in
match kind_of_term concl with
| Prod (name,t,u) when not dep_flag || (dependent (mkRel 1) u) ->
let name = find_name false (name,None,t) name_flag gl in
@@ -797,7 +808,7 @@ let rec intro_then_gen name_flag move_flag force_flag dep_flag tac =
Tacticals.New.tclZEROMSG (str "No product even after head-reduction.")
| e -> Proofview.tclZERO ~info e
end
- end
+ end }
let intro_gen n m f d = intro_then_gen n m f d (fun _ -> Proofview.tclUNIT ())
let intro_mustbe_force id = intro_gen (NamingMustBe (dloc,id)) MoveLast true false
@@ -861,14 +872,14 @@ let get_previous_hyp_position id gl =
aux MoveLast (Proofview.Goal.hyps (Proofview.Goal.assume gl))
let intro_replacing id =
- Proofview.Goal.enter begin fun gl ->
+ Proofview.Goal.enter { enter = begin fun gl ->
let next_hyp = get_next_hyp_position id gl in
Tacticals.New.tclTHENLIST [
Proofview.V82.tactic (thin_for_replacing [id]);
introduction id;
Proofview.V82.tactic (move_hyp id next_hyp);
]
- end
+ end }
(* We have e.g. [x, y, y', x', y'' |- forall y y' y'', G] and want to
reintroduce y, y,' y''. Note that we have to clear y, y' and y''
@@ -880,7 +891,7 @@ let intro_replacing id =
(* the behavior of inversion *)
let intros_possibly_replacing ids =
let suboptimal = true in
- Proofview.Goal.enter begin fun gl ->
+ Proofview.Goal.enter { enter = begin fun gl ->
let posl = List.map (fun id -> (id, get_next_hyp_position id gl)) ids in
Tacticals.New.tclTHEN
(Tacticals.New.tclMAP (fun id ->
@@ -889,38 +900,38 @@ let intros_possibly_replacing ids =
(Tacticals.New.tclMAP (fun (id,pos) ->
Tacticals.New.tclORELSE (intro_move (Some id) pos) (intro_using id))
posl)
- end
+ end }
(* This version assumes that replacement is actually possible *)
let intros_replacing ids =
- Proofview.Goal.enter begin fun gl ->
+ Proofview.Goal.enter { enter = begin fun gl ->
let posl = List.map (fun id -> (id, get_next_hyp_position id gl)) ids in
Tacticals.New.tclTHEN
(Proofview.V82.tactic (thin_for_replacing ids))
(Tacticals.New.tclMAP (fun (id,pos) -> intro_move (Some id) pos) posl)
- end
+ end }
(* User-level introduction tactics *)
-let pf_lookup_hypothesis_as_renamed env ccl = function
+let lookup_hypothesis_as_renamed env ccl = function
| AnonHyp n -> Detyping.lookup_index_as_renamed env ccl n
| NamedHyp id -> Detyping.lookup_name_as_displayed env ccl id
-let pf_lookup_hypothesis_as_renamed_gen red h gl =
- let env = pf_env gl in
+let lookup_hypothesis_as_renamed_gen red h gl =
+ let env = Proofview.Goal.env gl in
let rec aux ccl =
- match pf_lookup_hypothesis_as_renamed env ccl h with
+ match lookup_hypothesis_as_renamed env ccl h with
| None when red ->
aux
(snd ((fst (Redexpr.reduction_of_red_expr env (Red true)))
- env (project gl) ccl))
+ env (Sigma.to_evar_map (Proofview.Goal.sigma gl)) ccl))
| x -> x
in
- try aux (pf_concl gl)
+ try aux (Proofview.Goal.concl gl)
with Redelimination -> None
-let is_quantified_hypothesis id g =
- match pf_lookup_hypothesis_as_renamed_gen false (NamedHyp id) g with
+let is_quantified_hypothesis id gl =
+ match lookup_hypothesis_as_renamed_gen false (NamedHyp id) gl with
| Some _ -> true
| None -> false
@@ -932,7 +943,7 @@ let msg_quantified_hypothesis = function
str " non dependent hypothesis"
let depth_of_quantified_hypothesis red h gl =
- match pf_lookup_hypothesis_as_renamed_gen red h gl with
+ match lookup_hypothesis_as_renamed_gen red h gl with
| Some depth -> depth
| None ->
errorlabstrm "lookup_quantified_hypothesis"
@@ -942,10 +953,10 @@ let depth_of_quantified_hypothesis red h gl =
str".")
let intros_until_gen red h =
- Proofview.Goal.nf_enter begin fun gl ->
- let n = Tacmach.New.of_old (depth_of_quantified_hypothesis red h) gl in
+ Proofview.Goal.nf_enter { enter = begin fun gl ->
+ let n = depth_of_quantified_hypothesis red h gl in
Tacticals.New.tclDO n (if red then introf else intro)
- end
+ end }
let intros_until_id id = intros_until_gen false (NamedHyp id)
let intros_until_n_gen red n = intros_until_gen red (AnonHyp n)
@@ -953,7 +964,7 @@ let intros_until_n_gen red n = intros_until_gen red (AnonHyp n)
let intros_until = intros_until_gen true
let intros_until_n = intros_until_n_gen true
-let tclCHECKVAR id gl = ignore (pf_get_hyp gl id); tclIDTAC gl
+let tclCHECKVAR id gl = ignore (Tacmach.pf_get_hyp gl id); tclIDTAC gl
let try_intros_until_id_check id =
Tacticals.New.tclORELSE (intros_until_id id) (Proofview.V82.tactic (tclCHECKVAR id))
@@ -968,12 +979,15 @@ let rec intros_move = function
Tacticals.New.tclTHEN (intro_gen (NamingMustBe (dloc,hyp)) destopt false false)
(intros_move rest)
+let run_delayed env sigma c =
+ Sigma.run sigma { Sigma.run = fun sigma -> c.delayed env sigma }
+
(* Apply a tactic on a quantified hypothesis, an hypothesis in context
or a term with bindings *)
let onOpenInductionArg env sigma tac = function
| clear_flag,ElimOnConstr f ->
- let (sigma',cbl) = f env sigma in
+ let (cbl, sigma') = run_delayed env sigma f in
let pending = (sigma,sigma') in
Tacticals.New.tclTHEN
(Proofview.Unsafe.tclEVARS sigma')
@@ -983,20 +997,20 @@ let onOpenInductionArg env sigma tac = function
(intros_until_n n)
(Tacticals.New.onLastHyp
(fun c ->
- Proofview.Goal.enter begin fun gl ->
- let sigma = Proofview.Goal.sigma gl in
+ Proofview.Goal.enter { enter = begin fun gl ->
+ let sigma = Tacmach.New.project gl in
let pending = (sigma,sigma) in
tac clear_flag (pending,(c,NoBindings))
- end))
+ end }))
| clear_flag,ElimOnIdent (_,id) ->
(* A quantified hypothesis *)
Tacticals.New.tclTHEN
(try_intros_until_id_check id)
- (Proofview.Goal.enter begin fun gl ->
- let sigma = Proofview.Goal.sigma gl in
+ (Proofview.Goal.enter { enter = begin fun gl ->
+ let sigma = Tacmach.New.project gl in
let pending = (sigma,sigma) in
tac clear_flag (pending,(mkVar id,NoBindings))
- end)
+ end })
let onInductionArg tac = function
| clear_flag,ElimOnConstr cbl ->
@@ -1020,10 +1034,12 @@ let map_induction_arg f = function
(* tactic "cut" (actually modus ponens) *)
(****************************************)
+let normalize_cut = false
+
let cut c =
- Proofview.Goal.enter begin fun gl ->
+ Proofview.Goal.enter { enter = begin fun gl ->
let env = Proofview.Goal.env gl in
- let sigma = Proofview.Goal.sigma gl in
+ let sigma = Tacmach.New.project gl in
let concl = Tacmach.New.pf_nf_concl gl in
let is_sort =
try
@@ -1038,16 +1054,16 @@ let cut c =
if is_sort then
let id = next_name_away_with_default "H" Anonymous (Tacmach.New.pf_ids_of_hyps gl) in
(** Backward compat: normalize [c]. *)
- let c = local_strong whd_betaiota sigma c in
- Proofview.Refine.refine ~unsafe:true begin fun h ->
- let (h, f) = Evarutil.new_evar ~principal:true env h (mkArrow c (Vars.lift 1 concl)) in
- let (h, x) = Evarutil.new_evar env h c in
- let f = mkLambda (Name id, c, mkApp (Vars.lift 1 f, [|mkRel 1|])) in
- (h, mkApp (f, [|x|]))
- end
+ let c = if normalize_cut then local_strong whd_betaiota sigma c else c in
+ Proofview.Refine.refine ~unsafe:true { run = begin fun h ->
+ let Sigma (f, h, p) = Evarutil.new_evar ~principal:true env h (mkArrow c (Vars.lift 1 concl)) in
+ let Sigma (x, h, q) = Evarutil.new_evar env h c in
+ let f = mkLetIn (Name id, x, c, mkApp (Vars.lift 1 f, [|mkRel 1|])) in
+ Sigma (f, h, p +> q)
+ end }
else
Tacticals.New.tclZEROMSG (str "Not a proposition or a type.")
- end
+ end }
let error_uninstantiated_metas t clenv =
let na = meta_name clenv.evd (List.hd (Metaset.elements (metavars_of t))) in
@@ -1091,7 +1107,7 @@ let clenv_refine_in ?(sidecond_first=false) with_evars ?(with_classes=true)
if not with_evars && occur_meta new_hyp_typ then
error_uninstantiated_metas new_hyp_typ clenv;
let new_hyp_prf = clenv_value clenv in
- let exact_tac = Proofview.V82.tactic (refine_no_check new_hyp_prf) in
+ let exact_tac = Proofview.V82.tactic (Tacmach.refine_no_check new_hyp_prf) in
let naming = NamingMustBe (dloc,targetid) in
let with_clear = do_replace (Some id) naming in
Tacticals.New.tclTHEN
@@ -1156,12 +1172,12 @@ let enforce_prop_bound_names rename tac =
mkLetIn (na,c,t,aux (push_rel (na,Some c,t) env) sigma (i-1) t')
| _ -> print_int i; Pp.msg (print_constr t); assert false in
let rename_branch i =
- Proofview.Goal.nf_enter begin fun gl ->
+ Proofview.Goal.nf_enter { enter = begin fun gl ->
let env = Proofview.Goal.env gl in
- let sigma = Proofview.Goal.sigma gl in
+ let sigma = Tacmach.New.project gl in
let t = Proofview.Goal.concl gl in
change_concl (aux env sigma i t)
- end in
+ end } in
(if isrec then Tacticals.New.tclTHENFIRSTn else Tacticals.New.tclTHENLASTn)
tac
(Array.map rename_branch nn)
@@ -1176,9 +1192,9 @@ let rec contract_letin_in_lam_header c =
let elimination_clause_scheme with_evars ?(with_classes=true) ?(flags=elim_flags ())
rename i (elim, elimty, bindings) indclause =
- Proofview.Goal.enter begin fun gl ->
+ Proofview.Goal.enter { enter = begin fun gl ->
let env = Proofview.Goal.env gl in
- let sigma = Proofview.Goal.sigma gl in
+ let sigma = Tacmach.New.project gl in
let elim = contract_letin_in_lam_header elim in
let elimclause = make_clenv_binding env sigma (elim, elimty) bindings in
let indmv =
@@ -1189,7 +1205,7 @@ let elimination_clause_scheme with_evars ?(with_classes=true) ?(flags=elim_flags
in
let elimclause' = clenv_fchain ~flags indmv elimclause indclause in
enforce_prop_bound_names rename (Clenvtac.res_pf elimclause' ~with_evars ~with_classes ~flags)
- end
+ end }
(*
* Elimination tactic with bindings and using an arbitrary
@@ -1206,20 +1222,20 @@ type eliminator = {
}
let general_elim_clause_gen elimtac indclause elim =
- Proofview.Goal.enter begin fun gl ->
+ Proofview.Goal.enter { enter = begin fun gl ->
let env = Proofview.Goal.env gl in
- let sigma = Proofview.Goal.sigma gl in
+ let sigma = Tacmach.New.project gl in
let (elimc,lbindelimc) = elim.elimbody in
let elimt = Retyping.get_type_of env sigma elimc in
let i =
match elim.elimindex with None -> index_of_ind_arg elimt | Some i -> i in
elimtac elim.elimrename i (elimc, elimt, lbindelimc) indclause
- end
+ end }
let general_elim with_evars clear_flag (c, lbindc) elim =
- Proofview.Goal.enter begin fun gl ->
+ Proofview.Goal.enter { enter = begin fun gl ->
let env = Proofview.Goal.env gl in
- let sigma = Proofview.Goal.sigma gl in
+ let sigma = Tacmach.New.project gl in
let ct = Retyping.get_type_of env sigma c in
let t = try snd (reduce_to_quantified_ind env sigma ct) with UserError _ -> ct in
let elimtac = elimination_clause_scheme with_evars in
@@ -1227,28 +1243,30 @@ let general_elim with_evars clear_flag (c, lbindc) elim =
Tacticals.New.tclTHEN
(general_elim_clause_gen elimtac indclause elim)
(apply_clear_request clear_flag (use_clear_hyp_by_default ()) c)
- end
+ end }
(* Case analysis tactics *)
let general_case_analysis_in_context with_evars clear_flag (c,lbindc) =
- Proofview.Goal.nf_enter begin fun gl ->
- let env = Proofview.Goal.env gl in
+ Proofview.Goal.nf_s_enter { s_enter = begin fun gl ->
let sigma = Proofview.Goal.sigma gl in
+ let env = Proofview.Goal.env gl in
let concl = Proofview.Goal.concl gl in
- let t = Retyping.get_type_of env sigma c in
- let (mind,_) = reduce_to_quantified_ind env sigma t in
+ let t = Retyping.get_type_of env (Sigma.to_evar_map sigma) c in
+ let (mind,_) = reduce_to_quantified_ind env (Sigma.to_evar_map sigma) t in
let sort = Tacticals.New.elimination_sort_of_goal gl in
- let sigma, elim =
+ let Sigma (elim, sigma, p) =
if occur_term c concl then
build_case_analysis_scheme env sigma mind true sort
else
build_case_analysis_scheme_default env sigma mind sort in
- Tacticals.New.tclTHEN (Proofview.Unsafe.tclEVARS sigma)
+ let tac =
(general_elim with_evars clear_flag (c,lbindc)
{elimindex = None; elimbody = (elim,NoBindings);
elimrename = Some (false, constructors_nrealdecls (fst mind))})
- end
+ in
+ Sigma (tac, sigma, p)
+ end }
let general_case_analysis with_evars clear_flag (c,lbindc as cx) =
match kind_of_term c with
@@ -1281,11 +1299,13 @@ let find_eliminator c gl =
let default_elim with_evars clear_flag (c,_ as cx) =
Proofview.tclORELSE
- (Proofview.Goal.enter begin fun gl ->
- let evd, elim = find_eliminator c gl in
- Tacticals.New.tclTHEN (Proofview.Unsafe.tclEVARS evd)
+ (Proofview.Goal.s_enter { s_enter = begin fun gl ->
+ let sigma, elim = find_eliminator c gl in
+ let tac =
(general_elim with_evars clear_flag cx elim)
- end)
+ in
+ Sigma.Unsafe.of_pair (tac, sigma)
+ end })
begin function (e, info) -> match e with
| IsNonrec ->
(* For records, induction principles aren't there by default
@@ -1332,9 +1352,9 @@ let clenv_fchain_in id ?(flags=elim_flags ()) mv elimclause hypclause =
let elimination_in_clause_scheme with_evars ?(flags=elim_flags ())
id rename i (elim, elimty, bindings) indclause =
- Proofview.Goal.enter begin fun gl ->
+ Proofview.Goal.enter { enter = begin fun gl ->
let env = Proofview.Goal.env gl in
- let sigma = Proofview.Goal.sigma gl in
+ let sigma = Tacmach.New.project gl in
let elim = contract_letin_in_lam_header elim in
let elimclause = make_clenv_binding env sigma (elim, elimty) bindings in
let indmv = destMeta (nth_arg i elimclause.templval.rebus) in
@@ -1355,7 +1375,7 @@ let elimination_in_clause_scheme with_evars ?(flags=elim_flags ())
(str "Nothing to rewrite in " ++ pr_id id ++ str".");
clenv_refine_in with_evars id id sigma elimclause''
(fun id -> Proofview.tclUNIT ())
- end
+ end }
let general_elim_clause with_evars flags id c e =
let elim = match id with
@@ -1387,7 +1407,7 @@ let make_projection env sigma params cstr sign elim i n c u =
then
let t = lift (i+1-n) t in
let abselim = beta_applist (elim,params@[t;branch]) in
- let c = beta_applist (abselim, [mkApp (c, extended_rel_vect 0 sign)]) in
+ let c = beta_applist (abselim, [mkApp (c, Context.Rel.to_extended_vect 0 sign)]) in
Some (it_mkLambda_or_LetIn c sign, it_mkProd_or_LetIn t sign)
else
None
@@ -1395,7 +1415,7 @@ let make_projection env sigma params cstr sign elim i n c u =
(* goes from left to right when i increases! *)
match List.nth l i with
| Some proj ->
- let args = extended_rel_vect 0 sign in
+ let args = Context.Rel.to_extended_vect 0 sign in
let proj =
if Environ.is_projection proj env then
mkProj (Projection.make proj false, mkApp (c, args))
@@ -1410,9 +1430,9 @@ let make_projection env sigma params cstr sign elim i n c u =
in elim
let descend_in_conjunctions avoid tac (err, info) c =
- Proofview.Goal.nf_enter begin fun gl ->
+ Proofview.Goal.nf_enter { enter = begin fun gl ->
let env = Proofview.Goal.env gl in
- let sigma = Proofview.Goal.sigma gl in
+ let sigma = Tacmach.New.project gl in
try
let t = Retyping.get_type_of env sigma c in
let ((ind,u),t) = reduce_to_quantified_ind env sigma t in
@@ -1427,13 +1447,14 @@ let descend_in_conjunctions avoid tac (err, info) c =
let elim =
try DefinedRecord (Recordops.lookup_projections ind)
with Not_found ->
- let elim = build_case_analysis_scheme env sigma (ind,u) false sort in
- NotADefinedRecordUseScheme (snd elim) in
+ let sigma = Sigma.Unsafe.of_evar_map sigma in
+ let Sigma (elim, _, _) = build_case_analysis_scheme env sigma (ind,u) false sort in
+ NotADefinedRecordUseScheme elim in
Tacticals.New.tclFIRST
(List.init n (fun i ->
- Proofview.Goal.enter begin fun gl ->
+ Proofview.Goal.enter { enter = begin fun gl ->
let env = Proofview.Goal.env gl in
- let sigma = Proofview.Goal.sigma gl in
+ let sigma = Tacmach.New.project gl in
match make_projection env sigma params cstr sign elim i n c u with
| None -> Tacticals.New.tclFAIL 0 (mt())
| Some (p,pt) ->
@@ -1442,31 +1463,33 @@ let descend_in_conjunctions avoid tac (err, info) c =
[Proofview.V82.tactic (refine p);
(* Might be ill-typed due to forbidden elimination. *)
Tacticals.New.onLastHypId (tac (not isrec))]
- end))
+ end }))
| None -> Proofview.tclZERO ~info err
with RefinerError _|UserError _ -> Proofview.tclZERO ~info err
- end
+ end }
(****************************************************)
(* Resolution tactics *)
(****************************************************)
let solve_remaining_apply_goals =
- Proofview.Goal.nf_enter begin fun gl ->
+ Proofview.Goal.nf_s_enter { s_enter = begin fun gl ->
+ let sigma = Proofview.Goal.sigma gl in
if !apply_solve_class_goals then
try
let env = Proofview.Goal.env gl in
- let sigma = Proofview.Goal.sigma gl in
+ let evd = Sigma.to_evar_map sigma in
let concl = Proofview.Goal.concl gl in
- if Typeclasses.is_class_type sigma concl then
- let evd', c' = Typeclasses.resolve_one_typeclass env sigma concl in
- Tacticals.New.tclTHEN
- (Proofview.Unsafe.tclEVARS evd')
- (Proofview.V82.tactic (refine_no_check c'))
- else Proofview.tclUNIT ()
- with Not_found -> Proofview.tclUNIT ()
- else Proofview.tclUNIT ()
- end
+ if Typeclasses.is_class_type evd concl then
+ let evd', c' = Typeclasses.resolve_one_typeclass env evd concl in
+ let tac =
+ (Proofview.V82.tactic (Tacmach.refine_no_check c'))
+ in
+ Sigma.Unsafe.of_pair (tac, evd')
+ else Sigma.here (Proofview.tclUNIT ()) sigma
+ with Not_found -> Sigma.here (Proofview.tclUNIT ()) sigma
+ else Sigma.here (Proofview.tclUNIT ()) sigma
+ end }
let tclORELSEOPT t k =
Proofview.tclORELSE t
@@ -1477,23 +1500,23 @@ let tclORELSEOPT t k =
| Some tac -> tac)
let general_apply with_delta with_destruct with_evars clear_flag (loc,(c,lbind)) =
- Proofview.Goal.nf_enter begin fun gl ->
+ Proofview.Goal.nf_enter { enter = begin fun gl ->
let concl = Proofview.Goal.concl gl in
let flags =
if with_delta then default_unify_flags () else default_no_delta_unify_flags () in
(* The actual type of the theorem. It will be matched against the
goal. If this fails, then the head constant will be unfolded step by
step. *)
- let concl_nprod = nb_prod concl in
+ let concl_nprod = nb_prod_modulo_zeta concl in
let rec try_main_apply with_destruct c =
- Proofview.Goal.enter begin fun gl ->
+ Proofview.Goal.enter { enter = begin fun gl ->
let env = Proofview.Goal.env gl in
- let sigma = Proofview.Goal.sigma gl in
+ let sigma = Tacmach.New.project gl in
let thm_ty0 = nf_betaiota sigma (Retyping.get_type_of env sigma c) in
let try_apply thm_ty nprod =
try
- let n = nb_prod thm_ty - nprod in
+ let n = nb_prod_modulo_zeta thm_ty - nprod in
if n<0 then error "Applied theorem has not enough premisses.";
let clause = make_clenv_binding_apply env sigma (Some n) (c,thm_ty) lbind in
Clenvtac.res_pf clause ~with_evars ~flags
@@ -1540,14 +1563,14 @@ let general_apply with_delta with_destruct with_evars clear_flag (loc,(c,lbind))
| PretypeError _|RefinerError _|UserError _|Failure _ ->
Some (try_red_apply thm_ty0 (e, info))
| _ -> None)
- end
+ end }
in
Tacticals.New.tclTHENLIST [
try_main_apply with_destruct c;
solve_remaining_apply_goals;
apply_clear_request clear_flag (use_clear_hyp_by_default ()) c
]
- end
+ end }
let rec apply_with_bindings_gen b e = function
| [] -> Proofview.tclUNIT ()
@@ -1559,13 +1582,13 @@ let rec apply_with_bindings_gen b e = function
let apply_with_delayed_bindings_gen b e l =
let one k (loc, f) =
- Proofview.Goal.enter begin fun gl ->
- let sigma = Proofview.Goal.sigma gl in
+ Proofview.Goal.enter { enter = begin fun gl ->
+ let sigma = Tacmach.New.project gl in
let env = Proofview.Goal.env gl in
- let sigma, cb = f env sigma in
+ let (cb, sigma) = run_delayed env sigma f in
Tacticals.New.tclWITHHOLES e
(general_apply b b e k (loc,cb)) sigma
- end
+ end }
in
let rec aux = function
| [] -> Proofview.tclUNIT ()
@@ -1628,18 +1651,18 @@ let apply_in_once_main flags innerclause env sigma (d,lbind) =
let apply_in_once sidecond_first with_delta with_destruct with_evars naming
id (clear_flag,(loc,(d,lbind))) tac =
- Proofview.Goal.nf_enter begin fun gl ->
+ Proofview.Goal.nf_enter { enter = begin fun gl ->
let env = Proofview.Goal.env gl in
- let sigma = Proofview.Goal.sigma gl in
+ let sigma = Tacmach.New.project gl in
let flags =
if with_delta then default_unify_flags () else default_no_delta_unify_flags () in
let t' = Tacmach.New.pf_get_hyp_typ id gl in
let innerclause = mk_clenv_from_env env sigma (Some 0) (mkVar id,t') in
let targetid = find_name true (Anonymous,None,t') naming gl in
let rec aux idstoclear with_destruct c =
- Proofview.Goal.enter begin fun gl ->
+ Proofview.Goal.enter { enter = begin fun gl ->
let env = Proofview.Goal.env gl in
- let sigma = Proofview.Goal.sigma gl in
+ let sigma = Tacmach.New.project gl in
try
let clause = apply_in_once_main flags innerclause env sigma (c,lbind) in
clenv_refine_in ~sidecond_first with_evars targetid id sigma clause
@@ -1654,22 +1677,22 @@ let apply_in_once sidecond_first with_delta with_destruct with_evars naming
(descend_in_conjunctions [targetid]
(fun b id -> aux (id::idstoclear) b (mkVar id))
(e, info) c)
- end
+ end }
in
aux [] with_destruct d
- end
+ end }
let apply_in_delayed_once sidecond_first with_delta with_destruct with_evars naming
id (clear_flag,(loc,f)) tac =
- Proofview.Goal.enter begin fun gl ->
+ Proofview.Goal.enter { enter = begin fun gl ->
let env = Proofview.Goal.env gl in
- let sigma = Proofview.Goal.sigma gl in
- let sigma, c = f env sigma in
+ let sigma = Tacmach.New.project gl in
+ let (c, sigma) = run_delayed env sigma f in
Tacticals.New.tclWITHHOLES with_evars
(apply_in_once sidecond_first with_delta with_destruct with_evars
naming id (clear_flag,(loc,c)) tac)
sigma
- end
+ end }
(* A useful resolution tactic which, if c:A->B, transforms |- C into
|- B -> C and |- A
@@ -1689,20 +1712,20 @@ let apply_in_delayed_once sidecond_first with_delta with_destruct with_evars nam
*)
let cut_and_apply c =
- Proofview.Goal.nf_enter begin fun gl ->
+ Proofview.Goal.nf_enter { enter = begin fun gl ->
match kind_of_term (Tacmach.New.pf_hnf_constr gl (Tacmach.New.pf_unsafe_type_of gl c)) with
| Prod (_,c1,c2) when not (dependent (mkRel 1) c2) ->
let concl = Proofview.Goal.concl gl in
let env = Tacmach.New.pf_env gl in
- Proofview.Refine.refine begin fun sigma ->
+ Proofview.Refine.refine { run = begin fun sigma ->
let typ = mkProd (Anonymous, c2, concl) in
- let (sigma, f) = Evarutil.new_evar env sigma typ in
- let (sigma, x) = Evarutil.new_evar env sigma c1 in
+ let Sigma (f, sigma, p) = Evarutil.new_evar env sigma typ in
+ let Sigma (x, sigma, q) = Evarutil.new_evar env sigma c1 in
let ans = mkApp (f, [|mkApp (c, [|x|])|]) in
- (sigma, ans)
- end
+ Sigma (ans, sigma, p +> q)
+ end }
| _ -> error "lapply needs a non-dependent product."
- end
+ end }
(********************************************************************)
(* Exact tactics *)
@@ -1715,33 +1738,36 @@ let cut_and_apply c =
(* let refine_no_check = Profile.profile2 refine_no_checkkey refine_no_check *)
let new_exact_no_check c =
- Proofview.Refine.refine ~unsafe:true (fun h -> (h, c))
+ Proofview.Refine.refine ~unsafe:true { run = fun h -> Sigma.here c h }
let exact_check c =
- Proofview.Goal.enter begin fun gl ->
+ Proofview.Goal.s_enter { s_enter = begin fun gl ->
+ let sigma = Proofview.Goal.sigma gl in
(** We do not need to normalize the goal because we just check convertibility *)
let concl = Proofview.Goal.concl (Proofview.Goal.assume gl) in
let env = Proofview.Goal.env gl in
- let sigma = Proofview.Goal.sigma gl in
+ let sigma = Sigma.to_evar_map sigma in
let sigma, ct = Typing.type_of env sigma c in
- Proofview.Unsafe.tclEVARS sigma <*>
+ let tac =
Tacticals.New.tclTHEN (convert_leq ct concl) (new_exact_no_check c)
- end
+ in
+ Sigma.Unsafe.of_pair (tac, sigma)
+ end }
-let exact_no_check = refine_no_check
+let exact_no_check = Tacmach.refine_no_check
let vm_cast_no_check c gl =
- let concl = pf_concl gl in
- refine_no_check (Term.mkCast(c,Term.VMcast,concl)) gl
+ let concl = Tacmach.pf_concl gl in
+ Tacmach.refine_no_check (Term.mkCast(c,Term.VMcast,concl)) gl
let native_cast_no_check c gl =
- let concl = pf_concl gl in
- refine_no_check (Term.mkCast(c,Term.NATIVEcast,concl)) gl
+ let concl = Tacmach.pf_concl gl in
+ Tacmach.refine_no_check (Term.mkCast(c,Term.NATIVEcast,concl)) gl
let exact_proof c gl =
- let c,ctx = Constrintern.interp_casted_constr (pf_env gl) (project gl) c (pf_concl gl)
- in tclTHEN (tclEVARUNIVCONTEXT ctx) (refine_no_check c) gl
+ let c,ctx = Constrintern.interp_casted_constr (Tacmach.pf_env gl) (Tacmach.project gl) c (Tacmach.pf_concl gl)
+ in tclTHEN (tclEVARUNIVCONTEXT ctx) (Tacmach.refine_no_check c) gl
let assumption =
let rec arec gl only_eq = function
@@ -1752,7 +1778,7 @@ let assumption =
else Tacticals.New.tclZEROMSG (str "No such assumption.")
| (id, c, t)::rest ->
let concl = Proofview.Goal.concl gl in
- let sigma = Proofview.Goal.sigma gl in
+ let sigma = Tacmach.New.project gl in
let (sigma, is_same_type) =
if only_eq then (sigma, Constr.equal t concl)
else
@@ -1761,13 +1787,13 @@ let assumption =
in
if is_same_type then
(Proofview.Unsafe.tclEVARS sigma) <*>
- Proofview.Refine.refine ~unsafe:true (fun h -> (h, mkVar id))
+ Proofview.Refine.refine ~unsafe:true { run = fun h -> Sigma.here (mkVar id) h }
else arec gl only_eq rest
in
- let assumption_tac gl =
+ let assumption_tac = { enter = begin fun gl ->
let hyps = Proofview.Goal.hyps gl in
arec gl true hyps
- in
+ end } in
Proofview.Goal.nf_enter assumption_tac
(*****************************************************************)
@@ -1810,7 +1836,7 @@ let check_decl env (_, c, ty) msg =
msg e
let clear_body ids =
- Proofview.Goal.enter begin fun gl ->
+ Proofview.Goal.enter { enter = begin fun gl ->
let env = Proofview.Goal.env gl in
let concl = Proofview.Goal.concl (Proofview.Goal.assume gl) in
let ctx = named_context env in
@@ -1843,10 +1869,10 @@ let clear_body ids =
check_is_type env concl msg
in
check_hyps <*> check_concl <*>
- Proofview.Refine.refine ~unsafe:true begin fun sigma ->
+ Proofview.Refine.refine ~unsafe:true { run = begin fun sigma ->
Evarutil.new_evar env sigma ~principal:true concl
- end
- end
+ end }
+ end }
let clear_wildcards ids =
Proofview.V82.tactic (tclMAP (fun (loc,id) gl ->
@@ -1868,45 +1894,10 @@ let rec intros_clearing = function
Tacticals.New.tclTHENLIST
[ intro; Tacticals.New.onLastHypId (fun id -> Proofview.V82.tactic (clear [id])); intros_clearing tl]
-(* Modifying/Adding an hypothesis *)
-
-let specialize (c,lbind) g =
- let tac, term =
- if lbind == NoBindings then
- let evd = Typeclasses.resolve_typeclasses (pf_env g) (project g) in
- tclEVARS evd, nf_evar evd c
- else
- let clause = pf_apply make_clenv_binding g (c,pf_unsafe_type_of g c) lbind in
- let flags = { (default_unify_flags ()) with resolve_evars = true } in
- let clause = clenv_unify_meta_types ~flags clause in
- let (thd,tstack) = whd_nored_stack clause.evd (clenv_value clause) in
- let rec chk = function
- | [] -> []
- | t::l -> if occur_meta t then [] else t :: chk l
- in
- let tstack = chk tstack in
- let term = applist(thd,List.map (nf_evar clause.evd) tstack) in
- if occur_meta term then
- errorlabstrm "" (str "Cannot infer an instance for " ++
- pr_name (meta_name clause.evd (List.hd (collect_metas term))) ++
- str ".");
- tclEVARS clause.evd, term
- in
- match kind_of_term (fst(decompose_app (snd(decompose_lam_assum c)))) with
- | Var id when Id.List.mem id (pf_ids_of_hyps g) ->
- tclTHEN tac
- (tclTHENFIRST
- (fun g -> Proofview.V82.of_tactic (assert_before_replacing id (pf_unsafe_type_of g term)) g)
- (exact_no_check term)) g
- | _ -> tclTHEN tac
- (tclTHENLAST
- (fun g -> Proofview.V82.of_tactic (cut (pf_unsafe_type_of g term)) g)
- (exact_no_check term)) g
-
(* Keeping only a few hypotheses *)
let keep hyps =
- Proofview.Goal.nf_enter begin fun gl ->
+ Proofview.Goal.nf_enter { enter = begin fun gl ->
Proofview.tclENV >>= fun env ->
let ccl = Proofview.Goal.concl gl in
let cl,_ =
@@ -1919,7 +1910,54 @@ let keep hyps =
~init:([],[]) (Proofview.Goal.env gl)
in
Proofview.V82.tactic (fun gl -> thin cl gl)
- end
+ end }
+
+(*********************************)
+(* Basic generalization tactics *)
+(*********************************)
+
+(* Given a type [T] convertible to [forall x1..xn:A1..An(x1..xn-1), G(x1..xn)]
+ and [a1..an:A1..An(a1..an-1)] such that the goal is [G(a1..an)],
+ this generalizes [hyps |- goal] into [hyps |- T] *)
+
+let apply_type newcl args =
+ Proofview.Goal.enter { enter = begin fun gl ->
+ let env = Proofview.Goal.env gl in
+ let store = Proofview.Goal.extra gl in
+ Proofview.Refine.refine { run = begin fun sigma ->
+ let newcl = nf_betaiota (Sigma.to_evar_map sigma) newcl (* As in former Logic.refine *) in
+ let Sigma (ev, sigma, p) =
+ Evarutil.new_evar env sigma ~principal:true ~store newcl in
+ Sigma (applist (ev, args), sigma, p)
+ end }
+ end }
+
+(* Given a context [hyps] with domain [x1..xn], possibly with let-ins,
+ and well-typed in the current goal, [bring_hyps hyps] generalizes
+ [ctxt |- G(x1..xn] into [ctxt |- forall hyps, G(x1..xn)] *)
+
+let bring_hyps hyps =
+ if List.is_empty hyps then Tacticals.New.tclIDTAC
+ else
+ Proofview.Goal.enter { enter = begin fun gl ->
+ let env = Proofview.Goal.env gl in
+ let store = Proofview.Goal.extra gl in
+ let concl = Tacmach.New.pf_nf_concl gl in
+ let newcl = List.fold_right mkNamedProd_or_LetIn hyps concl in
+ let args = Array.of_list (Context.Named.to_instance hyps) in
+ Proofview.Refine.refine { run = begin fun sigma ->
+ let Sigma (ev, sigma, p) =
+ Evarutil.new_evar env sigma ~principal:true ~store newcl in
+ Sigma (mkApp (ev, args), sigma, p)
+ end }
+ end }
+
+let revert hyps =
+ Proofview.Goal.enter { enter = begin fun gl ->
+ let gl = Proofview.Goal.assume gl in
+ let ctx = List.map (fun id -> Tacmach.New.pf_get_hyp id gl) hyps in
+ (bring_hyps ctx) <*> (Proofview.V82.tactic (clear hyps))
+ end }
(************************)
(* Introduction tactics *)
@@ -1936,7 +1974,8 @@ let check_number_of_constructors expctdnumopt i nconstr =
if i > nconstr then error "Not enough constructors."
let constructor_tac with_evars expctdnumopt i lbind =
- Proofview.Goal.enter begin fun gl ->
+ Proofview.Goal.s_enter { s_enter = begin fun gl ->
+ let sigma = Proofview.Goal.sigma gl in
let cl = Tacmach.New.pf_nf_concl gl in
let reduce_to_quantified_ind =
Tacmach.New.pf_apply Tacred.reduce_to_quantified_ind gl
@@ -1946,16 +1985,19 @@ let constructor_tac with_evars expctdnumopt i lbind =
Array.length (snd (Global.lookup_inductive (fst mind))).mind_consnames in
check_number_of_constructors expctdnumopt i nconstr;
- let sigma, cons = Evd.fresh_constructor_instance
- (Proofview.Goal.env gl) (Proofview.Goal.sigma gl) (fst mind, i) in
+ let Sigma (cons, sigma, p) = Sigma.fresh_constructor_instance
+ (Proofview.Goal.env gl) sigma (fst mind, i) in
let cons = mkConstructU cons in
let apply_tac = general_apply true false with_evars None (dloc,(cons,lbind)) in
+ let tac =
(Tacticals.New.tclTHENLIST
- [Proofview.Unsafe.tclEVARS sigma;
+ [
convert_concl_no_check redcl DEFAULTcast;
intros; apply_tac])
- end
+ in
+ Sigma (tac, sigma, p)
+ end }
let one_constructor i lbind = constructor_tac false None i lbind
@@ -1972,7 +2014,7 @@ let rec tclANY tac = function
let any_constructor with_evars tacopt =
let t = match tacopt with None -> Proofview.tclUNIT () | Some t -> t in
let tac i = Tacticals.New.tclTHEN (constructor_tac with_evars None i NoBindings) t in
- Proofview.Goal.enter begin fun gl ->
+ Proofview.Goal.enter { enter = begin fun gl ->
let cl = Tacmach.New.pf_nf_concl gl in
let reduce_to_quantified_ind =
Tacmach.New.pf_apply Tacred.reduce_to_quantified_ind gl
@@ -1982,7 +2024,7 @@ let any_constructor with_evars tacopt =
Array.length (snd (Global.lookup_inductive (fst mind))).mind_consnames in
if Int.equal nconstr 0 then error "The type has no constructors.";
tclANY tac (List.interval 1 nconstr)
- end
+ end }
let left_with_bindings with_evars = constructor_tac with_evars (Some 2) 1
let right_with_bindings with_evars = constructor_tac with_evars (Some 2) 2
@@ -2033,7 +2075,7 @@ let my_find_eq_data_decompose gl t =
| Constr_matching.PatternMatchingFailure -> None
let intro_decomp_eq loc l thin tac id =
- Proofview.Goal.nf_enter begin fun gl ->
+ Proofview.Goal.nf_enter { enter = begin fun gl ->
let c = mkVar id in
let t = Tacmach.New.pf_unsafe_type_of gl c in
let _,t = Tacmach.New.pf_reduce_to_quantified_ind gl t in
@@ -2044,21 +2086,22 @@ let intro_decomp_eq loc l thin tac id =
(eq,t,eq_args) (c, t)
| None ->
Tacticals.New.tclZEROMSG (str "Not a primitive equality here.")
- end
+ end }
let intro_or_and_pattern loc bracketed ll thin tac id =
- Proofview.Goal.enter begin fun gl ->
+ Proofview.Goal.enter { enter = begin fun gl ->
let c = mkVar id in
let t = Tacmach.New.pf_unsafe_type_of gl c in
- let ((ind,u),t) = Tacmach.New.pf_reduce_to_quantified_ind gl t in
- let nv = constructors_nrealargs ind in
- let ll = fix_empty_or_and_pattern (Array.length nv) ll in
- check_or_and_pattern_size loc ll (Array.length nv);
+ let (ind,t) = Tacmach.New.pf_reduce_to_quantified_ind gl t in
+ let branchsigns = compute_constructor_signatures false ind in
+ let nv_with_let = Array.map List.length branchsigns in
+ let ll = fix_empty_or_and_pattern (Array.length branchsigns) ll in
+ let ll = get_and_check_or_and_pattern loc ll branchsigns in
Tacticals.New.tclTHENLASTn
(Tacticals.New.tclTHEN (simplest_case c) (Proofview.V82.tactic (clear [id])))
(Array.map2 (fun n l -> tac thin (Some (bracketed,n)) l)
- nv (Array.of_list ll))
- end
+ nv_with_let ll)
+ end }
let rewrite_hyp assert_style l2r id =
let rew_on l2r =
@@ -2066,7 +2109,7 @@ let rewrite_hyp assert_style l2r id =
let subst_on l2r x rhs =
Hook.get forward_subst_one true x (id,rhs,l2r) in
let clear_var_and_eq c = tclTHEN (clear [id]) (clear [destVar c]) in
- Proofview.Goal.enter begin fun gl ->
+ Proofview.Goal.enter { enter = begin fun gl ->
let env = Proofview.Goal.env gl in
let type_of = Tacmach.New.pf_unsafe_type_of gl in
let whd_betadeltaiota = Tacmach.New.pf_apply whd_betadeltaiota gl in
@@ -2088,9 +2131,9 @@ let rewrite_hyp assert_style l2r id =
Tacticals.New.tclTHEN (rew_on l2r onConcl) (Proofview.V82.tactic (clear [id]))
| _ ->
Tacticals.New.tclTHEN (rew_on l2r onConcl) (Proofview.V82.tactic (clear [id]))
- end
+ end }
-let rec prepare_naming loc = function
+let prepare_naming loc = function
| IntroIdentifier id -> NamingMustBe (loc,id)
| IntroAnonymous -> NamingAvoid []
| IntroFresh id -> NamingBasedOn (id,[])
@@ -2098,7 +2141,8 @@ let rec prepare_naming loc = function
let rec explicit_intro_names = function
| (_, IntroForthcoming _) :: l -> explicit_intro_names l
| (_, IntroNaming (IntroIdentifier id)) :: l -> id :: explicit_intro_names l
-| (_, IntroAction (IntroOrAndPattern ll)) :: l' ->
+| (_, IntroAction (IntroOrAndPattern l)) :: l' ->
+ let ll = match l with IntroAndPattern l -> [l] | IntroOrPattern ll -> ll in
List.flatten (List.map (fun l -> explicit_intro_names (l@l')) ll)
| (_, IntroAction (IntroInjection l)) :: l' ->
explicit_intro_names (l@l')
@@ -2212,7 +2256,7 @@ and intro_pattern_action loc b style pat thin destopt tac id = match pat with
| IntroInjection l' ->
intro_decomp_eq loc l' thin tac id
| IntroRewrite l2r ->
- Tacticals.New.tclTHENLAST
+ Tacticals.New.tclTHENFIRST
(* Skip the side conditions of the rewriting step *)
(rewrite_hyp style l2r id)
(tac thin None [])
@@ -2224,7 +2268,10 @@ and intro_pattern_action loc b style pat thin destopt tac id = match pat with
Proofview.tclUNIT () (* apply_in_once do a replacement *)
else
Proofview.V82.tactic (clear [id]) in
- let f env sigma = let (sigma,c) = f env sigma in (sigma,(c,NoBindings)) in
+ let f = { delayed = fun env sigma ->
+ let Sigma (c, sigma, p) = f.delayed env sigma in
+ Sigma ((c, NoBindings), sigma, p)
+ } in
apply_in_delayed_once false true true true naming id (None,(loc,f))
(fun id -> Tacticals.New.tclTHENLIST [doclear; tac_ipat id; tac thin None []])
@@ -2289,7 +2336,7 @@ let general_apply_in sidecond_first with_delta with_destruct with_evars
let tac (naming,lemma) tac id =
apply_in_delayed_once sidecond_first with_delta with_destruct with_evars
naming id lemma tac in
- Proofview.Goal.enter begin fun gl ->
+ Proofview.Goal.enter { enter = begin fun gl ->
let destopt =
if with_evars then MoveLast (* evars would depend on the whole context *)
else get_previous_hyp_position id gl in
@@ -2300,7 +2347,7 @@ let general_apply_in sidecond_first with_delta with_destruct with_evars
in
(* We chain apply_in_once, ending with an intro pattern *)
List.fold_right tac lemmas_target (tac last_lemma_target ipat_tac) id
- end
+ end }
(*
if sidecond_first then
@@ -2311,7 +2358,7 @@ let general_apply_in sidecond_first with_delta with_destruct with_evars
*)
let apply_in simple with_evars id lemmas ipat =
- let lemmas = List.map (fun (k,(loc,l)) -> k, (loc, fun _ sigma -> sigma, l)) lemmas in
+ let lemmas = List.map (fun (k,(loc,l)) -> k, (loc, { delayed = fun _ sigma -> Sigma.here l sigma })) lemmas in
general_apply_in false simple simple with_evars id lemmas ipat
let apply_delayed_in simple with_evars id lemmas ipat =
@@ -2342,16 +2389,17 @@ let decode_hyp = function
*)
let letin_tac_gen with_eq (id,depdecls,lastlhyp,ccl,c) ty =
- Proofview.Goal.enter begin fun gl ->
- let env = Proofview.Goal.env gl in
+ Proofview.Goal.s_enter { s_enter = begin fun gl ->
let sigma = Proofview.Goal.sigma gl in
- let (sigma, t) = match ty with
- | Some t -> (sigma, t)
+ let env = Proofview.Goal.env gl in
+ let Sigma (t, sigma, p) = match ty with
+ | Some t -> Sigma.here t sigma
| None ->
let t = typ_of env sigma c in
- Evarsolve.refresh_universes ~onlyalg:true (Some false) env sigma t
+ let sigma, c = Evarsolve.refresh_universes ~onlyalg:true (Some false) env (Sigma.to_evar_map sigma) t in
+ Sigma.Unsafe.of_pair (c, sigma)
in
- let eq_tac gl = match with_eq with
+ let Sigma ((newcl, eq_tac), sigma, q) = match with_eq with
| Some (lr,(loc,ido)) ->
let heq = match ido with
| IntroAnonymous -> new_fresh_id [id] (add_prefix "Heq" id) gl
@@ -2359,26 +2407,31 @@ let letin_tac_gen with_eq (id,depdecls,lastlhyp,ccl,c) ty =
| IntroIdentifier id -> id in
let eqdata = build_coq_eq_data () in
let args = if lr then [t;mkVar id;c] else [t;c;mkVar id]in
- let sigma, eq = Evd.fresh_global env sigma eqdata.eq in
- let sigma, refl = Evd.fresh_global env sigma eqdata.refl in
+ let Sigma (eq, sigma, p) = Sigma.fresh_global env sigma eqdata.eq in
+ let Sigma (refl, sigma, q) = Sigma.fresh_global env sigma eqdata.refl in
let eq = applist (eq,args) in
let refl = applist (refl, [t;mkVar id]) in
let term = mkNamedLetIn id c t (mkLetIn (Name heq, refl, eq, ccl)) in
+ let sigma = Sigma.to_evar_map sigma in
let sigma, _ = Typing.type_of env sigma term in
- sigma, term,
+ let ans = term,
Tacticals.New.tclTHEN
(intro_gen (NamingMustBe (loc,heq)) (decode_hyp lastlhyp) true false)
(clear_body [heq;id])
+ in
+ Sigma.Unsafe.of_pair (ans, sigma)
| None ->
- (sigma, mkNamedLetIn id c t ccl, Proofview.tclUNIT ()) in
- let (sigma,newcl,eq_tac) = eq_tac gl in
- Tacticals.New.tclTHENLIST
- [ Proofview.Unsafe.tclEVARS sigma;
- convert_concl_no_check newcl DEFAULTcast;
+ Sigma.here (mkNamedLetIn id c t ccl, Proofview.tclUNIT ()) sigma
+ in
+ let tac =
+ Tacticals.New.tclTHENLIST
+ [ convert_concl_no_check newcl DEFAULTcast;
intro_gen (NamingMustBe (dloc,id)) (decode_hyp lastlhyp) true false;
Tacticals.New.tclMAP convert_hyp_no_check depdecls;
eq_tac ]
- end
+ in
+ Sigma (tac, sigma, p +> q)
+ end }
let insert_before decls lasthyp env =
match lasthyp with
@@ -2406,55 +2459,57 @@ let mkletin_goal env sigma store with_eq dep (id,lastlhyp,ccl,c) ty =
id in
let eqdata = build_coq_eq_data () in
let args = if lr then [t;mkVar id;c] else [t;c;mkVar id]in
- let sigma, eq = Evd.fresh_global env sigma eqdata.eq in
- let sigma, refl = Evd.fresh_global env sigma eqdata.refl in
+ let Sigma (eq, sigma, p) = Sigma.fresh_global env sigma eqdata.eq in
+ let Sigma (refl, sigma, q) = Sigma.fresh_global env sigma eqdata.refl in
let eq = applist (eq,args) in
let refl = applist (refl, [t;mkVar id]) in
let newenv = insert_before [heq,None,eq;id,body,t] lastlhyp env in
- let (sigma,x) = new_evar newenv sigma ~principal:true ~store ccl in
- (sigma,mkNamedLetIn id c t (mkNamedLetIn heq refl eq x))
+ let Sigma (x, sigma, r) = new_evar newenv sigma ~principal:true ~store ccl in
+ Sigma (mkNamedLetIn id c t (mkNamedLetIn heq refl eq x), sigma, p +> q +> r)
| None ->
let newenv = insert_before [id,body,t] lastlhyp env in
- let (sigma,x) = new_evar newenv sigma ~principal:true ~store ccl in
- (sigma,mkNamedLetIn id c t x)
+ let Sigma (x, sigma, p) = new_evar newenv sigma ~principal:true ~store ccl in
+ Sigma (mkNamedLetIn id c t x, sigma, p)
let letin_tac with_eq id c ty occs =
- Proofview.Goal.nf_enter begin fun gl ->
- let env = Proofview.Goal.env gl in
+ Proofview.Goal.nf_s_enter { s_enter = begin fun gl ->
let sigma = Proofview.Goal.sigma gl in
+ let env = Proofview.Goal.env gl in
let ccl = Proofview.Goal.concl gl in
let abs = AbstractExact (id,c,ty,occs,true) in
let (id,_,depdecls,lastlhyp,ccl,_) = make_abstraction env sigma ccl abs in
(* We keep the original term to match *)
- letin_tac_gen with_eq (id,depdecls,lastlhyp,ccl,c) ty
- end
+ let tac = letin_tac_gen with_eq (id,depdecls,lastlhyp,ccl,c) ty in
+ Sigma.here tac sigma
+ end }
let letin_pat_tac with_eq id c occs =
- Proofview.Goal.nf_enter begin fun gl ->
- let env = Proofview.Goal.env gl in
+ Proofview.Goal.nf_s_enter { s_enter = begin fun gl ->
let sigma = Proofview.Goal.sigma gl in
+ let env = Proofview.Goal.env gl in
let ccl = Proofview.Goal.concl gl in
let check t = true in
let abs = AbstractPattern (false,check,id,c,occs,false) in
let (id,_,depdecls,lastlhyp,ccl,res) = make_abstraction env sigma ccl abs in
- let sigma,c = match res with
+ let Sigma (c, sigma, p) = match res with
| None -> finish_evar_resolution ~flags:(tactic_infer_flags false) env sigma c
- | Some (sigma,c) -> (sigma,c) in
- Tacticals.New.tclTHEN
- (Proofview.Unsafe.tclEVARS sigma)
+ | Some res -> res in
+ let tac =
(letin_tac_gen with_eq (id,depdecls,lastlhyp,ccl,c) None)
- end
+ in
+ Sigma (tac, sigma, p)
+ end }
(* Tactics "pose proof" (usetac=None) and "assert"/"enough" (otherwise) *)
let forward b usetac ipat c =
match usetac with
| None ->
- Proofview.Goal.enter begin fun gl ->
+ Proofview.Goal.enter { enter = begin fun gl ->
let t = Tacmach.New.pf_unsafe_type_of gl c in
let hd = head_ident c in
Tacticals.New.tclTHENFIRST (assert_as true hd ipat t)
(Proofview.V82.tactic (exact_no_check c))
- end
+ end }
| Some tac ->
if b then
Tacticals.New.tclTHENFIRST (assert_as b None ipat c) tac
@@ -2470,40 +2525,6 @@ let enough_by na t tac = forward false (Some tac) (ipat_of_name na) t
(* Generalization tactics *)
(***************************)
-(* Given a type [T] convertible to [forall x1..xn:A1..An(x1..xn-1), G(x1..xn)]
- and [a1..an:A1..An(a1..an-1)] such that the goal is [G(a1..an)],
- this generalizes [hyps |- goal] into [hyps |- T] *)
-
-let apply_type hdcty argl gl =
- refine (applist (mkCast (Evarutil.mk_new_meta(),DEFAULTcast, hdcty),argl)) gl
-
-(* Given a context [hyps] with domain [x1..xn], possibly with let-ins,
- and well-typed in the current goal, [bring_hyps hyps] generalizes
- [ctxt |- G(x1..xn] into [ctxt |- forall hyps, G(x1..xn)] *)
-
-let bring_hyps hyps =
- if List.is_empty hyps then Tacticals.New.tclIDTAC
- else
- Proofview.Goal.enter begin fun gl ->
- let env = Proofview.Goal.env gl in
- let store = Proofview.Goal.extra gl in
- let concl = Tacmach.New.pf_nf_concl gl in
- let newcl = List.fold_right mkNamedProd_or_LetIn hyps concl in
- let args = Array.of_list (instance_from_named_context hyps) in
- Proofview.Refine.refine begin fun sigma ->
- let (sigma, ev) =
- Evarutil.new_evar env sigma ~principal:true ~store newcl in
- (sigma, (mkApp (ev, args)))
- end
- end
-
-let revert hyps =
- Proofview.Goal.enter begin fun gl ->
- let gl = Proofview.Goal.assume gl in
- let ctx = List.map (fun id -> Tacmach.New.pf_get_hyp id gl) hyps in
- (bring_hyps ctx) <*> (Proofview.V82.tactic (clear hyps))
- end
-
(* Compute a name for a generalization *)
let generalized_name c t ids cl = function
@@ -2527,18 +2548,19 @@ let generalized_name c t ids cl = function
[forall x, x1:A1(x1), .., xi:Ai(x). T(x)] with all [c] abtracted in [Ai]
but only those at [occs] in [T] *)
-let generalize_goal_gen env ids i ((occs,c,b),na) t (cl,evd) =
+let generalize_goal_gen env sigma ids i ((occs,c,b),na) t cl =
let decls,cl = decompose_prod_n_assum i cl in
let dummy_prod = it_mkProd_or_LetIn mkProp decls in
let newdecls,_ = decompose_prod_n_assum i (subst_term_gen eq_constr_nounivs c dummy_prod) in
- let cl',evd' = subst_closed_term_occ env evd (AtOccs occs) c (it_mkProd_or_LetIn cl newdecls) in
+ let cl',sigma' = subst_closed_term_occ env sigma (AtOccs occs) c (it_mkProd_or_LetIn cl newdecls) in
let na = generalized_name c t ids cl' na in
- mkProd_or_LetIn (na,b,t) cl', evd'
+ mkProd_or_LetIn (na,b,t) cl', sigma'
-let generalize_goal gl i ((occs,c,b),na as o) cl =
- let t = pf_unsafe_type_of gl c in
- let env = pf_env gl in
- generalize_goal_gen env (pf_ids_of_hyps gl) i o t cl
+let generalize_goal gl i ((occs,c,b),na as o) (cl,sigma) =
+ let env = Tacmach.pf_env gl in
+ let ids = Tacmach.pf_ids_of_hyps gl in
+ let sigma, t = Typing.type_of env sigma c in
+ generalize_goal_gen env sigma ids i o t cl
let generalize_dep ?(with_let=false) c gl =
let env = pf_env gl in
@@ -2550,7 +2572,7 @@ let generalize_dep ?(with_let=false) c gl =
d::toquant
else
toquant in
- let to_quantify = Context.fold_named_context seek sign ~init:[] in
+ let to_quantify = Context.Named.fold_outside seek sign ~init:[] in
let to_quantify_rev = List.rev to_quantify in
let qhyps = List.map (fun (id,_,_) -> id) to_quantify_rev in
let tothin = List.filter (fun id -> not (Id.List.mem id init_ids)) qhyps in
@@ -2560,20 +2582,20 @@ let generalize_dep ?(with_let=false) c gl =
-> id::tothin
| _ -> tothin
in
- let cl' = it_mkNamedProd_or_LetIn (pf_concl gl) to_quantify in
+ let cl' = it_mkNamedProd_or_LetIn (Tacmach.pf_concl gl) to_quantify in
let body =
if with_let then
match kind_of_term c with
- | Var id -> pi2 (pf_get_hyp gl id)
+ | Var id -> pi2 (Tacmach.pf_get_hyp gl id)
| _ -> None
else None
in
let cl'',evd = generalize_goal gl 0 ((AllOccurrences,c,body),Anonymous)
(cl',project gl) in
- let args = instance_from_named_context to_quantify_rev in
+ let args = Context.Named.to_instance to_quantify_rev in
tclTHENLIST
[tclEVARS evd;
- apply_type cl'' (if Option.is_empty body then c::args else args);
+ Proofview.V82.of_tactic (apply_type cl'' (if Option.is_empty body then c::args else args));
thin (List.rev tothin')]
gl
@@ -2581,36 +2603,41 @@ let generalize_dep ?(with_let=false) c gl =
let generalize_gen_let lconstr gl =
let newcl, evd =
List.fold_right_i (generalize_goal gl) 0 lconstr
- (pf_concl gl,project gl)
+ (Tacmach.pf_concl gl,Tacmach.project gl)
in
- tclTHEN (tclEVARS evd)
+ Proofview.V82.of_tactic (Tacticals.New.tclTHEN (Proofview.Unsafe.tclEVARS evd)
(apply_type newcl (List.map_filter (fun ((_,c,b),_) ->
- if Option.is_empty b then Some c else None) lconstr)) gl
+ if Option.is_empty b then Some c else None) lconstr))) gl
let new_generalize_gen_let lconstr =
- Proofview.Goal.enter begin fun gl ->
+ Proofview.Goal.s_enter { s_enter = begin fun gl ->
+ let sigma = Proofview.Goal.sigma gl in
let gl = Proofview.Goal.assume gl in
let concl = Proofview.Goal.concl gl in
- let sigma = Proofview.Goal.sigma gl in
+ let sigma = Sigma.to_evar_map sigma in
let env = Proofview.Goal.env gl in
let ids = Tacmach.New.pf_ids_of_hyps gl in
- let (newcl, sigma), args =
+ let newcl, sigma, args =
List.fold_right_i
- (fun i ((_,c,b),_ as o) (cl, args) ->
- let t = Tacmach.New.pf_unsafe_type_of gl c in
+ (fun i ((_,c,b),_ as o) (cl, sigma, args) ->
+ let sigma, t = Typing.type_of env sigma c in
let args = if Option.is_empty b then c :: args else args in
- generalize_goal_gen env ids i o t cl, args)
- 0 lconstr ((concl, sigma), [])
+ let cl, sigma = generalize_goal_gen env sigma ids i o t cl in
+ (cl, sigma, args))
+ 0 lconstr (concl, sigma, [])
in
- Proofview.Unsafe.tclEVARS sigma <*>
- Proofview.Refine.refine begin fun sigma ->
- let (sigma, ev) = Evarutil.new_evar env sigma ~principal:true newcl in
- (sigma, (applist (ev, args)))
- end
- end
+ let tac =
+ Proofview.Refine.refine { run = begin fun sigma ->
+ let Sigma (ev, sigma, p) = Evarutil.new_evar env sigma ~principal:true newcl in
+ Sigma ((applist (ev, args)), sigma, p)
+ end }
+ in
+ Sigma.Unsafe.of_pair (tac, sigma)
+ end }
let generalize_gen lconstr =
- generalize_gen_let (List.map (fun ((occs,c),na) ->
+ generalize_gen_let (List.map (fun (occs_c,na) ->
+ let (occs,c) = Redexpr.out_with_occurrences occs_c in
(occs,c,None),na) lconstr)
let new_generalize_gen lconstr =
@@ -2635,6 +2662,49 @@ let quantify lconstr =
tclIDTAC
*)
+(* Modifying/Adding an hypothesis *)
+
+let specialize (c,lbind) =
+ Proofview.Goal.enter { enter = begin fun gl ->
+ let env = Proofview.Goal.env gl in
+ let sigma = Sigma.to_evar_map (Proofview.Goal.sigma gl) in
+ let sigma, term =
+ if lbind == NoBindings then
+ let sigma = Typeclasses.resolve_typeclasses env sigma in
+ sigma, nf_evar sigma c
+ else
+ let clause = make_clenv_binding env sigma (c,Retyping.get_type_of env sigma c) lbind in
+ let flags = { (default_unify_flags ()) with resolve_evars = true } in
+ let clause = clenv_unify_meta_types ~flags clause in
+ let (thd,tstack) = whd_nored_stack clause.evd (clenv_value clause) in
+ let rec chk = function
+ | [] -> []
+ | t::l -> if occur_meta t then [] else t :: chk l
+ in
+ let tstack = chk tstack in
+ let term = applist(thd,List.map (nf_evar clause.evd) tstack) in
+ if occur_meta term then
+ errorlabstrm "" (str "Cannot infer an instance for " ++
+ pr_name (meta_name clause.evd (List.hd (collect_metas term))) ++
+ str ".");
+ clause.evd, term in
+ let typ = Retyping.get_type_of env sigma term in
+ match kind_of_term (fst(decompose_app (snd(decompose_lam_assum c)))) with
+ | Var id when Id.List.mem id (Tacmach.New.pf_ids_of_hyps gl) ->
+ Tacticals.New.tclTHEN
+ (Proofview.Unsafe.tclEVARS sigma)
+ (Tacticals.New.tclTHENFIRST
+ (assert_before_replacing id typ)
+ (new_exact_no_check term))
+ | _ ->
+ (* To deprecate in favor of generalize? *)
+ Tacticals.New.tclTHEN
+ (Proofview.Unsafe.tclEVARS sigma)
+ (Tacticals.New.tclTHENLAST
+ (cut typ)
+ (new_exact_no_check term))
+ end }
+
(*****************************)
(* Ad hoc unfold *)
(*****************************)
@@ -2644,7 +2714,7 @@ let quantify lconstr =
let unfold_body x gl =
let hyps = pf_hyps gl in
let xval =
- match Context.lookup_named x hyps with
+ match Context.Named.lookup x hyps with
(_,Some xval,_) -> xval
| _ -> errorlabstrm "unfold_body"
(pr_id x ++ str" is not a defined hypothesis.") in
@@ -2670,8 +2740,6 @@ let expand_hyp id = tclTHEN (tclTRY (unfold_body id)) (clear [id])
- [hyp0] is the induction hypothesis
- we extract from [args] the variables which are not rigid parameters
of the inductive type, this is [indvars] (other terms are forgotten);
- [indhyps] are the ones which actually are declared in context
- (done in [find_atomic_param_of_ind])
- we look for all hyps depending of [hyp0] or one of [indvars]:
this is [dephyps] of types [deptyps] respectively
- [statuslist] tells for each hyps in [dephyps] after which other hyp
@@ -2683,7 +2751,7 @@ let expand_hyp id = tclTHEN (tclTRY (unfold_body id)) (clear [id])
Strategy: (cf in [induction_with_atomization_of_ind_arg])
- requantify and clear all [dephyps]
- apply induction on [hyp0]
- - clear [indhyps] and [hyp0]
+ - clear those of [indvars] that are variables and [hyp0]
- in the i-th subgoal, intro the arguments of the i-th constructor
of the inductive type after [hyp0succ] (done in
[induct_discharge]) let the induction hypotheses on top of the
@@ -2701,7 +2769,7 @@ let check_unused_names names =
(str"Unused introduction " ++ str (String.plural (List.length names) "pattern")
++ str": " ++ prlist_with_sep spc
(Miscprint.pr_intro_pattern
- (fun c -> Printer.pr_constr (snd (c (Global.env()) Evd.empty)))) names)
+ (fun c -> Printer.pr_constr (fst (run_delayed (Global.env()) Evd.empty c)))) names)
let intropattern_of_name gl avoid = function
| Anonymous -> IntroNaming IntroAnonymous
@@ -2779,9 +2847,9 @@ let induct_discharge dests avoid' tac (avoid,ra) names =
let avoid = avoid @ avoid' in
let rec peel_tac ra dests names thin =
match ra with
- | (RecArg,deprec,recvarname) ::
- (IndArg,depind,hyprecname) :: ra' ->
- Proofview.Goal.enter begin fun gl ->
+ | (RecArg,_,deprec,recvarname) ::
+ (IndArg,_,depind,hyprecname) :: ra' ->
+ Proofview.Goal.enter { enter = begin fun gl ->
let (recpat,names) = match names with
| [loc,IntroNaming (IntroIdentifier id) as pat] ->
let id' = next_ident_away (add_prefix "IH" id) avoid in
@@ -2789,37 +2857,37 @@ let induct_discharge dests avoid' tac (avoid,ra) names =
| _ -> consume_pattern avoid (Name recvarname) deprec gl names in
let dest = get_recarg_dest dests in
dest_intro_patterns avoid thin dest [recpat] (fun ids thin ->
- Proofview.Goal.enter begin fun gl ->
+ Proofview.Goal.enter { enter = begin fun gl ->
let (hyprec,names) =
consume_pattern avoid (Name hyprecname) depind gl names
in
dest_intro_patterns avoid thin MoveLast [hyprec] (fun ids' thin ->
peel_tac ra' (update_dest dests ids') names thin)
- end)
- end
- | (IndArg,dep,hyprecname) :: ra' ->
- Proofview.Goal.enter begin fun gl ->
+ end })
+ end }
+ | (IndArg,_,dep,hyprecname) :: ra' ->
+ Proofview.Goal.enter { enter = begin fun gl ->
(* Rem: does not happen in Coq schemes, only in user-defined schemes *)
let pat,names =
consume_pattern avoid (Name hyprecname) dep gl names in
dest_intro_patterns avoid thin MoveLast [pat] (fun ids thin ->
peel_tac ra' (update_dest dests ids) names thin)
- end
- | (RecArg,dep,recvarname) :: ra' ->
- Proofview.Goal.enter begin fun gl ->
+ end }
+ | (RecArg,_,dep,recvarname) :: ra' ->
+ Proofview.Goal.enter { enter = begin fun gl ->
let (pat,names) =
consume_pattern avoid (Name recvarname) dep gl names in
let dest = get_recarg_dest dests in
dest_intro_patterns avoid thin dest [pat] (fun ids thin ->
peel_tac ra' dests names thin)
- end
- | (OtherArg,dep,_) :: ra' ->
- Proofview.Goal.enter begin fun gl ->
+ end }
+ | (OtherArg,_,dep,_) :: ra' ->
+ Proofview.Goal.enter { enter = begin fun gl ->
let (pat,names) = consume_pattern avoid Anonymous dep gl names in
let dest = get_recarg_dest dests in
safe_dest_intro_patterns avoid thin dest [pat] (fun ids thin ->
peel_tac ra' dests names thin)
- end
+ end }
| [] ->
check_unused_names names;
Tacticals.New.tclTHEN (clear_wildcards thin) (tac dests)
@@ -2831,6 +2899,7 @@ let induct_discharge dests avoid' tac (avoid,ra) names =
substitutions aussi sur l'argument voisin *)
let expand_projections env sigma c =
+ let sigma = Sigma.to_evar_map sigma in
let rec aux env c =
match kind_of_term c with
| Proj (p, c) -> Retyping.expand_projection env sigma p (aux env c) []
@@ -2841,7 +2910,7 @@ let expand_projections env sigma c =
(* Marche pas... faut prendre en compte l'occurrence précise... *)
let atomize_param_of_ind_then (indref,nparams,_) hyp0 tac =
- Proofview.Goal.enter begin fun gl ->
+ Proofview.Goal.enter { enter = begin fun gl ->
let env = Proofview.Goal.env gl in
let tmptyp0 = Tacmach.New.pf_get_hyp_typ hyp0 (Proofview.Goal.assume gl) in
let reduce_to_quantified_ref = Tacmach.New.pf_apply reduce_to_quantified_ref gl in
@@ -2894,7 +2963,7 @@ let atomize_param_of_ind_then (indref,nparams,_) hyp0 tac =
(atomize_one (i-1) (mkVar x::args) (mkVar x::args') (x::avoid))
in
atomize_one (List.length argl) [] [] []
- end
+ end }
(* [cook_sign] builds the lists [beforetoclear] (preceding the
ind. var.) and [aftertoclear] (coming after the ind. var.) of hyps
@@ -2918,7 +2987,6 @@ let atomize_param_of_ind_then (indref,nparams,_) hyp0 tac =
Induction hypothesis is H4 ([hyp0])
Variable parameters of (le O n) is the singleton list with "n" ([indvars])
- Part of [indvars] really in context is the same ([indhyps])
The dependent hyps are H3 and H6 ([dephyps])
For H3 the memorized places are H5 ([lhyp]) and H2 ([rhyp])
because these names are among the hyp which are fixed through the induction
@@ -2963,7 +3031,7 @@ let atomize_param_of_ind_then (indref,nparams,_) hyp0 tac =
exception Shunt of Id.t move_location
let cook_sign hyp0_opt inhyps indvars env =
- (* First phase from L to R: get [indhyps], [decldep] and [statuslist]
+ (* First phase from L to R: get [toclear], [decldep] and [statuslist]
for the hypotheses before (= more ancient than) hyp0 (see above) *)
let toclear = ref [] in
let avoid = ref [] in
@@ -3064,20 +3132,20 @@ type elim_scheme = {
elimc: constr with_bindings option;
elimt: types;
indref: global_reference option;
- params: rel_context; (* (prm1,tprm1);(prm2,tprm2)...(prmp,tprmp) *)
- nparams: int; (* number of parameters *)
- predicates: rel_context; (* (Qq, (Tq_1 -> Tq_2 ->...-> Tq_nq)), (Q1,...) *)
- npredicates: int; (* Number of predicates *)
- branches: rel_context; (* branchr,...,branch1 *)
- nbranches: int; (* Number of branches *)
- args: rel_context; (* (xni, Ti_ni) ... (x1, Ti_1) *)
- nargs: int; (* number of arguments *)
- indarg: rel_declaration option; (* Some (H,I prm1..prmp x1...xni)
- if HI is in premisses, None otherwise *)
- concl: types; (* Qi x1...xni HI (f...), HI and (f...)
- are optional and mutually exclusive *)
- indarg_in_concl: bool; (* true if HI appears at the end of conclusion *)
- farg_in_concl: bool; (* true if (f...) appears at the end of conclusion *)
+ params: Context.Rel.t; (* (prm1,tprm1);(prm2,tprm2)...(prmp,tprmp) *)
+ nparams: int; (* number of parameters *)
+ predicates: Context.Rel.t; (* (Qq, (Tq_1 -> Tq_2 ->...-> Tq_nq)), (Q1,...) *)
+ npredicates: int; (* Number of predicates *)
+ branches: Context.Rel.t; (* branchr,...,branch1 *)
+ nbranches: int; (* Number of branches *)
+ args: Context.Rel.t; (* (xni, Ti_ni) ... (x1, Ti_1) *)
+ nargs: int; (* number of arguments *)
+ indarg: Context.Rel.Declaration.t option; (* Some (H,I prm1..prmp x1...xni)
+ if HI is in premisses, None otherwise *)
+ concl: types; (* Qi x1...xni HI (f...), HI and (f...)
+ are optional and mutually exclusive *)
+ indarg_in_concl: bool; (* true if HI appears at the end of conclusion *)
+ farg_in_concl: bool; (* true if (f...) appears at the end of conclusion *)
}
let empty_scheme =
@@ -3197,19 +3265,19 @@ let decompose_indapp f args =
| _ -> f, args
let mk_term_eq env sigma ty t ty' t' =
+ let sigma = Sigma.to_evar_map sigma in
if Reductionops.is_conv env sigma ty ty' then
mkEq ty t t', mkRefl ty' t'
else
mkHEq ty t ty' t', mkHRefl ty' t'
-let make_abstract_generalize gl id concl dep ctx body c eqs args refls =
- let meta = Evarutil.new_meta() in
+let make_abstract_generalize env id typ concl dep ctx body c eqs args refls =
+ Proofview.Refine.refine { run = begin fun sigma ->
let eqslen = List.length eqs in
- let term, typ = mkVar id, pf_get_hyp_typ gl id in
(* Abstract by the "generalized" hypothesis equality proof if necessary. *)
let abshypeq, abshypt =
if dep then
- let eq, refl = mk_term_eq (push_rel_context ctx (pf_env gl)) (project gl) (lift 1 c) (mkRel 1) typ term in
+ let eq, refl = mk_term_eq (push_rel_context ctx env) sigma (lift 1 c) (mkRel 1) typ (mkVar id) in
mkProd (Anonymous, eq, lift 1 concl), [| refl |]
else concl, [||]
in
@@ -3221,7 +3289,7 @@ let make_abstract_generalize gl id concl dep ctx body c eqs args refls =
(* Abstract by the extension of the context *)
let genctyp = it_mkProd_or_LetIn genarg ctx in
(* The goal will become this product. *)
- let genc = mkCast (mkMeta meta, DEFAULTcast, genctyp) in
+ let Sigma (genc, sigma, p) = Evarutil.new_evar env sigma ~principal:true genctyp in
(* Apply the old arguments giving the proper instantiation of the hyp *)
let instc = mkApp (genc, Array.of_list args) in
(* Then apply to the original instantiated hyp. *)
@@ -3229,13 +3297,14 @@ let make_abstract_generalize gl id concl dep ctx body c eqs args refls =
(* Apply the reflexivity proofs on the indices. *)
let appeqs = mkApp (instc, Array.of_list refls) in
(* Finally, apply the reflexivity proof for the original hyp, to get a term of type gl again. *)
- mkApp (appeqs, abshypt)
+ Sigma (mkApp (appeqs, abshypt), sigma, p)
+ end }
let hyps_of_vars env sign nogen hyps =
if Id.Set.is_empty hyps then []
else
let (_,lh) =
- Context.fold_named_context_reverse
+ Context.Named.fold_inside
(fun (hs,hl) (x,_,_ as d) ->
if Id.Set.mem x nogen then (hs,hl)
else if Id.Set.mem x hs then (hs,x::hl)
@@ -3270,9 +3339,9 @@ let is_defined_variable env id = match lookup_named id env with
| (_, Some _, _) -> true
let abstract_args gl generalize_vars dep id defined f args =
- let sigma = ref (project gl) in
- let env = pf_env gl in
- let concl = pf_concl gl in
+ let sigma = ref (Tacmach.project gl) in
+ let env = Tacmach.pf_env gl in
+ let concl = Tacmach.pf_concl gl in
let dep = dep || dependent (mkVar id) concl in
let avoid = ref [] in
let get_id name =
@@ -3290,7 +3359,7 @@ let abstract_args gl generalize_vars dep id defined f args =
let rel, c = Reductionops.splay_prod_n env !sigma 1 prod in
List.hd rel, c
in
- let argty = pf_unsafe_type_of gl arg in
+ let argty = Tacmach.pf_unsafe_type_of gl arg in
let sigma', ty = Evarsolve.refresh_universes (Some true) env !sigma ty in
let () = sigma := sigma' in
let lenctx = List.length ctx in
@@ -3331,7 +3400,7 @@ let abstract_args gl generalize_vars dep id defined f args =
true, mkApp (f', before), after
in
if dogen then
- let tyf' = pf_unsafe_type_of gl f' in
+ let tyf' = Tacmach.pf_unsafe_type_of gl f' in
let arity, ctx, ctxenv, c', args, eqs, refls, nogen, vars, env =
Array.fold_left aux (tyf',[],env,f',[],[],[],Id.Set.empty,Id.Set.empty,env) args'
in
@@ -3343,15 +3412,17 @@ let abstract_args gl generalize_vars dep id defined f args =
else []
in
let body, c' =
- if defined then Some c', typ_of ctxenv !sigma c'
+ if defined then Some c', Retyping.get_type_of ctxenv !sigma c'
else None, c'
in
- let term = make_abstract_generalize {gl with sigma = !sigma} id concl dep ctx body c' eqs args refls in
- Some (term, !sigma, dep, succ (List.length ctx), vars)
+ let typ = Tacmach.pf_get_hyp_typ gl id in
+ let tac = make_abstract_generalize (pf_env gl) id typ concl dep ctx body c' eqs args refls in
+ let tac = Proofview.Unsafe.tclEVARS !sigma <*> tac in
+ Some (tac, dep, succ (List.length ctx), vars)
else None
let abstract_generalize ?(generalize_vars=true) ?(force_dep=false) id =
- Proofview.Goal.nf_enter begin fun gl ->
+ Proofview.Goal.nf_enter { enter = begin fun gl ->
Coqlib.check_required_library Coqlib.jmeq_module_name;
let (f, args, def, id, oldid) =
let oldid = Tacmach.New.pf_get_new_id id gl in
@@ -3369,17 +3440,15 @@ let abstract_generalize ?(generalize_vars=true) ?(force_dep=false) id =
let newc = Tacmach.New.of_old (fun gl -> abstract_args gl generalize_vars force_dep id def f args) gl in
match newc with
| None -> Proofview.tclUNIT ()
- | Some (newc, sigma, dep, n, vars) ->
+ | Some (tac, dep, n, vars) ->
let tac =
if dep then
- Tacticals.New.tclTHENLIST
- [Proofview.Unsafe.tclEVARS sigma;
- Proofview.V82.tactic (refine newc);
+ Tacticals.New.tclTHENLIST [
+ tac;
rename_hyp [(id, oldid)]; Tacticals.New.tclDO n intro;
Proofview.V82.tactic (generalize_dep ~with_let:true (mkVar oldid))]
- else Tacticals.New.tclTHENLIST
- [Proofview.Unsafe.tclEVARS sigma;
- Proofview.V82.tactic (refine newc);
+ else Tacticals.New.tclTHENLIST [
+ tac;
Proofview.V82.tactic (clear [id]);
Tacticals.New.tclDO n intro]
in
@@ -3389,15 +3458,15 @@ let abstract_generalize ?(generalize_vars=true) ?(force_dep=false) id =
[revert vars ;
Proofview.V82.tactic (fun gl -> tclMAP (fun id ->
tclTRY (generalize_dep ~with_let:true (mkVar id))) vars gl)])
- end
+ end }
let rec compare_upto_variables x y =
if (isVar x || isRel x) && (isVar y || isRel y) then true
else compare_constr compare_upto_variables x y
let specialize_eqs id gl =
- let env = pf_env gl in
- let ty = pf_get_hyp_typ gl id in
+ let env = Tacmach.pf_env gl in
+ let ty = Tacmach.pf_get_hyp_typ gl id in
let evars = ref (project gl) in
let unif env evars c1 c2 =
compare_upto_variables c1 c2 && Evarconv.e_conv env evars c1 c2
@@ -3466,7 +3535,7 @@ let occur_rel n c =
We also return the conclusion.
*)
let decompose_paramspred_branch_args elimt =
- let rec cut_noccur elimt acc2 : rel_context * rel_context * types =
+ let rec cut_noccur elimt acc2 : Context.Rel.t * Context.Rel.t * types =
match kind_of_term elimt with
| Prod(nme,tpe,elimt') ->
let hd_tpe,_ = decompose_app ((strip_prod_assum tpe)) in
@@ -3475,7 +3544,7 @@ let decompose_paramspred_branch_args elimt =
else let acc3,ccl = decompose_prod_assum elimt in acc2 , acc3 , ccl
| App(_, _) | Rel _ -> acc2 , [] , elimt
| _ -> error_ind_scheme "" in
- let rec cut_occur elimt acc1 : rel_context * rel_context * rel_context * types =
+ let rec cut_occur elimt acc1 : Context.Rel.t * Context.Rel.t * Context.Rel.t * types =
match kind_of_term elimt with
| Prod(nme,tpe,c) when occur_rel 1 c -> cut_occur c ((nme,None,tpe)::acc1)
| Prod(nme,tpe,c) -> let acc2,acc3,ccl = cut_noccur elimt [] in acc1,acc2,acc3,ccl
@@ -3603,7 +3672,7 @@ let compute_scheme_signature scheme names_info ind_type_guess =
let ind_is_ok =
List.equal Term.eq_constr
(List.lastn scheme.nargs indargs)
- (extended_rel_list 0 scheme.args) in
+ (Context.Rel.to_extended_list 0 scheme.args) in
if not (ccl_arg_ok && ind_is_ok) then
error_ind_scheme "the conclusion of"
in (cond, check_concl)
@@ -3618,9 +3687,9 @@ let compute_scheme_signature scheme names_info ind_type_guess =
let rec check_branch p c =
match kind_of_term c with
| Prod (_,t,c) ->
- (is_pred p t, dependent (mkRel 1) c) :: check_branch (p+1) c
+ (is_pred p t, true, dependent (mkRel 1) c) :: check_branch (p+1) c
| LetIn (_,_,_,c) ->
- (OtherArg, dependent (mkRel 1) c) :: check_branch (p+1) c
+ (OtherArg, false, dependent (mkRel 1) c) :: check_branch (p+1) c
| _ when is_pred p c == IndArg -> []
| _ -> raise Exit
in
@@ -3630,12 +3699,12 @@ let compute_scheme_signature scheme names_info ind_type_guess =
(try
let lchck_brch = check_branch p t in
let n = List.fold_left
- (fun n (b,_) -> if b == RecArg then n+1 else n) 0 lchck_brch in
+ (fun n (b,_,_) -> if b == RecArg then n+1 else n) 0 lchck_brch in
let recvarname, hyprecname, avoid =
make_up_names n scheme.indref names_info in
let namesign =
- List.map (fun (b,dep) ->
- (b, dep, if b == IndArg then hyprecname else recvarname))
+ List.map (fun (b,is_assum,dep) ->
+ (b,is_assum,dep,if b == IndArg then hyprecname else recvarname))
lchck_brch in
(avoid,namesign) :: find_branches (p+1) brs
with Exit-> error_ind_scheme "the branches of")
@@ -3661,21 +3730,26 @@ let guess_elim isrec dep s hyp0 gl =
let evd, elimc =
if isrec && not (is_nonrec (fst mind)) then find_ind_eliminator (fst mind) s gl
else
+ let env = Tacmach.New.pf_env gl in
+ let sigma = Sigma.Unsafe.of_evar_map (Tacmach.New.project gl) in
if use_dependent_propositions_elimination () && dep
then
- Tacmach.New.pf_apply build_case_analysis_scheme gl mind true s
+ let Sigma (ind, sigma, _) = build_case_analysis_scheme env sigma mind true s in
+ (Sigma.to_evar_map sigma, ind)
else
- Tacmach.New.pf_apply build_case_analysis_scheme_default gl mind s in
+ let Sigma (ind, sigma, _) = build_case_analysis_scheme_default env sigma mind s in
+ (Sigma.to_evar_map sigma, ind)
+ in
let elimt = Tacmach.New.pf_unsafe_type_of gl elimc in
evd, ((elimc, NoBindings), elimt), mkIndU mind
let given_elim hyp0 (elimc,lbind as e) gl =
let tmptyp0 = Tacmach.New.pf_get_hyp_typ hyp0 gl in
let ind_type_guess,_ = decompose_app ((strip_prod tmptyp0)) in
- Proofview.Goal.sigma gl, (e, Tacmach.New.pf_unsafe_type_of gl elimc), ind_type_guess
+ Tacmach.New.project gl, (e, Tacmach.New.pf_unsafe_type_of gl elimc), ind_type_guess
type scheme_signature =
- (Id.t list * (elim_arg_kind * bool * Id.t) list) array
+ (Id.t list * (elim_arg_kind * bool * bool * Id.t) list) array
type eliminator_source =
| ElimUsing of (eliminator * types) * scheme_signature
@@ -3717,7 +3791,7 @@ let is_functional_induction elimc gl =
let get_eliminator elim dep s gl = match elim with
| ElimUsing (elim,indsign) ->
- Proofview.Goal.sigma gl, (* bugged, should be computed *) true, elim, indsign
+ Tacmach.New.project gl, (* bugged, should be computed *) true, elim, indsign
| ElimOver (isrec,id) ->
let evd, (elimc,elimt),_ as elims = guess_elim isrec dep s id gl in
let _, (l, s) = compute_elim_signature elims id in
@@ -3740,10 +3814,10 @@ let recolle_clenv i params args elimclause gl =
let k = match i with -1 -> Array.length lindmv - List.length args | _ -> i in
(* parameters correspond to first elts of lid. *)
let clauses_params =
- List.map_i (fun i id -> mkVar id , pf_get_hyp_typ gl id , lindmv.(i))
+ List.map_i (fun i id -> mkVar id , Tacmach.pf_get_hyp_typ gl id , lindmv.(i))
0 params in
let clauses_args =
- List.map_i (fun i id -> mkVar id , pf_get_hyp_typ gl id , lindmv.(k+i))
+ List.map_i (fun i id -> mkVar id , Tacmach.pf_get_hyp_typ gl id , lindmv.(k+i))
0 args in
let clauses = clauses_params@clauses_args in
(* iteration of clenv_fchain with all infos we have. *)
@@ -3770,7 +3844,7 @@ let induction_tac with_evars params indvars elim gl =
let elimc = contract_letin_in_lam_header elimc in
let elimc = mkCast (elimc, DEFAULTcast, elimt) in
let elimclause =
- pf_apply make_clenv_binding gl (elimc,elimt) lbindelimc in
+ Tacmach.pf_apply make_clenv_binding gl (elimc,elimt) lbindelimc in
(* elimclause' is built from elimclause by instanciating all args and params. *)
let elimclause' = recolle_clenv i params indvars elimclause gl in
(* one last resolution (useless?) *)
@@ -3782,24 +3856,29 @@ let induction_tac with_evars params indvars elim gl =
induction applies with the induction hypotheses *)
let apply_induction_in_context hyp0 inhyps elim indvars names induct_tac =
- Proofview.Goal.enter begin fun gl ->
- let env = Proofview.Goal.env gl in
+ Proofview.Goal.s_enter { s_enter = begin fun gl ->
let sigma = Proofview.Goal.sigma gl in
+ let env = Proofview.Goal.env gl in
+ let sigma = Sigma.to_evar_map sigma in
let concl = Tacmach.New.pf_nf_concl gl in
- let statuslists,lhyp0,toclear,deps,avoid,dep = cook_sign hyp0 inhyps indvars env in
- let dep = dep || Option.cata (fun id -> occur_var env id concl) false hyp0 in
+ let statuslists,lhyp0,toclear,deps,avoid,dep_in_hyps = cook_sign hyp0 inhyps indvars env in
+ let dep_in_concl = Option.cata (fun id -> occur_var env id concl) false hyp0 in
+ let dep = dep_in_hyps || dep_in_concl in
let tmpcl = it_mkNamedProd_or_LetIn concl deps in
let s = Retyping.get_sort_family_of env sigma tmpcl in
let deps_cstr =
List.fold_left
(fun a (id,b,_) -> if Option.is_empty b then (mkVar id)::a else a) [] deps in
let (sigma, isrec, elim, indsign) = get_eliminator elim dep s (Proofview.Goal.assume gl) in
- let names = compute_induction_names (Array.length indsign) names in
+ let branchletsigns =
+ let f (_,is_not_let,_,_) = is_not_let in
+ Array.map (fun (_,l) -> List.map f l) indsign in
+ let names = compute_induction_names branchletsigns names in
+ let tac =
(if isrec then Tacticals.New.tclTHENFIRSTn else Tacticals.New.tclTHENLASTn)
(Tacticals.New.tclTHENLIST [
- Proofview.Unsafe.tclEVARS sigma;
(* Generalize dependent hyps (but not args) *)
- if deps = [] then Proofview.tclUNIT () else Proofview.V82.tactic (apply_type tmpcl deps_cstr);
+ if deps = [] then Proofview.tclUNIT () else apply_type tmpcl deps_cstr;
(* side-conditions in elim (resp case) schemes come last (resp first) *)
induct_tac elim;
Proofview.V82.tactic (tclMAP expand_hyp toclear)
@@ -3807,15 +3886,17 @@ let apply_induction_in_context hyp0 inhyps elim indvars names induct_tac =
(Array.map2
(induct_discharge lhyp0 avoid (re_intro_dependent_hypotheses statuslists))
indsign names)
- end
+ in
+ Sigma.Unsafe.of_pair (tac, sigma)
+ end }
let induction_with_atomization_of_ind_arg isrec with_evars elim names hyp0 inhyps =
- Proofview.Goal.enter begin fun gl ->
+ Proofview.Goal.enter { enter = begin fun gl ->
let elim_info = find_induction_type isrec elim hyp0 (Proofview.Goal.assume gl) in
atomize_param_of_ind_then elim_info hyp0 (fun indvars ->
apply_induction_in_context (Some hyp0) inhyps (pi3 elim_info) indvars names
(fun elim -> Proofview.V82.tactic (induction_tac with_evars [] [hyp0] elim)))
- end
+ end }
let msg_not_right_number_induction_arguments scheme =
str"Not the right number of induction arguments (expected " ++
@@ -3832,7 +3913,7 @@ let msg_not_right_number_induction_arguments scheme =
must be given, so we help a bit the unifier by making the "pattern"
by hand before calling induction_tac *)
let induction_without_atomization isrec with_evars elim names lid =
- Proofview.Goal.nf_enter begin fun gl ->
+ Proofview.Goal.nf_enter { enter = begin fun gl ->
let sigma, (indsign,scheme) = get_elim_signature elim (List.hd lid) gl in
let nargs_indarg_farg =
scheme.nargs + (if scheme.farg_in_concl then 1 else 0) in
@@ -3863,11 +3944,11 @@ let induction_without_atomization isrec with_evars elim names lid =
]) in
let elim = ElimUsing (({elimindex = Some (-1); elimbody = Option.get scheme.elimc; elimrename = None}, scheme.elimt), indsign) in
apply_induction_in_context None [] elim indvars names induct_tac
- end
+ end }
(* assume that no occurrences are selected *)
let clear_unselected_context id inhyps cls gl =
- if occur_var (pf_env gl) id (pf_concl gl) &&
+ if occur_var (Tacmach.pf_env gl) id (Tacmach.pf_concl gl) &&
cls.concl_occs == NoOccurrences
then errorlabstrm ""
(str "Conclusion must be mentioned: it depends on " ++ pr_id id
@@ -3885,6 +3966,7 @@ let clear_unselected_context id inhyps cls gl =
| None -> tclIDTAC gl
let use_bindings env sigma elim must_be_closed (c,lbind) typ =
+ let sigma = Sigma.to_evar_map sigma in
let typ =
if elim == None then
(* w/o an scheme, the term has to be applied at least until
@@ -3906,7 +3988,8 @@ let use_bindings env sigma elim must_be_closed (c,lbind) typ =
if must_be_closed && occur_meta (clenv_value indclause) then
error "Need a fully applied argument.";
(* We lose the possibility of coercions in with-bindings *)
- pose_all_metas_as_evars env indclause.evd (clenv_value indclause)
+ let (sigma, c) = pose_all_metas_as_evars env indclause.evd (clenv_value indclause) in
+ Sigma.Unsafe.of_pair (c, sigma)
with e when catchable_exception e ->
try find_clause (try_red_product env sigma typ)
with Redelimination -> raise e in
@@ -3924,6 +4007,7 @@ let check_expected_type env sigma (elimc,bl) elimt =
fun t -> Evarconv.e_cumul env (ref sigma) t u
let check_enough_applied env sigma elim =
+ let sigma = Sigma.to_evar_map sigma in
(* A heuristic to decide whether the induction arg is enough applied *)
match elim with
| None ->
@@ -3931,7 +4015,7 @@ let check_enough_applied env sigma elim =
fun u ->
let t,_ = decompose_app (whd_betadeltaiota env sigma u) in isInd t
| Some elimc ->
- let elimt = typ_of env sigma (fst elimc) in
+ let elimt = Retyping.get_type_of env sigma (fst elimc) in
let scheme = compute_elim_sig ~elimc elimt in
match scheme.indref with
| None ->
@@ -3944,13 +4028,13 @@ let check_enough_applied env sigma elim =
let pose_induction_arg_then isrec with_evars (is_arg_pure_hyp,from_prefix) elim
id ((pending,(c0,lbind)),(eqname,names)) t0 inhyps cls tac =
- Proofview.Goal.enter begin fun gl ->
- let env = Proofview.Goal.env gl in
+ Proofview.Goal.s_enter { s_enter = begin fun gl ->
let sigma = Proofview.Goal.sigma gl in
+ let env = Proofview.Goal.env gl in
let ccl = Proofview.Goal.raw_concl gl in
let store = Proofview.Goal.extra gl in
let check = check_enough_applied env sigma elim in
- let (sigma',c) = use_bindings env sigma elim false (c0,lbind) t0 in
+ let Sigma (c, sigma', p) = use_bindings env sigma elim false (c0,lbind) t0 in
let abs = AbstractPattern (from_prefix,check,Name id,(pending,c),cls,false) in
let (id,sign,_,lastlhyp,ccl,res) = make_abstraction env sigma' ccl abs in
match res with
@@ -3960,7 +4044,8 @@ let pose_induction_arg_then isrec with_evars (is_arg_pure_hyp,from_prefix) elim
(* we restart using bindings after having tried type-class
resolution etc. on the term given by the user *)
let flags = tactic_infer_flags (with_evars && (* do not give a success semantics to edestruct on an open term yet *) false) in
- let (sigma,c0) = finish_evar_resolution ~flags env sigma (pending,c0) in
+ let Sigma (c0, sigma, q) = finish_evar_resolution ~flags env sigma (pending,c0) in
+ let tac =
(if isrec then
(* Historically, induction has side conditions last *)
Tacticals.New.tclTHENFIRST
@@ -3968,12 +4053,13 @@ let pose_induction_arg_then isrec with_evars (is_arg_pure_hyp,from_prefix) elim
(* and destruct has side conditions first *)
Tacticals.New.tclTHENLAST)
(Tacticals.New.tclTHENLIST [
- Proofview.Unsafe.tclEVARS sigma;
- Proofview.Refine.refine ~unsafe:true (fun sigma ->
+ Proofview.Refine.refine ~unsafe:true { run = begin fun sigma ->
let b = not with_evars && with_eq != None in
- let (sigma,c) = use_bindings env sigma elim b (c0,lbind) t0 in
- let t = Retyping.get_type_of env sigma c in
- mkletin_goal env sigma store with_eq false (id,lastlhyp,ccl,c) (Some t));
+ let Sigma (c, sigma, p) = use_bindings env sigma elim b (c0,lbind) t0 in
+ let t = Retyping.get_type_of env (Sigma.to_evar_map sigma) c in
+ let Sigma (ans, sigma, q) = mkletin_goal env sigma store with_eq false (id,lastlhyp,ccl,c) (Some t) in
+ Sigma (ans, sigma, p +> q)
+ end };
Proofview.(if with_evars then shelve_unifiable else guard_no_unifiable);
if is_arg_pure_hyp
then Tacticals.New.tclTRY (Proofview.V82.tactic (thin [destVar c0]))
@@ -3981,19 +4067,24 @@ let pose_induction_arg_then isrec with_evars (is_arg_pure_hyp,from_prefix) elim
if isrec then Proofview.cycle (-1) else Proofview.tclUNIT ()
])
tac
+ in
+ Sigma (tac, sigma, q)
- | Some (sigma',c) ->
+ | Some (Sigma (c, sigma', q)) ->
(* pattern found *)
let with_eq = Option.map (fun eq -> (false,eq)) eqname in
(* TODO: if ind has predicate parameters, use JMeq instead of eq *)
let env = reset_with_named_context sign env in
+ let tac =
Tacticals.New.tclTHENLIST [
- Proofview.Unsafe.tclEVARS sigma';
- Proofview.Refine.refine ~unsafe:true (fun sigma ->
- mkletin_goal env sigma store with_eq true (id,lastlhyp,ccl,c) None);
+ Proofview.Refine.refine ~unsafe:true { run = begin fun sigma ->
+ mkletin_goal env sigma store with_eq true (id,lastlhyp,ccl,c) None
+ end };
tac
]
- end
+ in
+ Sigma (tac, sigma', p +> q)
+ end }
let has_generic_occurrences_but_goal cls id env ccl =
clause_with_generic_context_selection cls &&
@@ -4005,7 +4096,7 @@ let induction_gen clear_flag isrec with_evars elim
let inhyps = match cls with
| Some {onhyps=Some hyps} -> List.map (fun ((_,id),_) -> id) hyps
| _ -> [] in
- Proofview.Goal.enter begin fun gl ->
+ Proofview.Goal.enter { enter = begin fun gl ->
let env = Proofview.Goal.env gl in
let sigma = Proofview.Goal.sigma gl in
let ccl = Proofview.Goal.raw_concl gl in
@@ -4040,7 +4131,7 @@ let induction_gen clear_flag isrec with_evars elim
isrec with_evars info_arg elim id arg t inhyps cls
(induction_with_atomization_of_ind_arg
isrec with_evars elim names id inhyps)
- end
+ end }
(* Induction on a list of arguments. First make induction arguments
atomic (using letins), then do induction. The specificity here is
@@ -4065,7 +4156,7 @@ let induction_gen_l isrec with_evars elim names lc =
atomize_list l'
| _ ->
- Proofview.Goal.enter begin fun gl ->
+ Proofview.Goal.enter { enter = begin fun gl ->
let type_of = Tacmach.New.pf_unsafe_type_of gl in
let x =
id_of_name_using_hdchar (Global.env()) (type_of c) Anonymous in
@@ -4076,7 +4167,7 @@ let induction_gen_l isrec with_evars elim names lc =
Tacticals.New.tclTHEN
(letin_tac None (Name id) c None allHypsAndConcl)
(atomize_list newl')
- end in
+ end } in
Tacticals.New.tclTHENLIST
[
(atomize_list lc);
@@ -4093,18 +4184,21 @@ let induction_destruct isrec with_evars (lc,elim) =
match lc with
| [] -> assert false (* ensured by syntax, but if called inside caml? *)
| [c,(eqname,names as allnames),cls] ->
- Proofview.Goal.nf_enter begin fun gl ->
+ Proofview.Goal.nf_enter { enter = begin fun gl ->
let env = Proofview.Goal.env gl in
- let sigma = Proofview.Goal.sigma gl in
+ let sigma = Tacmach.New.project gl in
match elim with
| Some elim when is_functional_induction elim gl ->
(* Standard induction on non-standard induction schemes *)
(* will be removable when is_functional_induction will be more clever *)
if not (Option.is_empty cls) then error "'in' clause not supported here.";
let finish_evar_resolution f =
- let (sigma',(c,lbind)) = f env sigma in
+ let ((c, lbind), sigma') = run_delayed env sigma f in
let pending = (sigma,sigma') in
- snd (finish_evar_resolution env sigma' (pending,c)),lbind in
+ let sigma' = Sigma.Unsafe.of_evar_map sigma' in
+ let Sigma (c, _, _) = finish_evar_resolution env sigma' (pending,c) in
+ (c, lbind)
+ in
let c = map_induction_arg finish_evar_resolution c in
onInductionArg
(fun _clear_flag (c,lbind) ->
@@ -4115,11 +4209,11 @@ let induction_destruct isrec with_evars (lc,elim) =
(* standard induction *)
onOpenInductionArg env sigma
(fun clear_flag c -> induction_gen clear_flag isrec with_evars elim (c,allnames) cls) c
- end
+ end }
| _ ->
- Proofview.Goal.enter begin fun gl ->
+ Proofview.Goal.enter { enter = begin fun gl ->
let env = Proofview.Goal.env gl in
- let sigma = Proofview.Goal.sigma gl in
+ let sigma = Tacmach.New.project gl in
match elim with
| None ->
(* Several arguments, without "using" clause *)
@@ -4133,20 +4227,23 @@ let induction_destruct isrec with_evars (lc,elim) =
(onOpenInductionArg env sigma (fun clear_flag a ->
induction_gen clear_flag isrec with_evars None (a,b) cl) a)
(Tacticals.New.tclMAP (fun (a,b,cl) ->
- Proofview.Goal.enter begin fun gl ->
+ Proofview.Goal.enter { enter = begin fun gl ->
let env = Proofview.Goal.env gl in
- let sigma = Proofview.Goal.sigma gl in
+ let sigma = Tacmach.New.project gl in
onOpenInductionArg env sigma (fun clear_flag a ->
induction_gen clear_flag false with_evars None (a,b) cl) a
- end) l)
+ end }) l)
| Some elim ->
(* Several induction hyps with induction scheme *)
let finish_evar_resolution f =
- let (sigma',(c,lbind)) = f env sigma in
+ let ((c, lbind), sigma') = run_delayed env sigma f in
let pending = (sigma,sigma') in
if lbind != NoBindings then
error "'with' clause not supported here.";
- snd (finish_evar_resolution env sigma' (pending,c)) in
+ let sigma' = Sigma.Unsafe.of_evar_map sigma' in
+ let Sigma (c, _, _) = finish_evar_resolution env sigma' (pending,c) in
+ c
+ in
let lc = List.map (on_pi1 (map_induction_arg finish_evar_resolution)) lc in
let newlc =
List.map (fun (x,(eqn,names),cls) ->
@@ -4163,7 +4260,7 @@ let induction_destruct isrec with_evars (lc,elim) =
error "'as' clause with multiple arguments and 'using' clause can only occur last.";
let newlc = List.map (fun (x,_) -> (x,None)) newlc in
induction_gen_l isrec with_evars elim names newlc
- end
+ end }
let induction ev clr c l e =
induction_gen clr true ev e
@@ -4205,7 +4302,7 @@ let simple_destruct = function
*)
let elim_scheme_type elim t =
- Proofview.Goal.nf_enter begin fun gl ->
+ Proofview.Goal.nf_enter { enter = begin fun gl ->
let clause = Tacmach.New.of_old (fun gl -> mk_clenv_type_of gl elim) gl in
match kind_of_term (last_arg clause.templval.rebus) with
| Meta mv ->
@@ -4215,23 +4312,24 @@ let elim_scheme_type elim t =
(clenv_meta_type clause mv) clause in
Clenvtac.res_pf clause' ~flags:(elim_flags ()) ~with_evars:false
| _ -> anomaly (Pp.str "elim_scheme_type")
- end
+ end }
let elim_type t =
- Proofview.Goal.enter begin fun gl ->
+ Proofview.Goal.s_enter { s_enter = begin fun gl ->
let (ind,t) = Tacmach.New.pf_apply reduce_to_atomic_ind gl t in
let evd, elimc = find_ind_eliminator (fst ind) (Tacticals.New.elimination_sort_of_goal gl) gl in
- Tacticals.New.tclTHEN (Proofview.Unsafe.tclEVARS evd) (elim_scheme_type elimc t)
- end
+ Sigma.Unsafe.of_pair (elim_scheme_type elimc t, evd)
+ end }
let case_type t =
- Proofview.Goal.enter begin fun gl ->
- let (ind,t) = Tacmach.New.pf_apply reduce_to_atomic_ind gl t in
- let evd, elimc =
- Tacmach.New.pf_apply build_case_analysis_scheme_default gl ind (Tacticals.New.elimination_sort_of_goal gl)
- in
- Tacticals.New.tclTHEN (Proofview.Unsafe.tclEVARS evd) (elim_scheme_type elimc t)
- end
+ Proofview.Goal.s_enter { s_enter = begin fun gl ->
+ let sigma = Proofview.Goal.sigma gl in
+ let env = Tacmach.New.pf_env gl in
+ let (ind,t) = reduce_to_atomic_ind env (Sigma.to_evar_map sigma) t in
+ let s = Tacticals.New.elimination_sort_of_goal gl in
+ let Sigma (elimc, evd, p) = build_case_analysis_scheme_default env sigma ind s in
+ Sigma (elim_scheme_type elimc t, evd, p)
+ end }
(************************************************)
@@ -4244,14 +4342,14 @@ let (forward_setoid_reflexivity, setoid_reflexivity) = Hook.make ()
let maybe_betadeltaiota_concl allowred gl =
let concl = Tacmach.New.pf_nf_concl gl in
- let sigma = Proofview.Goal.sigma gl in
+ let sigma = Tacmach.New.project gl in
if not allowred then concl
else
let env = Proofview.Goal.env gl in
whd_betadeltaiota env sigma concl
let reflexivity_red allowred =
- Proofview.Goal.enter begin fun gl ->
+ Proofview.Goal.enter { enter = begin fun gl ->
(* PL: usual reflexivity don't perform any reduction when searching
for an equality, but we may need to do some when called back from
inside setoid_reflexivity (see Optimize cases in setoid_replace.ml). *)
@@ -4259,7 +4357,7 @@ let reflexivity_red allowred =
match match_with_equality_type concl with
| None -> Proofview.tclZERO NoEquationFound
| Some _ -> one_constructor 1 NoBindings
- end
+ end }
let reflexivity =
Proofview.tclORELSE
@@ -4301,7 +4399,7 @@ let match_with_equation c =
Proofview.tclZERO NoEquationFound
let symmetry_red allowred =
- Proofview.Goal.enter begin fun gl ->
+ Proofview.Goal.enter { enter = begin fun gl ->
(* PL: usual symmetry don't perform any reduction when searching
for an equality, but we may need to do some when called back from
inside setoid_reflexivity (see Optimize cases in setoid_replace.ml). *)
@@ -4313,7 +4411,7 @@ let symmetry_red allowred =
(convert_concl_no_check concl DEFAULTcast)
(Tacticals.New.pf_constr_of_global eq_data.sym apply)
| None,eq,eq_kind -> prove_symmetry eq eq_kind
- end
+ end }
let symmetry =
Proofview.tclORELSE
@@ -4327,7 +4425,7 @@ let (forward_setoid_symmetry_in, setoid_symmetry_in) = Hook.make ()
let symmetry_in id =
- Proofview.Goal.enter begin fun gl ->
+ Proofview.Goal.enter { enter = begin fun gl ->
let ctype = Tacmach.New.pf_unsafe_type_of gl (mkVar id) in
let sign,t = decompose_prod_assum ctype in
Proofview.tclORELSE
@@ -4345,7 +4443,7 @@ let symmetry_in id =
| NoEquationFound -> Hook.get forward_setoid_symmetry_in id
| e -> Proofview.tclZERO ~info e
end
- end
+ end }
let intros_symmetry =
Tacticals.New.onClause
@@ -4370,7 +4468,7 @@ let (forward_setoid_transitivity, setoid_transitivity) = Hook.make ()
(* This is probably not very useful any longer *)
let prove_transitivity hdcncl eq_kind t =
- Proofview.Goal.enter begin fun gl ->
+ Proofview.Goal.enter { enter = begin fun gl ->
let (eq1,eq2) = match eq_kind with
| MonomorphicLeibnizEq (c1,c2) ->
mkApp (hdcncl, [| c1; t|]), mkApp (hdcncl, [| t; c2 |])
@@ -4378,7 +4476,7 @@ let prove_transitivity hdcncl eq_kind t =
mkApp (hdcncl, [| typ; c1; t |]), mkApp (hdcncl, [| typ; t; c2 |])
| HeterogenousEq (typ1,c1,typ2,c2) ->
let env = Proofview.Goal.env gl in
- let sigma = Proofview.Goal.sigma gl in
+ let sigma = Tacmach.New.project gl in
let type_of = Typing.unsafe_type_of env sigma in
let typt = type_of t in
(mkApp(hdcncl, [| typ1; c1; typt ;t |]),
@@ -4390,10 +4488,10 @@ let prove_transitivity hdcncl eq_kind t =
[ Tacticals.New.tclDO 2 intro;
Tacticals.New.onLastHyp simplest_case;
assumption ]))
- end
+ end }
let transitivity_red allowred t =
- Proofview.Goal.enter begin fun gl ->
+ Proofview.Goal.enter { enter = begin fun gl ->
(* PL: usual transitivity don't perform any reduction when searching
for an equality, but we may need to do some when called back from
inside setoid_reflexivity (see Optimize cases in setoid_replace.ml). *)
@@ -4410,7 +4508,7 @@ let transitivity_red allowred t =
match t with
| None -> Tacticals.New.tclZEROMSG (str"etransitivity not supported for this relation.")
| Some t -> prove_transitivity eq eq_kind t
- end
+ end }
let transitivity_gen t =
Proofview.tclORELSE
@@ -4436,22 +4534,67 @@ let interpretable_as_section_decl evd d1 d2 = match d2,d1 with
e_eq_constr_univs evd b1 b2 && e_eq_constr_univs evd t1 t2
| (_,None,t1), (_,_,t2) -> e_eq_constr_univs evd t1 t2
+let rec decompose len c t accu =
+ if len = 0 then (c, t, accu)
+ else match kind_of_term c, kind_of_term t with
+ | Lambda (na, u, c), Prod (_, _, t) ->
+ decompose (pred len) c t ((na, None, u) :: accu)
+ | LetIn (na, b, u, c), LetIn (_, _, _, t) ->
+ decompose (pred len) c t ((na, Some b, u) :: accu)
+ | _ -> assert false
+
+let rec shrink ctx sign c t accu = match ctx, sign with
+| [], [] -> (c, t, accu)
+| p :: ctx, (id, _, _) :: sign ->
+ if noccurn 1 c then
+ let c = subst1 mkProp c in
+ let t = subst1 mkProp t in
+ shrink ctx sign c t accu
+ else
+ let c = mkLambda_or_LetIn p c in
+ let t = mkProd_or_LetIn p t in
+ let accu = match p with
+ | (_, None, _) -> mkVar id :: accu
+ | (_, Some _, _) -> accu
+ in
+ shrink ctx sign c t accu
+| _ -> assert false
+
+let shrink_entry sign const =
+ let open Entries in
+ let typ = match const.const_entry_type with
+ | None -> assert false
+ | Some t -> t
+ in
+ (** The body has been forced by the call to [build_constant_by_tactic] *)
+ let () = assert (Future.is_over const.const_entry_body) in
+ let ((body, uctx), eff) = Future.force const.const_entry_body in
+ let (body, typ, ctx) = decompose (List.length sign) body typ [] in
+ let (body, typ, args) = shrink ctx sign body typ [] in
+ let const = { const with
+ const_entry_body = Future.from_val ((body, uctx), eff);
+ const_entry_type = Some typ;
+ } in
+ (const, args)
+
let abstract_subproof id gk tac =
let open Tacticals.New in
let open Tacmach.New in
let open Proofview.Notations in
- Proofview.Goal.nf_enter begin fun gl ->
+ Proofview.Goal.nf_s_enter { s_enter = begin fun gl ->
+ let sigma = Proofview.Goal.sigma gl in
let current_sign = Global.named_context()
and global_sign = Proofview.Goal.hyps gl in
- let evdref = ref (Proofview.Goal.sigma gl) in
+ let sigma = Sigma.to_evar_map sigma in
+ let evdref = ref sigma in
let sign,secsign =
List.fold_right
(fun (id,_,_ as d) (s1,s2) ->
if mem_named_context id current_sign &&
- interpretable_as_section_decl evdref (Context.lookup_named id current_sign) d
+ interpretable_as_section_decl evdref (Context.Named.lookup id current_sign) d
then (s1,push_named_context_val d s2)
- else (add_named_decl d s1,s2))
- global_sign (empty_named_context,empty_named_context_val) in
+ else (Context.Named.add d s1,s2))
+ global_sign (Context.Named.empty, empty_named_context_val) in
let id = next_global_ident_away id (pf_ids_of_hyps gl) in
let concl = it_mkNamedProd_or_LetIn (Proofview.Goal.concl gl) sign in
let concl =
@@ -4477,6 +4620,10 @@ let abstract_subproof id gk tac =
let (_, info) = Errors.push src in
iraise (e, info)
in
+ let const, args =
+ if !shrink_abstract then shrink_entry sign const
+ else (const, List.rev (Context.Named.to_instance sign))
+ in
let cd = Entries.DefinitionEntry const in
let decl = (cd, IsProof Lemma) in
(** ppedrot: seems legit to have abstracted subproofs as local*)
@@ -4488,14 +4635,13 @@ let abstract_subproof id gk tac =
let eff = private_con_of_con (Global.safe_env ()) cst in
let effs = add_private eff
Entries.(snd (Future.force const.const_entry_body)) in
- let args = List.rev (instance_from_named_context sign) in
let solve =
- Proofview.Unsafe.tclEVARS evd <*>
Proofview.tclEFFECTS effs <*>
new_exact_no_check (applist (lem, args))
in
- if not safe then Proofview.mark_as_unsafe <*> solve else solve
- end
+ let tac = if not safe then Proofview.mark_as_unsafe <*> solve else solve in
+ Sigma.Unsafe.of_pair (tac, evd)
+ end }
let anon_id = Id.of_string "anonymous"
@@ -4515,7 +4661,8 @@ let tclABSTRACT name_op tac =
abstract_subproof s gk tac
let unify ?(state=full_transparent_state) x y =
- Proofview.Goal.nf_enter begin fun gl ->
+ Proofview.Goal.nf_s_enter { s_enter = begin fun gl ->
+ let sigma = Proofview.Goal.sigma gl in
try
let core_flags =
{ (default_unify_flags ()).core_unify_flags with
@@ -4527,22 +4674,18 @@ let unify ?(state=full_transparent_state) x y =
merge_unify_flags = core_flags;
subterm_unify_flags = { core_flags with modulo_delta = empty_transparent_state } }
in
- let evd = w_unify (Tacmach.New.pf_env gl) (Proofview.Goal.sigma gl) Reduction.CONV ~flags x y
- in Proofview.Unsafe.tclEVARS evd
- with e when Errors.noncritical e -> Tacticals.New.tclFAIL 0 (str"Not unifiable")
- end
+ let sigma = Sigma.to_evar_map sigma in
+ let sigma = w_unify (Tacmach.New.pf_env gl) sigma Reduction.CONV ~flags x y in
+ Sigma.Unsafe.of_pair (Proofview.tclUNIT (), sigma)
+ with e when Errors.noncritical e ->
+ Sigma.here (Tacticals.New.tclFAIL 0 (str"Not unifiable")) sigma
+ end }
module Simple = struct
(** Simplified version of some of the above tactics *)
let intro x = intro_move (Some x) MoveLast
- let generalize_gen cl =
- generalize_gen (List.map (on_fst Redexpr.out_with_occurrences) cl)
- let generalize cl =
- generalize_gen (List.map (fun c -> ((AllOccurrences,c),Names.Anonymous))
- cl)
-
let apply c =
apply_with_bindings_gen false false [None,(Loc.ghost,(c,NoBindings))]
let eapply c =
diff --git a/tactics/tactics.mli b/tactics/tactics.mli
index c28cb521e..5564b61c3 100644
--- a/tactics/tactics.mli
+++ b/tactics/tactics.mli
@@ -9,7 +9,6 @@
open Loc
open Names
open Term
-open Context
open Environ
open Proof_type
open Evd
@@ -26,16 +25,16 @@ open Locus
(** {6 General functions. } *)
-val is_quantified_hypothesis : Id.t -> goal sigma -> bool
+val is_quantified_hypothesis : Id.t -> ([`NF],'b) Proofview.Goal.t -> bool
(** {6 Primitive tactics. } *)
val introduction : ?check:bool -> Id.t -> unit Proofview.tactic
val refine : constr -> tactic
val convert_concl : ?check:bool -> types -> cast_kind -> unit Proofview.tactic
-val convert_hyp : ?check:bool -> named_declaration -> unit Proofview.tactic
+val convert_hyp : ?check:bool -> Context.Named.Declaration.t -> unit Proofview.tactic
val convert_concl_no_check : types -> cast_kind -> unit Proofview.tactic
-val convert_hyp_no_check : named_declaration -> unit Proofview.tactic
+val convert_hyp_no_check : Context.Named.Declaration.t -> unit Proofview.tactic
val thin : Id.t list -> tactic
val mutual_fix :
Id.t -> int -> (Id.t * int * constr) list -> int -> tactic
@@ -50,7 +49,7 @@ val convert_leq : constr -> constr -> unit Proofview.tactic
val fresh_id_in_env : Id.t list -> Id.t -> env -> Id.t
val fresh_id : Id.t list -> Id.t -> goal sigma -> Id.t
-val find_intro_names : rel_context -> goal sigma -> Id.t list
+val find_intro_names : Context.Rel.t -> goal sigma -> Id.t list
val intro : unit Proofview.tactic
val introf : unit Proofview.tactic
@@ -74,7 +73,7 @@ val intros : unit Proofview.tactic
(** [depth_of_quantified_hypothesis b h g] returns the index of [h] in
the conclusion of goal [g], up to head-reduction if [b] is [true] *)
val depth_of_quantified_hypothesis :
- bool -> quantified_hypothesis -> goal sigma -> int
+ bool -> quantified_hypothesis -> ([`NF],'b) Proofview.Goal.t -> int
val intros_until : quantified_hypothesis -> unit Proofview.tactic
@@ -126,7 +125,7 @@ val exact_proof : Constrexpr.constr_expr -> tactic
type tactic_reduction = env -> evar_map -> constr -> constr
-type change_arg = patvar_map -> evar_map -> evar_map * constr
+type change_arg = patvar_map -> constr Sigma.run
val make_change_arg : constr -> change_arg
val reduct_in_hyp : ?check:bool -> tactic_reduction -> hyp_location -> tactic
@@ -170,7 +169,7 @@ val unfold_body : Id.t -> tactic
val keep : Id.t list -> unit Proofview.tactic
val apply_clear_request : clear_flag -> bool -> constr -> unit Proofview.tactic
-val specialize : constr with_bindings -> tactic
+val specialize : constr with_bindings -> unit Proofview.tactic
val move_hyp : Id.t -> Id.t move_location -> tactic
val rename_hyp : (Id.t * Id.t) list -> unit Proofview.tactic
@@ -179,8 +178,8 @@ val revert : Id.t list -> unit Proofview.tactic
(** {6 Resolution tactics. } *)
-val apply_type : constr -> constr list -> tactic
-val bring_hyps : named_context -> unit Proofview.tactic
+val apply_type : constr -> constr list -> unit Proofview.tactic
+val bring_hyps : Context.Named.t -> unit Proofview.tactic
val apply : constr -> unit Proofview.tactic
val eapply : constr -> unit Proofview.tactic
@@ -206,6 +205,8 @@ val apply_delayed_in :
(clear_flag * delayed_open_constr_with_bindings located) list ->
intro_pattern option -> unit Proofview.tactic
+val run_delayed : Environ.env -> evar_map -> 'a delayed_open -> 'a * evar_map
+
(** {6 Elimination tactics. } *)
(*
@@ -237,20 +238,20 @@ type elim_scheme = {
elimc: constr with_bindings option;
elimt: types;
indref: global_reference option;
- params: rel_context; (** (prm1,tprm1);(prm2,tprm2)...(prmp,tprmp) *)
- nparams: int; (** number of parameters *)
- predicates: rel_context; (** (Qq, (Tq_1 -> Tq_2 ->...-> Tq_nq)), (Q1,...) *)
- npredicates: int; (** Number of predicates *)
- branches: rel_context; (** branchr,...,branch1 *)
- nbranches: int; (** Number of branches *)
- args: rel_context; (** (xni, Ti_ni) ... (x1, Ti_1) *)
- nargs: int; (** number of arguments *)
- indarg: rel_declaration option; (** Some (H,I prm1..prmp x1...xni)
- if HI is in premisses, None otherwise *)
- concl: types; (** Qi x1...xni HI (f...), HI and (f...)
- are optional and mutually exclusive *)
- indarg_in_concl: bool; (** true if HI appears at the end of conclusion *)
- farg_in_concl: bool; (** true if (f...) appears at the end of conclusion *)
+ params: Context.Rel.t; (** (prm1,tprm1);(prm2,tprm2)...(prmp,tprmp) *)
+ nparams: int; (** number of parameters *)
+ predicates: Context.Rel.t; (** (Qq, (Tq_1 -> Tq_2 ->...-> Tq_nq)), (Q1,...) *)
+ npredicates: int; (** Number of predicates *)
+ branches: Context.Rel.t; (** branchr,...,branch1 *)
+ nbranches: int; (** Number of branches *)
+ args: Context.Rel.t; (** (xni, Ti_ni) ... (x1, Ti_1) *)
+ nargs: int; (** number of arguments *)
+ indarg: Context.Rel.Declaration.t option; (** Some (H,I prm1..prmp x1...xni)
+ if HI is in premisses, None otherwise *)
+ concl: types; (** Qi x1...xni HI (f...), HI and (f...)
+ are optional and mutually exclusive *)
+ indarg_in_concl: bool; (** true if HI appears at the end of conclusion *)
+ farg_in_concl: bool; (** true if (f...) appears at the end of conclusion *)
}
val compute_elim_sig : ?elimc: constr with_bindings -> types -> elim_scheme
@@ -384,7 +385,8 @@ val letin_pat_tac : (bool * intro_pattern_naming) option ->
(** {6 Generalize tactics. } *)
val generalize : constr list -> tactic
-val generalize_gen : ((occurrences * constr) * Name.t) list -> tactic
+val generalize_gen : (constr Locus.with_occurrences * Name.t) list -> tactic
+
val new_generalize : constr list -> unit Proofview.tactic
val new_generalize_gen : ((occurrences * constr) * Name.t) list -> unit Proofview.tactic
@@ -416,9 +418,6 @@ module Simple : sig
(** Simplified version of some of the above tactics *)
val intro : Id.t -> unit Proofview.tactic
- val generalize : constr list -> tactic
- val generalize_gen : (constr Locus.with_occurrences * Name.t) list -> tactic
-
val apply : constr -> unit Proofview.tactic
val eapply : constr -> unit Proofview.tactic
val elim : constr -> unit Proofview.tactic
@@ -431,7 +430,7 @@ end
module New : sig
- val refine : ?unsafe:bool -> (Evd.evar_map -> Evd.evar_map*constr) -> unit Proofview.tactic
+ val refine : ?unsafe:bool -> constr Sigma.run -> unit Proofview.tactic
(** [refine ?unsafe c] is [Proofview.Refine.refine ?unsafe c]
followed by beta-iota-reduction of the conclusion. *)
diff --git a/tactics/tauto.ml4 b/tactics/tauto.ml4
index f41fac547..4dc5388ee 100644
--- a/tactics/tauto.ml4
+++ b/tactics/tauto.ml4
@@ -14,10 +14,13 @@ open Names
open Pp
open Genarg
open Stdarg
+open Tacexpr
open Tacinterp
open Tactics
open Errors
open Util
+open Tacticals.New
+open Proofview.Notations
DECLARE PLUGIN "tauto"
@@ -51,6 +54,13 @@ type tauto_flags = {
strict_unit : bool;
}
+let wit_tauto_flags : tauto_flags uniform_genarg_type =
+ Genarg.create_arg None "tauto_flags"
+
+let assoc_flags ist =
+ let v = Id.Map.find (Names.Id.of_string "tauto_flags") ist.lfun in
+ try Value.cast (topwit wit_tauto_flags) v with _ -> assert false
+
(* Whether inner not are unfolded *)
let negation_unfolding = ref true
@@ -78,26 +88,70 @@ let _ =
optread = (fun () -> !iff_unfolding);
optwrite = (:=) iff_unfolding }
+(** Base tactics *)
+
+let idtac = Proofview.tclUNIT ()
+let fail = Proofview.tclINDEPENDENT (tclFAIL 0 (Pp.mt ()))
+
+let intro = Tactics.intro
+
+let assert_ ?by c =
+ let tac = match by with
+ | None -> None
+ | Some tac -> Some (tclCOMPLETE tac)
+ in
+ Proofview.tclINDEPENDENT (Tactics.forward true tac None c)
+
+let apply c = Tactics.apply c
+
+let clear id = Proofview.V82.tactic (fun gl -> Tactics.clear [id] gl)
+
+let assumption = Tactics.assumption
+
+let split = Tactics.split_with_bindings false [Misctypes.NoBindings]
+
(** Test *)
let make_lfun l =
let fold accu (id, v) = Id.Map.add (Id.of_string id) v accu in
List.fold_left fold Id.Map.empty l
-let is_empty ist =
- if is_empty_type (assoc_var "X1" ist) then
- <:tactic<idtac>>
- else
- <:tactic<fail>>
+let register_tauto_tactic tac name =
+ let name = { mltac_plugin = "tauto"; mltac_tactic = name; } in
+ let entry = { mltac_name = name; mltac_index = 0 } in
+ Tacenv.register_ml_tactic name [| tac |];
+ TacML (Loc.ghost, entry, [])
+
+let tacticIn_ist tac name =
+ let tac _ ist =
+ let avoid = Option.default [] (TacStore.get ist.extra f_avoid_ids) in
+ let debug = Option.default Tactic_debug.DebugOff (TacStore.get ist.extra f_debug) in
+ let (tac, ist) = tac ist in
+ interp_tac_gen ist.lfun avoid debug tac
+ in
+ register_tauto_tactic tac name
+
+let tacticIn tac name =
+ tacticIn_ist (fun ist -> tac ist, ist) name
+
+let push_ist ist args =
+ let fold accu (id, arg) = Id.Map.add (Id.of_string id) arg accu in
+ let lfun = List.fold_left fold ist.lfun args in
+ { ist with lfun = lfun }
+
+let is_empty _ ist =
+ if is_empty_type (assoc_var "X1" ist) then idtac else fail
+
+let t_is_empty = register_tauto_tactic is_empty "is_empty"
(* Strictly speaking, this exceeds the propositional fragment as it
matches also equality types (and solves them if a reflexivity) *)
-let is_unit_or_eq flags ist =
+let is_unit_or_eq _ ist =
+ let flags = assoc_flags ist in
let test = if flags.strict_unit then is_unit_type else is_unit_or_eq_type in
- if test (assoc_var "X1" ist) then
- <:tactic<idtac>>
- else
- <:tactic<fail>>
+ if test (assoc_var "X1" ist) then idtac else fail
+
+let t_is_unit_or_eq = register_tauto_tactic is_unit_or_eq "is_unit_or_eq"
let is_record t =
let (hdapp,args) = decompose_app t in
@@ -116,23 +170,22 @@ let bugged_is_binary t =
Int.equal mib.Declarations.mind_nparams 2
| _ -> false
-let iter_tac tacl =
- List.fold_right (fun tac tacs -> <:tactic< $tac; $tacs >>) tacl
-
(** Dealing with conjunction *)
-let is_conj flags ist =
+let is_conj _ ist =
+ let flags = assoc_flags ist in
let ind = assoc_var "X1" ist in
if (not flags.binary_mode_bugged_detection || bugged_is_binary ind) &&
is_conjunction
~strict:flags.strict_in_hyp_and_ccl
~onlybinary:flags.binary_mode ind
- then
- <:tactic<idtac>>
- else
- <:tactic<fail>>
+ then idtac
+ else fail
+
+let t_is_conj = register_tauto_tactic is_conj "is_conj"
-let flatten_contravariant_conj flags ist =
+let flatten_contravariant_conj _ ist =
+ let flags = assoc_flags ist in
let typ = assoc_var "X1" ist in
let c = assoc_var "X2" ist in
let hyp = assoc_var "id" ist in
@@ -141,39 +194,38 @@ let flatten_contravariant_conj flags ist =
~onlybinary:flags.binary_mode typ
with
| Some (_,args) ->
- let newtyp = valueIn (Value.of_constr (List.fold_right mkArrow args c)) in
- let hyp = valueIn (Value.of_constr hyp) in
- let intros =
- iter_tac (List.map (fun _ -> <:tactic< intro >>) args)
- <:tactic< idtac >> in
- <:tactic<
- let newtyp := $newtyp in
- let hyp := $hyp in
- assert newtyp by ($intros; apply hyp; split; assumption);
- clear hyp
- >>
- | _ ->
- <:tactic<fail>>
+ let newtyp = List.fold_right mkArrow args c in
+ let intros = tclMAP (fun _ -> intro) args in
+ let by = tclTHENLIST [intros; apply hyp; split; assumption] in
+ tclTHENLIST [assert_ ~by newtyp; clear (destVar hyp)]
+ | _ -> fail
+
+let t_flatten_contravariant_conj =
+ register_tauto_tactic flatten_contravariant_conj "flatten_contravariant_conj"
(** Dealing with disjunction *)
let constructor i =
let name = { Tacexpr.mltac_plugin = "coretactics"; mltac_tactic = "constructor" } in
+ (** Take care of the index: this is the second entry in constructor. *)
+ let name = { Tacexpr.mltac_name = name; mltac_index = 1 } in
let i = in_gen (rawwit Constrarg.wit_int_or_var) (Misctypes.ArgArg i) in
- Tacexpr.TacML (Loc.ghost, name, [i])
+ Tacexpr.TacML (Loc.ghost, name, [TacGeneric i])
-let is_disj flags ist =
+let is_disj _ ist =
+ let flags = assoc_flags ist in
let t = assoc_var "X1" ist in
if (not flags.binary_mode_bugged_detection || bugged_is_binary t) &&
is_disjunction
~strict:flags.strict_in_hyp_and_ccl
~onlybinary:flags.binary_mode t
- then
- <:tactic<idtac>>
- else
- <:tactic<fail>>
+ then idtac
+ else fail
+
+let t_is_disj = register_tauto_tactic is_disj "is_disj"
-let flatten_contravariant_disj flags ist =
+let flatten_contravariant_disj _ ist =
+ let flags = assoc_flags ist in
let typ = assoc_var "X1" ist in
let c = assoc_var "X2" ist in
let hyp = assoc_var "id" ist in
@@ -182,18 +234,19 @@ let flatten_contravariant_disj flags ist =
~onlybinary:flags.binary_mode
typ with
| Some (_,args) ->
- let hyp = valueIn (Value.of_constr hyp) in
- iter_tac (List.map_i (fun i arg ->
- let typ = valueIn (Value.of_constr (mkArrow arg c)) in
- let ci = constructor i in
- <:tactic<
- let typ := $typ in
- let hyp := $hyp in
- assert typ by (intro; apply hyp; $ci; assumption)
- >>) 1 args) <:tactic< let hyp := $hyp in clear hyp >>
- | _ ->
- <:tactic<fail>>
-
+ let map i arg =
+ let typ = mkArrow arg c in
+ let ci = Tactics.constructor_tac false None (succ i) Misctypes.NoBindings in
+ let by = tclTHENLIST [intro; apply hyp; ci; assumption] in
+ assert_ ~by typ
+ in
+ let tacs = List.mapi map args in
+ let tac0 = clear (destVar hyp) in
+ tclTHEN (tclTHENLIST tacs) tac0
+ | _ -> fail
+
+let t_flatten_contravariant_disj =
+ register_tauto_tactic flatten_contravariant_disj "flatten_contravariant_disj"
(** Main tactic *)
@@ -204,9 +257,9 @@ let not_dep_intros ist =
| |- (Coq.Init.Logic.not _) => unfold Coq.Init.Logic.not at 1; intro
end >>
-let axioms flags ist =
- let t_is_unit_or_eq = tacticIn (is_unit_or_eq flags)
- and t_is_empty = tacticIn is_empty in
+let t_not_dep_intros = tacticIn not_dep_intros "not_dep_intros"
+
+let axioms ist =
let c1 = constructor 1 in
<:tactic<
match reverse goal with
@@ -215,14 +268,9 @@ let axioms flags ist =
| _:?X1 |- ?X1 => assumption
end >>
+let t_axioms = tacticIn axioms "axioms"
-let simplif flags ist =
- let t_is_unit_or_eq = tacticIn (is_unit_or_eq flags)
- and t_is_conj = tacticIn (is_conj flags)
- and t_flatten_contravariant_conj = tacticIn (flatten_contravariant_conj flags)
- and t_flatten_contravariant_disj = tacticIn (flatten_contravariant_disj flags)
- and t_is_disj = tacticIn (is_disj flags)
- and t_not_dep_intros = tacticIn not_dep_intros in
+let simplif ist =
let c1 = constructor 1 in
<:tactic<
$t_not_dep_intros;
@@ -259,11 +307,11 @@ let simplif flags ist =
end;
$t_not_dep_intros) >>
-let rec tauto_intuit flags t_reduce solver =
- let t_axioms = tacticIn (axioms flags)
- and t_simplif = tacticIn (simplif flags)
- and t_is_disj = tacticIn (is_disj flags) in
- let lfun = make_lfun [("t_solver", solver)] in
+let t_simplif = tacticIn simplif "simplif"
+
+let tauto_intuit flags t_reduce solver =
+ let flags = Genarg.Val.Dyn (Genarg.val_tag (topwit wit_tauto_flags), flags) in
+ let lfun = make_lfun [("t_solver", solver); ("tauto_flags", flags)] in
let ist = { default_ist () with lfun = lfun; } in
let vars = [Id.of_string "t_solver"] in
(vars, ist, <:tactic<
@@ -300,16 +348,16 @@ let reduction_not_iff _ist =
| false, true -> <:tactic< unfold Coq.Init.Logic.iff in * >>
| false, false -> <:tactic< idtac >>
-let t_reduction_not_iff = tacticIn reduction_not_iff
+let t_reduction_not_iff = tacticIn reduction_not_iff "reduction_not_iff"
let intuition_gen ist flags tac =
- Proofview.Goal.enter begin fun gl ->
+ Proofview.Goal.enter { enter = begin fun gl ->
let tac = Value.of_closure ist tac in
let env = Proofview.Goal.env gl in
let vars, ist, intuition = tauto_intuit flags t_reduction_not_iff tac in
let glb_intuition = Tacintern.glob_tactic_env vars env intuition in
eval_tactic_ist ist glb_intuition
- end
+ end }
let tauto_intuitionistic flags =
Proofview.tclORELSE
@@ -345,7 +393,9 @@ let tauto_gen flags =
tauto_intuitionistic flags
end
-let default_intuition_tac = <:tactic< auto with * >>
+let default_intuition_tac =
+ let tac _ _ = Auto.h_auto None [] None in
+ register_tauto_tactic tac "auto_with"
(* This is the uniform mode dealing with ->, not, iff and types isomorphic to
/\ and *, \/ and +, False and Empty_set, True and unit, _and_ eq-like types.
diff --git a/test-suite/Makefile b/test-suite/Makefile
index 207f25ed0..f333ae63e 100644
--- a/test-suite/Makefile
+++ b/test-suite/Makefile
@@ -391,7 +391,7 @@ misc/deps-order.log:
} > "$@"
# Sort universes for the whole standard library
-EXPECTED_UNIVERSES := 5
+EXPECTED_UNIVERSES := 4 # Prop is not counted
universes: misc/universes.log
misc/universes.log: misc/universes/all_stdlib.v
@echo "TEST misc/universes"
diff --git a/test-suite/bugs/opened/3849.v b/test-suite/bugs/closed/3849.v
index 5290054a0..a8dc3af9c 100644
--- a/test-suite/bugs/opened/3849.v
+++ b/test-suite/bugs/closed/3849.v
@@ -5,4 +5,4 @@ Tactic Notation "bar" hyp_list(hs) := foo hs.
Goal True.
do 5 pose proof 0 as ?n0.
foo n1 n2.
-Fail bar n3 n4.
+bar n3 n4.
diff --git a/test-suite/bugs/closed/3911.v b/test-suite/bugs/closed/3911.v
new file mode 100644
index 000000000..b289eafbf
--- /dev/null
+++ b/test-suite/bugs/closed/3911.v
@@ -0,0 +1,26 @@
+(* Tested against coq ee596bc *)
+
+Set Nonrecursive Elimination Schemes.
+Set Primitive Projections.
+Set Universe Polymorphism.
+
+Record setoid := { base : Type }.
+
+Definition catdata (Obj Arr : Type) : Type := nat.
+ (* [nat] can be replaced by any other type, it seems,
+ without changing the error *)
+
+Record cat : Type :=
+ {
+ obj : setoid;
+ arr : Type;
+ dta : catdata (base obj) arr
+ }.
+
+Definition bcwa (C:cat) (B:setoid) :Type := nat.
+ (* As above, nothing special about [nat] here. *)
+
+Record temp {C}{B} (e:bcwa C B) :=
+ { fld : base (obj C) }.
+
+Print temp_rect.
diff --git a/test-suite/bugs/closed/3929.v b/test-suite/bugs/closed/3929.v
new file mode 100644
index 000000000..4031dcc45
--- /dev/null
+++ b/test-suite/bugs/closed/3929.v
@@ -0,0 +1,12 @@
+Goal True.
+evar (T:Type).
+pose (Z:=nat).
+let Tv:=eval cbv [T] in T in
+pose (x:=Tv).
+revert x.
+refine (_ : let x:=Z in True).
+let Zv:=eval cbv [Z] in Z in
+let Tv:=eval cbv [T] in T in
+constr_eq Zv Tv.
+Abort.
+
diff --git a/test-suite/bugs/closed/3957.v b/test-suite/bugs/closed/3957.v
new file mode 100644
index 000000000..e20a6e97f
--- /dev/null
+++ b/test-suite/bugs/closed/3957.v
@@ -0,0 +1,6 @@
+Ltac foo tac := tac.
+
+Goal True.
+Proof.
+foo subst.
+Admitted.
diff --git a/test-suite/bugs/opened/4214.v b/test-suite/bugs/closed/4214.v
index 3daf45213..d684e8cf4 100644
--- a/test-suite/bugs/opened/4214.v
+++ b/test-suite/bugs/closed/4214.v
@@ -2,4 +2,5 @@
Goal forall A (a b c : A), b = a -> b = c -> a = c.
intros.
subst.
-Fail reflexivity.
+reflexivity.
+Qed. \ No newline at end of file
diff --git a/test-suite/bugs/closed/4479.v b/test-suite/bugs/closed/4479.v
new file mode 100644
index 000000000..921579d1e
--- /dev/null
+++ b/test-suite/bugs/closed/4479.v
@@ -0,0 +1,3 @@
+Goal True.
+Fail autorewrite with foo.
+try autorewrite with foo.
diff --git a/test-suite/bugs/opened/3889.v b/test-suite/bugs/opened/3889.v
new file mode 100644
index 000000000..6b287324c
--- /dev/null
+++ b/test-suite/bugs/opened/3889.v
@@ -0,0 +1,11 @@
+Require Import Program.
+
+Inductive Even : nat -> Prop :=
+| evenO : Even O
+| evenS : forall n, Odd n -> Even (S n)
+with Odd : nat -> Prop :=
+| oddS : forall n, Even n -> Odd (S n).
+Axiom admit : forall {T}, T.
+Program Fixpoint doubleE {n} (e : Even n) : Even (2 * n) := admit
+with doubleO {n} (o : Odd n) : Odd (S (2 * n)) := _.
+Next Obligation of doubleE.
diff --git a/test-suite/bugs/opened/3890.v b/test-suite/bugs/opened/3890.v
new file mode 100644
index 000000000..f9ac9be2c
--- /dev/null
+++ b/test-suite/bugs/opened/3890.v
@@ -0,0 +1,18 @@
+Class Foo.
+Class Bar := b : Type.
+
+Instance foo : Foo := _.
+(* 1 subgoals, subgoal 1 (ID 4)
+
+ ============================
+ Foo *)
+
+Instance bar : Bar.
+exact Type.
+Defined.
+(* bar is defined *)
+
+About foo.
+(* foo not a defined object. *)
+
+Fail Defined.
diff --git a/test-suite/bugs/opened/3916.v b/test-suite/bugs/opened/3916.v
new file mode 100644
index 000000000..fd95503e6
--- /dev/null
+++ b/test-suite/bugs/opened/3916.v
@@ -0,0 +1,3 @@
+Require Import List.
+
+Fail Hint Resolve -> in_map. (* Also happens when using <- instead of -> *)
diff --git a/test-suite/bugs/opened/3919.v-disabled b/test-suite/bugs/opened/3919.v-disabled
new file mode 100644
index 000000000..0d661de9c
--- /dev/null
+++ b/test-suite/bugs/opened/3919.v-disabled
@@ -0,0 +1,13 @@
+Require Import MSets.
+Require Import Orders.
+
+Declare Module Signal : OrderedType.
+
+Module S := MSetAVL.Make(Signal).
+Module Sdec := Decide(S).
+Export Sdec.
+
+Hint Extern 0 (Signal.eq ?x ?y) => now symmetry.
+
+Goal forall o s, Signal.eq o s.
+Proof. fsetdec. Qed.
diff --git a/test-suite/bugs/opened/3922.v-disabled b/test-suite/bugs/opened/3922.v-disabled
new file mode 100644
index 000000000..ce4f509ca
--- /dev/null
+++ b/test-suite/bugs/opened/3922.v-disabled
@@ -0,0 +1,83 @@
+Set Universe Polymorphism.
+Notation Type0 := Set.
+
+Definition Type1 := Eval hnf in let gt := (Set : Type@{i}) in Type@{i}.
+
+Notation compose := (fun g f x => g (f x)).
+
+Notation "g 'o' f" := (compose g f) (at level 40, left associativity) : function_scope.
+Open Scope function_scope.
+
+Definition pointwise_paths {A} {P:A->Type} (f g:forall x:A, P x)
+ := forall x:A, f x = g x.
+
+Notation "f == g" := (pointwise_paths f g) (at level 70, no associativity) : type_scope.
+
+Class Contr_internal (A : Type) := BuildContr {
+ center : A ;
+ contr : (forall y : A, center = y)
+}.
+
+Inductive trunc_index : Type :=
+| minus_two : trunc_index
+| trunc_S : trunc_index -> trunc_index.
+
+Notation "n .+1" := (trunc_S n) (at level 2, left associativity, format "n .+1") : trunc_scope.
+Local Open Scope trunc_scope.
+Notation "-2" := minus_two (at level 0) : trunc_scope.
+Notation "-1" := (-2.+1) (at level 0) : trunc_scope.
+
+Fixpoint IsTrunc_internal (n : trunc_index) (A : Type) : Type :=
+ match n with
+ | -2 => Contr_internal A
+ | n'.+1 => forall (x y : A), IsTrunc_internal n' (x = y)
+ end.
+
+Class IsTrunc (n : trunc_index) (A : Type) : Type :=
+ Trunc_is_trunc : IsTrunc_internal n A.
+
+Notation Contr := (IsTrunc -2).
+Notation IsHProp := (IsTrunc -1).
+
+Monomorphic Axiom dummy_funext_type : Type0.
+Monomorphic Class Funext := { dummy_funext_value : dummy_funext_type }.
+
+Inductive Unit : Type1 :=
+ tt : Unit.
+
+Record TruncType (n : trunc_index) := BuildTruncType {
+ trunctype_type : Type ;
+ istrunc_trunctype_type : IsTrunc n trunctype_type
+}.
+
+Arguments BuildTruncType _ _ {_}.
+
+Coercion trunctype_type : TruncType >-> Sortclass.
+
+Notation "n -Type" := (TruncType n) (at level 1) : type_scope.
+Notation hProp := (-1)-Type.
+
+Notation BuildhProp := (BuildTruncType -1).
+
+Private Inductive Trunc (n : trunc_index) (A :Type) : Type :=
+ tr : A -> Trunc n A.
+Arguments tr {n A} a.
+
+Global Instance istrunc_truncation (n : trunc_index) (A : Type@{i})
+: IsTrunc@{j} n (Trunc@{i} n A).
+Admitted.
+
+Definition Trunc_ind {n A}
+ (P : Trunc n A -> Type) {Pt : forall aa, IsTrunc n (P aa)}
+ : (forall a, P (tr a)) -> (forall aa, P aa)
+:= (fun f aa => match aa with tr a => fun _ => f a end Pt).
+Definition merely (A : Type@{i}) : hProp@{i} := BuildhProp (Trunc -1 A).
+Definition cconst_factors_contr `{Funext} {X Y : Type} (f : X -> Y)
+ (P : Type) `{Pc : X -> Contr P}
+ (g : X -> P) (h : P -> Y) (p : h o g == f)
+: Unit.
+Proof.
+ assert (merely X -> IsHProp P) by admit.
+ refine (let g' := Trunc_ind (fun _ => P) g : merely X -> P in _);
+ [ assumption.. | ].
+ Fail pose (g' := Trunc_ind (fun _ => P) g : merely X -> P).
diff --git a/test-suite/bugs/opened/3926.v b/test-suite/bugs/opened/3926.v
new file mode 100644
index 000000000..cfad76357
--- /dev/null
+++ b/test-suite/bugs/opened/3926.v
@@ -0,0 +1,30 @@
+Notation compose := (fun g f x => g (f x)).
+Notation "g 'o' f" := (compose g f) (at level 40, left associativity) : function_scope.
+Open Scope function_scope.
+Inductive paths {A : Type} (a : A) : A -> Type := idpath : paths a a where "x = y" := (@paths _ x y) : type_scope.
+Arguments idpath {A a} , [A] a.
+Definition ap {A B:Type} (f:A -> B) {x y:A} (p:x = y) : f x = f y := match p with idpath => idpath end.
+Class IsEquiv {A B : Type} (f : A -> B) := { equiv_inv : B -> A }.
+Notation "f ^-1" := (@equiv_inv _ _ f _) (at level 3, format "f '^-1'") : equiv_scope.
+Local Open Scope equiv_scope.
+Axiom eisretr : forall {A B} (f : A -> B) `{IsEquiv A B f} x, f (f^-1 x) = x.
+Generalizable Variables A B C f g.
+Global Instance isequiv_compose `{IsEquiv A B f} `{IsEquiv B C g} : IsEquiv (compose g f) | 1000
+ := Build_IsEquiv A C (compose g f) (compose f^-1 g^-1).
+Definition isequiv_homotopic {A B} (f : A -> B) {g : A -> B} `{IsEquiv A B f} (h : forall x, f x = g x) : IsEquiv g
+ := Build_IsEquiv _ _ g (f ^-1).
+Global Instance isequiv_inverse {A B} (f : A -> B) `{IsEquiv A B f} : IsEquiv f^-1 | 10000
+ := Build_IsEquiv B A f^-1 f.
+Definition cancelR_isequiv {A B C} (f : A -> B) {g : B -> C}
+ `{IsEquiv A B f} `{IsEquiv A C (g o f)}
+ : IsEquiv g.
+Proof.
+ Unset Typeclasses Modulo Eta.
+ exact (isequiv_homotopic (compose (compose g f) f^-1)
+ (fun b => ap g (eisretr f b))) || fail "too early".
+ Undo.
+ Set Typeclasses Modulo Eta.
+ Set Typeclasses Dependency Order.
+ Set Typeclasses Debug.
+ Fail exact (isequiv_homotopic (compose (compose g f) f^-1)
+ (fun b => ap g (eisretr f b))).
diff --git a/test-suite/bugs/opened/3928.v-disabled b/test-suite/bugs/opened/3928.v-disabled
new file mode 100644
index 000000000..b470eb229
--- /dev/null
+++ b/test-suite/bugs/opened/3928.v-disabled
@@ -0,0 +1,12 @@
+Typeclasses eauto := bfs.
+
+Class Foo := {}.
+Class Bar := {}.
+
+Instance: Bar.
+Instance: Foo -> Bar -> Foo -> Foo | 1.
+Instance: Bar -> Foo | 100.
+Instance: Foo -> Bar -> Foo -> Foo | 1.
+
+Set Typeclasses Debug.
+Timeout 1 Check (_ : Foo). (* timeout *)
diff --git a/test-suite/bugs/opened/3938.v b/test-suite/bugs/opened/3938.v
new file mode 100644
index 000000000..2d0d1930f
--- /dev/null
+++ b/test-suite/bugs/opened/3938.v
@@ -0,0 +1,6 @@
+Require Import Coq.Arith.PeanoNat.
+Hint Extern 1 => admit : typeclass_instances.
+Goal forall a b (f : nat -> Set), Nat.eq a b -> f a = f b.
+ intros a b f H.
+ rewrite H. (* Toplevel input, characters 15-25:
+Anomaly: Evar ?X11 was not declared. Please report. *)
diff --git a/test-suite/bugs/opened/3946.v b/test-suite/bugs/opened/3946.v
new file mode 100644
index 000000000..e77bdbc65
--- /dev/null
+++ b/test-suite/bugs/opened/3946.v
@@ -0,0 +1,11 @@
+Require Import ZArith.
+
+Inductive foo := Foo : Z.le 0 1 -> foo.
+
+Definition bar (f : foo) := let (f) := f in f.
+
+(* Doesn't work: *)
+(* Arguments bar f.*)
+
+(* Does work *)
+Arguments bar f _.
diff --git a/test-suite/bugs/opened/3948.v b/test-suite/bugs/opened/3948.v
new file mode 100644
index 000000000..165813084
--- /dev/null
+++ b/test-suite/bugs/opened/3948.v
@@ -0,0 +1,25 @@
+Module Type S.
+Parameter t : Type.
+End S.
+
+Module Bar(X : S).
+Proof.
+ Definition elt := X.t.
+ Axiom fold : elt.
+End Bar.
+
+Module Make (X: S) := Bar(X).
+
+Declare Module X : S.
+
+Module Type Interface.
+ Parameter constant : unit.
+End Interface.
+
+Module DepMap : Interface.
+ Module Dom := Make(X).
+ Definition constant : unit :=
+ let _ := @Dom.fold in tt.
+End DepMap.
+
+Print Assumptions DepMap.constant. \ No newline at end of file
diff --git a/test-suite/failure/positivity.v b/test-suite/failure/positivity.v
index 91de87332..8089de2bf 100644
--- a/test-suite/failure/positivity.v
+++ b/test-suite/failure/positivity.v
@@ -5,5 +5,47 @@
(* // * This file is distributed under the terms of the *)
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
-Fail Inductive t : Set :=
- c : (t -> nat) -> t.
+
+(* Negative occurrence *)
+Fail Inductive t : Type :=
+ c : (t -> nat) -> t.
+
+(* Non-strictely positive occurrence *)
+Fail Inductive t : Type :=
+ c : ((t -> nat) -> nat) -> t.
+
+(* Self-nested type (no proof of
+ soundness yet *)
+Fail Inductive t (A:Type) : Type :=
+ c : t (t A) -> t A.
+
+(* Nested inductive types *)
+
+Inductive pos (A:Type) :=
+ p : pos A -> pos A.
+
+Inductive nnpos (A:Type) :=
+ nnp : ((A -> nat) -> nat) -> nnpos A.
+
+Inductive neg (A:Type) :=
+ n : (A->neg A) -> neg A.
+
+Inductive arg : Type -> Prop :=
+ a : forall A, arg A -> arg A.
+
+(* Strictly covariant parameter: accepted. *)
+Fail Fail Inductive t :=
+ c : pos t -> t.
+
+(* Non-strictly covariant parameter: not
+ strictly positive. *)
+Fail Inductive t :=
+ c : nnpos t -> t.
+
+(* Contravariant parameter: not positive. *)
+Fail Inductive t :=
+ c : neg t -> t.
+
+(* Strict index: not positive. *)
+Fail Inductive t :=
+ c : arg t -> t.
diff --git a/test-suite/micromega/square.v b/test-suite/micromega/square.v
index 8767f6874..abf8be72e 100644
--- a/test-suite/micromega/square.v
+++ b/test-suite/micromega/square.v
@@ -53,8 +53,7 @@ Qed.
Theorem sqrt2_not_rational : ~exists x:Q, x^2==2#1.
Proof.
- unfold Qeq; intros [x]; simpl (Qden (2#1)); rewrite Z.mul_1_r.
- intros HQeq.
+ unfold Qeq; intros (x,HQeq); simpl (Qden (2#1)) in HQeq; rewrite Z.mul_1_r in HQeq.
assert (Heq : (Qnum x ^ 2 = 2 * ' Qden x ^ 2%Q)%Z) by
(rewrite QnumZpower in HQeq ; rewrite QdenZpower in HQeq ; auto).
assert (Hnx : (Qnum x <> 0)%Z)
diff --git a/test-suite/output/Cases.out b/test-suite/output/Cases.out
index 09f032d47..f44465456 100644
--- a/test-suite/output/Cases.out
+++ b/test-suite/output/Cases.out
@@ -48,8 +48,8 @@ f =
fun H : B =>
match H with
| AC x =>
- (let b0 := b in
- if b0 as b return (P b -> True)
+ let b0 := b in
+ (if b0 as b return (P b -> True)
then fun _ : P true => Logic.I
else fun _ : P false => Logic.I) x
end
diff --git a/test-suite/output/Cases.v b/test-suite/output/Cases.v
index 4116a5ebc..a4d19d693 100644
--- a/test-suite/output/Cases.v
+++ b/test-suite/output/Cases.v
@@ -72,8 +72,8 @@ Inductive B : Prop := AC : P b -> B.
Definition f : B -> True.
Proof.
-intros [].
-destruct b as [|] ; intros _ ; exact Logic.I.
+intros [x].
+destruct b as [|] ; exact Logic.I.
Defined.
Print f.
diff --git a/test-suite/output/inference.out b/test-suite/output/inference.out
index f2d144778..c5a393408 100644
--- a/test-suite/output/inference.out
+++ b/test-suite/output/inference.out
@@ -6,7 +6,7 @@ fun e : option L => match e with
: option L -> option L
fun (m n p : nat) (H : S m <= S n + p) => le_S_n m (n + p) H
: forall m n p : nat, S m <= S n + p -> m <= n + p
-fun n : nat => let x := A n in ?y ?y0 : T n
+fun n : nat => let x := A n : T n in ?y ?y0 : T n
: forall n : nat, T n
where
?y : [n : nat x := A n : T n |- ?T0 -> T n]
diff --git a/test-suite/stm/Nijmegen_QArithSternBrocot_Zaux.v b/test-suite/stm/Nijmegen_QArithSternBrocot_Zaux.v
index 0d75d52a3..06357cfc2 100644
--- a/test-suite/stm/Nijmegen_QArithSternBrocot_Zaux.v
+++ b/test-suite/stm/Nijmegen_QArithSternBrocot_Zaux.v
@@ -1902,14 +1902,14 @@ Qed.
Lemma Zsgn_15 : forall x y : Z, Zsgn (x * y) = (Zsgn x * Zsgn y)%Z.
Proof.
- intros [y| p1 [| p2| p2]| p1 [| p2| p2]]; simpl in |- *; constructor.
+ intros [|p1|p1]; [intros y|intros [|p2|p2] ..]; simpl in |- *; constructor.
Qed.
Lemma Zsgn_16 :
forall x y : Z,
Zsgn (x * y) = 1%Z -> {(0 < x)%Z /\ (0 < y)%Z} + {(x < 0)%Z /\ (y < 0)%Z}.
Proof.
- intros [y| p1 [| p2| p2]| p1 [| p2| p2]]; simpl in |- *; intro H;
+ intros [|p1|p1]; [intros y|intros [|p2|p2] ..]; simpl in |- *; intro H;
try discriminate H; [ left | right ]; repeat split.
Qed.
@@ -1917,13 +1917,13 @@ Lemma Zsgn_17 :
forall x y : Z,
Zsgn (x * y) = (-1)%Z -> {(0 < x)%Z /\ (y < 0)%Z} + {(x < 0)%Z /\ (0 < y)%Z}.
Proof.
- intros [y| p1 [| p2| p2]| p1 [| p2| p2]]; simpl in |- *; intro H;
+ intros [|p1|p1]; [intros y|intros [|p2|p2] ..]; simpl in |- *; intro H;
try discriminate H; [ left | right ]; repeat split.
Qed.
Lemma Zsgn_18 : forall x y : Z, Zsgn (x * y) = 0%Z -> {x = 0%Z} + {y = 0%Z}.
Proof.
- intros [y| p1 [| p2| p2]| p1 [| p2| p2]]; simpl in |- *; intro H;
+ intros [|p1|p1]; [intros y|intros [|p2|p2] ..]; simpl in |- *; intro H;
try discriminate H; [ left | right | right ]; constructor.
Qed.
@@ -1932,40 +1932,40 @@ Qed.
Lemma Zsgn_19 : forall x y : Z, (0 < Zsgn x + Zsgn y)%Z -> (0 < x + y)%Z.
Proof.
Proof.
- intros [y| p1 [| p2| p2]| p1 [| p2| p2]]; simpl in |- *; intro H;
+ intros [|p1|p1]; [intros y|intros [|p2|p2] ..]; simpl in |- *; intro H;
discriminate H || (constructor || apply Zsgn_12; assumption).
Qed.
Lemma Zsgn_20 : forall x y : Z, (Zsgn x + Zsgn y < 0)%Z -> (x + y < 0)%Z.
Proof.
Proof.
- intros [y| p1 [| p2| p2]| p1 [| p2| p2]]; simpl in |- *; intro H;
+ intros [|p1|p1]; [intros y|intros [|p2|p2] ..]; simpl in |- *; intro H;
discriminate H || (constructor || apply Zsgn_11; assumption).
Qed.
Lemma Zsgn_21 : forall x y : Z, (0 < Zsgn x + Zsgn y)%Z -> (0 <= x)%Z.
Proof.
- intros [y| p1 [| p2| p2]| p1 [| p2| p2]]; simpl in |- *; intros H H0;
+ intros [|p1|p1]; [intros y|intros [|p2|p2] ..]; simpl in |- *; intros H H0;
discriminate H || discriminate H0.
Qed.
Lemma Zsgn_22 : forall x y : Z, (Zsgn x + Zsgn y < 0)%Z -> (x <= 0)%Z.
Proof.
Proof.
- intros [y| p1 [| p2| p2]| p1 [| p2| p2]]; simpl in |- *; intros H H0;
+ intros [|p1|p1]; [intros y|intros [|p2|p2] ..]; simpl in |- *; intros H H0;
discriminate H || discriminate H0.
Qed.
Lemma Zsgn_23 : forall x y : Z, (0 < Zsgn x + Zsgn y)%Z -> (0 <= y)%Z.
Proof.
- intros [[| p2| p2]| p1 [| p2| p2]| p1 [| p2| p2]]; simpl in |- *;
+ intros [|p1|p1] [|p2|p2]; simpl in |- *;
intros H H0; discriminate H || discriminate H0.
Qed.
Lemma Zsgn_24 : forall x y : Z, (Zsgn x + Zsgn y < 0)%Z -> (y <= 0)%Z.
Proof.
- intros [[| p2| p2]| p1 [| p2| p2]| p1 [| p2| p2]]; simpl in |- *;
+ intros [|p1|p1] [|p2|p2]; simpl in |- *;
intros H H0; discriminate H || discriminate H0.
Qed.
diff --git a/test-suite/success/Injection.v b/test-suite/success/Injection.v
index 25e464d67..8fd039462 100644
--- a/test-suite/success/Injection.v
+++ b/test-suite/success/Injection.v
@@ -68,6 +68,12 @@ einjection (H O).
instantiate (1:=O).
Abort.
+Goal (forall x y : nat, x = y -> S x = S y) -> True.
+intros.
+einjection (H O) as H0.
+instantiate (y:=O).
+Abort.
+
(* Test the injection intropattern *)
Goal forall (a b:nat) l l', cons a l = cons b l' -> a=b.
diff --git a/test-suite/success/Typeclasses.v b/test-suite/success/Typeclasses.v
index 30a2a7429..d6e590af3 100644
--- a/test-suite/success/Typeclasses.v
+++ b/test-suite/success/Typeclasses.v
@@ -57,4 +57,25 @@ Section sec.
let's try to get rid of the intermediate constant foo.
Surely we can just expand it inline, right? Wrong!: *)
Check U (fun x => e x) _.
-End sec. \ No newline at end of file
+End sec.
+
+Module IterativeDeepening.
+
+ Class A.
+ Class B.
+ Class C.
+
+ Instance: B -> A | 0.
+ Instance: C -> A | 0.
+ Instance: C -> B -> A | 0.
+ Instance: A -> A | 0.
+
+ Goal C -> A.
+ intros.
+ Set Typeclasses Debug.
+ Fail Timeout 1 typeclasses eauto.
+ Set Typeclasses Iterative Deepening.
+ typeclasses eauto.
+ Qed.
+
+End IterativeDeepening.
diff --git a/test-suite/success/decl_mode2.v b/test-suite/success/decl_mode2.v
new file mode 100644
index 000000000..46174e481
--- /dev/null
+++ b/test-suite/success/decl_mode2.v
@@ -0,0 +1,249 @@
+Theorem this_is_trivial: True.
+proof.
+ thus thesis.
+end proof.
+Qed.
+
+Theorem T: (True /\ True) /\ True.
+ split. split.
+proof. (* first subgoal *)
+ thus thesis.
+end proof.
+trivial. (* second subgoal *)
+proof. (* third subgoal *)
+ thus thesis.
+end proof.
+Abort.
+
+Theorem this_is_not_so_trivial: False.
+proof.
+end proof. (* here a warning is issued *)
+Fail Qed. (* fails: the proof in incomplete *)
+Admitted. (* Oops! *)
+
+Theorem T: True.
+proof.
+escape.
+auto.
+return.
+Abort.
+
+Theorem T: let a:=false in let b:= true in ( if a then True else False -> if b then True else False).
+intros a b.
+proof.
+assume H:(if a then True else False).
+reconsider H as False.
+reconsider thesis as True.
+Abort.
+
+Theorem T: forall x, x=2 -> 2+x=4.
+proof.
+let x be such that H:(x=2).
+have H':(2+x=2+2) by H.
+Abort.
+
+Theorem T: forall x, x=2 -> 2+x=4.
+proof.
+let x be such that H:(x=2).
+then (2+x=2+2).
+Abort.
+
+Theorem T: forall x, x=2 -> x + x = x * x.
+proof.
+let x be such that H:(x=2).
+have (4 = 4).
+ ~= (2 * 2).
+ ~= (x * x) by H.
+ =~ (2 + 2).
+ =~ H':(x + x) by H.
+Abort.
+
+Theorem T: forall x, x + x = x * x -> x = 0 \/ x = 2.
+proof.
+let x be such that H:(x + x = x * x).
+claim H':((x - 2) * x = 0).
+thus thesis.
+end claim.
+Abort.
+
+Theorem T: forall (A B:Prop), A -> B -> A /\ B.
+intros A B HA HB.
+proof.
+hence B.
+Abort.
+
+Theorem T: forall (A B C:Prop), A -> B -> C -> A /\ B /\ C.
+intros A B C HA HB HC.
+proof.
+thus B by HB.
+Abort.
+
+Theorem T: forall (A B C:Prop), A -> B -> C -> A /\ B.
+intros A B C HA HB HC.
+proof.
+Fail hence C. (* fails *)
+Abort.
+
+Theorem T: forall (A B:Prop), B -> A \/ B.
+intros A B HB.
+proof.
+hence B.
+Abort.
+
+Theorem T: forall (A B C D:Prop), C -> D -> (A /\ B) \/ (C /\ D).
+intros A B C D HC HD.
+proof.
+thus C by HC.
+Abort.
+
+Theorem T: forall (P:nat -> Prop), P 2 -> exists x,P x.
+intros P HP.
+proof.
+take 2.
+Abort.
+
+Theorem T: forall (P:nat -> Prop), P 2 -> exists x,P x.
+intros P HP.
+proof.
+hence (P 2).
+Abort.
+
+Theorem T: forall (P:nat -> Prop) (R:nat -> nat -> Prop), P 2 -> R 0 2 -> exists x, exists y, P y /\ R x y.
+intros P R HP HR.
+proof.
+thus (P 2) by HP.
+Abort.
+
+Theorem T: forall (A B:Prop) (P:nat -> Prop), (forall x, P x -> B) -> A -> A /\ B.
+intros A B P HP HA.
+proof.
+suffices to have x such that HP':(P x) to show B by HP,HP'.
+Abort.
+
+Theorem T: forall (A:Prop) (P:nat -> Prop), P 2 -> A -> A /\ (forall x, x = 2 -> P x).
+intros A P HP HA.
+proof.
+(* BUG: the next line fails when it should succeed.
+Waiting for someone to investigate the bug.
+focus on (forall x, x = 2 -> P x).
+let x be such that (x = 2).
+hence thesis by HP.
+end focus.
+*)
+Abort.
+
+Theorem T: forall x, x = 0 -> x + x = x * x.
+proof.
+let x be such that H:(x = 0).
+define sqr x as (x * x).
+reconsider thesis as (x + x = sqr x).
+Abort.
+
+Theorem T: forall (P:nat -> Prop), forall x, P x -> P x.
+proof.
+let P:(nat -> Prop).
+let x:nat.
+assume HP:(P x).
+Abort.
+
+Theorem T: forall (P:nat -> Prop), forall x, P x -> P x.
+proof.
+let P:(nat -> Prop).
+Fail let x. (* fails because x's type is not clear *)
+let x be such that HP:(P x). (* here x's type is inferred from (P x) *)
+Abort.
+
+Theorem T: forall (P:nat -> Prop), forall x, P x -> P x -> P x.
+proof.
+let P:(nat -> Prop).
+let x:nat.
+assume (P x). (* temporary name created *)
+Abort.
+
+Theorem T: forall (P:nat -> Prop), forall x, P x -> P x.
+proof.
+let P:(nat -> Prop).
+let x be such that (P x). (* temporary name created *)
+Abort.
+
+Theorem T: forall (P:nat -> Prop) (A:Prop), (exists x, (P x /\ A)) -> A.
+proof.
+let P:(nat -> Prop),A:Prop be such that H:(exists x, P x /\ A).
+consider x such that HP:(P x) and HA:A from H.
+Abort.
+
+(* Here is an example with pairs: *)
+
+Theorem T: forall p:(nat * nat)%type, (fst p >= snd p) \/ (fst p < snd p).
+proof.
+let p:(nat * nat)%type.
+consider x:nat,y:nat from p.
+reconsider thesis as (x >= y \/ x < y).
+Abort.
+
+Theorem T: forall P:(nat -> Prop), (forall n, P n -> P (n - 1)) ->
+(exists m, P m) -> P 0.
+proof.
+let P:(nat -> Prop) be such that HP:(forall n, P n -> P (n - 1)).
+given m such that Hm:(P m).
+Abort.
+
+Theorem T: forall (A B C:Prop), (A -> C) -> (B -> C) -> (A \/ B) -> C.
+proof.
+let A:Prop,B:Prop,C:Prop be such that HAC:(A -> C) and HBC:(B -> C).
+assume HAB:(A \/ B).
+per cases on HAB.
+suppose A.
+ hence thesis by HAC.
+suppose HB:B.
+ thus thesis by HB,HBC.
+end cases.
+Abort.
+
+Section Coq.
+
+Hypothesis EM : forall P:Prop, P \/ ~ P.
+
+Theorem T: forall (A C:Prop), (A -> C) -> (~A -> C) -> C.
+proof.
+let A:Prop,C:Prop be such that HAC:(A -> C) and HNAC:(~A -> C).
+per cases of (A \/ ~A) by EM.
+suppose (~A).
+ hence thesis by HNAC.
+suppose A.
+ hence thesis by HAC.
+end cases.
+Abort.
+
+Theorem T: forall (A C:Prop), (A -> C) -> (~A -> C) -> C.
+proof.
+let A:Prop,C:Prop be such that HAC:(A -> C) and HNAC:(~A -> C).
+per cases on (EM A).
+suppose (~A).
+Abort.
+End Coq.
+
+Theorem T: forall (A B:Prop) (x:bool), (if x then A else B) -> A \/ B.
+proof.
+let A:Prop,B:Prop,x:bool.
+per cases on x.
+suppose it is true.
+ assume A.
+ hence A.
+suppose it is false.
+ assume B.
+ hence B.
+end cases.
+Abort.
+
+Theorem T: forall (n:nat), n + 0 = n.
+proof.
+let n:nat.
+per induction on n.
+suppose it is 0.
+ thus (0 + 0 = 0).
+suppose it is (S m) and H:thesis for m.
+ then (S (m + 0) = S m).
+ thus =~ (S m + 0).
+end induction.
+Abort. \ No newline at end of file
diff --git a/test-suite/success/induct.v b/test-suite/success/induct.v
index b8c6bf3ff..1ed731f50 100644
--- a/test-suite/success/induct.v
+++ b/test-suite/success/induct.v
@@ -151,3 +151,46 @@ intros x H1 H.
induction H.
change (0 = z -> True) in IHrepr''.
Abort.
+
+(* Test double induction *)
+
+(* This was failing in 8.5 and before because of a bug in the order of
+ hypotheses *)
+
+Inductive I2 : Type :=
+ C2 : forall x:nat, x=x -> I2.
+Goal forall a b:I2, a = b.
+double induction a b.
+Abort.
+
+(* This was leaving useless hypotheses in 8.5 and before because of
+ the same bug. This is a change of compatibility. *)
+
+Inductive I3 : Prop :=
+ C3 : forall x:nat, x=x -> I3.
+Goal forall a b:I3, a = b.
+double induction a b.
+Fail clear H. (* H should have been erased *)
+Abort.
+
+(* This one had quantification in reverse order in 8.5 and before *)
+(* This is a change of compatibility. *)
+
+Goal forall m n, le m n -> le n m -> n=m.
+intros m n. double induction 1 2.
+3:destruct 1. (* Should be "S m0 <= m0" *)
+Abort.
+
+(* Idem *)
+
+Goal forall m n p q, le m n -> le p q -> n+p=m+q.
+intros *. double induction 1 2.
+3:clear H2. (* H2 should have been erased *)
+Abort.
+
+(* This is unchanged *)
+
+Goal forall m n:nat, n=m.
+double induction m n.
+Abort.
+
diff --git a/test-suite/success/intros.v b/test-suite/success/intros.v
index 11156aa0e..ee69df977 100644
--- a/test-suite/success/intros.v
+++ b/test-suite/success/intros.v
@@ -84,3 +84,47 @@ Qed.
Goal forall x : nat, True.
intros y%(fun x => x).
Abort.
+
+(* Fixing a bug in the order of side conditions of a "->" step *)
+
+Goal (True -> 1=0) -> 1=1.
+intros ->.
+- reflexivity.
+- exact I.
+Qed.
+
+Goal forall x, (True -> x=0) -> 0=x.
+intros x ->.
+- reflexivity.
+- exact I.
+Qed.
+
+(* Fixing a bug when destructing a type with let-ins in the constructor *)
+
+Inductive I := C : let x:=1 in x=1 -> I.
+Goal I -> True.
+intros [x H]. (* Was failing in 8.5 *)
+Abort.
+
+(* Ensuring that the (pat1,...,patn) intropatterns has the expected size, up
+ to skipping let-ins *)
+
+Goal I -> 1=1.
+intros (H). (* This skips x *)
+exact H.
+Qed.
+
+Goal I -> 1=1.
+Fail intros (x,H,H').
+Fail intros [|].
+intros (x,H).
+exact H.
+Qed.
+
+Goal Acc le 0 -> True.
+Fail induction 1 as (n,H). (* Induction hypothesis is missing *)
+induction 1 as (n,H,IH).
+exact Logic.I.
+Qed.
+
+
diff --git a/test-suite/success/shrink_abstract.v b/test-suite/success/shrink_abstract.v
new file mode 100644
index 000000000..3f6b9cb39
--- /dev/null
+++ b/test-suite/success/shrink_abstract.v
@@ -0,0 +1,13 @@
+Set Shrink Abstract.
+
+Definition foo : forall (n m : nat), bool.
+Proof.
+pose (p := 0).
+intros n.
+pose (q := n).
+intros m.
+pose (r := m).
+abstract (destruct m; [left|right]).
+Defined.
+
+Check (foo_subproof : nat -> bool).
diff --git a/test-suite/success/shrink_obligations.v b/test-suite/success/shrink_obligations.v
new file mode 100644
index 000000000..676b97878
--- /dev/null
+++ b/test-suite/success/shrink_obligations.v
@@ -0,0 +1,28 @@
+Require Program.
+
+Obligation Tactic := idtac.
+
+Set Shrink Obligations.
+
+Program Definition foo (m : nat) (p := S m) (n : nat) (q := S n) : unit :=
+let bar : {r | n < r} := _ in
+let qux : {r | p < r} := _ in
+let quz : m = n -> True := _ in
+tt.
+Next Obligation.
+intros m p n q.
+exists (S n); constructor.
+Qed.
+Next Obligation.
+intros m p n q.
+exists (S (S m)); constructor.
+Qed.
+Next Obligation.
+intros m p n q ? ? H.
+destruct H.
+constructor.
+Qed.
+
+Check (foo_obligation_1 : forall n, {r | n < r}).
+Check (foo_obligation_2 : forall m, {r | (S m) < r}).
+Check (foo_obligation_3 : forall m n, m = n -> True).
diff --git a/test-suite/success/subst.v b/test-suite/success/subst.v
new file mode 100644
index 000000000..8336f6a80
--- /dev/null
+++ b/test-suite/success/subst.v
@@ -0,0 +1,25 @@
+(* Test various subtleties of the "subst" tactics *)
+
+(* Should proceed from left to right (see #4222) *)
+Goal forall x y, x = y -> x = 3 -> y = 2 -> x = y.
+intros.
+subst.
+change (3 = 2) in H1.
+change (3 = 3).
+Abort.
+
+(* Should work with "x = y" and "x = t" equations (see #4214, failed in 8.4) *)
+Goal forall x y, x = y -> x = 3 -> x = y.
+intros.
+subst.
+change (3 = 3).
+Abort.
+
+(* Should substitute cycles once, until a recursive equation is obtained *)
+(* (failed in 8.4) *)
+Goal forall x y, x = S y -> y = S x -> x = y.
+intros.
+subst.
+change (y = S (S y)) in H0.
+change (S y = y).
+Abort.
diff --git a/theories/Compat/Coq85.v b/theories/Compat/Coq85.v
index 6e2b3564b..af2e04f88 100644
--- a/theories/Compat/Coq85.v
+++ b/theories/Compat/Coq85.v
@@ -7,3 +7,10 @@
(************************************************************************)
(** Compatibility file for making Coq act similar to Coq v8.5 *)
+
+(* In 8.5, "intros [|]", taken e.g. on a goal "A\/B->C", does not
+ behave as "intros [H|H]" but leave instead hypotheses quantified in
+ the goal, here producing subgoals A->C and B->C. *)
+
+Unset Bracketing Last Introduction Pattern.
+
diff --git a/theories/Init/Datatypes.v b/theories/Init/Datatypes.v
index 4850c9cae..ddaf08bf7 100644
--- a/theories/Init/Datatypes.v
+++ b/theories/Init/Datatypes.v
@@ -151,6 +151,7 @@ Inductive option (A:Type) : Type :=
| Some : A -> option A
| None : option A.
+Arguments Some {A} a.
Arguments None {A}.
Definition option_map (A B:Type) (f:A->B) (o : option A) : option B :=
@@ -225,6 +226,7 @@ Inductive list (A : Type) : Type :=
| cons : A -> list A -> list A.
Arguments nil {A}.
+Arguments cons {A} a l.
Infix "::" := cons (at level 60, right associativity) : list_scope.
Delimit Scope list_scope with list.
Bind Scope list_scope with list.
diff --git a/theories/Init/Notations.v b/theories/Init/Notations.v
index ab6bf472d..e1ddaeaef 100644
--- a/theories/Init/Notations.v
+++ b/theories/Init/Notations.v
@@ -85,6 +85,7 @@ Open Scope type_scope.
Declare ML Module "coretactics".
Declare ML Module "extratactics".
+Declare ML Module "g_auto".
Declare ML Module "eauto".
Declare ML Module "g_class".
Declare ML Module "g_eqdecide".
diff --git a/theories/Lists/List.v b/theories/Lists/List.v
index cc7586fec..62b01eb7d 100644
--- a/theories/Lists/List.v
+++ b/theories/Lists/List.v
@@ -7,7 +7,7 @@
(************************************************************************)
Require Setoid.
-Require Import PeanoNat Le Gt Minus Bool.
+Require Import PeanoNat Le Gt Minus Bool Lt.
Set Implicit Arguments.
(* Set Universe Polymorphism. *)
@@ -1634,6 +1634,80 @@ Section Cutting.
end
end.
+ Lemma firstn_nil n: firstn n [] = [].
+ Proof. induction n; now simpl. Qed.
+
+ Lemma firstn_cons n a l: firstn (S n) (a::l) = a :: (firstn n l).
+ Proof. now simpl. Qed.
+
+ Lemma firstn_all l: firstn (length l) l = l.
+ Proof. induction l as [| ? ? H]; simpl; [reflexivity | now rewrite H]. Qed.
+
+ Lemma firstn_all2 n: forall (l:list A), (length l) <= n -> firstn n l = l.
+ Proof. induction n as [|k iHk].
+ - intro. inversion 1 as [H1|?].
+ rewrite (length_zero_iff_nil l) in H1. subst. now simpl.
+ - destruct l as [|x xs]; simpl.
+ * now reflexivity.
+ * simpl. intro H. apply Peano.le_S_n in H. f_equal. apply iHk, H.
+ Qed.
+
+ Lemma firstn_O l: firstn 0 l = [].
+ Proof. now simpl. Qed.
+
+ Lemma firstn_le_length n: forall l:list A, length (firstn n l) <= n.
+ Proof.
+ induction n as [|k iHk]; simpl; [auto | destruct l as [|x xs]; simpl].
+ - auto with arith.
+ - apply Peano.le_n_S, iHk.
+ Qed.
+
+ Lemma firstn_length_le: forall l:list A, forall n:nat,
+ n <= length l -> length (firstn n l) = n.
+ Proof. induction l as [|x xs Hrec].
+ - simpl. intros n H. apply le_n_0_eq in H. rewrite <- H. now simpl.
+ - destruct n.
+ * now simpl.
+ * simpl. intro H. apply le_S_n in H. now rewrite (Hrec n H).
+ Qed.
+
+ Lemma firstn_app n:
+ forall l1 l2,
+ firstn n (l1 ++ l2) = (firstn n l1) ++ (firstn (n - length l1) l2).
+ Proof. induction n as [|k iHk]; intros l1 l2.
+ - now simpl.
+ - destruct l1 as [|x xs].
+ * unfold firstn at 2, length. now rewrite 2!app_nil_l, <- minus_n_O.
+ * rewrite <- app_comm_cons. simpl. f_equal. apply iHk.
+ Qed.
+
+ Lemma firstn_app_2 n:
+ forall l1 l2,
+ firstn ((length l1) + n) (l1 ++ l2) = l1 ++ firstn n l2.
+ Proof. induction n as [| k iHk];intros l1 l2.
+ - unfold firstn at 2. rewrite <- plus_n_O, app_nil_r.
+ rewrite firstn_app. rewrite <- minus_diag_reverse.
+ unfold firstn at 2. rewrite app_nil_r. apply firstn_all.
+ - destruct l2 as [|x xs].
+ * simpl. rewrite app_nil_r. apply firstn_all2. auto with arith.
+ * rewrite firstn_app. assert (H0 : (length l1 + S k - length l1) = S k).
+ auto with arith.
+ rewrite H0, firstn_all2; [reflexivity | auto with arith].
+ Qed.
+
+ Lemma firstn_firstn:
+ forall l:list A,
+ forall i j : nat,
+ firstn i (firstn j l) = firstn (min i j) l.
+ Proof. induction l as [|x xs Hl].
+ - intros. simpl. now rewrite ?firstn_nil.
+ - destruct i.
+ * intro. now simpl.
+ * destruct j.
+ + now simpl.
+ + simpl. f_equal. apply Hl.
+ Qed.
+
Fixpoint skipn (n:nat)(l:list A) : list A :=
match n with
| 0 => l
diff --git a/theories/Lists/ListSet.v b/theories/Lists/ListSet.v
index fd0464fb4..655d3940c 100644
--- a/theories/Lists/ListSet.v
+++ b/theories/Lists/ListSet.v
@@ -48,7 +48,11 @@ Section first_definitions.
end
end.
- (** If [a] belongs to [x], removes [a] from [x]. If not, does nothing *)
+ (** If [a] belongs to [x], removes [a] from [x]. If not, does nothing.
+ Invariant: any element should occur at most once in [x], see for
+ instance [set_add]. We hence remove here only the first occurrence
+ of [a] in [x]. *)
+
Fixpoint set_remove (a:A) (x:set) : set :=
match x with
| nil => empty_set
@@ -227,6 +231,68 @@ Section first_definitions.
intros; elim (Aeq_dec a a0); intros; discriminate.
Qed.
+ Lemma set_add_iff a b l : In a (set_add b l) <-> a = b \/ In a l.
+ Proof.
+ split. apply set_add_elim. apply set_add_intro.
+ Qed.
+
+ Lemma set_add_nodup a l : NoDup l -> NoDup (set_add a l).
+ Proof.
+ induction 1 as [|x l H H' IH]; simpl.
+ - constructor; [ tauto | constructor ].
+ - destruct (Aeq_dec a x) as [<-|Hax]; constructor; trivial.
+ rewrite set_add_iff. intuition.
+ Qed.
+
+ Lemma set_remove_1 (a b : A) (l : set) :
+ In a (set_remove b l) -> In a l.
+ Proof.
+ induction l as [|x xs Hrec].
+ - intros. auto.
+ - simpl. destruct (Aeq_dec b x).
+ * tauto.
+ * intro H. destruct H.
+ + rewrite H. apply in_eq.
+ + apply in_cons. apply Hrec. assumption.
+ Qed.
+
+ Lemma set_remove_2 (a b:A) (l : set) :
+ NoDup l -> In a (set_remove b l) -> a <> b.
+ Proof.
+ induction l as [|x l IH]; intro ND; simpl.
+ - tauto.
+ - inversion_clear ND.
+ destruct (Aeq_dec b x) as [<-|Hbx].
+ + congruence.
+ + destruct 1; subst; auto.
+ Qed.
+
+ Lemma set_remove_3 (a b : A) (l : set) :
+ In a l -> a <> b -> In a (set_remove b l).
+ Proof.
+ induction l as [|x xs Hrec].
+ - now simpl.
+ - simpl. destruct (Aeq_dec b x) as [<-|Hbx]; simpl; intuition.
+ congruence.
+ Qed.
+
+ Lemma set_remove_iff (a b : A) (l : set) :
+ NoDup l -> (In a (set_remove b l) <-> In a l /\ a <> b).
+ Proof.
+ split; try split.
+ - eapply set_remove_1; eauto.
+ - eapply set_remove_2; eauto.
+ - destruct 1; apply set_remove_3; auto.
+ Qed.
+
+ Lemma set_remove_nodup a l : NoDup l -> NoDup (set_remove a l).
+ Proof.
+ induction 1 as [|x l H H' IH]; simpl.
+ - constructor.
+ - destruct (Aeq_dec a x) as [<-|Hax]; trivial.
+ constructor; trivial.
+ rewrite set_remove_iff; trivial. intuition.
+ Qed.
Lemma set_union_intro1 :
forall (a:A) (x y:set), set_In a x -> set_In a (set_union x y).
@@ -264,18 +330,26 @@ Section first_definitions.
tauto.
Qed.
+ Lemma set_union_iff a l l': In a (set_union l l') <-> In a l \/ In a l'.
+ Proof.
+ split. apply set_union_elim. apply set_union_intro.
+ Qed.
+
+ Lemma set_union_nodup l l' : NoDup l -> NoDup l' -> NoDup (set_union l l').
+ Proof.
+ induction 2 as [|x' l' ? ? IH]; simpl; trivial. now apply set_add_nodup.
+ Qed.
+
Lemma set_union_emptyL :
forall (a:A) (x:set), set_In a (set_union empty_set x) -> set_In a x.
intros a x H; case (set_union_elim _ _ _ H); auto || contradiction.
Qed.
-
Lemma set_union_emptyR :
forall (a:A) (x:set), set_In a (set_union x empty_set) -> set_In a x.
intros a x H; case (set_union_elim _ _ _ H); auto || contradiction.
Qed.
-
Lemma set_inter_intro :
forall (a:A) (x y:set),
set_In a x -> set_In a y -> set_In a (set_inter x y).
@@ -326,6 +400,21 @@ Section first_definitions.
eauto with datatypes.
Qed.
+ Lemma set_inter_iff a l l' : In a (set_inter l l') <-> In a l /\ In a l'.
+ Proof.
+ split.
+ - apply set_inter_elim.
+ - destruct 1. now apply set_inter_intro.
+ Qed.
+
+ Lemma set_inter_nodup l l' : NoDup l -> NoDup l' -> NoDup (set_inter l l').
+ Proof.
+ induction 1 as [|x l H H' IH]; intro Hl'; simpl.
+ - constructor.
+ - destruct (set_mem x l'); auto.
+ constructor; auto. rewrite set_inter_iff; tauto.
+ Qed.
+
Lemma set_diff_intro :
forall (a:A) (x y:set),
set_In a x -> ~ set_In a y -> set_In a (set_diff x y).
@@ -360,6 +449,20 @@ Section first_definitions.
rewrite H; trivial.
Qed.
+ Lemma set_diff_iff a l l' : In a (set_diff l l') <-> In a l /\ ~In a l'.
+ Proof.
+ split.
+ - split; [eapply set_diff_elim1 | eapply set_diff_elim2]; eauto.
+ - destruct 1. now apply set_diff_intro.
+ Qed.
+
+ Lemma set_diff_nodup l l' : NoDup l -> NoDup l' -> NoDup (set_diff l l').
+ Proof.
+ induction 1 as [|x l H H' IH]; intro Hl'; simpl.
+ - constructor.
+ - destruct (set_mem x l'); auto using set_add_nodup.
+ Qed.
+
Lemma set_diff_trivial : forall (a:A) (x:set), ~ set_In a (set_diff x x).
red; intros a x H.
apply (set_diff_elim2 _ _ _ H).
diff --git a/theories/Logic/ClassicalFacts.v b/theories/Logic/ClassicalFacts.v
index c947062a9..afd64efdf 100644
--- a/theories/Logic/ClassicalFacts.v
+++ b/theories/Logic/ClassicalFacts.v
@@ -34,6 +34,8 @@ Table of contents:
3 3. Independence of general premises and drinker's paradox
+4. Classical logic and principle of unrestricted minimization
+
*)
(************************************************************************)
@@ -658,3 +660,79 @@ Proof.
exists x; intro; exact Hx.
exists x0; exact Hnot.
Qed.
+
+(** ** Principle of unrestricted minimization *)
+
+Require Import Coq.Arith.PeanoNat.
+
+Definition Minimal (P:nat -> Prop) (n:nat) : Prop :=
+ P n /\ forall k, P k -> n<=k.
+
+Definition Minimization_Property (P : nat -> Prop) : Prop :=
+ forall n, P n -> exists m, Minimal P m.
+
+Section Unrestricted_minimization_entails_excluded_middle.
+
+ Hypothesis unrestricted_minimization: forall P, Minimization_Property P.
+
+ Theorem unrestricted_minimization_entails_excluded_middle : forall A, A\/~A.
+ Proof.
+ intros A.
+ pose (P := fun n:nat => n=0/\A \/ n=1).
+ assert (P 1) as h.
+ { unfold P. intuition. }
+ assert (P 0 <-> A) as p₀.
+ { split.
+ + intros [[_ h₀]|[=]]. assumption.
+ + unfold P. tauto. }
+ apply unrestricted_minimization in h as ([|[|m]] & hm & hmm).
+ + intuition.
+ + right.
+ intros HA. apply p₀, hmm, PeanoNat.Nat.nle_succ_0 in HA. assumption.
+ + destruct hm as [([=],_) | [=] ].
+ Qed.
+
+End Unrestricted_minimization_entails_excluded_middle.
+
+Require Import Wf_nat.
+
+Section Excluded_middle_entails_unrestricted_minimization.
+
+ Hypothesis em : forall A, A\/~A.
+
+ Theorem excluded_middle_entails_unrestricted_minimization :
+ forall P, Minimization_Property P.
+ Proof.
+ intros P n HPn.
+ assert (dec : forall n, P n \/ ~ P n) by auto using em.
+ assert (ex : exists n, P n) by (exists n; assumption).
+ destruct (dec_inh_nat_subset_has_unique_least_element P dec ex) as (n' & HPn' & _).
+ exists n'. assumption.
+ Qed.
+
+End Excluded_middle_entails_unrestricted_minimization.
+
+(** However, minimization for a given predicate does not necessarily imply
+ decidability of this predicate *)
+
+Section Example_of_undecidable_predicate_with_the_minimization_property.
+
+ Variable s : nat -> bool.
+
+ Let P n := exists k, n<=k /\ s k = true.
+
+ Example undecidable_predicate_with_the_minimization_property :
+ Minimization_Property P.
+ Proof.
+ unfold Minimization_Property.
+ intros h hn.
+ exists 0. split.
+ + unfold P in *. destruct hn as (k&hk₁&hk₂).
+ exists k. split.
+ * rewrite <- hk₁.
+ apply PeanoNat.Nat.le_0_l.
+ * assumption.
+ + intros **. apply PeanoNat.Nat.le_0_l.
+ Qed.
+
+End Example_of_undecidable_predicate_with_the_minimization_property.
diff --git a/theories/Logic/PropFacts.v b/theories/Logic/PropFacts.v
new file mode 100644
index 000000000..309539e5c
--- /dev/null
+++ b/theories/Logic/PropFacts.v
@@ -0,0 +1,50 @@
+(************************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2015 *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(************************************************************************)
+
+(** * Basic facts about Prop as a type *)
+
+(** An intuitionistic theorem from topos theory [[LambekScott]]
+
+References:
+
+[[LambekScott]] Jim Lambek, Phil J. Scott, Introduction to higher
+order categorical logic, Cambridge Studies in Advanced Mathematics
+(Book 7), 1988.
+
+*)
+
+Theorem injection_is_involution_in_Prop
+ (f : Prop -> Prop)
+ (inj : forall A B, (f A <-> f B) -> (A <-> B))
+ (ext : forall A B, A <-> B -> f A <-> f B)
+ : forall A, f (f A) <-> A.
+Proof.
+intros.
+enough (f (f (f A)) <-> f A) by (apply inj; assumption).
+split; intro H.
+- now_show (f A).
+ enough (f A <-> True) by firstorder.
+ enough (f (f A) <-> f True) by (apply inj; assumption).
+ split; intro H'.
+ + now_show (f True).
+ enough (f (f (f A)) <-> f True) by firstorder.
+ apply ext; firstorder.
+ + now_show (f (f A)).
+ enough (f (f A) <-> True) by firstorder.
+ apply inj; firstorder.
+- now_show (f (f (f A))).
+ enough (f A <-> f (f (f A))) by firstorder.
+ apply ext.
+ split; intro H'.
+ + now_show (f (f A)).
+ enough (f A <-> f (f A)) by firstorder.
+ apply ext; firstorder.
+ + now_show A.
+ enough (f A <-> A) by firstorder.
+ apply inj; firstorder.
+Defined.
diff --git a/theories/Program/Wf.v b/theories/Program/Wf.v
index 154200d76..a2fd05cd9 100644
--- a/theories/Program/Wf.v
+++ b/theories/Program/Wf.v
@@ -89,7 +89,7 @@ Section Measure_well_founded.
Lemma measure_wf: well_founded MR.
Proof with auto.
unfold well_founded.
- cut (forall a: M, (fun mm: M => forall a0: T, m a0 = mm -> Acc MR a0) a).
+ cut (forall (a: M) (a0: T), m a0 = a -> Acc MR a0).
intros.
apply (H (m a))...
apply (@well_founded_ind M R wf (fun mm => forall a, m a = mm -> Acc MR a)).
diff --git a/theories/Sorting/Permutation.v b/theories/Sorting/Permutation.v
index e159efa81..8470b7955 100644
--- a/theories/Sorting/Permutation.v
+++ b/theories/Sorting/Permutation.v
@@ -321,7 +321,7 @@ Proof.
induction H; intros; try (injection Heqm; intros; subst; clear Heqm);
discriminate || (try tauto).
apply Permutation_length_1_inv in H as ->; left; auto.
- apply IHPermutation1 in Heqm as [H1|H1]; apply IHPermutation2 in H1 as ();
+ apply IHPermutation1 in Heqm as [H1|H1]; apply IHPermutation2 in H1 as [];
auto.
Qed.
diff --git a/theories/Wellfounded/Lexicographic_Exponentiation.v b/theories/Wellfounded/Lexicographic_Exponentiation.v
index 992263cbc..d90f9956b 100644
--- a/theories/Wellfounded/Lexicographic_Exponentiation.v
+++ b/theories/Wellfounded/Lexicographic_Exponentiation.v
@@ -75,7 +75,7 @@ Section Wf_Lexicographic_Exponentiation.
Proof.
intros.
inversion H.
- - apply app_cons_not_nil in H1 as ().
+ - apply app_cons_not_nil in H1 as [].
- assert (x ++ [a] = [x0]) by auto with sets.
apply app_eq_unit in H0 as [(->, _)| (_, [=])].
auto using d_nil.
@@ -98,7 +98,7 @@ Section Wf_Lexicographic_Exponentiation.
destruct (app_inj_tail (l ++ [y]) ([] ++ [b]) _ _ H0) as ((?, <-)%app_inj_tail, <-).
inversion H1; subst; [ apply rt_step; assumption | apply rt_refl ].
- inversion H0.
- + apply app_cons_not_nil in H3 as ().
+ + apply app_cons_not_nil in H3 as [].
+ rewrite app_comm_cons in H0, H1. apply desc_prefix in H0.
pose proof (H x0 b H0).
apply rt_trans with (y := x0); auto with sets.
@@ -145,7 +145,7 @@ Section Wf_Lexicographic_Exponentiation.
pose proof H0 as H0'.
apply app_inj_tail in H0' as (_, ->).
rewrite app_assoc_reverse in H0.
- apply Hind in H0 as ().
+ apply Hind in H0 as [].
split.
assumption.
apply d_conc; auto with sets.
diff --git a/tools/coq_makefile.ml b/tools/coq_makefile.ml
index 478cf8875..f9bff3ac9 100644
--- a/tools/coq_makefile.ml
+++ b/tools/coq_makefile.ml
@@ -355,7 +355,7 @@ let clean sds sps =
sds;
print "\n";
print "printenv:\n\t@\"$(COQBIN)coqtop\" -config\n";
- print "\t@echo 'CAMLC =\t$(CAMLC)'\n\t@echo 'CAMLOPTC =\t$(CAMLOPTC)'\n\t@echo 'PP =\t$(PP)'\n\t@echo 'COQFLAGS =\t$(COQFLAGS)'\n";
+ print "\t@echo 'OCAMLFIND =\t$(OCAMLFIND)'\n\t@echo 'PP =\t$(PP)'\n\t@echo 'COQFLAGS =\t$(COQFLAGS)'\n";
print "\t@echo 'COQLIBINSTALL =\t$(COQLIBINSTALL)'\n\t@echo 'COQDOCINSTALL =\t$(COQDOCINSTALL)'\n\n"
let header_includes () = ()
@@ -365,19 +365,19 @@ let implicit () =
let mli_rules () =
print "$(MLIFILES:.mli=.cmi): %.cmi: %.mli\n\t$(CAMLC) $(ZDEBUG) $(ZFLAGS) $<\n\n";
print "$(addsuffix .d,$(MLIFILES)): %.mli.d: %.mli\n";
- print "\t$(OCAMLDEP) -slash $(OCAMLLIBS) \"$<\" > \"$@\" || ( RV=$$?; rm -f \"$@\"; exit $${RV} )\n\n" in
+ print "\t$(OCAMLFIND) ocamldep -slash $(OCAMLLIBS) \"$<\" > \"$@\" || ( RV=$$?; rm -f \"$@\"; exit $${RV} )\n\n" in
let ml4_rules () =
print "$(ML4FILES:.ml4=.cmo): %.cmo: %.ml4\n\t$(CAMLC) $(ZDEBUG) $(ZFLAGS) $(PP) -impl $<\n\n";
print "$(filter-out $(addsuffix .cmx,$(foreach lib,$(MLPACKFILES:.mlpack=_MLPACK_DEPENDENCIES),$($(lib)))),$(ML4FILES:.ml4=.cmx)): %.cmx: %.ml4\n";
print "\t$(CAMLOPTC) $(ZDEBUG) $(ZFLAGS) $(PP) -impl $<\n\n";
print "$(addsuffix .d,$(ML4FILES)): %.ml4.d: %.ml4\n";
- print "\t$(OCAMLDEP) -slash $(OCAMLLIBS) $(PP) -impl \"$<\" > \"$@\" || ( RV=$$?; rm -f \"$@\"; exit $${RV} )\n\n" in
+ print "\t$(OCAMLFIND) ocamldep -slash $(OCAMLLIBS) $(PP) -impl \"$<\" > \"$@\" || ( RV=$$?; rm -f \"$@\"; exit $${RV} )\n\n" in
let ml_rules () =
print "$(MLFILES:.ml=.cmo): %.cmo: %.ml\n\t$(CAMLC) $(ZDEBUG) $(ZFLAGS) $<\n\n";
print "$(filter-out $(addsuffix .cmx,$(foreach lib,$(MLPACKFILES:.mlpack=_MLPACK_DEPENDENCIES),$($(lib)))),$(MLFILES:.ml=.cmx)): %.cmx: %.ml\n";
print "\t$(CAMLOPTC) $(ZDEBUG) $(ZFLAGS) $<\n\n";
print "$(addsuffix .d,$(MLFILES)): %.ml.d: %.ml\n";
- print "\t$(OCAMLDEP) -slash $(OCAMLLIBS) \"$<\" > \"$@\" || ( RV=$$?; rm -f \"$@\"; exit $${RV} )\n\n" in
+ print "\t$(OCAMLFIND) ocamldep -slash $(OCAMLLIBS) \"$<\" > \"$@\" || ( RV=$$?; rm -f \"$@\"; exit $${RV} )\n\n" in
let cmxs_rules () = (* order is important here when there is foo.ml and foo.mllib *)
print "$(filter-out $(MLLIBFILES:.mllib=.cmxs),$(MLFILES:.ml=.cmxs) $(ML4FILES:.ml4=.cmxs) $(MLPACKFILES:.mlpack=.cmxs)): %.cmxs: %.cmx
\t$(CAMLOPTLINK) $(ZDEBUG) $(ZFLAGS) -shared -o $@ $<\n\n";
@@ -447,7 +447,7 @@ let variables is_install opt (args,defs) =
(* Caml executables and relative variables *)
if !some_ml4file || !some_mlfile || !some_mlifile then begin
print "COQSRCLIBS?=-I \"$(COQLIB)kernel\" -I \"$(COQLIB)lib\" \\
- -I \"$(COQLIB)library\" -I \"$(COQLIB)parsing\" -I \"$(COQLIB)pretyping\" \\
+ -I \"$(COQLIB)library\" -I \"$(COQLIB)parsing\" -I \"$(COQLIB)engine\" -I \"$(COQLIB)pretyping\" \\
-I \"$(COQLIB)interp\" -I \"$(COQLIB)printing\" -I \"$(COQLIB)intf\" \\
-I \"$(COQLIB)proofs\" -I \"$(COQLIB)tactics\" -I \"$(COQLIB)tools\" \\
-I \"$(COQLIB)toplevel\" -I \"$(COQLIB)stm\" -I \"$(COQLIB)grammar\" \\
@@ -455,17 +455,18 @@ let variables is_install opt (args,defs) =
List.iter (fun c -> print " \\
-I \"$(COQLIB)/"; print c; print "\"") Coq_config.plugins_dirs; print "\n";
print "ZFLAGS=$(OCAMLLIBS) $(COQSRCLIBS) -I $(CAMLP4LIB)\n\n";
- print "CAMLC?=$(OCAMLC) -c -rectypes -thread\n";
- print "CAMLOPTC?=$(OCAMLOPT) -c -rectypes -thread\n";
- print "CAMLLINK?=$(OCAMLC) -rectypes -thread\n";
- print "CAMLOPTLINK?=$(OCAMLOPT) -rectypes -thread\n";
+ print "CAMLC?=$(OCAMLFIND) ocamlc -c -rectypes -thread\n";
+ print "CAMLOPTC?=$(OCAMLFIND) opt -c -rectypes -thread\n";
+ print "CAMLLINK?=$(OCAMLFIND) ocamlc -rectypes -thread\n";
+ print "CAMLOPTLINK?=$(OCAMLFIND) opt -rectypes -thread\n";
+ print "CAMLLIB?=$(shell $(OCAMLFIND) printconf stdlib)\n";
print "GRAMMARS?=grammar.cma\n";
print "ifeq ($(CAMLP4),camlp5)
CAMLP4EXTEND=pa_extend.cmo q_MLast.cmo pa_macro.cmo unix.cma threads.cma
else
CAMLP4EXTEND=threads.cma
endif\n";
- print "PP?=-pp '$(CAMLP4O) -I $(CAMLLIB) -I $(CAMLLIB)threads/ $(COQSRCLIBS) compat5.cmo \\
+ print "PP?=-pp '$(CAMLP4O) -I $(CAMLLIB) -I $(CAMLLIB)/threads/ $(COQSRCLIBS) compat5.cmo \\
$(CAMLP4EXTEND) $(GRAMMARS) $(CAMLP4OPTIONS) -impl'\n\n";
end;
match is_install with
@@ -507,7 +508,7 @@ let parameters () =
print "define donewline\n\n\nendef\n";
print "includecmdwithout@ = $(eval $(subst @,$(donewline),$(shell { $(1) | tr -d '\\r' | tr '\\n' '@'; })))\n";
print "$(call includecmdwithout@,$(COQBIN)coqtop -config)\n\n";
- print "TIMED=\nTIMECMD=\nSTDTIME?=/usr/bin/time -f \"$* (user: %U mem: %M ko)\"\n";
+ print "TIMED?=\nTIMECMD?=\nSTDTIME=/usr/bin/time -f \"$* (user: %U mem: %M ko)\"\n";
print "TIMER=$(if $(TIMED), $(STDTIME), $(TIMECMD))\n\n";
print "vo_to_obj = $(addsuffix .o,\\\n";
print " $(filter-out Warning: Error:,\\\n";
@@ -682,9 +683,9 @@ let main_targets vfiles (mlifiles,ml4files,mlfiles,mllibfiles,mlpackfiles) other
begin
print "mlihtml: $(MLIFILES:.mli=.cmi)\n";
print "\t mkdir $@ || rm -rf $@/*\n";
- print "\t$(OCAMLDOC) -html -rectypes -d $@ -m A $(ZDEBUG) $(ZFLAGS) $(^:.cmi=.mli)\n\n";
+ print "\t$(OCAMLFIND) ocamldoc -html -rectypes -d $@ -m A $(ZDEBUG) $(ZFLAGS) $(^:.cmi=.mli)\n\n";
print "all-mli.tex: $(MLIFILES:.mli=.cmi)\n";
- print "\t$(OCAMLDOC) -latex -rectypes -o $@ -m A $(ZDEBUG) $(ZFLAGS) $(^:.cmi=.mli)\n\n";
+ print "\t$(OCAMLFIND) ocamldoc -latex -rectypes -o $@ -m A $(ZDEBUG) $(ZFLAGS) $(^:.cmi=.mli)\n\n";
end;
if !some_vfile then
begin
diff --git a/tools/coqc.ml b/tools/coqc.ml
index b7910e13a..f957200ab 100644
--- a/tools/coqc.ml
+++ b/tools/coqc.ml
@@ -70,17 +70,6 @@ let parse_args () =
| "-byte" :: rem -> binary := "coqtop.byte"; parse (cfiles,args) rem
| "-opt" :: rem -> binary := "coqtop"; parse (cfiles,args) rem
-(* Obsolete options *)
-
- | "-libdir" :: _ :: rem ->
- print_string "Warning: option -libdir deprecated and ignored\n";
- flush stdout;
- parse (cfiles,args) rem
- | ("-db"|"-debugger") :: rem ->
- print_string "Warning: option -db/-debugger deprecated and ignored\n";
- flush stdout;
- parse (cfiles,args) rem
-
(* Informative options *)
| ("-?"|"-h"|"-H"|"-help"|"--help") :: _ -> usage ()
@@ -124,21 +113,11 @@ let parse_args () =
| s :: rem' -> parse (cfiles,s::o::args) rem'
| [] -> usage ()
end
+ | ("-I"|"-include" as o) :: s :: rem -> parse (cfiles,s::o::args) rem
(* Options for coqtop : c) options with 1 argument and possibly more *)
- | ("-I"|"-include" as o) :: rem ->
- begin
- match rem with
- | s :: "-as" :: t :: rem' -> parse (cfiles,t::"-as"::s::o::args) rem'
- | s :: "-as" :: [] -> usage ()
- | s :: rem' -> parse (cfiles,s::o::args) rem'
- | [] -> usage ()
- end
- | "-R" :: s :: "-as" :: t :: rem -> parse (cfiles,t::"-as"::s::"-R"::args) rem
- | "-R" :: s :: "-as" :: [] -> usage ()
- | "-R" :: s :: t :: rem -> parse (cfiles,t::s::"-R"::args) rem
- | "-Q" :: s :: t :: rem -> parse (cfiles,t::s::"-Q"::args) rem
+ | ("-R"|"-Q" as o) :: s :: t :: rem -> parse (cfiles,t::s::o::args) rem
| ("-schedule-vio-checking"
|"-check-vio-tasks" | "-schedule-vio2vo" as o) :: s :: rem ->
let nodash, rem =
diff --git a/tools/coqdep.ml b/tools/coqdep.ml
index 79662a5d3..13705edaa 100644
--- a/tools/coqdep.ml
+++ b/tools/coqdep.ml
@@ -9,6 +9,7 @@
open Printf
open Coqdep_lexer
open Coqdep_common
+open System
(** The basic parts of coqdep (i.e. the parts used by [coqdep -boot])
are now in [Coqdep_common]. The code that remains here concerns
@@ -459,21 +460,14 @@ let rec parse = function
| "-boot" :: ll -> option_boot := true; parse ll
| "-sort" :: ll -> option_sort := true; parse ll
| ("-noglob" | "-no-glob") :: ll -> option_noglob := true; parse ll
- | "-I" :: r :: "-as" :: ln :: ll ->
- add_rec_dir_no_import add_known r [];
- add_rec_dir_no_import add_known r (split_period ln);
- parse ll
- | "-I" :: r :: "-as" :: [] -> usage ()
| "-I" :: r :: ll -> add_caml_dir r; parse ll
| "-I" :: [] -> usage ()
- | "-R" :: r :: "-as" :: ln :: ll -> add_rec_dir_import add_known r (split_period ln); parse ll
- | "-R" :: r :: "-as" :: [] -> usage ()
| "-R" :: r :: ln :: ll -> add_rec_dir_import add_known r (split_period ln); parse ll
| "-Q" :: r :: ln :: ll -> add_rec_dir_no_import add_known r (split_period ln); parse ll
| "-R" :: ([] | [_]) -> usage ()
| "-dumpgraph" :: f :: ll -> option_dump := Some (false, f); parse ll
| "-dumpgraphbox" :: f :: ll -> option_dump := Some (true, f); parse ll
- | "-exclude-dir" :: r :: ll -> norec_dirnames := StrSet.add r !norec_dirnames; parse ll
+ | "-exclude-dir" :: r :: ll -> System.exclude_directory r; parse ll
| "-exclude-dir" :: [] -> usage ()
| "-coqlib" :: r :: ll -> Flags.coqlib_spec := true; Flags.coqlib := r; parse ll
| "-coqlib" :: [] -> usage ()
@@ -497,6 +491,7 @@ let coqdep () =
if !option_boot then begin
add_rec_dir_import add_known "theories" ["Coq"];
add_rec_dir_import add_known "plugins" ["Coq"];
+ add_caml_dir "tactics";
add_rec_dir_import (fun _ -> add_caml_known) "theories" ["Coq"];
add_rec_dir_import (fun _ -> add_caml_known) "plugins" ["Coq"];
end else begin
diff --git a/tools/coqdep_common.ml b/tools/coqdep_common.ml
index 58c8e884c..f5eccbfa4 100644
--- a/tools/coqdep_common.ml
+++ b/tools/coqdep_common.ml
@@ -9,6 +9,7 @@
open Printf
open Coqdep_lexer
open Unix
+open System
(** [coqdep_boot] is a stripped-down version of [coqdep], whose
behavior is the one of [coqdep -boot]. Its only dependencies
@@ -32,26 +33,11 @@ let option_boot = ref false
let option_mldep = ref None
let norec_dirs = ref StrSet.empty
-let norec_dirnames = ref (List.fold_right StrSet.add ["CVS"; "_darcs"] StrSet.empty)
let suffixe = ref ".vo"
type dir = string option
-(* Filename.concat but always with a '/' *)
-let is_dir_sep s i =
- match Sys.os_type with
- | "Unix" -> s.[i] = '/'
- | "Cygwin" | "Win32" ->
- let c = s.[i] in c = '/' || c = '\\' || c = ':'
- | _ -> assert false
-
-let (//) dirname filename =
- let l = String.length dirname in
- if l = 0 || is_dir_sep dirname (l-1)
- then dirname ^ filename
- else dirname ^ "/" ^ filename
-
(** [get_extension f l] checks whether [f] has one of the extensions
listed in [l]. It returns [f] without its extension, alongside with
the extension. When no extension match, [(f,"")] is returned *)
@@ -179,11 +165,6 @@ let warning_module_notfound f s =
eprintf "*** Warning: in file %s, library %s is required and has not been found in the loadpath!\n%!"
f (String.concat "." s)
-let warning_notfound f s =
- eprintf "*** Warning: in file %s, the file " f;
- eprintf "%s.v is required and has not been found!\n" s;
- flush stderr
-
let warning_declare f s =
eprintf "*** Warning: in file %s, declared ML module " f;
eprintf "%s has not been found!\n" s;
@@ -203,6 +184,10 @@ let warning_clash file dir =
eprintf "%s and %s; used the latter)\n" d2 d1
| _ -> assert false
+let warning_cannot_open_dir dir =
+ eprintf "*** Warning: cannot open %s\n" dir;
+ flush stderr
+
let safe_assoc from verbose file k =
if verbose && StrListMap.mem k !clash_v then warning_clash file k;
match search_v_known ?from k with
@@ -527,31 +512,25 @@ let add_known recur phys_dir log_dir f =
List.iter (fun f -> Hashtbl.add coqlibKnown f ()) paths
| _ -> ()
-(** Visit directory [phys_dir] (recursively unless [recur=false]) and
- apply function add_file to each regular file encountered.
- [log_dir] is the logical name of the [phys_dir].
- [add_file] takes both directory names and the file. *)
+(* Visits all the directories under [dir], including [dir] *)
+
+let is_not_seen_directory phys_f =
+ not (StrSet.mem phys_f !norec_dirs)
+
let rec add_directory recur add_file phys_dir log_dir =
- let dirh = opendir phys_dir in
register_dir_logpath phys_dir log_dir;
- try
- while true do
- let f = readdir dirh in
- (* we avoid all files and subdirs starting by '.' (e.g. .svn),
- plus CVS and _darcs and any subdirs given via -exclude-dirs *)
- if f.[0] <> '.' then
- let phys_f = if phys_dir = "." then f else phys_dir//f in
- match try (stat phys_f).st_kind with _ -> S_BLK with
- | S_DIR when recur ->
- if StrSet.mem f !norec_dirnames then ()
- else
- if StrSet.mem phys_f !norec_dirs then ()
- else (* TODO: warn if already seen this physycal dir? *)
- add_directory recur add_file phys_f (log_dir@[f])
- | S_REG -> add_file phys_dir log_dir f
- | _ -> ()
- done
- with End_of_file -> closedir dirh
+ let f = function
+ | FileDir (phys_f,f) ->
+ if is_not_seen_directory phys_f && recur then
+ add_directory true add_file phys_f (log_dir @ [f])
+ | FileRegular f ->
+ add_file phys_dir log_dir f
+ in
+ System.check_unix_dir (fun s -> eprintf "*** Warning: %s\n" s) phys_dir;
+ if exists_dir phys_dir then
+ process_directory f phys_dir
+ else
+ warning_cannot_open_dir phys_dir
(** Simply add this directory and imports it, no subdirs. This is used
by the implicit adding of the current path (which is not recursive). *)
@@ -564,12 +543,18 @@ let add_rec_dir_no_import add_file phys_dir log_dir =
(** -R semantic: go in subdirs and suffixes of logical paths are known. *)
let add_rec_dir_import add_file phys_dir log_dir =
- handle_unix_error (add_directory true (add_file true) phys_dir) log_dir
+ add_directory true (add_file true) phys_dir log_dir
+
+(** -R semantic but only on immediate capitalized subdirs *)
+
+let add_rec_uppercase_subdirs add_file phys_dir log_dir =
+ process_subdirectories (fun phys_dir f ->
+ add_directory true (add_file true) phys_dir (log_dir@[String.capitalize f]))
+ phys_dir
(** -I semantic: do not go in subdirs. *)
let add_caml_dir phys_dir =
- handle_unix_error (add_directory false add_caml_known phys_dir) []
-
+ add_directory false add_caml_known phys_dir []
let rec treat_file old_dirname old_name =
let name = Filename.basename old_name
@@ -584,15 +569,12 @@ let rec treat_file old_dirname old_name =
match try (stat complete_name).st_kind with _ -> S_BLK with
| S_DIR ->
(if name.[0] <> '.' then
- let dir=opendir complete_name in
let newdirname =
match dirname with
| None -> name
| Some d -> d//name
in
- try
- while true do treat_file (Some newdirname) (readdir dir) done
- with End_of_file -> closedir dir)
+ Array.iter (treat_file (Some newdirname)) (Sys.readdir complete_name))
| S_REG ->
(match get_extension name [".v";".ml";".mli";".ml4";".mllib";".mlpack"] with
| (base,".v") ->
diff --git a/tools/coqdep_common.mli b/tools/coqdep_common.mli
index 97bdfaefb..633c474ad 100644
--- a/tools/coqdep_common.mli
+++ b/tools/coqdep_common.mli
@@ -22,10 +22,8 @@ val option_boot : bool ref
val option_natdynlk : bool ref
val option_mldep : string option ref
val norec_dirs : StrSet.t ref
-val norec_dirnames : StrSet.t ref
val suffixe : string ref
type dir = string option
-val ( // ) : string -> string -> string
val get_extension : string -> string list -> string * string
val basename_noext : string -> string
val mlAccu : (string * string * dir) list ref
@@ -51,9 +49,6 @@ val suffixes : 'a list -> 'a list list
val add_known : bool -> string -> string list -> string -> unit
val add_coqlib_known : bool -> string -> string list -> string -> unit
val add_caml_known : string -> string list -> string -> unit
-val add_directory :
- bool ->
- (string -> string list -> string -> unit) -> string -> string list -> unit
val add_caml_dir : string -> unit
(** Simply add this directory and imports it, no subdirs. This is used
@@ -69,5 +64,8 @@ val add_rec_dir_no_import :
val add_rec_dir_import :
(bool -> string -> string list -> string -> unit) -> string -> string list -> unit
+val add_rec_uppercase_subdirs :
+ (bool -> string -> string list -> string -> unit) -> string -> string list -> unit
+
val treat_file : dir -> string -> unit
val error_cannot_parse : string -> int * int -> 'a
diff --git a/tools/coqdep_lexer.mll b/tools/coqdep_lexer.mll
index b16dd3380..eb233b8f9 100644
--- a/tools/coqdep_lexer.mll
+++ b/tools/coqdep_lexer.mll
@@ -25,13 +25,6 @@
exception Fin_fichier
exception Syntax_error of int*int
- let module_current_name = ref []
- let module_names = ref []
- let ml_module_name = ref ""
- let loadpath = ref ""
-
- let mllist = ref ([] : string list)
-
let field_name s = String.sub s 1 (String.length s - 1)
let unquote_string s =
@@ -46,11 +39,6 @@
let syntax_error lexbuf =
raise (Syntax_error (Lexing.lexeme_start lexbuf, Lexing.lexeme_end lexbuf))
-
- (** This is the prefix that should be pre-prepended to files due to the use
- ** of [From], i.e. [From Xxx... Require ...]
- **)
- let from_pre_ident = ref None
}
let space = [' ' '\t' '\n' '\r']
@@ -81,9 +69,9 @@ let dot = '.' ( space+ | eof)
rule coq_action = parse
| "Require" space+
- { require_modifiers lexbuf }
+ { require_modifiers None lexbuf }
| "Local"? "Declare" space+ "ML" space+ "Module" space+
- { mllist := []; modules lexbuf }
+ { modules [] lexbuf }
| "Load" space+
{ load_file lexbuf }
| "Add" space+ "LoadPath" space+
@@ -109,38 +97,34 @@ and from_rule = parse
| space+
{ from_rule lexbuf }
| coq_ident
- { module_current_name := [Lexing.lexeme lexbuf];
- from_pre_ident := Some (coq_qual_id_tail lexbuf);
- module_names := [];
- consume_require lexbuf }
+ { let from = coq_qual_id_tail [Lexing.lexeme lexbuf] lexbuf in
+ consume_require (Some from) lexbuf }
| eof
{ syntax_error lexbuf }
| _
{ syntax_error lexbuf }
-and require_modifiers = parse
+and require_modifiers from = parse
| "(*"
- { comment lexbuf; require_modifiers lexbuf }
+ { comment lexbuf; require_modifiers from lexbuf }
| "Import" space+
- { require_file lexbuf }
+ { require_file from lexbuf }
| "Export" space+
- { require_file lexbuf }
+ { require_file from lexbuf }
| space+
- { require_modifiers lexbuf }
+ { require_modifiers from lexbuf }
| eof
{ syntax_error lexbuf }
| _
- { backtrack lexbuf ; require_file lexbuf }
+ { backtrack lexbuf ; require_file from lexbuf }
-and consume_require = parse
+and consume_require from = parse
| "(*"
- { comment lexbuf; consume_require lexbuf }
+ { comment lexbuf; consume_require from lexbuf }
| space+
- { consume_require lexbuf }
+ { consume_require from lexbuf }
| "Require" space+
- { require_modifiers lexbuf }
- | eof
- { syntax_error lexbuf }
+ { require_modifiers from lexbuf }
| _
{ syntax_error lexbuf }
@@ -152,20 +136,19 @@ and add_loadpath = parse
| eof
{ syntax_error lexbuf }
| '"' [^ '"']* '"' (*'"'*)
- { loadpath := unquote_string (lexeme lexbuf);
- add_loadpath_as lexbuf }
+ { add_loadpath_as (unquote_string (lexeme lexbuf)) lexbuf }
-and add_loadpath_as = parse
+and add_loadpath_as path = parse
| "(*"
- { comment lexbuf; add_loadpath_as lexbuf }
+ { comment lexbuf; add_loadpath_as path lexbuf }
| space+
- { add_loadpath_as lexbuf }
+ { add_loadpath_as path lexbuf }
| "as"
{ let qid = coq_qual_id lexbuf in
skip_to_dot lexbuf;
- AddRecLoadPath (!loadpath,qid) }
+ AddRecLoadPath (path, qid) }
| dot
- { AddLoadPath !loadpath }
+ { AddLoadPath path }
and caml_action = parse
| space +
@@ -176,8 +159,7 @@ and caml_action = parse
{ caml_action lexbuf }
| caml_low_ident { caml_action lexbuf }
| caml_up_ident
- { ml_module_name := Lexing.lexeme lexbuf;
- qual_id lexbuf }
+ { qual_id (Lexing.lexeme lexbuf) lexbuf }
| ['0'-'9']+
| '0' ['x' 'X'] ['0'-'9' 'A'-'F' 'a'-'f']+
| '0' ['o' 'O'] ['0'-'7']+
@@ -260,18 +242,15 @@ and load_file = parse
| _
{ syntax_error lexbuf }
-and require_file = parse
+and require_file from = parse
| "(*"
- { comment lexbuf; require_file lexbuf }
+ { comment lexbuf; require_file from lexbuf }
| space+
- { require_file lexbuf }
+ { require_file from lexbuf }
| coq_ident
- { module_current_name := [Lexing.lexeme lexbuf];
- module_names := [coq_qual_id_tail lexbuf];
- let qid = coq_qual_id_list lexbuf in
+ { let name = coq_qual_id_tail [Lexing.lexeme lexbuf] lexbuf in
+ let qid = coq_qual_id_list [name] lexbuf in
parse_dot lexbuf;
- let from = !from_pre_ident in
- from_pre_ident := None;
Require (from, qid) }
| eof
{ syntax_error lexbuf }
@@ -294,66 +273,55 @@ and coq_qual_id = parse
| space+
{ coq_qual_id lexbuf }
| coq_ident
- { module_current_name := [Lexing.lexeme lexbuf];
- coq_qual_id_tail lexbuf }
- | eof
- { syntax_error lexbuf }
+ { coq_qual_id_tail [Lexing.lexeme lexbuf] lexbuf }
| _
- { backtrack lexbuf;
- let qid = List.rev !module_current_name in
- module_current_name := [];
- qid }
+ { syntax_error lexbuf }
-and coq_qual_id_tail = parse
+and coq_qual_id_tail module_name = parse
| "(*"
- { comment lexbuf; coq_qual_id_tail lexbuf }
+ { comment lexbuf; coq_qual_id_tail module_name lexbuf }
| space+
- { coq_qual_id_tail lexbuf }
+ { coq_qual_id_tail module_name lexbuf }
| coq_field
- { module_current_name :=
- field_name (Lexing.lexeme lexbuf) :: !module_current_name;
- coq_qual_id_tail lexbuf }
+ { coq_qual_id_tail (field_name (Lexing.lexeme lexbuf) :: module_name) lexbuf }
| eof
{ syntax_error lexbuf }
| _
{ backtrack lexbuf;
- let qid = List.rev !module_current_name in
- module_current_name := [];
- qid }
+ List.rev module_name }
-and coq_qual_id_list = parse
+and coq_qual_id_list module_names = parse
| "(*"
- { comment lexbuf; coq_qual_id_list lexbuf }
+ { comment lexbuf; coq_qual_id_list module_names lexbuf }
| space+
- { coq_qual_id_list lexbuf }
+ { coq_qual_id_list module_names lexbuf }
| coq_ident
- { module_current_name := [Lexing.lexeme lexbuf];
- module_names := coq_qual_id_tail lexbuf :: !module_names;
- coq_qual_id_list lexbuf
+ { let name = coq_qual_id_tail [Lexing.lexeme lexbuf] lexbuf in
+ coq_qual_id_list (name :: module_names) lexbuf
}
| eof
{ syntax_error lexbuf }
| _
{ backtrack lexbuf;
- List.rev !module_names }
+ List.rev module_names }
-and modules = parse
+and modules mllist = parse
| space+
- { modules lexbuf }
+ { modules mllist lexbuf }
| "(*"
- { comment lexbuf; modules lexbuf }
+ { comment lexbuf; modules mllist lexbuf }
| '"' [^'"']* '"'
{ let lex = (Lexing.lexeme lexbuf) in
let str = String.sub lex 1 (String.length lex - 2) in
- mllist := str :: !mllist; modules lexbuf}
+ modules (str :: mllist) lexbuf}
| eof
{ syntax_error lexbuf }
| _
- { (Declare (List.rev !mllist)) }
+ { Declare (List.rev mllist) }
-and qual_id = parse
- | '.' [^ '.' '(' '['] {
- Use_module (String.uncapitalize !ml_module_name) }
+and qual_id ml_module_name = parse
+ | '.' [^ '.' '(' '[']
+ { Use_module (String.uncapitalize ml_module_name) }
| eof { raise Fin_fichier }
| _ { caml_action lexbuf }
diff --git a/tools/coqmktop.ml b/tools/coqmktop.ml
index a45c625bc..6f3d8e2b8 100644
--- a/tools/coqmktop.ml
+++ b/tools/coqmktop.ml
@@ -149,7 +149,7 @@ let usage () =
prerr_endline "Usage: coqmktop <options> <ocaml options> files\
\nFlags are:\
\n -coqlib dir Specify where the Coq object files are\
-\n -camlbin dir Specify where the OCaml binaries are\
+\n -ocamlfind dir Specify where the ocamlfind binary is\
\n -camlp4bin dir Specify where the Camlp4/5 binaries are\
\n -o exec-file Specify the name of the resulting toplevel\
\n -boot Run in boot mode\
@@ -167,8 +167,8 @@ let parse_args () =
(* Directories *)
| "-coqlib" :: d :: rem ->
Flags.coqlib_spec := true; Flags.coqlib := d ; parse (op,fl) rem
- | "-camlbin" :: d :: rem ->
- Flags.camlbin_spec := true; Flags.camlbin := d ; parse (op,fl) rem
+ | "-ocamlfind" :: d :: rem ->
+ Flags.ocamlfind_spec := true; Flags.ocamlfind := d ; parse (op,fl) rem
| "-camlp4bin" :: d :: rem ->
Flags.camlp4bin_spec := true; Flags.camlp4bin := d ; parse (op,fl) rem
| "-R" :: d :: rem -> parse (incl_all_subdirs d op,fl) rem
@@ -266,10 +266,9 @@ let main () =
let (options, userfiles) = parse_args () in
(* Directories: *)
let () = Envars.set_coqlib ~fail:Errors.error in
- let camlbin = Envars.camlbin () in
let basedir = if !Flags.boot then None else Some (Envars.coqlib ()) in
(* Which ocaml compiler to invoke *)
- let prog = camlbin/(if !opt then "ocamlopt" else "ocamlc") in
+ let prog = if !opt then "opt" else "ocamlc" in
(* Which arguments ? *)
if !opt && !top then failwith "no custom toplevel in native code !";
let flags = if !opt then [] else Coq_config.vmbyteflags in
@@ -284,14 +283,14 @@ let main () =
(std_includes basedir) @ tolink @ [ main_file ] @ topstart
in
if !echo then begin
- let command = String.concat " " (prog::args) in
+ let command = String.concat " " (Envars.ocamlfind ()::prog::args) in
print_endline command;
print_endline
("(command length is " ^
(string_of_int (String.length command)) ^ " characters)");
flush Pervasives.stdout
end;
- let exitcode = run_command prog args in
+ let exitcode = run_command (Envars.ocamlfind ()) (prog::args) in
clean main_file;
exitcode
with reraise -> clean main_file; raise reraise
diff --git a/tools/fake_ide.ml b/tools/fake_ide.ml
index 1fdda04cb..e81f4038d 100644
--- a/tools/fake_ide.ml
+++ b/tools/fake_ide.ml
@@ -17,7 +17,18 @@ type coqtop = {
xml_parser : Xml_parser.t;
}
-let logger level content = prerr_endline content
+let print_xml chan xml =
+ let rec print = function
+ | Xml_datatype.PCData s -> output_string chan s
+ | Xml_datatype.Element (_, _, children) -> List.iter print children
+ in
+ print xml
+
+let error_xml s =
+ Printf.eprintf "fake_id: error: %a\n%!" print_xml s;
+ exit 1
+
+let logger level content = Printf.eprintf "%a\n%! " print_xml content
let base_eval_call ?(print=true) ?(fail=true) call coqtop =
if print then prerr_endline (Xmlprotocol.pr_call call);
@@ -38,8 +49,8 @@ let base_eval_call ?(print=true) ?(fail=true) call coqtop =
let res = loop () in
if print then prerr_endline (Xmlprotocol.pr_full_value call res);
match res with
- | Interface.Fail (_,_,s) when fail -> error s
- | Interface.Fail (_,_,s) as x -> prerr_endline s; x
+ | Interface.Fail (_,_,s) when fail -> error_xml (Richpp.repr s)
+ | Interface.Fail (_,_,s) as x -> Printf.eprintf "%a\n%!" print_xml (Richpp.repr s); x
| x -> x
let eval_call c q = ignore(base_eval_call c q)
@@ -188,7 +199,7 @@ let print_document () =
module GUILogic = struct
let after_add = function
- | Interface.Fail (_,_,s) -> error s
+ | Interface.Fail (_,_,s) -> error_xml (Richpp.repr s)
| Interface.Good (id, (Util.Inl (), _)) ->
Document.assign_tip_id doc id
| Interface.Good (id, (Util.Inr tip, _)) ->
@@ -200,7 +211,7 @@ module GUILogic = struct
let at id id' _ = Stateid.equal id' id
let after_edit_at (id,need_unfocus) = function
- | Interface.Fail (_,_,s) -> error s
+ | Interface.Fail (_,_,s) -> error_xml (Richpp.repr s)
| Interface.Good (Util.Inl ()) ->
if need_unfocus then Document.unfocus doc;
ignore(Document.cut_at doc id);
@@ -323,7 +334,7 @@ let main =
let finish () =
match base_eval_call (Xmlprotocol.status true) coq with
| Interface.Good _ -> exit 0
- | Interface.Fail (_,_,s) -> error s in
+ | Interface.Fail (_,_,s) -> error_xml (Richpp.repr s) in
(* The main loop *)
init ();
while true do
diff --git a/tools/ocamllibdep.mll b/tools/ocamllibdep.mll
new file mode 100644
index 000000000..670ff487c
--- /dev/null
+++ b/tools/ocamllibdep.mll
@@ -0,0 +1,201 @@
+(************************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2015 *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(************************************************************************)
+
+{
+ exception Syntax_error of int*int
+
+ let syntax_error lexbuf =
+ raise (Syntax_error (Lexing.lexeme_start lexbuf, Lexing.lexeme_end lexbuf))
+}
+
+let space = [' ' '\t' '\n' '\r']
+let lowercase = ['a'-'z' '\223'-'\246' '\248'-'\255']
+let uppercase = ['A'-'Z' '\192'-'\214' '\216'-'\222']
+let identchar =
+ ['A'-'Z' 'a'-'z' '_' '\192'-'\214' '\216'-'\246' '\248'-'\255' '\'' '0'-'9']
+let caml_up_ident = uppercase identchar*
+let caml_low_ident = lowercase identchar*
+
+rule mllib_list = parse
+ | caml_up_ident { let s = String.uncapitalize (Lexing.lexeme lexbuf)
+ in s :: mllib_list lexbuf }
+ | "*predef*" { mllib_list lexbuf }
+ | space+ { mllib_list lexbuf }
+ | eof { [] }
+ | _ { syntax_error lexbuf }
+
+{
+open Printf
+open Unix
+
+(** [coqdep_boot] is a stripped-down version of [coqdep] used to treat
+ with mllib files.
+*)
+
+(* Makefile's escaping rules are awful: $ is escaped by doubling and
+ other special characters are escaped by backslash prefixing while
+ backslashes themselves must be escaped only if part of a sequence
+ followed by a special character (i.e. in case of ambiguity with a
+ use of it as escaping character). Moreover (even if not crucial)
+ it is apparently not possible to directly escape ';' and leading '\t'. *)
+
+let escape =
+ let s' = Buffer.create 10 in
+ fun s ->
+ Buffer.clear s';
+ for i = 0 to String.length s - 1 do
+ let c = s.[i] in
+ if c = ' ' || c = '#' || c = ':' (* separators and comments *)
+ || c = '%' (* pattern *)
+ || c = '?' || c = '[' || c = ']' || c = '*' (* expansion in filenames *)
+ || i=0 && c = '~' && (String.length s = 1 || s.[1] = '/' ||
+ 'A' <= s.[1] && s.[1] <= 'Z' ||
+ 'a' <= s.[1] && s.[1] <= 'z') (* homedir expansion *)
+ then begin
+ let j = ref (i-1) in
+ while !j >= 0 && s.[!j] = '\\' do
+ Buffer.add_char s' '\\'; decr j (* escape all preceding '\' *)
+ done;
+ Buffer.add_char s' '\\';
+ end;
+ if c = '$' then Buffer.add_char s' '$';
+ Buffer.add_char s' c
+ done;
+ Buffer.contents s'
+
+(* Filename.concat but always with a '/' *)
+let is_dir_sep s i =
+ match Sys.os_type with
+ | "Unix" -> s.[i] = '/'
+ | "Cygwin" | "Win32" ->
+ let c = s.[i] in c = '/' || c = '\\' || c = ':'
+ | _ -> assert false
+
+let (//) dirname filename =
+ let l = String.length dirname in
+ if l = 0 || is_dir_sep dirname (l-1)
+ then dirname ^ filename
+ else dirname ^ "/" ^ filename
+
+(** [get_extension f l] checks whether [f] has one of the extensions
+ listed in [l]. It returns [f] without its extension, alongside with
+ the extension. When no extension match, [(f,"")] is returned *)
+
+let rec get_extension f = function
+ | [] -> (f, "")
+ | s :: _ when Filename.check_suffix f s -> (Filename.chop_suffix f s, s)
+ | _ :: l -> get_extension f l
+
+let file_name s = function
+ | None -> s
+ | Some "." -> s
+ | Some d -> d // s
+
+type dir = string option
+
+let add_directory add_file phys_dir =
+ Array.iter (fun f ->
+ (* we avoid all files starting by '.' *)
+ if f.[0] <> '.' then
+ let phys_f = if phys_dir = "." then f else phys_dir//f in
+ match try (stat phys_f).st_kind with _ -> S_BLK with
+ | S_REG -> add_file phys_dir f
+ | _ -> ()) (Sys.readdir phys_dir)
+
+let error_cannot_parse s (i,j) =
+ Printf.eprintf "File \"%s\", characters %i-%i: Syntax error\n" s i j;
+ exit 1
+
+let warning_ml_clash x s suff s' suff' =
+ if suff = suff' then
+ eprintf
+ "*** Warning: %s%s already found in %s (discarding %s%s)\n" x suff
+ (match s with None -> "." | Some d -> d)
+ ((match s' with None -> "." | Some d -> d) // x) suff
+
+let mkknown () =
+ let h = (Hashtbl.create 19 : (string, dir * string) Hashtbl.t) in
+ let add x s suff =
+ try let s',suff' = Hashtbl.find h x in warning_ml_clash x s' suff' s suff
+ with Not_found -> Hashtbl.add h x (s,suff)
+ and search x =
+ try Some (fst (Hashtbl.find h x))
+ with Not_found -> None
+ in add, search
+
+let add_ml_known, search_ml_known = mkknown ()
+let add_mlpack_known, search_mlpack_known = mkknown ()
+
+let mllibAccu = ref ([] : (string * dir) list)
+
+let add_caml_known phys_dir f =
+ let basename,suff = get_extension f [".ml";".ml4";".mlpack"] in
+ match suff with
+ | ".ml"|".ml4" -> add_ml_known basename (Some phys_dir) suff
+ | ".mlpack" -> add_mlpack_known basename (Some phys_dir) suff
+ | _ -> ()
+
+let add_caml_dir phys_dir =
+ handle_unix_error (add_directory add_caml_known) phys_dir
+
+let traite_fichier_modules md ext =
+ try
+ let chan = open_in (md ^ ext) in
+ let list = mllib_list (Lexing.from_channel chan) in
+ List.fold_left
+ (fun a_faire str -> match search_mlpack_known str with
+ | Some mldir ->
+ let file = file_name str mldir in
+ a_faire^" "^file
+ | None ->
+ match search_ml_known str with
+ | Some mldir ->
+ let file = file_name str mldir in
+ a_faire^" "^file
+ | None -> a_faire) "" list
+ with
+ | Sys_error _ -> ""
+ | Syntax_error (i,j) -> error_cannot_parse (md^ext) (i,j)
+
+let addQueue q v = q := v :: !q
+
+let treat_file old_name =
+ let name = Filename.basename old_name in
+ let dirname = Some (Filename.dirname old_name) in
+ match get_extension name [".mllib"] with
+ | (base,".mllib") -> addQueue mllibAccu (base,dirname)
+ | _ -> ()
+
+let mllib_dependencies () =
+ List.iter
+ (fun (name,dirname) ->
+ let fullname = file_name name dirname in
+ let dep = traite_fichier_modules fullname ".mllib" in
+ let efullname = escape fullname in
+ printf "%s_MLLIB_DEPENDENCIES:=%s\n" efullname dep;
+ printf "%s.cma:$(addsuffix .cmo,$(%s_MLLIB_DEPENDENCIES))\n" efullname efullname;
+ printf "%s.cmxa %s.cmxs:$(addsuffix .cmx,$(%s_MLLIB_DEPENDENCIES))\n" efullname efullname efullname;
+ flush Pervasives.stdout)
+ (List.rev !mllibAccu)
+
+let rec parse = function
+ | "-I" :: r :: ll ->
+ (* To solve conflict (e.g. same filename in kernel and checker)
+ we allow to state an explicit order *)
+ add_caml_dir r;
+ parse ll
+ | f :: ll -> treat_file f; parse ll
+ | [] -> ()
+
+let coqdep_boot () =
+ if Array.length Sys.argv < 2 then exit 1;
+ parse (List.tl (Array.to_list Sys.argv));
+ mllib_dependencies ()
+
+let _ = Printexc.catch coqdep_boot ()
+}
diff --git a/toplevel/assumptions.ml b/toplevel/assumptions.ml
index 2a3e65361..cddc55515 100644
--- a/toplevel/assumptions.ml
+++ b/toplevel/assumptions.ml
@@ -141,7 +141,7 @@ let label_of = function
| ConstructRef ((kn,_),_) -> pi3 (repr_mind kn)
| VarRef id -> Label.of_id id
-let push (r : Context.rel_declaration) (ctx : Context.rel_context) = r :: ctx
+let push (r : Context.Rel.Declaration.t) (ctx : Context.Rel.t) = r :: ctx
let rec traverse current ctx accu t = match kind_of_term t with
| Var id ->
diff --git a/toplevel/assumptions.mli b/toplevel/assumptions.mli
index 666218fe7..072675783 100644
--- a/toplevel/assumptions.mli
+++ b/toplevel/assumptions.mli
@@ -6,7 +6,6 @@
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
-open Util
open Names
open Term
open Globnames
@@ -22,7 +21,7 @@ open Printer
val traverse :
Label.t -> constr ->
(Refset_env.t * Refset_env.t Refmap_env.t *
- (label * Context.rel_context * types) list Refmap_env.t)
+ (label * Context.Rel.t * types) list Refmap_env.t)
(** Collects all the assumptions (optionally including opaque definitions)
on which a term relies (together with their type). The above warning of
diff --git a/toplevel/auto_ind_decl.ml b/toplevel/auto_ind_decl.ml
index b3144fa92..f0c7a3961 100644
--- a/toplevel/auto_ind_decl.ml
+++ b/toplevel/auto_ind_decl.ml
@@ -85,7 +85,7 @@ let destruct_on c = destruct false None c None None
let destruct_on_using c id =
destruct false None c
- (Some (dl,[[dl,IntroNaming IntroAnonymous];
+ (Some (dl,IntroOrPattern [[dl,IntroNaming IntroAnonymous];
[dl,IntroNaming (IntroIdentifier id)]]))
None
@@ -102,7 +102,7 @@ let mkFullInd (ind,u) n =
context_chop (nparams-nparrec) mib.mind_params_ctxt in
if nparrec > 0
then mkApp (mkIndU (ind,u),
- Array.of_list(extended_rel_list (nparrec+n) lnamesparrec))
+ Array.of_list(Context.Rel.to_extended_list (nparrec+n) lnamesparrec))
else mkIndU (ind,u)
let check_bool_is_defined () =
@@ -137,7 +137,7 @@ let build_beq_scheme mode kn =
| Name s -> Id.of_string ("eq_"^(Id.to_string s))
| Anonymous -> Id.of_string "eq_A"
in
- let ext_rel_list = extended_rel_list 0 lnamesparrec in
+ let ext_rel_list = Context.Rel.to_extended_list 0 lnamesparrec in
let lift_cnt = ref 0 in
let eqs_typ = List.map (fun aa ->
let a = lift !lift_cnt aa in
@@ -233,7 +233,7 @@ let build_beq_scheme mode kn =
Cn => match Y with ... end |] part *)
let ci = make_case_info env (fst ind) MatchStyle in
let constrs n = get_constructors env (make_ind_family (ind,
- extended_rel_list (n+nb_ind-1) mib.mind_params_ctxt)) in
+ Context.Rel.to_extended_list (n+nb_ind-1) mib.mind_params_ctxt)) in
let constrsi = constrs (3+nparrec) in
let n = Array.length constrsi in
let ar = Array.make n (Lazy.force ff) in
@@ -354,7 +354,7 @@ let do_replace_lb mode lb_scheme_key aavoid narg p q =
)))
)
in
- Proofview.Goal.nf_enter begin fun gl ->
+ Proofview.Goal.nf_enter { enter = begin fun gl ->
let type_of_pq = Tacmach.New.of_old (fun gl -> pf_unsafe_type_of gl p) gl in
let u,v = destruct_ind type_of_pq
in let lb_type_of_p =
@@ -384,7 +384,7 @@ let do_replace_lb mode lb_scheme_key aavoid narg p q =
Tacticals.New.tclTHENLIST [
Proofview.tclEFFECTS eff;
Equality.replace p q ; apply app ; Auto.default_auto]
- end
+ end }
(* used in the bool -> leib side *)
let do_replace_bl mode bl_scheme_key (ind,u as indu) aavoid narg lft rgt =
@@ -416,7 +416,7 @@ let do_replace_bl mode bl_scheme_key (ind,u as indu) aavoid narg lft rgt =
let rec aux l1 l2 =
match (l1,l2) with
| (t1::q1,t2::q2) ->
- Proofview.Goal.enter begin fun gl ->
+ Proofview.Goal.enter { enter = begin fun gl ->
let tt1 = Tacmach.New.pf_unsafe_type_of gl t1 in
if eq_constr t1 t2 then aux q1 q2
else (
@@ -457,7 +457,7 @@ let do_replace_bl mode bl_scheme_key (ind,u as indu) aavoid narg lft rgt =
aux q1 q2 ]
)
)
- end
+ end }
| ([],[]) -> Proofview.tclUNIT ()
| _ -> Tacticals.New.tclZEROMSG (str "Both side of the equality must have the same arity.")
in
@@ -564,7 +564,7 @@ let compute_bl_tact mode bl_scheme_key ind lnamesparrec nparrec =
avoid := fresh::(!avoid); fresh
end gl
in
- Proofview.Goal.nf_enter begin fun gl ->
+ Proofview.Goal.nf_enter { enter = begin fun gl ->
let fresh_first_intros = List.map (fun id -> fresh_id id gl) first_intros in
let freshn = fresh_id (Id.of_string "x") gl in
let freshm = fresh_id (Id.of_string "y") gl in
@@ -587,18 +587,18 @@ repeat ( apply andb_prop in z;let z1:= fresh "Z" in destruct z as [z1 z]).
Tacticals.New.tclREPEAT (
Tacticals.New.tclTHENLIST [
Simple.apply_in freshz (andb_prop());
- Proofview.Goal.nf_enter begin fun gl ->
+ Proofview.Goal.nf_enter { enter = begin fun gl ->
let fresht = fresh_id (Id.of_string "Z") gl in
- (destruct_on_as (mkVar freshz)
- [[dl,IntroNaming (IntroIdentifier fresht);
+ destruct_on_as (mkVar freshz)
+ (IntroOrPattern [[dl,IntroNaming (IntroIdentifier fresht);
dl,IntroNaming (IntroIdentifier freshz)]])
- end
+ end }
]);
(*
Ci a1 ... an = Ci b1 ... bn
replace bi with ai; auto || replace bi with ai by apply typeofbi_prod ; auto
*)
- Proofview.Goal.nf_enter begin fun gls ->
+ Proofview.Goal.nf_enter { enter = begin fun gls ->
let gl = Proofview.Goal.concl gls in
match (kind_of_term gl) with
| App (c,ca) -> (
@@ -617,10 +617,10 @@ repeat ( apply andb_prop in z;let z1:= fresh "Z" in destruct z as [z1 z]).
| _ -> Tacticals.New.tclZEROMSG (str" Failure while solving Boolean->Leibniz.")
)
| _ -> Tacticals.New.tclZEROMSG (str "Failure while solving Boolean->Leibniz.")
- end
+ end }
]
- end
+ end }
let bl_scheme_kind_aux = ref (fun _ -> failwith "Undefined")
@@ -707,7 +707,7 @@ let compute_lb_tact mode lb_scheme_key ind lnamesparrec nparrec =
avoid := fresh::(!avoid); fresh
end gl
in
- Proofview.Goal.nf_enter begin fun gl ->
+ Proofview.Goal.nf_enter { enter = begin fun gl ->
let fresh_first_intros = List.map (fun id -> fresh_id id gl) first_intros in
let freshn = fresh_id (Id.of_string "x") gl in
let freshm = fresh_id (Id.of_string "y") gl in
@@ -730,7 +730,7 @@ let compute_lb_tact mode lb_scheme_key ind lnamesparrec nparrec =
Tacticals.New.tclTHENLIST [apply (andb_true_intro());
simplest_split ;Auto.default_auto ]
);
- Proofview.Goal.nf_enter begin fun gls ->
+ Proofview.Goal.nf_enter { enter = begin fun gls ->
let gl = Proofview.Goal.concl gls in
(* assume the goal to be eq (eq_type ...) = true *)
match (kind_of_term gl) with
@@ -746,9 +746,9 @@ let compute_lb_tact mode lb_scheme_key ind lnamesparrec nparrec =
)
| _ ->
Tacticals.New.tclZEROMSG (str "Failure while solving Leibniz->Boolean.")
- end
+ end }
]
- end
+ end }
let lb_scheme_kind_aux = ref (fun () -> failwith "Undefined")
@@ -854,7 +854,7 @@ let compute_dec_tact ind lnamesparrec nparrec =
avoid := fresh::(!avoid); fresh
end gl
in
- Proofview.Goal.nf_enter begin fun gl ->
+ Proofview.Goal.nf_enter { enter = begin fun gl ->
let fresh_first_intros = List.map (fun id -> fresh_id id gl) first_intros in
let freshn = fresh_id (Id.of_string "x") gl in
let freshm = fresh_id (Id.of_string "y") gl in
@@ -885,7 +885,7 @@ let compute_dec_tact ind lnamesparrec nparrec =
)
(Tacticals.New.tclTHEN (destruct_on eqbnm) Auto.default_auto);
- Proofview.Goal.nf_enter begin fun gl ->
+ Proofview.Goal.nf_enter { enter = begin fun gl ->
let freshH2 = fresh_id (Id.of_string "H") gl in
Tacticals.New.tclTHENS (destruct_on_using (mkVar freshH) freshH2) [
(* left *)
@@ -897,7 +897,7 @@ let compute_dec_tact ind lnamesparrec nparrec =
;
(*right *)
- Proofview.Goal.nf_enter begin fun gl ->
+ Proofview.Goal.nf_enter { enter = begin fun gl ->
let freshH3 = fresh_id (Id.of_string "H") gl in
Tacticals.New.tclTHENLIST [
simplest_right ;
@@ -919,11 +919,11 @@ let compute_dec_tact ind lnamesparrec nparrec =
true;
Equality.discr_tac false None
]
- end
+ end }
]
- end
+ end }
]
- end
+ end }
let make_eq_decidability mode mind =
let mib = Global.lookup_mind mind in
diff --git a/toplevel/class.ml b/toplevel/class.ml
index 3d6d567cc..a9c53b4d4 100644
--- a/toplevel/class.ml
+++ b/toplevel/class.ml
@@ -197,13 +197,13 @@ let build_id_coercion idf_opt source poly =
let val_f =
it_mkLambda_or_LetIn
(mkLambda (Name Namegen.default_dependent_ident,
- applistc vs (extended_rel_list 0 lams),
+ applistc vs (Context.Rel.to_extended_list 0 lams),
mkRel 1))
lams
in
let typ_f =
it_mkProd_wo_LetIn
- (mkProd (Anonymous, applistc vs (extended_rel_list 0 lams), lift 1 t))
+ (mkProd (Anonymous, applistc vs (Context.Rel.to_extended_list 0 lams), lift 1 t))
lams
in
(* juste pour verification *)
diff --git a/toplevel/classes.ml b/toplevel/classes.ml
index 3a0b5f24f..936343628 100644
--- a/toplevel/classes.ml
+++ b/toplevel/classes.ml
@@ -20,6 +20,7 @@ open Libnames
open Globnames
open Constrintern
open Constrexpr
+open Sigma.Notations
(*i*)
open Decl_kinds
@@ -194,7 +195,7 @@ let new_instance ?(abstract=false) ?(global=false) poly ctx (instid, bk, cl) pro
else (
let props =
match props with
- | Some (true, CRecord (loc, _, fs)) ->
+ | Some (true, CRecord (loc, fs)) ->
if List.length fs > List.length k.cl_props then
mismatched_props env' (List.map snd fs) k.cl_props;
Some (Inl fs)
@@ -322,7 +323,7 @@ let new_instance ?(abstract=false) ?(global=false) poly ctx (instid, bk, cl) pro
if not (Option.is_empty term) then
let init_refine =
Tacticals.New.tclTHENLIST [
- Proofview.Refine.refine (fun evm -> evm, Option.get term);
+ Proofview.Refine.refine { run = fun evm -> Sigma (Option.get term, evm, Sigma.refl) };
Proofview.Unsafe.tclNEWGOALS gls;
Tactics.New.reduce_after_refine;
]
@@ -350,7 +351,7 @@ let context poly l =
let evars = ref (Evd.from_env env) in
let _, ((env', fullctx), impls) = interp_context_evars env evars l in
let subst = Evarutil.evd_comb0 Evarutil.nf_evars_and_universes evars in
- let fullctx = Context.map_rel_context subst fullctx in
+ let fullctx = Context.Rel.map subst fullctx in
let ce t = Evarutil.check_evars env Evd.empty !evars t in
let () = List.iter (fun (n, b, t) -> Option.iter ce b; ce t) fullctx in
let ctx =
diff --git a/toplevel/classes.mli b/toplevel/classes.mli
index 24c51b31a..8dcfabae4 100644
--- a/toplevel/classes.mli
+++ b/toplevel/classes.mli
@@ -7,7 +7,6 @@
(************************************************************************)
open Names
-open Context
open Environ
open Constrexpr
open Typeclasses
@@ -15,9 +14,9 @@ open Libnames
(** Errors *)
-val mismatched_params : env -> constr_expr list -> rel_context -> 'a
+val mismatched_params : env -> constr_expr list -> Context.Rel.t -> 'a
-val mismatched_props : env -> constr_expr list -> rel_context -> 'a
+val mismatched_props : env -> constr_expr list -> Context.Rel.t -> 'a
(** Instance declaration *)
diff --git a/toplevel/command.ml b/toplevel/command.ml
index 5d2a7638a..4adb66bc9 100644
--- a/toplevel/command.ml
+++ b/toplevel/command.ml
@@ -12,7 +12,6 @@ open Util
open Flags
open Term
open Vars
-open Context
open Termops
open Entries
open Environ
@@ -87,7 +86,7 @@ let interp_definition pl bl p red_option c ctypopt =
match ctypopt with
None ->
let subst = evd_comb0 Evd.nf_univ_variables evdref in
- let ctx = map_rel_context (Vars.subst_univs_constr subst) ctx in
+ let ctx = Context.Rel.map (Vars.subst_univs_constr subst) ctx in
let env_bl = push_rel_context ctx env in
let c, imps2 = interp_constr_evars_impls ~impls env_bl evdref c in
let nf,subst = Evarutil.e_nf_evars_and_universes evdref in
@@ -100,7 +99,7 @@ let interp_definition pl bl p red_option c ctypopt =
| Some ctyp ->
let ty, impsty = interp_type_evars_impls ~impls env_bl evdref ctyp in
let subst = evd_comb0 Evd.nf_univ_variables evdref in
- let ctx = map_rel_context (Vars.subst_univs_constr subst) ctx in
+ let ctx = Context.Rel.map (Vars.subst_univs_constr subst) ctx in
let env_bl = push_rel_context ctx env in
let c, imps2 = interp_casted_constr_evars_impls ~impls env_bl evdref c ty in
let nf, subst = Evarutil.e_nf_evars_and_universes evdref in
@@ -125,7 +124,7 @@ let interp_definition pl bl p red_option c ctypopt =
definition_entry ~types:typ ~poly:p
~univs:uctx body
in
- red_constant_entry (rel_context_length ctx) ce !evdref red_option, !evdref, pl, imps
+ red_constant_entry (Context.Rel.length ctx) ce !evdref red_option, !evdref, pl, imps
let check_definition (ce, evd, _, imps) =
check_evars_are_solved (Global.env ()) evd (Evd.empty,evd);
@@ -566,7 +565,7 @@ let interp_mutual_inductive (paramsl,indl) notations poly prv finite =
(* Compute interpretation metadatas *)
let indimpls = List.map (fun (_, _, impls) -> userimpls @
- lift_implicits (rel_context_nhyps ctx_params) impls) arities in
+ lift_implicits (Context.Rel.nhyps ctx_params) impls) arities in
let arities = List.map pi1 arities and aritypoly = List.map pi2 arities in
let impls = compute_internalization_env env0 (Inductive params) indnames fullarities indimpls in
let mldatas = List.map2 (mk_mltype_data evdref env_params params) arities indnames in
@@ -592,11 +591,11 @@ let interp_mutual_inductive (paramsl,indl) notations poly prv finite =
let nf x = nf' (nf x) in
let arities = List.map nf' arities in
let constructors = List.map (fun (idl,cl,impsl) -> (idl,List.map nf' cl,impsl)) constructors in
- let ctx_params = map_rel_context nf ctx_params in
+ let ctx_params = Context.Rel.map nf ctx_params in
let evd = !evdref in
let pl, uctx = Evd.universe_context ?names:pl evd in
List.iter (check_evars env_params Evd.empty evd) arities;
- iter_rel_context (check_evars env0 Evd.empty evd) ctx_params;
+ Context.Rel.iter (check_evars env0 Evd.empty evd) ctx_params;
List.iter (fun (_,ctyps,_) ->
List.iter (check_evars env_ar_params Evd.empty evd) ctyps)
constructors;
@@ -610,7 +609,7 @@ let interp_mutual_inductive (paramsl,indl) notations poly prv finite =
mind_entry_lc = ctypes
}) indl arities aritypoly constructors in
let impls =
- let len = rel_context_nhyps ctx_params in
+ let len = Context.Rel.nhyps ctx_params in
List.map2 (fun indimpls (_,_,cimpls) ->
indimpls, List.map (fun impls ->
userimpls @ (lift_implicits len impls)) cimpls) indimpls constructors
diff --git a/toplevel/coqinit.ml b/toplevel/coqinit.ml
index 91cec4bbd..b81c8da71 100644
--- a/toplevel/coqinit.ml
+++ b/toplevel/coqinit.ml
@@ -125,7 +125,7 @@ let init_ocaml_path () =
Mltop.add_ml_dir (Envars.coqlib ());
List.iter add_subdir
[ [ "config" ]; [ "dev" ]; [ "lib" ]; [ "kernel" ]; [ "library" ];
- [ "pretyping" ]; [ "interp" ]; [ "parsing" ]; [ "proofs" ];
+ [ "engine" ]; [ "pretyping" ]; [ "interp" ]; [ "parsing" ]; [ "proofs" ];
[ "tactics" ]; [ "toplevel" ]; [ "printing" ]; [ "intf" ];
[ "grammar" ]; [ "ide" ] ]
diff --git a/toplevel/coqtop.ml b/toplevel/coqtop.ml
index afd4ef40e..8f56cddfa 100644
--- a/toplevel/coqtop.ml
+++ b/toplevel/coqtop.ml
@@ -257,18 +257,19 @@ let set_emacs () =
*)
let init_gc () =
- let param =
- try ignore (Sys.getenv "OCAMLRUNPARAM"); true
- with Not_found -> false
- in
- let control = Gc.get () in
- let tweaked_control = { control with
- Gc.minor_heap_size = 33554432; (** 4M *)
-(* Gc.major_heap_increment = 268435456; (** 32M *) *)
- Gc.space_overhead = 120;
- } in
- if param then ()
- else Gc.set tweaked_control
+ try
+ (* OCAMLRUNPARAM environment variable is set.
+ * In that case, we let ocamlrun to use the values provided by the user.
+ *)
+ ignore (Sys.getenv "OCAMLRUNPARAM")
+
+ with Not_found ->
+ (* OCAMLRUNPARAM environment variable is not set.
+ * In this case, we put in place our preferred configuration.
+ *)
+ Gc.set { (Gc.get ()) with
+ Gc.minor_heap_size = 33554432; (** 4M *)
+ Gc.space_overhead = 120}
(*s Parsing of the command line.
We no longer use [Arg.parse], in order to use share [Usage.print_usage]
@@ -442,10 +443,6 @@ let parse_args arglist =
end
|"-R" ->
begin match rem with
- | d :: "-as" :: [] -> error_missing_arg opt
- | d :: "-as" :: p :: rem ->
- warning "option -R * -as * deprecated, remove the -as";
- set_include d p true; args := rem
| d :: p :: rem -> set_include d p true; args := rem
| _ -> error_missing_arg opt
end
@@ -485,7 +482,7 @@ let parse_args arglist =
|"-compile-verbose" -> add_compile true (next ())
|"-dump-glob" -> Dumpglob.dump_into_file (next ()); glob_opt := true
|"-feedback-glob" -> Dumpglob.feedback_glob ()
- |"-exclude-dir" -> exclude_search_in_dirname (next ())
+ |"-exclude-dir" -> System.exclude_directory (next ())
|"-init-file" -> set_rcfile (next ())
|"-inputstate"|"-is" -> set_inputstate (next ())
|"-load-ml-object" -> Mltop.dir_ml_load (next ())
@@ -576,7 +573,7 @@ let parse_args arglist =
else fatal_error (Errors.print e) false
| any -> fatal_error (Errors.print any) (Errors.is_anomaly any)
-let init arglist =
+let init_toplevel arglist =
init_gc ();
Sys.catch_break false; (* Ctrl-C is fatal during the initialisation *)
Lib.init();
@@ -640,8 +637,6 @@ let init arglist =
exit 0
end
-let init_toplevel = init
-
let start () =
let () = init_toplevel (List.tl (Array.to_list Sys.argv)) in
(* In batch mode, Coqtop has already exited at this point. In interactive one,
diff --git a/toplevel/discharge.ml b/toplevel/discharge.ml
index 615730910..61a6e1094 100644
--- a/toplevel/discharge.ml
+++ b/toplevel/discharge.ml
@@ -9,7 +9,6 @@
open Names
open Errors
open Util
-open Context
open Term
open Vars
open Entries
@@ -37,8 +36,8 @@ let detype_param = function
let abstract_inductive hyps nparams inds =
let ntyp = List.length inds in
- let nhyp = named_context_length hyps in
- let args = instance_from_named_context (List.rev hyps) in
+ let nhyp = Context.Named.length hyps in
+ let args = Context.Named.to_instance (List.rev hyps) in
let args = Array.of_list args in
let subs = List.init ntyp (fun k -> lift nhyp (mkApp(mkRel (k+1),args))) in
let inds' =
@@ -100,7 +99,7 @@ let process_inductive (sechyps,abs_ctx) modlist mib =
Array.to_list mip.mind_consnames,
Array.to_list lc))
mib.mind_packets in
- let sechyps' = map_named_context (expmod_constr modlist) sechyps in
+ let sechyps' = Context.Named.map (expmod_constr modlist) sechyps in
let (params',inds') = abstract_inductive sechyps' nparams inds in
let abs_ctx = Univ.instantiate_univ_context abs_ctx in
let univs = Univ.UContext.union abs_ctx univs in
diff --git a/toplevel/discharge.mli b/toplevel/discharge.mli
index 59140157c..18d1b6776 100644
--- a/toplevel/discharge.mli
+++ b/toplevel/discharge.mli
@@ -6,10 +6,9 @@
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
-open Context
open Declarations
open Entries
open Opaqueproof
val process_inductive :
- named_context Univ.in_universe_context -> work_list -> mutual_inductive_body -> mutual_inductive_entry
+ Context.Named.t Univ.in_universe_context -> work_list -> mutual_inductive_body -> mutual_inductive_entry
diff --git a/toplevel/himsg.ml b/toplevel/himsg.ml
index 7ddfd46cd..819c290af 100644
--- a/toplevel/himsg.ml
+++ b/toplevel/himsg.ml
@@ -260,7 +260,7 @@ let explain_generalization env sigma (name,var) j =
str "it has type" ++ spc () ++ pt ++
spc () ++ str "which should be Set, Prop or Type."
-let rec explain_unification_error env sigma p1 p2 = function
+let explain_unification_error env sigma p1 p2 = function
| None -> mt()
| Some e ->
let rec aux p1 p2 = function
@@ -822,7 +822,7 @@ let explain_not_match_error = function
| ModuleTypeFieldExpected ->
strbrk "a module type is expected"
| NotConvertibleInductiveField id | NotConvertibleConstructorField id ->
- str "types given to " ++ str (Id.to_string id) ++ str " differ"
+ str "types given to " ++ pr_id id ++ str " differ"
| NotConvertibleBodyField ->
str "the body of definitions differs"
| NotConvertibleTypeField (env, typ1, typ2) ->
@@ -847,7 +847,7 @@ let explain_not_match_error = function
| RecordProjectionsExpected nal ->
(if List.length nal >= 2 then str "expected projection names are "
else str "expected projection name is ") ++
- pr_enum (function Name id -> str (Id.to_string id) | _ -> str "_") nal
+ pr_enum (function Name id -> pr_id id | _ -> str "_") nal
| NotEqualInductiveAliases ->
str "Aliases to inductive types do not match"
| NoTypeConstraintExpected ->
@@ -896,11 +896,11 @@ let explain_not_equal_module_paths mp1 mp2 =
str "Non equal modules."
let explain_no_such_label l =
- str "No such label " ++ str (Label.to_string l) ++ str "."
+ str "No such label " ++ pr_label l ++ str "."
let explain_incompatible_labels l l' =
str "Opening and closing labels are not the same: " ++
- str (Label.to_string l) ++ str " <> " ++ str (Label.to_string l') ++ str "!"
+ pr_label l ++ str " <> " ++ pr_label l' ++ str "!"
let explain_not_a_module s =
quote (str s) ++ str " is not a module."
@@ -909,19 +909,19 @@ let explain_not_a_module_type s =
quote (str s) ++ str " is not a module type."
let explain_not_a_constant l =
- quote (Label.print l) ++ str " is not a constant."
+ quote (pr_label l) ++ str " is not a constant."
let explain_incorrect_label_constraint l =
str "Incorrect constraint for label " ++
- quote (Label.print l) ++ str "."
+ quote (pr_label l) ++ str "."
let explain_generative_module_expected l =
- str "The module " ++ str (Label.to_string l) ++ str " is not generative." ++
+ str "The module " ++ pr_label l ++ str " is not generative." ++
strbrk " Only components of generative modules can be changed" ++
strbrk " using the \"with\" construct."
let explain_label_missing l s =
- str "The field " ++ str (Label.to_string l) ++ str " is missing in "
+ str "The field " ++ pr_label l ++ str " is missing in "
++ str s ++ str "."
let explain_include_restricted_functor mp =
diff --git a/toplevel/metasyntax.ml b/toplevel/metasyntax.ml
index ae82b64e8..6534c39a7 100644
--- a/toplevel/metasyntax.ml
+++ b/toplevel/metasyntax.ml
@@ -47,20 +47,14 @@ let add_token_obj s = Lib.add_anonymous_leaf (inToken s)
let interp_prod_item lev = function
| TacTerm s -> GramTerminal s
- | TacNonTerm (loc, nt, po) ->
- let sep = match po with Some (_,sep) -> sep | _ -> "" in
- let (etyp, e) = interp_entry_name true (Some lev) nt sep in
- GramNonTerminal (loc, etyp, e, Option.map fst po)
+ | TacNonTerm (loc, nt, (_, sep)) ->
+ let EntryName (etyp, e) = interp_entry_name (TgTactic lev) nt sep in
+ GramNonTerminal (loc, etyp, e)
let make_terminal_status = function
| GramTerminal s -> Some s
| GramNonTerminal _ -> None
-let rec make_tags = function
- | GramTerminal s :: l -> make_tags l
- | GramNonTerminal (loc, etyp, _, po) :: l -> etyp :: make_tags l
- | [] -> []
-
let make_fresh_key =
let id = Summary.ref ~name:"TACTIC-NOTATION-COUNTER" 0 in
fun () ->
@@ -81,7 +75,7 @@ type tactic_grammar_obj = {
tacobj_local : locality_flag;
tacobj_tacgram : tactic_grammar;
tacobj_tacpp : Pptactic.pp_tactic;
- tacobj_body : Tacexpr.glob_tactic_expr
+ tacobj_body : Id.t list * Tacexpr.glob_tactic_expr;
}
let check_key key =
@@ -111,9 +105,10 @@ let load_tactic_notation i (_, tobj) =
Egramcoq.extend_tactic_grammar key tobj.tacobj_tacgram
let subst_tactic_notation (subst, tobj) =
+ let (ids, body) = tobj.tacobj_body in
{ tobj with
tacobj_key = Mod_subst.subst_kn subst tobj.tacobj_key;
- tacobj_body = Tacsubst.subst_tactic subst tobj.tacobj_body;
+ tacobj_body = (ids, Tacsubst.subst_tactic subst body);
}
let classify_tactic_notation tacobj = Substitute tacobj
@@ -126,18 +121,17 @@ let inTacticGrammar : tactic_grammar_obj -> obj =
subst_function = subst_tactic_notation;
classify_function = classify_tactic_notation}
-let cons_production_parameter l = function
- | GramTerminal _ -> l
- | GramNonTerminal (_,_,_,ido) -> Option.List.cons ido l
+let cons_production_parameter = function
+| TacTerm _ -> None
+| TacNonTerm (_, _, (id, _)) -> Some id
let add_tactic_notation (local,n,prods,e) =
+ let ids = List.map_filter cons_production_parameter prods in
let prods = List.map (interp_prod_item n) prods in
- let tags = make_tags prods in
let pprule = {
- Pptactic.pptac_args = tags;
- pptac_prods = (n, List.map make_terminal_status prods);
+ Pptactic.pptac_level = n;
+ pptac_prods = prods;
} in
- let ids = List.fold_left cons_production_parameter [] prods in
let tac = Tacintern.glob_tactic_env ids (Global.env()) e in
let parule = {
tacgram_level = n;
@@ -148,7 +142,7 @@ let add_tactic_notation (local,n,prods,e) =
tacobj_local = local;
tacobj_tacgram = parule;
tacobj_tacpp = pprule;
- tacobj_body = tac;
+ tacobj_body = (ids, tac);
} in
Lib.add_anonymous_leaf (inTacticGrammar tacobj)
@@ -160,20 +154,23 @@ type atomic_entry = string * Genarg.glob_generic_argument list option
type ml_tactic_grammar_obj = {
mltacobj_name : Tacexpr.ml_tactic_name;
(** ML-side unique name *)
- mltacobj_prod : grammar_prod_item list list;
+ mltacobj_prod : Tacexpr.raw_tactic_expr grammar_prod_item list list;
(** Grammar rules generating the ML tactic. *)
}
(** ML tactic notations whose use can be restricted to an identifier are added
as true Ltac entries. *)
let extend_atomic_tactic name entries =
- let add_atomic (id, args) = match args with
+ let add_atomic i (id, args) = match args with
| None -> ()
| Some args ->
- let body = Tacexpr.TacML (Loc.ghost, name, args) in
+ let open Tacexpr in
+ let args = List.map (fun a -> TacGeneric a) args in
+ let entry = { mltac_name = name; mltac_index = i } in
+ let body = TacML (Loc.ghost, entry, args) in
Tacenv.register_ltac false false (Names.Id.of_string id) body
in
- List.iter add_atomic entries
+ List.iteri add_atomic entries
let cache_ml_tactic_notation (_, obj) =
extend_ml_tactic_grammar obj.mltacobj_name obj.mltacobj_prod
diff --git a/toplevel/metasyntax.mli b/toplevel/metasyntax.mli
index ffebd07d8..826886f67 100644
--- a/toplevel/metasyntax.mli
+++ b/toplevel/metasyntax.mli
@@ -24,7 +24,7 @@ val add_tactic_notation :
type atomic_entry = string * Genarg.glob_generic_argument list option
val add_ml_tactic_notation : ml_tactic_name ->
- Egramml.grammar_prod_item list list -> atomic_entry list -> unit
+ Tacexpr.raw_tactic_expr Egramml.grammar_prod_item list list -> atomic_entry list -> unit
(** Adding a (constr) notation in the environment*)
diff --git a/toplevel/mltop.ml b/toplevel/mltop.ml
index 0b6d93d60..d0fa7a80c 100644
--- a/toplevel/mltop.ml
+++ b/toplevel/mltop.ml
@@ -155,7 +155,7 @@ let add_ml_dir s =
| WithoutTop when has_dynlink -> keep_copy_mlpath s
| _ -> ()
-(* For Rec Add ML Path *)
+(* For Rec Add ML Path (-R) *)
let add_rec_ml_dir unix_path =
List.iter (fun (lp,_) -> add_ml_dir lp) (all_subdirs ~unix_path)
diff --git a/toplevel/obligations.ml b/toplevel/obligations.ml
index 314789ced..fd91cfb5c 100644
--- a/toplevel/obligations.ml
+++ b/toplevel/obligations.ml
@@ -13,7 +13,6 @@ open Declare
*)
open Term
-open Context
open Vars
open Names
open Evd
@@ -44,7 +43,7 @@ let check_evars env evm =
type oblinfo =
{ ev_name: int * Id.t;
- ev_hyps: named_context;
+ ev_hyps: Context.Named.t;
ev_status: Evar_kinds.obligation_definition_status;
ev_chop: int option;
ev_src: Evar_kinds.t Loc.located;
@@ -52,9 +51,6 @@ type oblinfo =
ev_tac: unit Proofview.tactic option;
ev_deps: Int.Set.t }
-(* spiwack: Store field for internalizing ev_tac in evar_infos' evar_extra. *)
-let evar_tactic = Store.field ()
-
(** Substitute evar references in t using De Bruijn indices,
where n binders were passed through. *)
@@ -194,7 +190,7 @@ open Environ
let eterm_obligations env name evm fs ?status t ty =
(* 'Serialize' the evars *)
let nc = Environ.named_context env in
- let nc_len = Context.named_context_length nc in
+ let nc_len = Context.Named.length nc in
let evm = Evarutil.nf_evar_map_undefined evm in
let evl = Evarutil.non_instantiated evm in
let evl = Evar.Map.bindings evl in
@@ -229,17 +225,9 @@ let eterm_obligations env name evm fs ?status t ty =
| Some s -> s, None
| None -> Evar_kinds.Define true, None
in
- let tac = match Store.get ev.evar_extra evar_tactic with
- | Some t ->
- if Dyn.has_tag t "tactic" then
- Some (Tacinterp.interp
- (Tacinterp.globTacticIn (Tacinterp.tactic_out t)))
- else None
- | None -> None
- in
let info = { ev_name = (n, nstr);
ev_hyps = hyps; ev_status = status; ev_chop = chop;
- ev_src = loc, k; ev_typ = evtyp ; ev_deps = deps; ev_tac = tac }
+ ev_src = loc, k; ev_typ = evtyp ; ev_deps = deps; ev_tac = None }
in (id, info) :: l)
evn []
in
@@ -277,7 +265,7 @@ let reduce c =
exception NoObligations of Id.t option
let explain_no_obligations = function
- Some ident -> str "No obligations for program " ++ str (Id.to_string ident)
+ Some ident -> str "No obligations for program " ++ Id.print ident
| None -> str "No obligations remaining"
type obligation_info =
@@ -539,7 +527,7 @@ let compute_possible_guardness_evidences (n,_) fixbody fixtype =
but doing it properly involves delta-reduction, and it finally
doesn't seem to worth the effort (except for huge mutual
fixpoints ?) *)
- let m = nb_prod fixtype in
+ let m = Termops.nb_prod fixtype in
let ctx = fst (decompose_prod_n_assum m fixtype) in
List.map_i (fun i _ -> i) 0 ctx
@@ -595,14 +583,16 @@ let declare_mutual_definition l =
List.iter progmap_remove l; kn
let shrink_body c =
- let ctx, b = decompose_lam c in
+ let ctx, b = decompose_lam_assum c in
let b', n, args =
- List.fold_left (fun (b, i, args) (n,t) ->
+ List.fold_left (fun (b, i, args) (n, u, t) ->
if noccurn 1 b then
subst1 mkProp b, succ i, args
- else mkLambda (n,t,b), succ i, mkRel i :: args)
+ else
+ let args = if Option.is_empty u then mkRel i :: args else args in
+ mkLambda_or_LetIn (n, u, t) b, succ i, args)
(b, 1, []) ctx
- in List.map (fun (c,t) -> (c,None,t)) ctx, b', Array.of_list args
+ in ctx, b', Array.of_list args
let unfold_entry cst = Hints.HintsUnfoldEntry [EvalConstRef cst]
@@ -807,6 +797,36 @@ let solve_by_tac name evi t poly ctx =
Inductiveops.control_only_guard (Global.env ()) (fst body);
(fst body), entry.const_entry_type, Evd.evar_universe_context ctx'
+let obligation_terminator name num guard hook pf =
+ let open Proof_global in
+ let term = Lemmas.universe_proof_terminator guard hook in
+ match pf with
+ | Admitted _ -> apply_terminator term pf
+ | Proved (opq, id, proof) ->
+ if not !shrink_obligations then apply_terminator term pf
+ else
+ let (_, (entry, uctx, _)) = Pfedit.cook_this_proof proof in
+ let env = Global.env () in
+ let entry = Safe_typing.inline_private_constants_in_definition_entry env entry in
+ let ty = entry.Entries.const_entry_type in
+ let (body, cstr), eff = Future.force entry.Entries.const_entry_body in
+ assert(Safe_typing.empty_private_constants = eff);
+ assert(Univ.ContextSet.is_empty cstr);
+ Inductiveops.control_only_guard (Global.env ()) body;
+ (** Declare the obligation ourselves and drop the hook *)
+ let prg = get_info (ProgMap.find name !from_prg) in
+ let prg = { prg with prg_ctx = fst uctx } in
+ let obls, rem = prg.prg_obligations in
+ let obl = obls.(num) in
+ let ctx = Evd.evar_context_universe_context (fst uctx) in
+ let (_, obl) = declare_obligation prg obl body ty ctx in
+ let obls = Array.copy obls in
+ let _ = obls.(num) <- obl in
+ try ignore (update_obls prg obls (pred rem))
+ with e when Errors.noncritical e ->
+ let e = Errors.push e in
+ pperror (Errors.iprint (Cerrors.process_vernac_interp_error e))
+
let obligation_hook prg obl num auto ctx' _ gr =
let obls, rem = prg.prg_obligations in
let cst = match gr with ConstRef cst -> cst | _ -> assert false in
@@ -859,8 +879,9 @@ let rec solve_obligation prg num tac =
let evd = Evd.from_ctx prg.prg_ctx in
let evd = Evd.update_sigma_env evd (Global.env ()) in
let auto n tac oblset = auto_solve_obligations n ~oblset tac in
+ let terminator guard hook = Proof_global.make_terminator (obligation_terminator prg.prg_name num guard hook) in
let hook ctx = Lemmas.mk_hook (obligation_hook prg obl num auto ctx) in
- let () = Lemmas.start_proof_univs ~sign:prg.prg_sign obl.obl_name kind evd obl.obl_type hook in
+ let () = Lemmas.start_proof_univs ~sign:prg.prg_sign obl.obl_name kind evd obl.obl_type ~terminator hook in
let () = trace (str "Started obligation " ++ int user_num ++ str " proof: " ++
Printer.pr_constr_env (Global.env ()) Evd.empty obl.obl_type) in
let _ = Pfedit.by (snd (get_default_tactic ())) in
@@ -974,7 +995,7 @@ let show_obligations_of_prg ?(msg=true) prg =
if !showed > 0 then (
decr showed;
msg_info (str "Obligation" ++ spc() ++ int (succ i) ++ spc () ++
- str "of" ++ spc() ++ str (Id.to_string n) ++ str ":" ++ spc () ++
+ str "of" ++ spc() ++ Id.print n ++ str ":" ++ spc () ++
hov 1 (Printer.pr_constr_env (Global.env ()) Evd.empty x.obl_type ++
str "." ++ fnl ())))
| Some _ -> ())
@@ -991,14 +1012,14 @@ let show_obligations ?(msg=true) n =
let show_term n =
let prg = get_prog_err n in
let n = prg.prg_name in
- (str (Id.to_string n) ++ spc () ++ str":" ++ spc () ++
+ (Id.print n ++ spc () ++ str":" ++ spc () ++
Printer.pr_constr_env (Global.env ()) Evd.empty prg.prg_type ++ spc () ++ str ":=" ++ fnl ()
++ Printer.pr_constr_env (Global.env ()) Evd.empty prg.prg_body)
let add_definition n ?term t ctx ?(implicits=[]) ?(kind=Global,false,Definition) ?tactic
?(reduce=reduce) ?(hook=Lemmas.mk_hook (fun _ _ _ -> ())) ?(opaque = false) obls =
let sign = Decls.initialize_named_context_for_proof () in
- let info = str (Id.to_string n) ++ str " has type-checked" in
+ let info = Id.print n ++ str " has type-checked" in
let prg = init_prog_info sign ~opaque n term t ctx [] None [] obls implicits kind reduce hook in
let obls,_ = prg.prg_obligations in
if Int.equal (Array.length obls) 0 then (
diff --git a/toplevel/record.ml b/toplevel/record.ml
index 04da628c3..7ae203034 100644
--- a/toplevel/record.ml
+++ b/toplevel/record.ml
@@ -13,7 +13,6 @@ open Names
open Globnames
open Nameops
open Term
-open Context
open Vars
open Environ
open Declarations
@@ -148,8 +147,8 @@ let typecheck_params_and_fields def id pl t ps nots fs =
else arity, evars
in
let evars, nf = Evarutil.nf_evars_and_universes evars in
- let newps = map_rel_context nf newps in
- let newfs = map_rel_context nf newfs in
+ let newps = Context.Rel.map nf newps in
+ let newfs = Context.Rel.map nf newfs in
let ce t = Evarutil.check_evars env0 Evd.empty evars t in
List.iter (fun (n, b, t) -> Option.iter ce b; ce t) (List.rev newps);
List.iter (fun (n, b, t) -> Option.iter ce b; ce t) (List.rev newfs);
@@ -171,7 +170,7 @@ let warning_or_error coe indsp err =
let st = match err with
| MissingProj (fi,projs) ->
let s,have = if List.length projs > 1 then "s","were" else "","was" in
- (str(Id.to_string fi) ++
+ (pr_id fi ++
strbrk" cannot be defined because the projection" ++ str s ++ spc () ++
prlist_with_sep pr_comma pr_id projs ++ spc () ++ str have ++
strbrk " not defined.")
@@ -244,8 +243,8 @@ let declare_projections indsp ?(kind=StructureComponent) binder_name coers field
let ctx = Univ.instantiate_univ_context mib.mind_universes in
let indu = indsp, u in
let r = mkIndU (indsp,u) in
- let rp = applist (r, Termops.extended_rel_list 0 paramdecls) in
- let paramargs = Termops.extended_rel_list 1 paramdecls in (*def in [[params;x:rp]]*)
+ let rp = applist (r, Context.Rel.to_extended_list 0 paramdecls) in
+ let paramargs = Context.Rel.to_extended_list 1 paramdecls in (*def in [[params;x:rp]]*)
let x = Name binder_name in
let fields = instantiate_possibly_recursive_type indu paramdecls fields in
let lifted_fields = Termops.lift_rel_context 1 fields in
@@ -353,7 +352,7 @@ open Typeclasses
let declare_structure finite poly ctx id idbuild paramimpls params arity template
fieldimpls fields ?(kind=StructureComponent) ?name is_coe coers sign =
let nparams = List.length params and nfields = List.length fields in
- let args = Termops.extended_rel_list nfields params in
+ let args = Context.Rel.to_extended_list nfields params in
let ind = applist (mkRel (1+nparams+nfields), args) in
let type_constructor = it_mkProd_or_LetIn ind fields in
let binder_name =
diff --git a/toplevel/record.mli b/toplevel/record.mli
index 4ce27755a..26eb3378b 100644
--- a/toplevel/record.mli
+++ b/toplevel/record.mli
@@ -8,7 +8,6 @@
open Names
open Term
-open Context
open Vernacexpr
open Constrexpr
open Impargs
@@ -22,15 +21,15 @@ val primitive_flag : bool ref
val declare_projections :
inductive -> ?kind:Decl_kinds.definition_object_kind -> Id.t ->
- coercion_flag list -> manual_explicitation list list -> rel_context ->
+ coercion_flag list -> manual_explicitation list list -> Context.Rel.t ->
(Name.t * bool) list * constant option list
val declare_structure : Decl_kinds.recursivity_kind ->
bool (** polymorphic?*) -> Univ.universe_context ->
Id.t -> Id.t ->
- manual_explicitation list -> rel_context -> (** params *) constr -> (** arity *)
+ manual_explicitation list -> Context.Rel.t -> (** params *) constr -> (** arity *)
bool (** template arity ? *) ->
- Impargs.manual_explicitation list list -> rel_context -> (** fields *)
+ Impargs.manual_explicitation list list -> Context.Rel.t -> (** fields *)
?kind:Decl_kinds.definition_object_kind -> ?name:Id.t ->
bool -> (** coercion? *)
bool list -> (** field coercions *)
diff --git a/toplevel/search.ml b/toplevel/search.ml
index d7a4cbe78..89e0eb88a 100644
--- a/toplevel/search.ml
+++ b/toplevel/search.ml
@@ -18,10 +18,28 @@ open Printer
open Libnames
open Globnames
open Nametab
+open Goptions
type filter_function = global_reference -> env -> constr -> bool
type display_function = global_reference -> env -> constr -> unit
+(* This option restricts the output of [SearchPattern ...],
+[SearchAbout ...], etc. to the names of the symbols matching the
+query, separated by a newline. This type of output is useful for
+editors (like emacs), to generate a list of completion candidates
+without having to parse thorugh the types of all symbols. *)
+
+let search_output_name_only = ref false
+
+let _ =
+ declare_bool_option
+ { optsync = true;
+ optdepr = false;
+ optname = "output-name-only search";
+ optkey = ["Search";"Output";"Name";"Only"];
+ optread = (fun () -> !search_output_name_only);
+ optwrite = (:=) search_output_name_only }
+
type glob_search_about_item =
| GlobSearchSubPattern of constr_pattern
| GlobSearchString of string
@@ -98,11 +116,14 @@ let generic_search glnumopt fn =
iter_declarations fn
(** Standard display *)
-
let plain_display accu ref env c =
- let pc = pr_lconstr_env env Evd.empty c in
let pr = pr_global ref in
- accu := hov 2 (pr ++ str":" ++ spc () ++ pc) :: !accu
+ if !search_output_name_only then
+ accu := pr :: !accu
+ else begin
+ let pc = pr_lconstr_env env Evd.empty c in
+ accu := hov 2 (pr ++ str":" ++ spc () ++ pc) :: !accu
+ end
let format_display l = prlist_with_sep fnl (fun x -> x) (List.rev l)
diff --git a/toplevel/usage.ml b/toplevel/usage.ml
index 4280006ba..f855c096e 100644
--- a/toplevel/usage.ml
+++ b/toplevel/usage.ml
@@ -117,12 +117,7 @@ let print_config () =
if Coq_config.local then Printf.printf "LOCAL=1\n" else Printf.printf "LOCAL=0\n";
Printf.printf "COQLIB=%s/\n" (Envars.coqlib ());
Printf.printf "DOCDIR=%s/\n" (Envars.docdir ());
- Printf.printf "OCAMLDEP=%s\n" Coq_config.ocamldep;
- Printf.printf "OCAMLC=%s\n" Coq_config.ocamlc;
- Printf.printf "OCAMLOPT=%s\n" Coq_config.ocamlopt;
- Printf.printf "OCAMLDOC=%s\n" Coq_config.ocamldoc;
- Printf.printf "CAMLBIN=%s/\n" (Envars.camlbin ());
- Printf.printf "CAMLLIB=%s/\n" (Envars.camllib ());
+ Printf.printf "OCAMLFIND=%s\n" (Envars.ocamlfind ());
Printf.printf "CAMLP4=%s\n" Coq_config.camlp4;
Printf.printf "CAMLP4O=%s\n" Coq_config.camlp4o;
Printf.printf "CAMLP4BIN=%s/\n" (Envars.camlp4bin ());
diff --git a/toplevel/vernac.ml b/toplevel/vernac.ml
index 7c4920dfb..89bc31d0a 100644
--- a/toplevel/vernac.ml
+++ b/toplevel/vernac.ml
@@ -27,9 +27,9 @@ let rec is_navigation_vernac = function
| VernacBacktrack _
| VernacBackTo _
| VernacBack _ -> true
- | VernacRedirect (_, l) | VernacTime l ->
- List.exists
- (fun (_,c) -> is_navigation_vernac c) l (* Time Back* is harmless *)
+ | VernacRedirect (_, (_,c))
+ | VernacTime (_,c) ->
+ is_navigation_vernac c (* Time Back* is harmless *)
| c -> is_deep_navigation_vernac c
and is_deep_navigation_vernac = function
@@ -150,7 +150,6 @@ let pr_new_syntax loc ocom =
if !beautify_file then set_formatter_translator();
let fs = States.freeze ~marshallable:`No in
let com = match ocom with
- | Some VernacNop -> mt()
| Some com -> Ppvernac.pr_vernac com
| None -> mt() in
if !beautify_file then
@@ -229,7 +228,7 @@ let rec vernac_com verbose checknav (loc,com) =
checknav loc com;
if do_beautify () then pr_new_syntax loc (Some com);
if !Flags.time then display_cmd_header loc com;
- let com = if !Flags.time then VernacTime [loc,com] else com in
+ let com = if !Flags.time then VernacTime (loc,com) else com in
interp com
with reraise ->
let (reraise, info) = Errors.push reraise in
diff --git a/toplevel/vernacentries.ml b/toplevel/vernacentries.ml
index 72dd967b9..0f81943e2 100644
--- a/toplevel/vernacentries.ml
+++ b/toplevel/vernacentries.ml
@@ -156,7 +156,7 @@ let show_match id =
(* "Print" commands *)
let print_path_entry p =
- let dir = str (DirPath.to_string (Loadpath.logical p)) in
+ let dir = pr_dirpath (Loadpath.logical p) in
let path = str (Loadpath.physical p) in
(dir ++ str " " ++ tbrk (0, 0) ++ path)
@@ -347,7 +347,7 @@ let dump_universes_gen g s =
end
in
try
- Univ.dump_universes output_constraint g;
+ UGraph.dump_universes output_constraint g;
close ();
msg_info (str "Universes written to file \"" ++ str s ++ str "\".")
with reraise ->
@@ -942,40 +942,37 @@ type tacdef_kind =
let is_defined_tac kn =
try ignore (Tacenv.interp_ltac kn); true with Not_found -> false
-let make_absolute_name ident repl =
- let loc = loc_of_reference ident in
- if repl then
- let kn =
- try Nametab.locate_tactic (snd (qualid_of_reference ident))
- with Not_found ->
- Errors.user_err_loc (loc, "",
- str "There is no Ltac named " ++ pr_reference ident ++ str ".")
- in
- UpdateTac kn
- else
- let id = Constrexpr_ops.coerce_reference_to_id ident in
- let kn = Lib.make_kn id in
- let () = if is_defined_tac kn then
- Errors.user_err_loc (loc, "",
- str "There is already an Ltac named " ++ pr_reference ident ++ str".")
- in
- let is_primitive =
- try
- match Pcoq.parse_string Pcoq.Tactic.tactic (Id.to_string id) with
- | Tacexpr.TacArg _ -> false
- | _ -> true (* most probably TacAtom, i.e. a primitive tactic ident *)
- with e when Errors.noncritical e -> true (* prim tactics with args, e.g. "apply" *)
- in
- let () = if is_primitive then
- msg_warning (str "The Ltac name " ++ pr_reference ident ++
- str " may be unusable because of a conflict with a notation.")
- in
- NewTac id
-
-let register_ltac local isrec tacl =
- let map (ident, repl, body) =
- let name = make_absolute_name ident repl in
- (name, body)
+let register_ltac local tacl =
+ let map tactic_body =
+ match tactic_body with
+ | TacticDefinition ((loc,id), body) ->
+ let kn = Lib.make_kn id in
+ let id_pp = pr_id id in
+ let () = if is_defined_tac kn then
+ Errors.user_err_loc (loc, "",
+ str "There is already an Ltac named " ++ id_pp ++ str".")
+ in
+ let is_primitive =
+ try
+ match Pcoq.parse_string Pcoq.Tactic.tactic (Id.to_string id) with
+ | Tacexpr.TacArg _ -> false
+ | _ -> true (* most probably TacAtom, i.e. a primitive tactic ident *)
+ with e when Errors.noncritical e -> true (* prim tactics with args, e.g. "apply" *)
+ in
+ let () = if is_primitive then
+ msg_warning (str "The Ltac name " ++ id_pp ++
+ str " may be unusable because of a conflict with a notation.")
+ in
+ NewTac id, body
+ | TacticRedefinition (ident, body) ->
+ let loc = loc_of_reference ident in
+ let kn =
+ try Nametab.locate_tactic (snd (qualid_of_reference ident))
+ with Not_found ->
+ Errors.user_err_loc (loc, "",
+ str "There is no Ltac named " ++ pr_reference ident ++ str ".")
+ in
+ UpdateTac kn, body
in
let rfun = List.map map tacl in
let recvars =
@@ -983,8 +980,7 @@ let register_ltac local isrec tacl =
| UpdateTac _ -> accu
| NewTac id -> (Lib.make_path id, Lib.make_kn id) :: accu
in
- if isrec then List.fold_left fold [] rfun
- else []
+ List.fold_left fold [] rfun
in
let ist = Tacintern.make_empty_glob_sign () in
let map (name, body) =
@@ -1010,9 +1006,9 @@ let register_ltac local isrec tacl =
in
List.iter iter defs
-let vernac_declare_tactic_definition locality (x,def) =
+let vernac_declare_tactic_definition locality def =
let local = make_module_locality locality in
- register_ltac local x def
+ register_ltac local def
let vernac_create_hintdb locality id b =
let local = make_module_locality locality in
@@ -1554,7 +1550,7 @@ let vernac_global_check c =
let sigma = Evd.from_env env in
let c,ctx = interp_constr env sigma c in
let senv = Global.safe_env() in
- let cstrs = snd (Evd.evar_universe_context_set Univ.UContext.empty ctx) in
+ let cstrs = snd (UState.context_set ctx) in
let senv = Safe_typing.add_constraints cstrs senv in
let j = Safe_typing.typing senv c in
let env = Safe_typing.env_of_safe_env senv in
@@ -1584,11 +1580,11 @@ let print_about_hyp_globs ref_or_by_not glnumopt =
(str "No such goal: " ++ int n ++ str "."))
| _ , _ -> raise NoHyp in
let hyps = pf_hyps gl in
- let (id,bdyopt,typ) = Context.lookup_named id hyps in
+ let (id,bdyopt,typ) = Context.Named.lookup id hyps in
let natureofid = match bdyopt with
| None -> "Hypothesis"
| Some bdy ->"Constant (let in)" in
- v 0 (str (Id.to_string id) ++ str":" ++ pr_constr typ ++ fnl() ++ fnl()
+ v 0 (pr_id id ++ str":" ++ pr_constr typ ++ fnl() ++ fnl()
++ str natureofid ++ str " of the goal context.")
with (* fallback to globals *)
| NoHyp | Not_found -> print_about ref_or_by_not
@@ -1620,13 +1616,13 @@ let vernac_print = function
| PrintCanonicalConversions -> msg_notice (Prettyp.print_canonical_projections ())
| PrintUniverses (b, dst) ->
let univ = Global.universes () in
- let univ = if b then Univ.sort_universes univ else univ in
+ let univ = if b then UGraph.sort_universes univ else univ in
let pr_remaining =
if Global.is_joined_environment () then mt ()
else str"There may remain asynchronous universe constraints"
in
begin match dst with
- | None -> msg_notice (Univ.pr_universes Universes.pr_with_global_universes univ ++ pr_remaining)
+ | None -> msg_notice (UGraph.pr_universes Universes.pr_with_global_universes univ ++ pr_remaining)
| Some s -> dump_universes_gen univ s
end
| PrintHint r -> msg_notice (Hints.pr_hint_ref (smart_global r))
@@ -1964,7 +1960,6 @@ let interp ?proof ~loc locality poly c =
| VernacLocate l -> vernac_locate l
| VernacRegister (id, r) -> vernac_register id r
| VernacComments l -> if_verbose msg_info (str "Comments ok\n")
- | VernacNop -> ()
(* The STM should handle that, but LOAD bypasses the STM... *)
| VernacAbort id -> msg_warning (str "VernacAbort not handled by Stm")
@@ -2132,11 +2127,11 @@ let interp ?(verbosely=true) ?proof (loc,c) =
| VernacTimeout (n,v) ->
current_timeout := Some n;
aux ?locality ?polymorphism isprogcmd v
- | VernacRedirect (s, v) ->
- Pp.with_output_to_file s (aux_list ?locality ?polymorphism isprogcmd) v;
- | VernacTime v ->
+ | VernacRedirect (s, (_,v)) ->
+ Pp.with_output_to_file s (aux false) v
+ | VernacTime (_,v) ->
System.with_time !Flags.time
- (aux_list ?locality ?polymorphism isprogcmd) v;
+ (aux ?locality ?polymorphism isprogcmd) v;
| VernacLoad (_,fname) -> vernac_load (aux false) fname
| c ->
check_vernac_supports_locality c locality;
@@ -2164,8 +2159,6 @@ let interp ?(verbosely=true) ?proof (loc,c) =
Flags.program_mode := orig_program_mode;
ignore (Flags.use_polymorphic_flag ());
iraise e
- and aux_list ?locality ?polymorphism isprogcmd l =
- List.iter (aux false) (List.map snd l)
in
if verbosely then Flags.verbosely (aux false) c
else aux false c