Codebase list coq / bf12eb9
Imported Upstream version 8.4pl1dfsg Stephane Glondu 11 years ago
76 changed file(s) with 1540 addition(s) and 1654 deletion(s). Raw diff Collapse all Expand all
+0
-8
.dir-locals.el less more
0 ((nil . ((eval . (setq default-directory (locate-dominating-file
1 buffer-file-name
2 ".dir-locals.el")
3 tags-file-name (concat default-directory
4 "TAGS")
5 camldebug-command-name (concat
6 default-directory "dev/ocamldebug-coq")
7 )))))
+0
-185
.gitignore less more
0 *.glob
1 *.d
2 *.d.raw
3 *.vo
4 *.cm*
5 *.annot
6 *.spit
7 *.spot
8 *.o
9 *.a
10 *.log
11 *.aux
12 *.dvi
13 *.blg
14 *.bbl
15 *.idx
16 *.ilg
17 *.toc
18 *.atoc
19 *.comidx
20 *.comind
21 *.erridx
22 *.errind
23 *.haux
24 *.hcomind
25 *.herrind
26 *.hind
27 *.htacind
28 *.htoc
29 *.ind
30 *.lof
31 *.tacidx
32 *.tacind
33 *.v.tex
34 *.v.pdf
35 *.v.ps
36 *.v.html
37 *.stamp
38 revision
39 TAGS
40 .DS_Store
41 .pc
42 bin/
43 _build
44 plugins/*/*_mod.ml
45 myocamlbuild_config.ml
46 config/Makefile
47 config/coq_config.ml
48 dev/ocamldebug-coq
49 plugins/micromega/csdpcert
50 kernel/byterun/dllcoqrun.so
51 states/initial.coq
52 coqdoc.sty
53 test-suite/lia.cache
54 test-suite/trace
55 test-suite/misc/universes/all_stdlib.v
56 test-suite/misc/universes/universes.txt
57
58 # documentation
59
60 doc/faq/html/
61 doc/refman/csdp.cache
62 doc/refman/trace
63 doc/refman/Reference-Manual.pdf
64 doc/refman/Reference-Manual.ps
65 doc/refman/Reference-Manual.html
66 doc/refman/Reference-Manual.out
67 doc/refman/Reference-Manual.sh
68 doc/refman/cover.html
69 doc/refman/styles.hva
70 doc/common/version.tex
71 doc/refman/coqide-queries.eps
72 doc/refman/coqide.eps
73 doc/refman/euclid.ml
74 doc/refman/euclid.mli
75 doc/refman/heapsort.ml
76 doc/refman/heapsort.mli
77 doc/refman/html/
78 doc/stdlib/Library.out
79 doc/stdlib/Library.pdf
80 doc/stdlib/Library.ps
81 doc/stdlib/Library.coqdoc.tex
82 doc/stdlib/FullLibrary.pdf
83 doc/stdlib/FullLibrary.ps
84 doc/stdlib/FullLibrary.coqdoc.tex
85 doc/stdlib/html/
86 doc/stdlib/index-body.html
87 doc/stdlib/index-list.html
88 doc/RecTutorial/RecTutorial.html
89 doc/RecTutorial/RecTutorial.pdf
90 doc/RecTutorial/RecTutorial.ps
91 dev/doc/naming-conventions.pdf
92
93 # .mll files
94
95 dev/ocamlweb-doc/lex.ml
96 ide/coq_lex.ml
97 ide/config_lexer.ml
98 ide/utf8_convert.ml
99 ide/highlight.ml
100 plugins/dp/dp_zenon.ml
101 tools/gallina_lexer.ml
102 tools/coqwc.ml
103 tools/coqdep_lexer.ml
104 tools/coqdoc/cpretty.ml
105 lib/xml_lexer.ml
106
107 # .mly files
108
109 ide/config_parser.ml
110 ide/config_parser.mli
111
112 # .ml4 files
113
114 ide/project_file.ml
115 lib/pp.ml
116 lib/compat.ml
117 parsing/g_xml.ml
118 parsing/g_prim.ml
119 parsing/q_util.ml
120 parsing/tacextend.ml
121 parsing/q_constr.ml
122 parsing/g_vernac.ml
123 parsing/pcoq.ml
124 parsing/g_constr.ml
125 parsing/g_ltac.ml
126 parsing/vernacextend.ml
127 parsing/g_tactic.ml
128 parsing/argextend.ml
129 parsing/g_decl_mode.ml
130 parsing/q_coqast.ml
131 parsing/g_proofs.ml
132 parsing/lexer.ml
133 plugins/xml/proofTree2Xml.ml
134 plugins/xml/acic2Xml.ml
135 plugins/xml/xml.ml
136 plugins/xml/dumptree.ml
137 plugins/xml/xmlentries.ml
138 plugins/extraction/g_extraction.ml
139 plugins/rtauto/g_rtauto.ml
140 plugins/romega/g_romega.ml
141 plugins/setoid_ring/newring.ml
142 plugins/firstorder/g_ground.ml
143 plugins/dp/g_dp.ml
144 plugins/cc/g_congruence.ml
145 plugins/ring/g_ring.ml
146 plugins/field/field.ml
147 plugins/funind/g_indfun.ml
148 plugins/omega/g_omega.ml
149 plugins/quote/g_quote.ml
150 plugins/nsatz/nsatz.ml
151 plugins/micromega/g_micromega.ml
152 plugins/subtac/g_subtac.ml
153 plugins/fourier/g_fourier.ml
154 plugins/decl_mode/g_decl_mode.ml
155 tactics/tauto.ml
156 tactics/eauto.ml
157 tactics/hipattern.ml
158 tactics/class_tactics.ml
159 tactics/rewrite.ml
160 tactics/eqdecide.ml
161 tactics/extratactics.ml
162 tactics/extraargs.ml
163 tools/coq_tex.ml
164 toplevel/mltop.ml
165 toplevel/whelp.ml
166 ide/coqide_main.ml
167 ide/coqide_main_opt.ml
168
169 # other auto-generated files
170
171 ide/undo.mli
172 toplevel/mltop.optml
173 toplevel/mltop.byteml
174 kernel/byterun/coq_jumptbl.h
175 kernel/copcodes.ml
176 scripts/tolink.ml
177 theories/Numbers/Natural/BigN/NMake_gen.v
178 ide/index_urls.txt
179
180 # mlis documentation
181
182 dev/ocamldoc/html/
183 dev/ocamldoc/coq.*
184 dev/ocamldoc/ocamldoc.sty
0 Changes from V8.4 to V8.4pl1
1 ============================
2
3 Bug fixes
4
5 - Solved bugs :
6 #2851 #2863 #2865 #2893 #2895 #2892 #2905 #2906 #2907 #2917 #2921
7 #2930 #2941 #2878
8 - Partially fixed bug : #2904
9 - Various fixes concerning coq_makefile
10
11 Optimizations
12
13 - "Union by rank" optimization for universes contributed by J.H. Jourdan
14 and G. Sherrer (see union-find-and-coq-universes on gagallium blog).
15
16 Libraries
17
18 - Internal organisation of some modular libraries have slightly changed
19 due to bug #2904 (GenericMinMax, OrdersTac)
20 - No more constant "int" in ZArith/Int.v to avoid name clash with OCaml
21 (cf bug #2878).
22
23 Coqide
24
25 - Improved shutdown of coqtop processes spawned by coqide
26 (in particular added a missing close_on_exec primitive before forking).
27 - On windows, launching coqide with the -debug option now produces
28 a log file in the user's temporary directory. The location of this
29 log file is displayed in the "About" message.
30
31
032 Changes from V8.4beta2 to V8.4
133 ==============================
234
153153 -opt
154154 Use the ocamlc.opt compiler instead of ocamlc (and ocamlopt.opt
155155 compiler instead of ocamlopt). Makes compilation faster (recommended).
156
157 -nowarnings
158 Disable the Objective Caml compiler warnings. This option has no
159 effect on the result of the compilation.
160156
161157 -browser <command>
162158 Use <command> to open an URL in a browser. %s must appear in <command>,
8383
8484 LOCALINCLUDES=$(addprefix -I , $(SRCDIRS) )
8585 MLINCLUDES=$(LOCALINCLUDES) -I $(MYCAMLP4LIB)
86 COREMLINCLUDES=$(addprefix -I , $(CORESRCDIRS)) -I $(MYCAMLP4LIB)
8786
8887 OCAMLC += $(CAMLFLAGS)
8988 OCAMLOPT += $(CAMLFLAGS)
9089
91 BYTEFLAGS=$(MLINCLUDES) $(CAMLDEBUG) $(USERFLAGS)
92 OPTFLAGS=$(MLINCLUDES) $(CAMLDEBUGOPT) $(CAMLTIMEPROF) $(USERFLAGS)
93 COREBYTEFLAGS=$(COREMLINCLUDES) $(CAMLDEBUG) $(USERFLAGS)
94 COREOPTFLAGS=$(COREMLINCLUDES) $(CAMLDEBUGOPT) $(CAMLTIMEPROF) $(USERFLAGS)
90 BAREBYTEFLAGS=$(CAMLDEBUG) $(USERFLAGS)
91 BAREOPTFLAGS=$(CAMLDEBUGOPT) $(CAMLTIMEPROF) $(USERFLAGS)
92 BYTEFLAGS=$(MLINCLUDES) $(BAREBYTEFLAGS)
93 OPTFLAGS=$(MLINCLUDES) $(BAREOPTFLAGS)
9594 DEPFLAGS= -slash $(LOCALINCLUDES)
9695
9796 define bestocaml
193192 # Main targets (coqmktop, coqtop.opt, coqtop.byte)
194193 ###########################################################################
195194
195 ## In Win32, cygwin provides an emulation of ln -s, but this emulation
196 ## won't work outside of cygwin shell (i.e. typically in a Sys.command).
197 ## So we just forget about it, and do a simple copy.
198
199 ifeq ($(ARCH),win32)
200 LN:=cp -f
201 else
202 LN:=ln -sf
203 endif
204
196205 .PHONY: coqbinaries coq coqlib coqlight states
197206
198207 coqbinaries:: ${COQBINARIES} ${CSDPCERT} ${FAKEIDE}
207216
208217 $(COQTOPOPT): $(BESTCOQMKTOP) $(LINKCMX) $(LIBCOQRUN)
209218 $(SHOW)'COQMKTOP -o $@'
210 $(HIDE)$(BESTCOQMKTOP) -boot -opt $(COREOPTFLAGS) -o $@
219 $(HIDE)$(BESTCOQMKTOP) -boot -opt $(BAREOPTFLAGS) -o $@
211220 $(STRIP) $@
212221
213222 $(COQTOPBYTE): $(BESTCOQMKTOP) $(LINKCMO) $(LIBCOQRUN)
214223 $(SHOW)'COQMKTOP -o $@'
215 $(HIDE)$(BESTCOQMKTOP) -boot -top $(COREBYTEFLAGS) -o $@
224 $(HIDE)$(BESTCOQMKTOP) -boot -top $(BAREBYTEFLAGS) -o $@
216225
217226 $(COQTOPEXE): $(ORDER_ONLY_SEP) $(BESTCOQTOP)
218 cd bin; ln -sf coqtop.$(BEST)$(EXE) coqtop$(EXE)
227 cd bin && $(LN) coqtop.$(BEST)$(EXE) coqtop$(EXE)
219228
220229 LOCALCHKLIBS:=$(addprefix -I , $(CHKSRCDIRS) )
221230 CHKLIBS:=$(LOCALCHKLIBS) -I $(MYCAMLP4LIB)
232241 $(HIDE)$(OCAMLC) $(CHKBYTEFLAGS) $(COQTOOLSBYTEFLAGS) -o $@ $(SYSCMA) $^
233242
234243 $(CHICKEN): $(ORDER_ONLY_SEP) $(BESTCHICKEN)
235 cd bin && ln -sf coqchk.$(BEST)$(EXE) coqchk$(EXE)
244 cd bin && $(LN) coqchk.$(BEST)$(EXE) coqchk$(EXE)
236245
237246 # coqmktop
238247
246255 $(STRIP) $@
247256
248257 $(COQMKTOP): $(ORDER_ONLY_SEP) $(BESTCOQMKTOP)
249 cd bin; ln -sf coqmktop.$(BEST)$(EXE) coqmktop$(EXE)
258 cd bin && $(LN) coqmktop.$(BEST)$(EXE) coqmktop$(EXE)
250259
251260 scripts/tolink.ml: Makefile.build Makefile.common
252261 $(SHOW)"ECHO... >" $@
266275 $(STRIP) $@
267276
268277 $(COQC): $(ORDER_ONLY_SEP) $(BESTCOQC)
269 cd bin; ln -sf coqc.$(BEST)$(EXE) coqc$(EXE)
278 cd bin && $(LN) coqc.$(BEST)$(EXE) coqc$(EXE)
270279
271280 # target for libraries
272281
319328
320329 $(COQIDEOPT): $(LINKIDEOPT) | $(COQTOPOPT)
321330 $(SHOW)'OCAMLOPT -o $@'
322 $(HIDE)$(OCAMLOPT) $(COQIDEFLAGS) $(OPTFLAGS) $(IDEOPTFLAGS) -o $@ unix.cmxa threads.cmxa lablgtk.cmxa\
323 gtkThread.cmx str.cmxa $(LINKIDEOPT)
331 $(HIDE)$(OCAMLOPT) $(COQIDEFLAGS) $(OPTFLAGS) -o $@ unix.cmxa threads.cmxa \
332 lablgtk.cmxa $(IDEOPTFLAGS) gtkThread.cmx str.cmxa $(LINKIDEOPT)
324333 $(STRIP) $@
325334
326335 $(COQIDEBYTE): $(LINKIDE) | $(COQTOPBYTE)
329338 str.cma $(COQRUNBYTEFLAGS) $(LINKIDE)
330339
331340 $(COQIDE):
332 cd bin; ln -sf coqide.$(HASCOQIDE)$(EXE) coqide$(EXE)
341 cd bin && $(LN) coqide.$(HASCOQIDE)$(EXE) coqide$(EXE)
333342
334343 # install targets
335344
345354 $(INSTALLBIN) $(COQIDEBYTE) $(FULLBINDIR)
346355 $(INSTALLSH) $(FULLCOQLIB) $(IDECMA) \
347356 $(foreach lib,$(IDECMA:.cma=_MLLIB_DEPENDENCIES),$(addsuffix .cmi,$($(lib))))
348 cd $(FULLBINDIR); ln -sf coqide.byte$(EXE) coqide$(EXE)
357 cd $(FULLBINDIR) && $(LN) coqide.byte$(EXE) coqide$(EXE)
349358
350359 install-ide-opt:
351360 $(MKDIR) $(FULLBINDIR)
352361 $(INSTALLBIN) $(COQIDEOPT) $(FULLBINDIR)
353362 $(INSTALLSH) $(FULLCOQLIB) $(IDECMA) $(IDECMA:.cma=.cmxa) $(IDECMA:.cma=.a) \
354363 $(foreach lib,$(IDECMA:.cma=_MLLIB_DEPENDENCIES),$(addsuffix .cmi,$($(lib))))
355 cd $(FULLBINDIR); ln -sf coqide.opt$(EXE) coqide$(EXE)
364 cd $(FULLBINDIR) && $(LN) coqide.opt$(EXE) coqide$(EXE)
356365
357366 install-ide-files:
358367 $(MKDIR) $(FULLDATADIR)
603612 install-byte::
604613 $(MKDIR) $(FULLBINDIR)
605614 $(INSTALLBIN) $(COQMKTOP) $(COQC) $(COQTOPBYTE) $(CHICKEN) $(FULLBINDIR)
606 cd $(FULLBINDIR); ln -sf coqtop.byte$(EXE) coqtop$(EXE); ln -sf coqchk.byte$(EXE) coqchk$(EXE)
615 cd $(FULLBINDIR); $(LN) coqtop.byte$(EXE) coqtop$(EXE); $(LN) coqchk.byte$(EXE) coqchk$(EXE)
607616
608617 install-opt::
609618 $(MKDIR) $(FULLBINDIR)
610619 $(INSTALLBIN) $(COQMKTOP) $(COQC) $(COQTOPBYTE) $(COQTOPOPT) $(CHICKEN) $(CHICKENOPT) $(FULLBINDIR)
611 cd $(FULLBINDIR); ln -sf coqtop.opt$(EXE) coqtop$(EXE); ln -sf coqchk.opt$(EXE) coqchk$(EXE)
620 cd $(FULLBINDIR); $(LN) coqtop.opt$(EXE) coqtop$(EXE); $(LN) coqchk.opt$(EXE) coqchk$(EXE)
612621
613622 install-tools::
614623 $(MKDIR) $(FULLBINDIR)
632641 $(MKDIR) $(FULLCOQLIB)/states
633642 $(INSTALLLIB) states/*.coq $(FULLCOQLIB)/states
634643 $(MKDIR) $(FULLCOQLIB)/user-contrib
644 ifneq ($(COQRUNBYTEFLAGS),"-custom")
635645 $(INSTALLLIB) $(DLLCOQRUN) $(FULLCOQLIB)
646 endif
636647 $(INSTALLSH) $(FULLCOQLIB) $(CONFIG) $(LINKCMO) $(GRAMMARCMA)
637648 $(INSTALLSH) $(FULLCOQLIB) $(INSTALLCMI)
638649 ifeq ($(BEST),opt)
118118 HEVEAOPTS:=-fix -exec xxdate.exe
119119 HEVEALIB:=/usr/local/lib/hevea:/usr/lib/hevea
120120 HTMLSTYLE:=simple
121 export TEXINPUTS:=$(COQSRC)/doc:$(HEVEALIB):
122 COQTEXOPTS:=-n 72 -image "$(COQSRC)/$(COQTOPEXE) -boot" -sl -small
121 export TEXINPUTS:=$(HEVEALIB):
122 COQTEXOPTS:=-boot -n 72 -sl -small
123123
124124 DOCCOMMON:=doc/common/version.tex doc/common/title.tex doc/common/macros.tex
125125
5252
5353 ifdef QUICK
5454 %.v.tex: %.tex
55 (cd `dirname $<`; $(COQSRC)/$(COQTEX) $(COQTEXOPTS) `basename $<`)
55 $(COQTEX) $(COQTEXOPTS) $<
5656 else
5757 %.v.tex: %.tex $(COQTEX) $(COQTOPEXE) $(PLUGINSVO) $(THEORIESVO)
58 (cd `dirname $<`; $(COQSRC)/$(COQTEX) $(COQTEXOPTS) `basename $<`)
58 $(COQTEX) $(COQTEXOPTS) $<
5959 endif
6060
6161 %.ps: %.dvi
+0
-53
TODO less more
0 Langage:
1
2 Distribution:
3
4 Environnement:
5
6 - Porter SearchIsos
7
8 Noyau:
9
10 Tactic:
11
12 - Que contradiction raisonne a isomorphisme pres de False
13
14 Vernac:
15
16 - Print / Print Proof en fait identiques ; Print ne devrait pas afficher
17 les constantes opaques (devrait afficher qqchose comme <opaque>)
18
19 Theories:
20
21 - Rendre transparent tous les theoremes prouvant {A}+{B}
22 - Faire demarrer PolyList.nth a` l'indice 0
23 Renommer l'actuel nth en nth1 ??
24
25 Doc:
26
27 - Mettre à jour les messages d'erreurs de Discriminate/Simplify_eq/Injection
28 - Documenter le filtrage sur les types inductifs avec let-ins (dont la
29 compatibilite V6)
30
31 - Ajouter let dans les règles du CIC
32 -> FAIT, mais reste a documenter le let dans les inductifs
33 et les champs manifestes dans les Record
34 - revoir le chapitre sur les tactiques utilisateur
35 - faut-il mieux spécifier la sémantique de Simpl (??)
36
37 - Préciser la clarification syntaxique de IntroPattern
38 - preciser que Goal vient en dernier dans une clause pattern list et
39 qu'il doit apparaitre si il y a un "in"
40
41 - Omega Time debranche mais Omega System et Omega Action remarchent ?
42 - Ajout "Replace in" (mais TODO)
43 - Syntaxe Conditional tac Rewrite marche, à documenter
44 - Documenter Dependent Rewrite et CutRewrite ?
45 - Ajouter les motifs sous-termes de ltac
46
47 - ajouter doc de GenFixpoint (mais avant: changer syntaxe) (J. Forest ou Pierre C.)
48 - mettre à jour la doc de induction (arguments multiples) (Pierre C.)
49 - mettre à jour la doc de functional induction/scheme (J. Forest ou Pierre C.)
50 --> mettre à jour le CHANGES (vers la ligne 72)
51
52
1111 [ -L $MYCFG ] || ln -sf $CFG $MYCFG
1212 }
1313
14 ocb() { $OCAMLBUILD $FLAGS $*; }
14 # NB: we exec ocamlbuild and run ocb last for a correct exit code
15
16 ocb() { exec $OCAMLBUILD $FLAGS $*; }
1517
1618 rule() {
1719 check_config
1820 case $1 in
19 clean) ocb -clean && rm -rf bin/* && rm -f $MYCFG;;
21 clean) rm -rf bin/* $MYCFG && ocb -clean;;
2022 all) ocb coq.otarget;;
2123 win32) ocb coq-win32.otarget;;
2224 *) ocb $1;;
55 #
66 ##################################
77
8 VERSION=8.4
8 VERSION=8.4pl1
99 VOMAGIC=08400
1010 STATEMAGIC=58400
1111 DATE=`LC_ALL=C LANG=C date +"%B %Y"`
3434 printf "\tSet installation directory to <dir>\n"
3535 echo "-local"
3636 printf "\tSet installation directory to the current source tree\n"
37 echo "-coqrunbyteflags"
37 echo "-coqrunbyteflags <flags>"
3838 printf "\tSet link flags for VM-dependent bytecode (coqtop)\n"
39 echo "-coqtoolsbyteflags"
39 echo "-coqtoolsbyteflags <flags>"
4040 printf "\tSet link flags for VM-independant bytecode (coqdep, coqdoc, ...)\n"
4141 echo "-custom"
4242 printf "\tGenerate all bytecode executables with -custom (not recommended)\n"
43 echo "-src"
43 echo "-src <dir>"
4444 printf "\tSpecifies the source directory\n"
45 echo "-bindir"
46 echo "-libdir"
47 echo "-configdir"
48 echo "-datadir"
49 echo "-mandir"
50 echo "-docdir"
45 echo "-bindir <dir>"
46 echo "-libdir <dir>"
47 echo "-configdir <dir>"
48 echo "-datadir <dir>"
49 echo "-mandir <dir>"
50 echo "-docdir <dir>"
5151 printf "\tSpecifies where to install bin/lib/config/data/man/doc files resp.\n"
52 echo "-emacslib"
53 echo "-emacs"
52 echo "-emacslib <dir>"
5453 printf "\tSpecifies where emacs files are to be installed\n"
55 echo "-coqdocdir"
54 echo "-coqdocdir <dir>"
5655 printf "\tSpecifies where Coqdoc style files are to be installed\n"
57 echo "-camldir"
56 echo "-camldir <dir>"
5857 printf "\tSpecifies the path to the OCaml library\n"
59 echo "-lablgtkdir"
58 echo "-lablgtkdir <dir>"
6059 printf "\tSpecifies the path to the Lablgtk library\n"
6160 echo "-usecamlp5"
6261 printf "\tSpecifies to use camlp5 instead of camlp4\n"
6362 echo "-usecamlp4"
6463 printf "\tSpecifies to use camlp4 instead of camlp5\n"
65 echo "-camlp5dir"
64 echo "-camlp5dir <dir>"
6665 printf "\tSpecifies where to look for the Camlp5 library and tells to use it\n"
67 echo "-arch"
66 echo "-arch <arch>"
6867 printf "\tSpecifies the architecture\n"
6968 echo "-opt"
7069 printf "\tSpecifies whether or not to use OCaml *.opt optimized compilers\n"
162161 -coqtoolsbyteflags|--coqtoolsbyteflags) coqtoolsbyteflags_spec=yes
163162 coqtoolsbyteflags="$2"
164163 shift;;
165 -custom|--custom) custom_spec=yes
166 shift;;
164 -custom|--custom) custom_spec=yes;;
167165 -src|--src) src_spec=yes
168166 COQSRC="$2"
169167 shift;;
190188 shift;;
191189 -emacs |--emacs) emacs_spec=yes
192190 emacs="$2"
191 printf "Warning: obsolete -emacs option\n"
193192 shift;;
194193 -coqdocdir|--coqdocdir) coqdocdir_spec=yes
195194 coqdocdir="$2"
594593 # OS dependent libraries
595594
596595 OSDEPLIBS="-cclib -lunix"
597 case $ARCH,$CYGWIN in
596 case $ARCH in
598597 sun4*) OS=`uname -r`
599598 case $OS in
600599 5*) OS="Sun Solaris $OS"
601600 OSDEPLIBS="$OSDEPLIBS -cclib -lnsl -cclib -lsocket";;
602601 *) OS="Sun OS $OS"
603602 esac;;
604 win32,yes) OS="Win32 (Cygwin)"
605 cflags="-mno-cygwin $cflags";;
606 win32,*) OS="Win32 (MinGW)";;
607603 esac
608604
609605 # lablgtk2 and CoqIDE
626622 else
627623 case $lablgtkdir_spec in
628624 no)
629 if lablgtkdir=$(ocamlfind query lablgtk2 2> /dev/null); then
630 lablgtkdir_spec=yes
631 elif [ -f "${CAMLLIB}/lablgtk2/glib.mli" ]; then
625 if lablgtkdirtmp=$(ocamlfind query lablgtk2 2> /dev/null); then
626 if [ -f "$lablgtkdirtmp/glib.cmi" -a -f "$lablgtkdirtmp/glib.mli" ]; then
627 lablgtkdirfoundmsg="LabelGtk2 found by ocamlfind"
628 lablgtkdir=$lablgtkdirtmp
629 LABLGTKLIB=$lablgtkdir # Pour le message utilisateur
630 else
631 echo "Headers missings in Lablgtk2 found by ocamlfind (glib.cmi/glib.mli not found)."
632 fi
633 fi
634 if [ "$lablgtkdir" = "" -a -f "${CAMLLIB}/lablgtk2/glib.mli" -a -f "${CAMLLIB}/glib.mli" ]; then
635 lablgtkdirfoundmsg="LablGtk2 found in ocaml lib directory"
632636 lablgtkdir=${CAMLLIB}/lablgtk2
637 LABLGTKLIB=+lablgtk2 # Pour le message utilisateur
633638 fi;;
634639 yes)
635 if [ ! -f "$lablgtkdir/glib.mli" ]; then
636 echo "Incorrect LablGtk2 library (glib.mli not found)."
640 if [ ! -d "$lablgtkdir" ]; then
641 echo "$lablgtkdir is not a valid directory."
642 echo "Configuration script failed!"
643 exit 1
644 elif [ -f "$lablgtkdir/glib.cmi" -a -f "$lablgtkdir/glib.mli" ]; then
645 lablgtkdirfoundmsg="LablGtk2 directory found"
646 LABLGTKLIB=$lablgtkdir # Pour le message utilisateur
647 else
648 echo "Headers missing in LablGtk2 library (glib.cmi/glib.mli not found)."
637649 echo "Configuration script failed!"
638650 exit 1
639651 fi;;
642654 echo "LablGtk2 not found: CoqIde will not be available."
643655 COQIDE=no
644656 elif [ -z "`grep -w convert_with_fallback "$lablgtkdir/glib.mli"`" ]; then
645 echo "LablGtk2 found but too old: CoqIde will not be available."
657 echo "$lablgtkdirfoundmsg but too old: CoqIde will not be available."
646658 COQIDE=no;
647659 elif [ "$coqide_spec" = "yes" -a "$COQIDE" = "byte" ]; then
648 echo "LablGtk2 found, bytecode CoqIde will be used as requested."
660 echo "$lablgtkdirfoundmsg, bytecode CoqIde will be used as requested."
649661 COQIDE=byte
650662 elif [ ! -f "${CAMLLIB}/threads/threads.cmxa" ]; then
651 echo "LablGtk2 found, no native threads: bytecode CoqIde will be available."
663 echo "$lablgtkdirfoundmsg, no native threads: bytecode CoqIde will be available."
652664 COQIDE=byte
653665 else
654 echo "LablGtk2 found, native threads: native CoqIde will be available."
666 echo "$lablgtkdirfoundmsg, native threads: native CoqIde will be available."
655667 COQIDE=opt
656 if [ "$nomacintegration_spec" = "no" ] && pkg-config --exists gtk-mac-integration;
668 if [ "$nomacintegration_spec" = "no" ] && lablgtkosxdir=$(ocamlfind query lablgtkosx 2> /dev/null);
657669 then
658 cflags=$cflags" `pkg-config --cflags gtk-mac-integration`"
659 IDEARCHFLAGS='-ccopt "`pkg-config --libs gtk-mac-integration`"'
660 IDEARCHFILE=ide/ide_mac_stubs.o
670 IDEARCHFLAGS=lablgtkosx.cmxa
661671 IDEARCHDEF=QUARTZ
662672 elif [ "$ARCH" = "win32" ];
663673 then
670680
671681 case $COQIDE in
672682 byte|opt)
673 case $lablgtkdir_spec in
674 no) LABLGTKLIB=+lablgtk2 # Pour le message
675 LABLGTKINCLUDES="-I $LABLGTKLIB";; # Pour le makefile
676 yes) LABLGTKLIB=$lablgtkdir # Pour le message
677 LABLGTKINCLUDES="-I $LABLGTKLIB";; # Pour le makefile
678 esac;;
679 no) LABLGTKINCLUDES="";;
680 esac
683 LABLGTKINCLUDES="-I $LABLGTKLIB";;
684 no)
685 LABLGTKINCLUDES="";;
686 esac
687
688 [ x$lablgtkosxdir = x ] || LABLGTKINCLUDES="$LABLGTKINCLUDES -I $lablgtkosxdir"
681689
682690 # strip command
683691
0 <div id="sidebarWrapper">
1 <div id="sidebar">
0 <div id="sidebarWrapper">
1 <div id="sidebar">
2 <div class="block">
3 <h2 class="title">Navigation</h2>
4 <div class="content">
5 <ul class="menu">
6 <li class="leaf">Standard Library
7 <ul class="menu">
8 <li><a href="index.html">Table of contents</a></li>
9 <li><a href="genindex.html">Index</a></li>
10 </ul>
11 </li>
12 </ul>
13 </div>
14 </div>
15 </div>
16 </div>
217
3 <div class="block">
4 <h2 class="title">Navigation</h2>
5 <div class="content">
18 </div>
619
7 <ul class="menu">
8
9 <li class="leaf">Standard Library
10 <ul class="menu">
11 <li><a href="index.html">Table of contents</a></li>
12 <li><a href="genindex.html">Index</a></li>
13 </ul>
14 </li>
15
16 </ul>
17
18 </div>
19 </div>
20
21 </div>
22 </div>
23
24
25 </div>
26
27 </div>
28
29 <div id="footer">
30 <div id="nav-footer">
31 <ul class="links-menu-footer">
32 <li><a href="mailto:webmaster_@_www.lix.polytechnique.fr">webmaster</a></li>
33 <li><a href="http://validator.w3.org/check?uri=referer">xhtml valid</a></li>
34 <li><a href="http://jigsaw.w3.org/css-validator/check/referer">CSS valid</a></li>
35 </ul>
36
37 </div>
38 </div>
20 <div id="footer">
21 <div id="nav-footer">
22 <ul class="links-menu-footer">
23 <li><a href="mailto:www-coq_@_lix.polytechnique.fr">webmaster</a></li>
24 <li><a href="http://validator.w3.org/check?uri=referer">xhtml valid</a></li>
25 <li><a href="http://jigsaw.w3.org/css-validator/check/referer">CSS valid</a></li>
26 </ul>
27 </div>
28 </div>
3929
4030 </div>
4131
4232 </body>
4333 </html>
44
55 <title>Standard Library | The Coq Proof Assistant</title>
66
77 <link rel="shortcut icon" href="favicon.ico" type="image/x-icon" />
8 <style type="text/css" media="all">@import "http://www.lix.polytechnique.fr/coq/modules/node/node.css";</style>
8 <style type="text/css" media="all">@import "http://coq.inria.fr/modules/node/node.css";</style>
99
10 <style type="text/css" media="all">@import "http://www.lix.polytechnique.fr/coq/modules/system/defaults.css";</style>
11 <style type="text/css" media="all">@import "http://www.lix.polytechnique.fr/coq/modules/system/system.css";</style>
12 <style type="text/css" media="all">@import "http://www.lix.polytechnique.fr/coq/modules/user/user.css";</style>
10 <style type="text/css" media="all">@import "http://coq.inria.fr/modules/system/defaults.css";</style>
11 <style type="text/css" media="all">@import "http://coq.inria.fr/modules/system/system.css";</style>
12 <style type="text/css" media="all">@import "http://coq.inria.fr/modules/user/user.css";</style>
1313
14 <style type="text/css" media="all">@import "http://www.lix.polytechnique.fr/coq/sites/all/themes/coq/style.css";</style>
15 <style type="text/css" media="all">@import "http://www.lix.polytechnique.fr/coq/sites/all/themes/coq/coqdoc.css";</style>
14 <style type="text/css" media="all">@import "http://coq.inria.fr/sites/all/themes/coq/style.css";</style>
15 <style type="text/css" media="all">@import "http://coq.inria.fr/sites/all/themes/coq/coqdoc.css";</style>
1616
1717 </head>
1818
1919 <body>
2020
2121 <div id="container">
22 <div id="headertop">
23 <div id="nav">
24 <ul class="links-menu">
25 <li><a href="http://www.lix.polytechnique.fr/coq/" class="active">Home</a></li>
22 <div id="headertop">
23 <div id="nav">
24 <ul class="links-menu">
25 <li><a href="http://coq.inria.fr/" class="active">Home</a></li>
26 <li><a href="http://coq.inria.fr/about-coq" title="More about coq">About Coq</a></li>
27 <li><a href="http://coq.inria.fr/download">Get Coq</a></li>
28 <li><a href="http://coq.inria.fr/documentation">Documentation</a></li>
29 <li><a href="http://coq.inria.fr/community">Community</a></li>
30 </ul>
31 </div>
32 </div>
2633
27 <li><a href="http://www.lix.polytechnique.fr/coq/about-coq" title="More about coq">About Coq</a></li>
28 <li><a href="http://www.lix.polytechnique.fr/coq/download">Get Coq</a></li>
29 <li><a href="http://www.lix.polytechnique.fr/coq/documentation">Documentation</a></li>
30 <li><a href="http://www.lix.polytechnique.fr/coq/community">Community</a></li>
31 </ul>
32 </div>
33 </div>
34 <div id="header">
35 <div id="logoWrapper">
36 <div id="logo"><a href="http://coq.inria.fr/" title="Home"><img src="http://coq.inria.fr/files/barron_logo.png" alt="Home" /></a>
37 </div>
38 <div id="siteName"><a href="http://coq.inria.fr/" title="Home">The Coq Proof Assistant</a>
39 </div>
40 </div>
41 </div>
3442
35 <div id="header">
43 <div id="content">
3644
37 <div id="logoWrapper">
38
39 <div id="logo"><a href="http://www.lix.polytechnique.fr/coq/" title="Home"><img src="http://www.lix.polytechnique.fr/coq/files/barron_logo.png" alt="Home" /></a>
40 </div>
41 <div id="siteName"><a href="http://www.lix.polytechnique.fr/coq/" title="Home">The Coq Proof Assistant</a>
42 </div>
43
44 </div>
45 </div>
46
47 <div id="content">
48
190190
191191 Note: we use Unix.stderr in Unix.create_process to get debug
192192 messages from the coqtop's Ide_slave loop.
193
194 NB: it's important to close coqide's descriptors (ide2top_w and top2ide_r)
195 in coqtop. We do this indirectly via [Unix.set_close_on_exec].
196 This way, coqide has the only remaining copies of these descriptors,
197 and closing them later will have visible effects in coqtop. Cf man 7 pipe :
198
199 - If all file descriptors referring to the write end of a pipe have been
200 closed, then an attempt to read(2) from the pipe will see end-of-file
201 (read(2) will return 0).
202 - If all file descriptors referring to the read end of a pipe have been
203 closed, then a write(2) will cause a SIGPIPE signal to be generated for
204 the calling process. If the calling process is ignoring this signal,
205 then write(2) fails with the error EPIPE.
206
207 Symmetrically, coqtop's descriptors (ide2top_r and top2ide_w) should be
208 closed in coqide.
193209 *)
194210
195211 let open_process_pid prog args =
196212 let (ide2top_r,ide2top_w) = Unix.pipe () in
197213 let (top2ide_r,top2ide_w) = Unix.pipe () in
214 Unix.set_close_on_exec ide2top_w;
215 Unix.set_close_on_exec top2ide_r;
198216 let pid = Unix.create_process prog args ide2top_r top2ide_w Unix.stderr in
199217 assert (pid <> 0);
200218 Unix.close ide2top_r;
249267 Xml_utils.print_xml coqtop.cin (Ide_intf.of_call c);
250268 flush coqtop.cin;
251269 let xml = Xml_parser.parse p (Xml_parser.SChannel coqtop.cout) in
252 (Ide_intf.to_answer xml : 'a Interface.value)
270 (Ide_intf.to_answer xml c : 'a Interface.value)
253271
254272 let interp coqtop ?(raw=false) ?(verbose=true) s =
255273 eval_call coqtop (Ide_intf.interp (raw,verbose,s))
4040 val mutable read_only : bool
4141 val mutable filename : string option
4242 val mutable stats : Unix.stats option
43 val mutable detached_views : GWindow.window list
4443 method without_auto_complete : 'a 'b. ('a -> 'b) -> 'a -> 'b
4544 method set_auto_complete : bool -> unit
46
47 method kill_detached_views : unit -> unit
48 method add_detached_view : GWindow.window -> unit
49 method remove_detached_view : GWindow.window -> unit
5045
5146 method filename : string option
5247 method stats : Unix.stats option
10398 }
10499
105100 let kill_session s =
106 s.analyzed_view#kill_detached_views ();
101 (* To close the detached views of this script, we call manually
102 [destroy] on it, triggering some callbacks in [detach_view].
103 In a more modern lablgtk, rather use the page-removed signal ? *)
104 s.script#destroy ();
107105 Coq.kill_coqtop !(s.toplvl)
108106
109107 let build_session s =
441439 Tags.Script.proof_decl; Tags.Script.qed ]
442440
443441 (** Cut a part of the buffer in sentences and tag them.
442 Invariant: either this slice ends the buffer, or it ends with ".".
444443 May raise [Coq_lex.Unterminated] when the zone ends with
445444 an unterminated sentence. *)
446445
479478
480479 (** Search backward the first character of a sentence, starting at [iter]
481480 and going at most up to [soi] (meant to be the end of the locked zone).
482 Raise [Not_found] when no proper sentence start has been found,
483 in particular when the final "." of the locked zone is followed
484 by a non-blank character outside the locked zone. This non-blank
485 character will be signaled as erroneous in [tag_on_insert] below. *)
481 Raise [StartError] when no proper sentence start has been found.
482 A character following a ending "." is considered as a sentence start
483 only if this character is a blank. In particular, when a final "."
484 at the end of the locked zone isn't followed by a blank, then this
485 non-blank character will be signaled as erroneous in [tag_on_insert] below.
486 *)
487
488 exception StartError
486489
487490 let grab_sentence_start (iter:GText.iter) soi =
488491 let cond iter =
489 if iter#compare soi < 0 then raise Not_found;
492 if iter#compare soi < 0 then raise StartError;
490493 let prev = iter#backward_char in
491494 is_sentence_end prev &&
492495 (not (is_char prev '.') ||
508511
509512 (** Retag a zone that has been edited *)
510513
511 let tag_on_insert =
512 (* possible race condition here : editing two buffers with a timedelta smaller
513 * than 1.5s might break the error recovery mechanism. *)
514 let skip_last = ref (ref true) in (* ref to the mutable flag created on last call *)
515 fun buffer ->
516 try
517 (* the start of the non-locked zone *)
518 let soi = buffer#get_iter_at_mark (`NAME "start_of_input") in
519 (* the inserted zone is between [prev_insert] and [insert] *)
520 let insert = buffer#get_iter_at_mark `INSERT in
521 let prev_insert = buffer#get_iter_at_mark (`NAME "prev_insert") in
522 (* [prev_insert] is normally always before [insert] even when deleting.
523 Let's check this nonetheless *)
524 let prev_insert =
525 if insert#compare prev_insert < 0 then insert else prev_insert
526 in
527 let start = grab_sentence_start prev_insert soi in
528 (** The status of "{" "}" as sentence delimiters is too fragile.
529 We retag up to the next "." instead. *)
530 let stop = grab_ending_dot insert in
531 let skip_curr = ref true in (* shall the callback be skipped ? by default yes*)
532 (!skip_last) := true; (* skip the previously created callback *)
533 skip_last := skip_curr;
534 try split_slice_lax buffer start stop
535 with Coq_lex.Unterminated ->
536 skip_curr := false;
537 let callback () =
538 if not !skip_curr then begin
539 try split_slice_lax buffer start buffer#end_iter
540 with Coq_lex.Unterminated -> ()
541 end; false
542 in
543 ignore (Glib.Timeout.add ~ms:1500 ~callback)
544 with Not_found ->
545 let err_pos = buffer#get_iter_at_mark (`NAME "start_of_input") in
546 buffer#apply_tag Tags.Script.error ~start:err_pos ~stop:err_pos#forward_char
514 let tag_on_insert buffer =
515 (* the start of the non-locked zone *)
516 let soi = buffer#get_iter_at_mark (`NAME "start_of_input") in
517 (* the inserted zone is between [prev_insert] and [insert] *)
518 let insert = buffer#get_iter_at_mark `INSERT in
519 let prev = buffer#get_iter_at_mark (`NAME "prev_insert") in
520 (* [prev] is normally always before [insert] even when deleting.
521 Let's check this nonetheless *)
522 let prev, insert =
523 if insert#compare prev < 0 then insert, prev else prev, insert
524 in
525 try
526 let start = grab_sentence_start prev soi in
527 (** The status of "{" "}" as sentence delimiters is too fragile.
528 We retag up to the next "." instead. *)
529 let stop = grab_ending_dot insert in
530 try split_slice_lax buffer start stop
531 with Coq_lex.Unterminated ->
532 (* This shouldn't happen frequently. Either:
533 - we are at eof, with indeed an unfinished sentence.
534 - we have just inserted an opening of comment or string.
535 - the inserted text ends with a "." that interacts with the "."
536 found by [grab_ending_dot] to form a non-ending "..".
537 In any case, we retag up to eof, since this isn't that costly. *)
538 if not stop#is_end then
539 try split_slice_lax buffer start buffer#end_iter
540 with Coq_lex.Unterminated -> ()
541 with StartError ->
542 buffer#apply_tag Tags.Script.error ~start:soi ~stop:soi#forward_char
547543
548544 let force_retag buffer =
549545 try split_slice_lax buffer buffer#start_iter buffer#end_iter
590586 val mutable stats = None
591587 val mutable last_modification_time = 0.
592588 val mutable last_auto_save_time = 0.
593 val mutable detached_views = []
594589 val mutable find_forward_instead_of_backward = false
595590
596591 val mutable auto_complete_on = !current.auto_complete
605600 let y = f x in
606601 self#set_auto_complete old;
607602 y
608 method add_detached_view (w:GWindow.window) =
609 detached_views <- w::detached_views
610 method remove_detached_view (w:GWindow.window) =
611 detached_views <- List.filter (fun e -> w#misc#get_oid<>e#misc#get_oid) detached_views
612
613 method kill_detached_views () =
614 List.iter (fun w -> w#destroy ()) detached_views;
615 detached_views <- []
616603
617604 method filename = filename
618605 method stats = stats
819806 begin
820807 let menu_callback = if !current.contextual_menus_on_goal then
821808 (fun s () -> ignore (self#insert_this_phrase_on_success
822 true true false ("progress "^s) s))
809 true true false ("progress "^s) s))
823810 else
824811 (fun _ _ -> ()) in
825812 try
1006993 if stop#starts_line then
1007994 input_buffer#insert ~iter:stop insertphrase
1008995 else input_buffer#insert ~iter:stop ("\n"^insertphrase);
996 tag_on_insert input_buffer;
1009997 let start = self#get_start_of_input in
1010998 input_buffer#move_mark ~where:stop (`NAME "start_of_input");
1011999 input_buffer#apply_tag (safety_tag safe) ~start ~stop;
12301218 (List.exists
12311219 (fun p ->
12321220 self#insert_this_phrase_on_success true false false
1233 ("progress "^p^".\n") (p^".\n")) l)
1221 ("progress "^p^".") (p^".")) l)
12341222
12351223 method active_keypress_handler k =
12361224 let state = GdkEvent.Key.state k in
13811369 );
13821370 ignore (input_buffer#connect#begin_user_action
13831371 ~callback:(fun () ->
1384 let here = input_buffer#get_iter_at_mark `INSERT in
1385 input_buffer#move_mark (`NAME "prev_insert") here
1386 )
1372 let where = self#get_insert in
1373 input_buffer#move_mark (`NAME "prev_insert") ~where;
1374 let start = self#get_start_of_input in
1375 let stop = input_buffer#end_iter in
1376 input_buffer#remove_tag Tags.Script.error ~start ~stop)
13871377 );
13881378 ignore (input_buffer#connect#end_user_action
13891379 ~callback:(fun () ->
13901380 last_modification_time <- Unix.time ();
1391 let r = input_view#visible_rect in
1392 let stop =
1393 input_view#get_iter_at_location
1394 ~x:(Gdk.Rectangle.x r + Gdk.Rectangle.width r)
1395 ~y:(Gdk.Rectangle.y r + Gdk.Rectangle.height r)
1396 in
1397 input_buffer#remove_tag
1398 Tags.Script.error
1399 ~start:self#get_start_of_input
1400 ~stop;
14011381 tag_on_insert input_buffer
14021382 )
14031383 );
17941774 end
17951775 else false)
17961776
1777 let logfile = ref None
1778
17971779 let main files =
17981780
17991781 (* Main window *)
23532335 let tactic_shortcut s sc = GAction.add_action s ~label:("_"^s)
23542336 ~accel:(!current.modifier_for_tactics^sc)
23552337 ~callback:(do_if_active (fun a -> a#insert_command
2356 ("progress "^s^".\n") (s^".\n"))) in
2338 ("progress "^s^".") (s^"."))) in
23572339 let query_callback command _ =
23582340 let word = get_current_word () in
23592341 if not (word = "") then
23792361 match key with
23802362 |Some ac -> GAction.add_action name ~label ~callback ~accel:(!current.modifier_for_templates^ac)
23812363 |None -> GAction.add_action name ~label ~callback ?accel:None
2364 in
2365 let detach_view _ =
2366 (* Open a separate window containing the current buffer *)
2367 let trm = session_notebook#current_term in
2368 let w = GWindow.window ~show:true
2369 ~width:(!current.window_width*2/3)
2370 ~height:(!current.window_height*2/3)
2371 ~position:`CENTER
2372 ~title:(if trm.filename = "" then "*scratch*" else trm.filename)
2373 ()
2374 in
2375 let sb = GBin.scrolled_window ~packing:w#add ()
2376 in
2377 let nv = GText.view ~buffer:trm.script#buffer ~packing:sb#add ()
2378 in
2379 nv#misc#modify_font !current.text_font;
2380 (* If the buffer in the main window is closed, destroy this detached view *)
2381 ignore (trm.script#connect#destroy ~callback:w#destroy)
23822382 in
23832383 GAction.add_actions file_actions [
23842384 GAction.add_action "File" ~label:"_File";
25672567 ];
25682568 GAction.add_actions windows_actions [
25692569 GAction.add_action "Windows" ~label:"_Windows";
2570 GAction.add_action "Detach View" ~label:"Detach _View"
2571 ~callback:(fun _ -> do_if_not_computing "detach view"
2572 (function {script=v;analyzed_view=av} ->
2573 let w = GWindow.window ~show:true
2574 ~width:(!current.window_width*2/3)
2575 ~height:(!current.window_height*2/3)
2576 ~position:`CENTER
2577 ~title:(match av#filename with
2578 | None -> "*Unnamed*"
2579 | Some f -> f)
2580 ()
2581 in
2582 let sb = GBin.scrolled_window
2583 ~packing:w#add ()
2584 in
2585 let nv = GText.view
2586 ~buffer:v#buffer
2587 ~packing:sb#add
2588 ()
2589 in
2590 nv#misc#modify_font
2591 !current.text_font;
2592 ignore (w#connect#destroy
2593 ~callback:
2594 (fun () -> av#remove_detached_view w));
2595 av#add_detached_view w)
2596 [session_notebook#current_term]);
2570 GAction.add_action "Detach View" ~label:"Detach _View" ~callback:detach_view
25972571 ];
25982572 GAction.add_actions help_actions [
25992573 GAction.add_action "Help" ~label:"_Help";
28452819 \n-------------------\
28462820 \n"
28472821 in
2822 let display_log_file (b:GText.buffer) =
2823 if !debug then
2824 let file = match !logfile with None -> "stderr" | Some f -> f in
2825 b#insert ("Debug mode is on, log file is "^file)
2826 in
28482827 let initial_about (b:GText.buffer) =
28492828 let initial_string =
28502829 "Welcome to CoqIDE, an Integrated Development Environment for Coq\n"
28512830 in
28522831 let coq_version = Coq.short_version () in
2853 b#insert ~iter:b#start_iter "\n\n";
2832 display_log_file b;
28542833 if Glib.Utf8.validate ("You are running " ^ coq_version) then
28552834 b#insert ~iter:b#start_iter ("You are running " ^ coq_version);
28562835 if Glib.Utf8.validate initial_string then
28802859 then b#insert about_full_string;
28812860 let coq_version = Coq.version () in
28822861 if Glib.Utf8.validate coq_version
2883 then b#insert coq_version
2884
2862 then b#insert coq_version;
2863 display_log_file b;
28852864 in
28862865 (* Remove default pango menu for textviews *)
28872866 w#show ();
1010 (** The arguments that will be passed to coqtop. No quoting here, since
1111 no /bin/sh when using create_process instead of open_process. *)
1212 val sup_args : string list ref
13
14 (** In debug mode under win32, messages are written to a log file *)
15 val logfile : string option ref
1316
1417 (** Filter the argv from coqide specific options, and set
1518 Minilib.coqtop_path accordingly *)
55 (* * GNU Lesser General Public License Version 2.1 *)
66 (************************************************************************)
77
8 IFDEF QUARTZ THEN
9 external gtk_mac_init : (string -> unit) -> (unit -> bool) -> unit
10 = "caml_gtk_mac_init"
8 let _ = Coqide.ignore_break ()
9 let _ = GtkMain.Main.init ()
1110
12 external gtk_mac_ready : ([> Gtk.widget ] as 'a) Gtk.obj -> ([> Gtk.widget ] as 'a) Gtk.obj ->
13 ([> Gtk.widget ] as 'a) Gtk.obj -> unit
14 = "caml_gtk_mac_ready"
15 END
11 (* We handle Gtk warning messages ourselves :
12 - on win32, we don't want them to end on a non-existing console
13 - we display critical messages via pop-ups *)
1614
17 let initmac () = IFDEF QUARTZ THEN gtk_mac_init Coqide.do_load Coqide.forbid_quit_to_save ELSE () END
15 let catch_gtk_messages () =
16 let all_levels =
17 [`FLAG_RECURSION;`FLAG_FATAL;`ERROR;`CRITICAL;`WARNING;
18 `MESSAGE;`INFO;`DEBUG]
19 in
20 let handler ~level msg =
21 let header = "Coqide internal error: " in
22 let level_is tag = (level land Glib.Message.log_level tag) <> 0 in
23 if level_is `ERROR then
24 let () = GToolbox.message_box ~title:"Error" (header ^ msg) in
25 Coqide.crash_save 1
26 else if level_is `CRITICAL then
27 GToolbox.message_box ~title:"Error" (header ^ msg)
28 else if level_is `DEBUG || Sys.os_type = "Win32" then
29 Ideutils.prerr_endline msg (* no-op unless in debug mode *)
30 else
31 Printf.eprintf "%s\n" msg
32 in
33 let catch domain =
34 ignore (Glib.Message.set_log_handler ~domain ~levels:all_levels handler)
35 in
36 List.iter catch ["GLib";"Gtk";"Gdk";"Pango"]
1837
19 let macready x y z = IFDEF QUARTZ THEN gtk_mac_ready x#as_widget y#as_widget z#as_widget ELSE () END
38 let () = catch_gtk_messages ()
2039
2140 (* On win32, we add the directory of coqide to the PATH at launch-time
2241 (this used to be done in a .bat script). *)
3251 *)
3352
3453 let reroute_stdout_stderr () =
54 (* We anticipate a bit the argument parsing and look for -debug *)
55 let debug = List.mem "-debug" (Array.to_list Sys.argv) in
56 Ideutils.debug := debug;
3557 let out_descr =
36 if !Ideutils.debug then
37 Unix.descr_of_out_channel (snd (Filename.open_temp_file "coqide_" ".log"))
58 if debug then
59 let (name,chan) = Filename.open_temp_file "coqide_" ".log" in
60 Coqide.logfile := Some name;
61 Unix.descr_of_out_channel chan
3862 else
3963 snd (Unix.pipe ())
4064 in
65 Unix.set_close_on_exec out_descr;
4166 Unix.dup2 out_descr Unix.stdout;
4267 Unix.dup2 out_descr Unix.stderr
4368
6388 reroute_stdout_stderr ()
6489 END
6590
91 IFDEF QUARTZ THEN
92 let osx = GosxApplication.osxapplication ()
93
94 let _ =
95 osx#connect#ns_application_open_file ~callback:(fun x -> Coqide.do_load x; true) in
96 let _ =
97 osx#connect#ns_application_block_termination ~callback:Coqide.forbid_quit_to_save in
98 ()
99 END
100
66101 let () =
67 Coqide.ignore_break ();
68 ignore (GtkMain.Main.init ());
69 initmac () ;
70102 (try
71103 let gtkrcdir = List.find
72104 (fun x -> Sys.file_exists (Filename.concat x "coqide-gtk2rc"))
81113 end;
82114 (* GtkData.AccelGroup.set_default_mod_mask
83115 (Some [`CONTROL;`SHIFT;`MOD1;`MOD3;`MOD4]);*)
84 ignore (
85 Glib.Message.set_log_handler ~domain:"Gtk" ~levels:[`ERROR;`FLAG_FATAL;
86 `WARNING;`CRITICAL]
87 (fun ~level msg ->
88 if level land Glib.Message.log_level `WARNING <> 0
89 then Printf.eprintf "Warning: %s\n" msg
90 else failwith ("Coqide internal error: " ^ msg)));
91116 let argl = Array.to_list Sys.argv in
92117 let argl = Coqide.read_coqide_args argl in
93118 let files = Coq.filter_coq_opts (List.tl argl) in
95120 Coq.check_connection args;
96121 Coqide.sup_args := args;
97122 Coqide.main files;
98 if !Coq_config.with_geoproof then ignore (Thread.create Coqide.check_for_geoproof_input ());
99 macready (Coqide_ui.ui_m#get_widget "/CoqIde MenuBar") (Coqide_ui.ui_m#get_widget "/CoqIde MenuBar/Edit/Prefs")
100 (Coqide_ui.ui_m#get_widget "/CoqIde MenuBar/Help/Abt");
123 if !Coq_config.with_geoproof then ignore (Thread.create Coqide.check_for_geoproof_input ())
124
125 IFDEF QUARTZ THEN
126 let () =
127 GtkosxApplication.Application.set_menu_bar osx#as_osxapplication (GtkMenu.MenuShell.cast (Coqide_ui.ui_m#get_widget "/CoqIde MenuBar")#as_widget) in
128 let () =
129 GtkosxApplication.Application.insert_app_menu_item osx#as_osxapplication (Coqide_ui.ui_m#get_widget "/CoqIde MenuBar/Edit/Prefs")#as_widget 1 in
130 let () =
131 GtkosxApplication.Application.set_help_menu osx#as_osxapplication (Some (GtkMenu.MenuItem.cast (Coqide_ui.ui_m#get_widget "/CoqIde MenuBar/Help")#as_widget)) in
132 osx#ready ()
133 END
134
101135 while true do
102136 try
103137 GtkThread.main ()
+0
-85
ide/ide_mac_stubs.c less more
0 #include <caml/mlvalues.h>
1 #include <caml/alloc.h>
2 #include <caml/memory.h>
3 #include <caml/callback.h>
4 #include <caml/fail.h>
5
6 #include <gtk/gtk.h>
7 #include <lablgtk2/wrappers.h>
8 #include <lablgtk2/ml_glib.h>
9 #include <lablgtk2/ml_gobject.h>
10 #include <gtkmacintegration/gtkosxapplication.h>
11
12 GtkOSXApplication *theApp;
13 value open_file_fun, forbid_quit_fun, themenubar, pref_item, about_item;
14
15 static void osx_accel_map_foreach_lcb(gpointer data,const gchar *accel_path,
16 guint accel_key, GdkModifierType accel_mods,
17 gboolean changed) {
18 if (accel_mods & GDK_CONTROL_MASK) {
19 accel_mods |= GDK_META_MASK;
20 accel_mods &= (accel_mods & GDK_MOD1_MASK) ? ~GDK_MOD1_MASK : ~GDK_CONTROL_MASK;
21 if (!gtk_accel_map_change_entry(accel_path,accel_key,accel_mods,FALSE)) {
22 g_print("could not change accelerator %s\n",accel_path);
23 }
24 }
25 if (accel_mods & GDK_MOD1_MASK) {
26 accel_mods &= ~ GDK_MOD1_MASK;
27 accel_mods |= GDK_CONTROL_MASK;
28 if (!gtk_accel_map_change_entry(accel_path,accel_key,accel_mods,FALSE)) {
29 g_print("could not change accelerator %s\n",accel_path);
30 }
31 }
32 }
33
34 static gboolean deal_with_open(GtkOSXApplication *app, gchar *path, gpointer user_data)
35 {
36 CAMLparam0();
37 CAMLlocal2(string_path, res);
38 string_path = caml_copy_string(path);
39 res = caml_callback_exn(open_file_fun,string_path);
40 gboolean truc = !(Is_exception_result(res));
41 CAMLreturnT(gboolean, truc);
42 }
43
44 static gboolean deal_with_quit(GtkOSXApplication *app, gpointer user_data)
45 {
46 CAMLparam0();
47 CAMLlocal1(res);
48 res = caml_callback_exn(forbid_quit_fun,Val_unit);
49 gboolean truc = (Bool_val(res))||((Is_exception_result(res)));
50 CAMLreturnT(gboolean, truc);
51 }
52
53 CAMLprim value caml_gtk_mac_init(value open_file_the_fun, value forbid_quit_the_fun)
54 {
55 CAMLparam2(open_file_the_fun,forbid_quit_the_fun);
56 open_file_fun = open_file_the_fun;
57 caml_register_generational_global_root(&open_file_fun);
58 forbid_quit_fun = forbid_quit_the_fun;
59 caml_register_generational_global_root(&forbid_quit_fun);
60 theApp = g_object_new(GTK_TYPE_OSX_APPLICATION, NULL);
61 g_signal_connect(theApp, "NSApplicationOpenFile", G_CALLBACK(deal_with_open), NULL);
62 g_signal_connect(theApp, "NSApplicationBlockTermination", G_CALLBACK(deal_with_quit), NULL);
63 CAMLreturn (Val_unit);
64 }
65
66 CAMLprim value caml_gtk_mac_ready(value menubar, value prefs, value about)
67 {
68 GtkOSXApplicationMenuGroup * pref_grp, * about_grp;
69 CAMLparam3(menubar,prefs,about);
70 themenubar = menubar;
71 pref_item = prefs;
72 about_item = about;
73 caml_register_generational_global_root(&themenubar);
74 caml_register_generational_global_root(&pref_item);
75 caml_register_generational_global_root(&about_item);
76 /* gtk_accel_map_foreach(NULL, osx_accel_map_foreach_lcb);*/
77 gtk_osxapplication_set_menu_bar(theApp,check_cast(GTK_MENU_SHELL,themenubar));
78 gtk_osxapplication_insert_app_menu_item(theApp,check_cast(GTK_WIDGET,about_item),1);
79 gtk_osxapplication_insert_app_menu_item(theApp,gtk_separator_menu_item_new(),2);
80 gtk_osxapplication_insert_app_menu_item(theApp,check_cast(GTK_WIDGET,pref_item),3);
81 gtk_osxapplication_insert_app_menu_item(theApp,gtk_separator_menu_item_new(),4);
82 gtk_osxapplication_ready(theApp);
83 CAMLreturn(Val_unit);
84 }
3434 | `MOD5 -> "<Mod5>"
3535 | `CONTROL -> "<Control>"
3636 | `SHIFT -> "<Shift>"
37 | `HYPER -> "<Hyper>"
38 | `META -> "<Meta>"
39 | `RELEASE -> ""
40 | `SUPER -> "<Super>"
3741 | `BUTTON1| `BUTTON2| `BUTTON3| `BUTTON4| `BUTTON5| `LOCK -> ""
3842
3943 let mod_list_to_str l = List.fold_left (fun s m -> (mod_to_str m)^s) "" l
4646 | `BUTTON3 -> 1024
4747 | `BUTTON4 -> 2048
4848 | `BUTTON5 -> 4096
49 | `HYPER -> 1 lsl 22
50 | `META -> 1 lsl 20
51 | `RELEASE -> 1 lsl 30
52 | `SUPER -> 1 lsl 21
4953
5054 let print_modifier l =
5155 List.iter
6468 | `BUTTON2 -> "B2"
6569 | `BUTTON3 -> "B3"
6670 | `BUTTON4 -> "B4"
67 | `BUTTON5 -> "B5")
71 | `BUTTON5 -> "B5"
72 | `HYPER -> "HYPER"
73 | `META -> "META"
74 | `RELEASE -> ""
75 | `SUPER -> "SUPER")
6876 m)^" ")
6977 )
7078 l;
249249 check_same_binder ([na1],default_binder_kind,def1) ([na2],default_binder_kind,def2)
250250 | _ -> failwith "not same binder") bl1 bl2
251251
252 let is_same_type c d = try let () = check_same_type c d in true with Failure _ -> false
252 let is_same_type c d =
253 try let () = check_same_type c d in true
254 with Failure _ | Invalid_argument _ -> false
253255
254256 (**********************************************************************)
255257 (* mapping patterns to cases_pattern_expr *)
373375 | (keyrule,pat,n as _rule)::rules ->
374376 try
375377 match t,n with
376 | PatCstr (loc,(ind,_),l,na), n when n = Some 0 or n = None or
377 n = Some(fst(Global.lookup_inductive ind)).Declarations.mind_nparams ->
378 | PatCstr (loc,(ind,_),l,na), n when (n = Some 0 or n = None or
379 n = Some(fst(Global.lookup_inductive ind)).Declarations.mind_nparams)
380 && (match keyrule with SynDefRule _ -> true | _ -> false) ->
378381 (* Abbreviation for the constructor name only *)
379382 (match keyrule with
380 | NotationRule (sc,ntn) -> raise No_match
383 | NotationRule _ -> assert false
381384 | SynDefRule kn ->
382385 let qid = Qualid (loc, shortest_qualid_of_syndef vars kn) in
383386 let l = List.map (extern_cases_pattern_in_scope allscopes vars) l in
14101410 | None ->
14111411 [], None in
14121412 let na = match tm', na with
1413 | GVar (loc,id), None when Idset.mem id env.ids -> loc,Name id
1413 | GVar (loc,id), None when not (List.mem_assoc id (snd lvar)) ->
1414 loc,Name id
14141415 | GRef (loc, VarRef id), None -> loc,Name id
14151416 | _, None -> dummy_loc,Anonymous
14161417 | _, Some (loc,na) -> loc,na in
124124
125125 (* Comparison on this type is pointer equality *)
126126 type canonical_arc =
127 { univ: UniverseLevel.t; lt: UniverseLevel.t list; le: UniverseLevel.t list }
128
129 let terminal u = {univ=u; lt=[]; le=[]}
127 { univ: UniverseLevel.t;
128 lt: UniverseLevel.t list;
129 le: UniverseLevel.t list;
130 rank: int }
131
132 let terminal u = {univ=u; lt=[]; le=[]; rank=0}
130133
131134 (* A UniverseLevel.t is either an alias for another one, or a canonical one,
132135 for which we know the universes that are above *)
404407 (* we assume compare(u,v) = LE *)
405408 (* merge u v forces u ~ v with repr u as canonical repr *)
406409 let merge g arcu arcv =
407 match between g arcu arcv with
408 | arcu::v -> (* arcu is chosen as canonical and all others (v) are *)
409 (* redirected to it *)
410 let redirect (g,w,w') arcv =
411 let g' = enter_equiv_arc arcv.univ arcu.univ g in
412 (g',list_unionq arcv.lt w,arcv.le@w')
413 in
414 let (g',w,w') = List.fold_left redirect (g,[],[]) v in
415 let g_arcu = (g',arcu) in
416 let g_arcu = List.fold_left setlt_if g_arcu w in
417 let g_arcu = List.fold_left setleq_if g_arcu w' in
418 fst g_arcu
419 | [] -> anomaly "Univ.between"
410 (* we find the arc with the biggest rank, and we redirect all others to it *)
411 let arcu, g, v =
412 let best_ranked (max_rank, old_max_rank, best_arc, rest) arc =
413 if arc.rank >= max_rank
414 then (arc.rank, max_rank, arc, best_arc::rest)
415 else (max_rank, old_max_rank, best_arc, arc::rest)
416 in
417 match between g arcu arcv with
418 | [] -> anomaly "Univ.between"
419 | arc::rest ->
420 let (max_rank, old_max_rank, best_arc, rest) =
421 List.fold_left best_ranked (arc.rank, min_int, arc, []) rest in
422 if max_rank > old_max_rank then best_arc, g, rest
423 else begin
424 (* one redirected node also has max_rank *)
425 let arcu = {best_arc with rank = max_rank + 1} in
426 arcu, enter_arc arcu g, rest
427 end
428 in
429 let redirect (g,w,w') arcv =
430 let g' = enter_equiv_arc arcv.univ arcu.univ g in
431 (g',list_unionq arcv.lt w,arcv.le@w')
432 in
433 let (g',w,w') = List.fold_left redirect (g,[],[]) v in
434 let g_arcu = (g',arcu) in
435 let g_arcu = List.fold_left setlt_if g_arcu w in
436 let g_arcu = List.fold_left setleq_if g_arcu w' in
437 fst g_arcu
420438
421439 (* merge_disc : UniverseLevel.t -> UniverseLevel.t -> unit *)
422440 (* we assume compare(u,v) = compare(v,u) = NLE *)
423441 (* merge_disc u v forces u ~ v with repr u as canonical repr *)
424 let merge_disc g arcu arcv =
442 let merge_disc g arc1 arc2 =
443 let arcu, arcv = if arc1.rank < arc2.rank then arc2, arc1 else arc1, arc2 in
444 let arcu, g =
445 if arc1.rank <> arc2.rank then arcu, g
446 else
447 let arcu = {arcu with rank = succ arcu.rank} in
448 arcu, enter_arc arcu g
449 in
425450 let g' = enter_equiv_arc arcv.univ arcu.univ g in
426451 let g_arcu = (g',arcu) in
427452 let g_arcu = List.fold_left setlt_if g_arcu arcv.lt in
562587 in
563588 let canonicalize u = function
564589 | Equiv _ -> Equiv (repr u)
565 | Canonical {univ=v; lt=lt; le=le} ->
590 | Canonical {univ=v; lt=lt; le=le; rank=rank} ->
566591 assert (u == v);
567592 (* avoid duplicates and self-loops *)
568593 let lt = lrepr lt and le = lrepr le in
574599 univ = v;
575600 lt = UniverseLSet.elements lt;
576601 le = UniverseLSet.elements le;
602 rank = rank
577603 }
578604 in
579605 UniverseLMap.mapi canonicalize g
631657 let node = Canonical {
632658 univ = bottom;
633659 lt = [];
634 le = UniverseLSet.elements vertices
660 le = UniverseLSet.elements vertices;
661 rank = 0
635662 } in UniverseLMap.add bottom node g
636663 in
637664 let rec iter count accu =
691718 | false, true -> push res v
692719 | false, false -> res
693720 end
694 | Canonical {univ=v; lt=lt; le=le} ->
721 | Canonical {univ=v; lt=lt; le=le; rank=r} ->
695722 assert (u == v);
696723 if filter u then
697724 let lt = List.filter filter lt in
698725 let le = List.filter filter le in
699 UniverseLMap.add u (Canonical {univ=u; lt=lt; le=le}) res
726 UniverseLMap.add u (Canonical {univ=u; lt=lt; le=le; rank=r}) res
700727 else
701728 let res = List.fold_left (fun g u -> if filter u then push g u else g) res lt in
702729 let res = List.fold_left (fun g u -> if filter u then push g u else g) res le in
716743 let g = UniverseLMap.add u (Canonical {
717744 univ = u;
718745 le = [];
719 lt = [types.(i+1)]
746 lt = [types.(i+1)];
747 rank = 1
720748 }) g in aux (i+1) g
721749 else g
722750 in aux 0 g
4141 | AttributeValueExpected
4242 | EndOfTagExpected of string
4343 | EOFExpected
44 | Empty
4445
4546 type error = error_msg * error_pos
4647
116117 | Xml_lexer.PCData s -> PCData s
117118 | Xml_lexer.Tag (tag, attr, true) -> Element (tag, attr, [])
118119 | Xml_lexer.Tag (tag, attr, false) ->
119 let elements = read_elems ~tag s in
120 let elements = read_elems tag s in
120121 Element (tag, attr, canonicalize elements)
121122 | t ->
122123 push t s;
123124 raise NoMoreData
124125 and
125 read_elems ?tag s =
126 read_elems tag s =
126127 let elems = ref [] in
127128 (try
128129 while true do
136137 with
137138 NoMoreData -> ());
138139 match pop s with
139 | Xml_lexer.Endtag s when Some s = tag -> List.rev !elems
140 | Xml_lexer.Eof when tag = None -> List.rev !elems
141 | t ->
142 match tag with
143 | None -> raise (Internal_error EOFExpected)
144 | Some s -> raise (Internal_error (EndOfTagExpected s))
140 | Xml_lexer.Endtag s when s = tag -> List.rev !elems
141 | t -> raise (Internal_error (EndOfTagExpected tag))
145142
146143 let rec read_xml s =
147144 let node = read_node s in
161158 | Xml_lexer.EAttributeValueExpected -> AttributeValueExpected
162159 | Xml_lexer.EUnterminatedEntity -> UnterminatedEntity
163160
161 let error_of_exn stk = function
162 | NoMoreData when Stack.pop stk = Xml_lexer.Eof -> Empty
163 | NoMoreData -> NodeExpected
164 | Internal_error e -> e
165 | Xml_lexer.Error e -> convert e
166 | e -> raise e
167
164168 let do_parse xparser source =
169 let stk = Stack.create() in
165170 try
166171 Xml_lexer.init source;
167 let s = { source = source; xparser = xparser; stack = Stack.create(); } in
172 let s = { source = source; xparser = xparser; stack = stk } in
168173 let x = read_xml s in
169174 if xparser.check_eof && pop s <> Xml_lexer.Eof then raise (Internal_error EOFExpected);
170175 Xml_lexer.close source;
171176 x
172 with
173 | NoMoreData ->
174 Xml_lexer.close source;
175 raise (!xml_error NodeExpected source)
176 | Internal_error e ->
177 Xml_lexer.close source;
178 raise (!xml_error e source)
179 | Xml_lexer.Error e ->
180 Xml_lexer.close source;
181 raise (!xml_error (convert e) source)
177 with e ->
178 Xml_lexer.close source;
179 raise (!xml_error (error_of_exn stk e) source)
182180
183181 let parse p = function
184182 | SChannel ch -> do_parse p (Lexing.from_channel ch)
207205 | AttributeValueExpected -> "Attribute value expected"
208206 | EndOfTagExpected tag -> sprintf "End of tag expected : '%s'" tag
209207 | EOFExpected -> "End of file expected"
208 | Empty -> "Empty"
210209
211210 let error (msg,pos) =
212211 if pos.emin = pos.emax then
5858 | AttributeValueExpected
5959 | EndOfTagExpected of string
6060 | EOFExpected
61 | Empty
6162
6263 type error = error_msg * error_pos
6364
421421 if not w32 then N else S ([A"-camlbin";A w32bin;A "-ccopt";P w32ico])
422422 in
423423 if opt then rule fo ~prod:fo ~deps:(depsall@depso) ~insert:`top
424 (cmd [P coqmktop_boot;w32flag;A"-boot";A"-opt";incl fo;A"-o";Px fo]);
424 (cmd [P coqmktop_boot;w32flag;A"-boot";A"-opt";incl fo;camlp4incl;A"-o";Px fo]);
425425 rule fb ~prod:fb ~deps:(depsall@depsb) ~insert:`top
426 (cmd [P coqmktop_boot;w32flag;A"-boot";A"-top";incl fb;A"-o";Px fb]);
426 (cmd [P coqmktop_boot;w32flag;A"-boot";A"-top";incl fb;camlp4incl;A"-o";Px fb]);
427427 in
428428
429429 (** Coq files dependencies *)
259259
260260 let rec tacarg_using_rule_token pr_gen = function
261261 | Some s :: l, al -> str s :: tacarg_using_rule_token pr_gen (l,al)
262 | None :: l, a :: al -> pr_gen a :: tacarg_using_rule_token pr_gen (l,al)
262 | None :: l, a :: al ->
263 let print_it =
264 match genarg_tag a with
265 | OptArgType _ -> fold_opt (fun _ -> true) false a
266 | _ -> true
267 in
268 let r = tacarg_using_rule_token pr_gen (l,al) in
269 if print_it then pr_gen a :: r else r
263270 | [], [] -> []
264271 | _ -> failwith "Inconsistent arguments of extended tactic"
265272
422429 (if occs = no_occurrences_expr then mt ()
423430 else pr_with_occurrences (fun () -> str" |- *") (occs,())))
424431
425 let pr_orient b = if b then mt () else str " <-"
432 let pr_orient b = if b then mt () else str "<- "
426433
427434 let pr_multi = function
428435 | Precisely 1 -> mt ()
805812
806813 (* Equivalence relations *)
807814 | TacReflexivity as x -> pr_atom0 x
808 | TacSymmetry cls -> str "symmetry " ++ pr_clauses (Some true) pr_ident cls
815 | TacSymmetry cls -> str "symmetry" ++ pr_clauses (Some true) pr_ident cls
809816 | TacTransitivity (Some c) -> str "transitivity" ++ pr_constrarg c
810817 | TacTransitivity None -> str "etransitivity"
811818
812819 (* Equality and inversion *)
813820 | TacRewrite (ev,l,cl,by) ->
814 hov 1 (str (with_evars ev "rewrite") ++
821 hov 1 (str (with_evars ev "rewrite") ++ spc () ++
815822 prlist_with_sep
816823 (fun () -> str ","++spc())
817824 (fun (b,m,c) ->
818 pr_orient b ++ spc() ++ pr_multi m ++ pr_with_bindings c)
825 pr_orient b ++ pr_multi m ++ pr_with_bindings c)
819826 l
820827 ++ pr_clauses (Some true) pr_ident cl
821828 ++ (match by with Some by -> pr_by_tactic (pr_tac_level ltop) by | None -> mt()))
1212
1313 (** Disclaimer: trying to obtain efficient certified programs
1414 by extracting [nat] into [int] is definitively *not* a good idea:
15
16 - This is just a syntactic adaptation, many things can go wrong,
17 such as name captures (e.g. if you have a constant named "int"
18 in your development, or a module named "Pervasives"). See bug #2878.
1519
1620 - Since [int] is bounded while [nat] is (theoretically) infinite,
1721 you have to make sure by yourself that your program will not
3337 (** Mapping of [nat] into [int]. The last string corresponds to
3438 a [nat_case], see documentation of [Extract Inductive]. *)
3539
36 Extract Inductive nat => int [ "0" "succ" ]
40 Extract Inductive nat => int [ "0" "Pervasives.succ" ]
3741 "(fun fO fS n -> if n=0 then fO () else fS (n-1))".
3842
3943 (** Efficient (but uncertified) versions for usual [nat] functions *)
4044
4145 Extract Constant plus => "(+)".
42 Extract Constant pred => "fun n -> max 0 (n-1)".
43 Extract Constant minus => "fun n m -> max 0 (n-m)".
46 Extract Constant pred => "fun n -> Pervasives.max 0 (n-1)".
47 Extract Constant minus => "fun n m -> Pervasives.max 0 (n-m)".
4448 Extract Constant mult => "( * )".
45 Extract Inlined Constant max => max.
46 Extract Inlined Constant min => min.
49 Extract Inlined Constant max => "Pervasives.max".
50 Extract Inlined Constant min => "Pervasives.min".
4751 (*Extract Inlined Constant nat_beq => "(=)".*)
4852 Extract Inlined Constant EqNat.beq_nat => "(=)".
4953 Extract Inlined Constant EqNat.eq_nat_decide => "(=)".
3333 (** Efficient (but uncertified) versions for usual functions *)
3434
3535 Extract Constant Pos.add => "(+)".
36 Extract Constant Pos.succ => "succ".
37 Extract Constant Pos.pred => "fun n -> max 1 (n-1)".
38 Extract Constant Pos.sub => "fun n m -> max 1 (n-m)".
36 Extract Constant Pos.succ => "Pervasives.succ".
37 Extract Constant Pos.pred => "fun n -> Pervasives.max 1 (n-1)".
38 Extract Constant Pos.sub => "fun n m -> Pervasives.max 1 (n-m)".
3939 Extract Constant Pos.mul => "( * )".
40 Extract Constant Pos.min => "min".
41 Extract Constant Pos.max => "max".
40 Extract Constant Pos.min => "Pervasives.min".
41 Extract Constant Pos.max => "Pervasives.max".
4242 Extract Constant Pos.compare =>
4343 "fun x y -> if x=y then Eq else if x<y then Lt else Gt".
4444 Extract Constant Pos.compare_cont =>
4646
4747
4848 Extract Constant N.add => "(+)".
49 Extract Constant N.succ => "succ".
50 Extract Constant N.pred => "fun n -> max 0 (n-1)".
51 Extract Constant N.sub => "fun n m -> max 0 (n-m)".
49 Extract Constant N.succ => "Pervasives.succ".
50 Extract Constant N.pred => "fun n -> Pervasives.max 0 (n-1)".
51 Extract Constant N.sub => "fun n m -> Pervasives.max 0 (n-m)".
5252 Extract Constant N.mul => "( * )".
53 Extract Constant N.min => "min".
54 Extract Constant N.max => "max".
53 Extract Constant N.min => "Pervasives.min".
54 Extract Constant N.max => "Pervasives.max".
5555 Extract Constant N.div => "fun a b -> if b=0 then 0 else a/b".
5656 Extract Constant N.modulo => "fun a b -> if b=0 then a else a mod b".
5757 Extract Constant N.compare =>
5959
6060
6161 Extract Constant Z.add => "(+)".
62 Extract Constant Z.succ => "succ".
63 Extract Constant Z.pred => "pred".
62 Extract Constant Z.succ => "Pervasives.succ".
63 Extract Constant Z.pred => "Pervasives.pred".
6464 Extract Constant Z.sub => "(-)".
6565 Extract Constant Z.mul => "( * )".
6666 Extract Constant Z.opp => "(~-)".
67 Extract Constant Z.abs => "abs".
68 Extract Constant Z.min => "min".
69 Extract Constant Z.max => "max".
67 Extract Constant Z.abs => "Pervasives.abs".
68 Extract Constant Z.min => "Pervasives.min".
69 Extract Constant Z.max => "Pervasives.max".
7070 Extract Constant Z.compare =>
7171 "fun x y -> if x=y then Eq else if x<y then Lt else Gt".
7272
7373 Extract Constant Z.of_N => "fun p -> p".
74 Extract Constant Z.abs_N => "abs".
74 Extract Constant Z.abs_N => "Pervasives.abs".
7575
7676 (** Z.div and Z.modulo are quite complex to define in terms of (/) and (mod).
7777 For the moment we don't even try *)
129129
130130 (* Enriching a signature with implicit information *)
131131
132 let sign_with_implicits r s =
132 let sign_with_implicits r s nb_params =
133133 let implicits = implicits_of_global r in
134134 let rec add_impl i = function
135135 | [] -> []
138138 if sign = Keep && List.mem i implicits then Kill Kother else sign
139139 in sign' :: add_impl (succ i) s
140140 in
141 add_impl 1 s
141 add_impl (1+nb_params) s
142142
143143 (* Enriching a exception message *)
144144
666666 let head = put_magic_if magic1 (MLglob (ConstRef kn)) in
667667 (* Now, the extraction of the arguments. *)
668668 let s_full = type2signature env (snd schema) in
669 let s_full = sign_with_implicits (ConstRef kn) s_full in
669 let s_full = sign_with_implicits (ConstRef kn) s_full 0 in
670670 let s = sign_no_final_keeps s_full in
671671 let ls = List.length s in
672672 let la = List.length args in
673673 (* The ml arguments, already expunged from known logical ones *)
674674 let mla = make_mlargs env mle s args metas in
675675 let mla =
676 if not magic1 then
676 if magic1 || lang () <> Ocaml then mla
677 else
677678 try
679 (* for better optimisations later, we discard dependent args
680 of projections and replace them by fake args that will be
681 removed during final pretty-print. *)
678682 let l,l' = list_chop (projection_arity (ConstRef kn)) mla in
679683 if l' <> [] then (List.map (fun _ -> MLexn "Proj Args") l) @ l'
680684 else mla
681685 with _ -> mla
682 else mla
683686 in
684687 (* For strict languages, purely logical signatures with at least
685688 one [Kill Kother] lead to a dummy lam. So a [MLdummy] is left
725728 let type_cons = instantiation (nb_tvars, type_cons) in
726729 (* Then, the usual variables [s], [ls], [la], ... *)
727730 let s = List.map (type2sign env) types in
728 let s = sign_with_implicits (ConstructRef cp) s in
731 let s = sign_with_implicits (ConstructRef cp) s params_nb in
729732 let ls = List.length s in
730733 let la = List.length args in
731734 assert (la <= ls + params_nb);
804807 let l = List.map f oi.ip_types.(i) in
805808 (* the corresponding signature *)
806809 let s = List.map (type2sign env) oi.ip_types.(i) in
807 let s = sign_with_implicits r s in
810 let s = sign_with_implicits r s mi.ind_nparams in
808811 (* Extraction of the branch (in functional form). *)
809812 let e = extract_maybe_term env mle (type_recomp (l,mlt)) br.(i) in
810813 (* We suppress dummy arguments according to signature. *)
875878 let l,t' = type_decomp (expand env (var2var' t)) in
876879 let s = List.map (type2sign env) l in
877880 (* Check for user-declared implicit information *)
878 let s = sign_with_implicits (ConstRef kn) s in
881 let s = sign_with_implicits (ConstRef kn) s 0 in
879882 (* Decomposing the top level lambdas of [body].
880883 If there isn't enough, it's ok, as long as remaining args
881884 aren't to be pruned (and initial lambdas aren't to be all
921924 let trm = handle_exn (ConstRef kn) n (fun i -> fst (List.nth rels (i-1))) trm
922925 in
923926 trm, type_expunge_from_sign env s t
927
928 (* Extracts the type of an axiom, honors the Extraction Implicit declaration. *)
929 let extract_axiom env kn typ =
930 reset_meta_count ();
931 (* The short type [t] (i.e. possibly with abbreviations). *)
932 let t = snd (record_constant_type env kn (Some typ)) in
933 (* The real type [t']: without head products, expanded, *)
934 (* and with [Tvar] translated to [Tvar'] (not instantiable). *)
935 let l,_ = type_decomp (expand env (var2var' t)) in
936 let s = List.map (type2sign env) l in
937 (* Check for user-declared implicit information *)
938 let s = sign_with_implicits (ConstRef kn) s 0 in
939 type_expunge_from_sign env s t
924940
925941 let extract_fixpoint env vkn (fi,ti,ci) =
926942 let n = Array.length vkn in
958974 in Dtype (r, vl, t)
959975 in
960976 let mk_ax () =
961 let t = snd (record_constant_type env kn (Some typ)) in
962 Dterm (r, MLaxiom, type_expunge env t)
977 let t = extract_axiom env kn typ in
978 Dterm (r, MLaxiom, t)
963979 in
964980 let mk_def c =
965981 let e,t = extract_std_constant env kn c typ in
2525 (*s Apply some functions upon all [ml_decl] and [ml_spec] found in a
2626 [ml_structure]. *)
2727
28 let se_iter do_decl do_spec =
28 let se_iter do_decl do_spec do_mp =
2929 let rec mt_iter = function
30 | MTident _ -> ()
30 | MTident mp -> do_mp mp
3131 | MTfunsig (_,mt,mt') -> mt_iter mt; mt_iter mt'
3232 | MTwith (mt,ML_With_type(idl,l,t))->
3333 let mp_mt = msid_of_mt mt in
3737 in
3838 let r = ConstRef (make_con mp_w empty_dirpath (label_of_id l')) in
3939 mt_iter mt; do_decl (Dtype(r,l,t))
40 | MTwith (mt,_)->mt_iter mt
40 | MTwith (mt,ML_With_module(idl,mp))->
41 let mp_mt = msid_of_mt mt in
42 let mp_w =
43 List.fold_left (fun mp l -> MPdot(mp,label_of_id l)) mp_mt idl
44 in
45 mt_iter mt; do_mp mp_w; do_mp mp
4146 | MTsig (_, sign) -> List.iter spec_iter sign
4247 and spec_iter = function
4348 | (_,Spec s) -> do_spec s
5055 me_iter m.ml_mod_expr; mt_iter m.ml_mod_type
5156 | (_,SEmodtype m) -> mt_iter m
5257 and me_iter = function
53 | MEident _ -> ()
58 | MEident mp -> do_mp mp
5459 | MEfunctor (_,mt,me) -> me_iter me; mt_iter mt
5560 | MEapply (me,me') -> me_iter me; me_iter me'
5661 | MEstruct (msid, sel) -> List.iter se_iter sel
5762 in
5863 se_iter
5964
60 let struct_iter do_decl do_spec s =
61 List.iter (function (_,sel) -> List.iter (se_iter do_decl do_spec) sel) s
65 let struct_iter do_decl do_spec do_mp s =
66 List.iter
67 (function (_,sel) -> List.iter (se_iter do_decl do_spec do_mp) sel) s
6268
6369 (*s Apply some fonctions upon all references in [ml_type], [ml_ast],
6470 [ml_decl], [ml_spec] and [ml_structure]. *)
140146 | _ -> ()
141147
142148 let struct_ast_search f s =
143 try struct_iter (decl_ast_search f) (fun _ -> ()) s; false
149 try struct_iter (decl_ast_search f) (fun _ -> ()) (fun _ -> ()) s; false
144150 with Found -> true
145151
146152 let rec type_search f = function
164170 | Sval (_,u) -> type_search f u
165171
166172 let struct_type_search f s =
167 try struct_iter (decl_type_search f) (spec_type_search f) s; false
173 try
174 struct_iter (decl_type_search f) (spec_type_search f) (fun _ -> ()) s;
175 false
168176 with Found -> true
169177
170178
246254 let c = Array.map (subst 0) av
247255 in MLfix(i, ids, c)
248256
257 (* [optim_se] applies the [normalize] function everywhere and does the
258 inlining of code. The inlined functions are kept for the moment in
259 order to preserve the global interface, later [depcheck_se] will get
260 rid of them if possible *)
261
249262 let rec optim_se top to_appear s = function
250263 | [] -> []
251264 | (l,SEdecl (Dterm (r,a,t))) :: lse ->
252265 let a = normalize (ast_glob_subst !s a) in
253266 let i = inline r a in
254267 if i then s := Refmap'.add r a !s;
255 if top && i && not (library ()) && not (List.mem r to_appear)
256 then optim_se top to_appear s lse
257 else
258 let d = match optimize_fix a with
259 | MLfix (0, _, [|c|]) ->
260 Dfix ([|r|], [|ast_subst (MLglob r) c|], [|t|])
261 | a -> Dterm (r, a, t)
262 in (l,SEdecl d) :: (optim_se top to_appear s lse)
268 let d = match optimize_fix a with
269 | MLfix (0, _, [|c|]) ->
270 Dfix ([|r|], [|ast_subst (MLglob r) c|], [|t|])
271 | a -> Dterm (r, a, t)
272 in
273 (l,SEdecl d) :: (optim_se top to_appear s lse)
263274 | (l,SEdecl (Dfix (rv,av,tv))) :: lse ->
264275 let av = Array.map (fun a -> normalize (ast_glob_subst !s a)) av in
265 let all = ref true in
266276 (* This fake body ensures that no fixpoint will be auto-inlined. *)
267277 let fake_body = MLfix (0,[||],[||]) in
268278 for i = 0 to Array.length rv - 1 do
269279 if inline rv.(i) fake_body
270280 then s := Refmap'.add rv.(i) (dfix_to_mlfix rv av i) !s
271 else all := false
272281 done;
273 if !all && top && not (library ())
274 && (array_for_all (fun r -> not (List.mem r to_appear)) rv)
275 then optim_se top to_appear s lse
276 else (l,SEdecl (Dfix (rv, av, tv))) :: (optim_se top to_appear s lse)
282 (l,SEdecl (Dfix (rv, av, tv))) :: (optim_se top to_appear s lse)
277283 | (l,SEmodule m) :: lse ->
278284 let m = { m with ml_mod_expr = optim_me to_appear s m.ml_mod_expr}
279285 in (l,SEmodule m) :: (optim_se top to_appear s lse)
288294
289295 (* After these optimisations, some dependencies may not be needed anymore.
290296 For non-library extraction, we recompute a minimal set of dependencies
291 for first-level objects *)
297 for first-level definitions (no module pruning yet). *)
292298
293299 exception NoDepCheck
294300
361367 end
362368 | t :: se ->
363369 let se' = depcheck_se se in
364 se_iter compute_deps_decl compute_deps_spec t;
370 se_iter compute_deps_decl compute_deps_spec add_needed_mp t;
365371 t :: se'
366372
367373 let rec depcheck_struct = function
369375 | (mp,lse)::struc ->
370376 let struc' = depcheck_struct struc in
371377 let lse' = depcheck_se lse in
372 (mp,lse')::struc'
378 if lse' = [] then struc' else (mp,lse')::struc'
373379
374380 let check_implicits = function
375381 | MLexn s ->
388394 List.map (fun (mp,lse) -> (mp, optim_se true (fst to_appear) subst lse))
389395 struc
390396 in
391 let opt_struc = List.filter (fun (_,lse) -> lse<>[]) opt_struc in
392397 ignore (struct_ast_search check_implicits opt_struc);
393 if library () then opt_struc
398 if library () then
399 List.filter (fun (_,lse) -> lse<>[]) opt_struc
394400 else begin
395401 reset_needed ();
396402 List.iter add_needed (fst to_appear);
307307 (Global.env ())
308308 construct
309309 in
310 let argl =
311 if argl = []
312 then
310 let argl = match argl with
311 | None ->
313312 Array.to_list
314 (Array.init (cst_narg - npar) (fun _ -> mkGHole ())
313 (Array.init cst_narg (fun _ -> mkGHole ())
315314 )
316 else argl
315 | Some l ->
316 Array.to_list
317 (Array.init npar (fun _ -> mkGHole ()))@l
317318 in
318319 let pat_as_term =
319320 mkGApp(mkGRef (ConstructRef(ind',i+1)),argl)
652653 Printer.pr_glob_constr b ++ str " in " ++
653654 Printer.pr_glob_constr rt ++ str ". try again with a cast")
654655 in
655 let case_pats = build_constructors_of_type ind [] in
656 let case_pats = build_constructors_of_type ind None in
656657 assert (Array.length case_pats = 2);
657658 let brl =
658659 list_map_i
668669 | GLetTuple(_,nal,_,b,e) ->
669670 begin
670671 let nal_as_glob_constr =
671 List.map
672 Some (List.map
672673 (function
673674 Name id -> mkGVar id
674675 | Anonymous -> mkGHole ()
675676 )
676 nal
677 nal)
677678 in
678679 let b_as_constr = Pretyping.Default.understand Evd.empty env b in
679680 let b_typ = Typing.type_of env Evd.empty b_as_constr in
1313
1414 Module Type Int.
1515
16 Parameter int : Set.
17
18 Parameter zero : int.
19 Parameter one : int.
20 Parameter plus : int -> int -> int.
21 Parameter opp : int -> int.
22 Parameter minus : int -> int -> int.
23 Parameter mult : int -> int -> int.
16 Parameter t : Set.
17
18 Parameter zero : t.
19 Parameter one : t.
20 Parameter plus : t -> t -> t.
21 Parameter opp : t -> t.
22 Parameter minus : t -> t -> t.
23 Parameter mult : t -> t -> t.
2424
2525 Notation "0" := zero : Int_scope.
2626 Notation "1" := one : Int_scope.
3232 Open Scope Int_scope.
3333
3434 (* First, int is a ring: *)
35 Axiom ring : @ring_theory int 0 1 plus mult minus opp (@eq int).
35 Axiom ring : @ring_theory t 0 1 plus mult minus opp (@eq t).
3636
3737 (* int should also be ordered: *)
3838
39 Parameter le : int -> int -> Prop.
40 Parameter lt : int -> int -> Prop.
41 Parameter ge : int -> int -> Prop.
42 Parameter gt : int -> int -> Prop.
39 Parameter le : t -> t -> Prop.
40 Parameter lt : t -> t -> Prop.
41 Parameter ge : t -> t -> Prop.
42 Parameter gt : t -> t -> Prop.
4343 Notation "x <= y" := (le x y): Int_scope.
4444 Notation "x < y" := (lt x y) : Int_scope.
4545 Notation "x >= y" := (ge x y) : Int_scope.
6060 forall i j k, 0 < k -> i < j -> k*i<k*j.
6161
6262 (* We should have a way to decide the equality and the order*)
63 Parameter compare : int -> int -> comparison.
63 Parameter compare : t -> t -> comparison.
6464 Infix "?=" := compare (at level 70, no associativity) : Int_scope.
6565 Axiom compare_Eq : forall i j, compare i j = Eq <-> i=j.
6666 Axiom compare_Lt : forall i j, compare i j = Lt <-> i<j.
8282
8383 Open Scope Z_scope.
8484
85 Definition int := Z.
85 Definition t := Z.
8686 Definition zero := 0.
8787 Definition one := 1.
8888 Definition plus := Z.add.
9090 Definition minus := Z.sub.
9191 Definition mult := Z.mul.
9292
93 Lemma ring : @ring_theory int zero one plus mult minus opp (@eq int).
93 Lemma ring : @ring_theory t zero one plus mult minus opp (@eq t).
9494 Proof.
9595 constructor.
9696 exact Z.add_0_l.
137137
138138 Module IntProperties (I:Int).
139139 Import I.
140 Local Notation int := I.t.
140141
141142 (* Primo, some consequences of being a ring theory... *)
142143
826827 Import I.
827828 Module IP:=IntProperties(I).
828829 Import IP.
830 Local Notation int := I.t.
829831
830832 (* \subsubsection{Definition of reified integer expressions}
831833 Terms are either:
10361038
10371039 Theorem eq_term_true : forall t1 t2 : term, eq_term t1 t2 = true -> t1 = t2.
10381040 Proof.
1039 simple induction t1; intros until t2; case t2; simpl in *;
1040 try (intros; discriminate; fail);
1041 [ intros; elim beq_true with (1 := H); trivial
1042 | intros t21 t22 H3; elim andb_prop with (1 := H3); intros H4 H5;
1043 elim H with (1 := H4); elim H0 with (1 := H5);
1044 trivial
1045 | intros t21 t22 H3; elim andb_prop with (1 := H3); intros H4 H5;
1046 elim H with (1 := H4); elim H0 with (1 := H5);
1047 trivial
1048 | intros t21 t22 H3; elim andb_prop with (1 := H3); intros H4 H5;
1049 elim H with (1 := H4); elim H0 with (1 := H5);
1050 trivial
1051 | intros t21 H3; elim H with (1 := H3); trivial
1052 | intros; elim beq_nat_true with (1 := H); trivial ].
1041 induction t1; destruct t2; simpl in *; try discriminate;
1042 (rewrite andb_true_iff; intros (H1,H2)) || intros H; f_equal;
1043 auto using beq_true, beq_nat_true.
1044 Qed.
1045
1046 Theorem eq_term_refl : forall t0 : term, eq_term t0 t0 = true.
1047 Proof.
1048 induction t0; simpl in *; try (apply andb_true_iff; split); trivial.
1049 - now apply beq_iff.
1050 - now apply beq_nat_true_iff.
10531051 Qed.
10541052
10551053 Ltac trivial_case := unfold not; intros; discriminate.
10571055 Theorem eq_term_false :
10581056 forall t1 t2 : term, eq_term t1 t2 = false -> t1 <> t2.
10591057 Proof.
1060 simple induction t1;
1061 [ intros z t2; case t2; try trivial_case; simpl; unfold not;
1062 intros; elim beq_false with (1 := H); simplify_eq H0;
1063 auto
1064 | intros t11 H1 t12 H2 t2; case t2; try trivial_case; simpl;
1065 intros t21 t22 H3; unfold not; intro H4;
1066 elim andb_false_elim with (1 := H3); intros H5;
1067 [ elim H1 with (1 := H5); simplify_eq H4; auto
1068 | elim H2 with (1 := H5); simplify_eq H4; auto ]
1069 | intros t11 H1 t12 H2 t2; case t2; try trivial_case; simpl;
1070 intros t21 t22 H3; unfold not; intro H4;
1071 elim andb_false_elim with (1 := H3); intros H5;
1072 [ elim H1 with (1 := H5); simplify_eq H4; auto
1073 | elim H2 with (1 := H5); simplify_eq H4; auto ]
1074 | intros t11 H1 t12 H2 t2; case t2; try trivial_case; simpl;
1075 intros t21 t22 H3; unfold not; intro H4;
1076 elim andb_false_elim with (1 := H3); intros H5;
1077 [ elim H1 with (1 := H5); simplify_eq H4; auto
1078 | elim H2 with (1 := H5); simplify_eq H4; auto ]
1079 | intros t11 H1 t2; case t2; try trivial_case; simpl; intros t21 H3;
1080 unfold not; intro H4; elim H1 with (1 := H3);
1081 simplify_eq H4; auto
1082 | intros n t2; case t2; try trivial_case; simpl; unfold not;
1083 intros; elim beq_nat_false with (1 := H); simplify_eq H0;
1084 auto ].
1058 intros t1 t2 H E. subst t2. now rewrite eq_term_refl in H.
10851059 Qed.
10861060
10871061 (* \subsubsection{Tactiques pour éliminer ces tests}
19181892 end
19191893 end.
19201894
1921 Theorem fusion_stable : forall t : list t_fusion, term_stable (fusion t).
1922 Proof.
1923 simple induction t; simpl;
1895 Theorem fusion_stable : forall trace : list t_fusion, term_stable (fusion trace).
1896 Proof.
1897 simple induction trace; simpl;
19241898 [ exact reduce_stable
19251899 | intros stp l H; case stp;
19261900 [ apply compose_term_stable;
20922066 Theorem constant_not_nul_valid :
20932067 forall i : nat, valid_hyps (constant_not_nul i).
20942068 Proof.
2095 unfold valid_hyps, constant_not_nul; intros;
2096 generalize (nth_valid ep e i lp); Simplify; simpl.
2097
2098 elim_beq i1 i0; auto; simpl; intros H1 H2;
2099 elim H1; symmetry ; auto.
2069 unfold valid_hyps, constant_not_nul; intros i ep e lp H.
2070 generalize (nth_valid ep e i lp H); Simplify.
21002071 Qed.
21012072
21022073 (* \paragraph{[O_CONSTANT_NEG]} *)
21302101 end.
21312102
21322103 Theorem not_exact_divide_valid :
2133 forall (k1 k2 : int) (body : term) (t i : nat),
2134 valid_hyps (not_exact_divide k1 k2 body t i).
2104 forall (k1 k2 : int) (body : term) (t0 i : nat),
2105 valid_hyps (not_exact_divide k1 k2 body t0 i).
21352106 Proof.
21362107 unfold valid_hyps, not_exact_divide; intros;
21372108 generalize (nth_valid ep e i lp); Simplify.
2138 rewrite (scalar_norm_add_stable t e), <-H1.
2109 rewrite (scalar_norm_add_stable t0 e), <-H1.
21392110 do 2 rewrite <- scalar_norm_add_stable; simpl in *; intros.
21402111 absurd (interp_term e body * k1 + k2 = 0);
21412112 [ now apply OMEGA4 | symmetry; auto ].
25082479 execute_omega cont (apply_oper_2 i1 i2 (state m s) l)
25092480 end.
25102481
2511 Theorem omega_valid : forall t : t_omega, valid_list_hyps (execute_omega t).
2512 Proof.
2513 simple induction t; simpl;
2482 Theorem omega_valid : forall tr : t_omega, valid_list_hyps (execute_omega tr).
2483 Proof.
2484 simple induction tr; simpl;
25142485 [ unfold valid_list_hyps; simpl; intros; left;
25152486 apply (constant_not_nul_valid n ep e lp H)
25162487 | unfold valid_list_hyps; simpl; intros; left;
25212492 (apply_oper_1_valid m (divide_and_approx k1 k2 body n)
25222493 (divide_and_approx_valid k1 k2 body n) ep e lp H)
25232494 | unfold valid_list_hyps; simpl; intros; left;
2524 apply (not_exact_divide_valid i i0 t0 n n0 ep e lp H)
2495 apply (not_exact_divide_valid _ _ _ _ _ ep e lp H)
25252496 | unfold valid_list_hyps, valid_hyps;
25262497 intros k body n t' Ht' m ep e lp H; apply Ht';
25272498 apply
26172588 (* \subsubsection{Exécution de la trace} *)
26182589
26192590 Theorem execute_goal :
2620 forall (t : t_omega) (ep : list Prop) (env : list int) (l : hyps),
2621 interp_list_goal ep env (execute_omega t l) -> interp_goal ep env l.
2622 Proof.
2623 intros; apply (goal_valid (execute_omega t) (omega_valid t) ep env l H).
2591 forall (tr : t_omega) (ep : list Prop) (env : list int) (l : hyps),
2592 interp_list_goal ep env (execute_omega tr l) -> interp_goal ep env l.
2593 Proof.
2594 intros; apply (goal_valid (execute_omega tr) (omega_valid tr) ep env l H).
26242595 Qed.
26252596
26262597
29352906 | intro; apply ne_left_2; assumption ]
29362907 | case p; simpl; intros; auto; generalize H; elim (t_rewrite_stable s);
29372908 simpl; intro H1;
2938 [ rewrite (plus_0_r_reverse (interp_term e t0)); rewrite H1;
2909 [ rewrite (plus_0_r_reverse (interp_term e t1)); rewrite H1;
29392910 rewrite plus_permute; rewrite plus_opp_r;
29402911 rewrite plus_0_r; trivial
2941 | apply (fun a b => plus_le_reg_r a b (- interp_term e t));
2912 | apply (fun a b => plus_le_reg_r a b (- interp_term e t0));
29422913 rewrite plus_opp_r; assumption
29432914 | rewrite ge_le_iff;
2944 apply (fun a b => plus_le_reg_r a b (- interp_term e t0));
2915 apply (fun a b => plus_le_reg_r a b (- interp_term e t1));
29452916 rewrite plus_opp_r; assumption
29462917 | rewrite gt_lt_iff; apply lt_left_inv; assumption
29472918 | apply lt_left_inv; assumption
662662 let admit_obligations n =
663663 let prg = get_prog_err n in
664664 let obls, rem = prg.prg_obligations in
665 let obls = Array.copy obls in
665666 Array.iteri
666667 (fun i x ->
667668 match x.obl_body with
17621762 (* First strategy: we build an "inversion" predicate *)
17631763 let sigma1,pred1 = build_inversion_problem loc env sigma tomatchs t in
17641764 (* Second strategy: we directly use the evar as a non dependent pred *)
1765 let pred2 = lift (List.length arsign) t in
1765 let pred2 = lift (List.length (List.flatten arsign)) t in
17661766 [sigma1, pred1; sigma, pred2]
17671767 (* Some type annotation *)
17681768 | Some rtntyp, _ ->
388388 with _ ->
389389 GVar (dl, id))
390390 | Sort s -> GSort (dl,detype_sort s)
391 | Cast (c1,REVERTcast,c2) when not !Flags.raw_print ->
392 detype isgoal avoid env c1
391393 | Cast (c1,k,c2) ->
392394 GCast(dl,detype isgoal avoid env c1, CastConv (k, detype isgoal avoid env c2))
393395 | Prod (na,ty,c) -> detype_binder isgoal BProd avoid env na ty c
134134
135135 let whd_head_evar sigma c = applist (whd_head_evar_stack sigma c)
136136
137 let noccur_evar evd evk c =
138 let rec occur_rec c = match kind_of_term c with
139 | Evar (evk',_ as ev') ->
137 let noccur_evar env evd evk c =
138 let rec occur_rec k c = match kind_of_term c with
139 | Evar (evk',args' as ev') ->
140140 (match safe_evar_value evd ev' with
141 | Some c -> occur_rec c
142 | None -> if evk = evk' then raise Occur)
143 | _ -> iter_constr occur_rec c
141 | Some c -> occur_rec k c
142 | None ->
143 if evk = evk' then raise Occur else Array.iter (occur_rec k) args')
144 | Rel i when i > k ->
145 (match pi2 (Environ.lookup_rel (i-k) env) with
146 | None -> ()
147 | Some b -> occur_rec k (lift i b))
148 | _ -> iter_constr_with_binders succ occur_rec k c
144149 in
145 try occur_rec c; true with Occur -> false
150 try occur_rec 0 c; true with Occur -> false
146151
147152 let normalize_evar evd ev =
148153 match kind_of_term (whd_evar evd (mkEvar ev)) with
740745 None
741746
742747 let is_unification_pattern_evar env evd (evk,args) l t =
743 if List.for_all (fun x -> isRel x || isVar x) l & noccur_evar evd evk t then
748 if List.for_all (fun x -> isRel x || isVar x) l & noccur_evar env evd evk t
749 then
744750 let args = remove_instance_local_defs evd evk (Array.to_list args) in
745751 let n = List.length args in
746752 match find_unification_pattern_args env (args @ l) t with
11111117 | Not_found -> CannotInvert
11121118 | NotUnique -> Invertible NoUniqueProjection
11131119
1114 let invert_arg evd aliases k evk subst_in_env_extended_with_k_binders c_in_env_extended_with_k_binders =
1120 let invert_arg fullenv evd aliases k evk subst_in_env_extended_with_k_binders c_in_env_extended_with_k_binders =
11151121 let res = invert_arg_from_subst evd aliases k subst_in_env_extended_with_k_binders c_in_env_extended_with_k_binders in
11161122 match res with
1117 | Invertible (UniqueProjection (c,_)) when not (noccur_evar evd evk c) ->
1123 | Invertible (UniqueProjection (c,_)) when not (noccur_evar fullenv evd evk c)
1124 ->
11181125 CannotInvert
11191126 | _ ->
11201127 res
11521159
11531160 let filter_of_projection = function Invertible _ -> true | _ -> false
11541161
1155 let invert_invertible_arg evd aliases k (evk,argsv) args' =
1162 let invert_invertible_arg fullenv evd aliases k (evk,argsv) args' =
11561163 let evi = Evd.find_undefined evd evk in
11571164 let subst,_ = make_projectable_subst aliases evd evi argsv in
1158 let projs = array_map_to_list (invert_arg evd aliases k evk subst) args' in
1165 let projs =
1166 array_map_to_list (invert_arg fullenv evd aliases k evk subst) args' in
11591167 Array.of_list (extract_unique_projections projs)
11601168
11611169 (* Redefines an evar with a smaller context (i.e. it may depend on less
13631371
13641372 let ensure_evar_independent g env evd (evk1,argsv1 as ev1) (evk2,argsv2 as ev2)=
13651373 let filter1 =
1366 restrict_upon_filter evd evk1 (noccur_evar evd evk2) (Array.to_list argsv1)
1374 restrict_upon_filter evd evk1 (noccur_evar env evd evk2)
1375 (Array.to_list argsv1)
13671376 in
13681377 let candidates1 = restrict_candidates g env evd filter1 ev1 ev2 in
13691378 let evd,(evk1,_ as ev1) = do_restrict_hyps evd ev1 filter1 candidates1 in
13701379 let filter2 =
1371 restrict_upon_filter evd evk2 (noccur_evar evd evk1) (Array.to_list argsv2)
1380 restrict_upon_filter evd evk2 (noccur_evar env evd evk1)
1381 (Array.to_list argsv2)
13721382 in
13731383 let candidates2 = restrict_candidates g env evd filter2 ev2 ev1 in
13741384 let evd,ev2 = do_restrict_hyps evd ev2 filter2 candidates2 in
13881398 try
13891399 let candidates1 = restrict_candidates g env evd filter1 ev1 ev2 in
13901400 let evd,(evk1',args1) = do_restrict_hyps evd ev1 filter1 candidates1 in
1391 evd,mkEvar (evk1',invert_invertible_arg evd aliases k2 ev2 args1)
1401 evd,mkEvar (evk1',invert_invertible_arg env evd aliases k2 ev2 args1)
13921402 with
13931403 | EvarSolvedWhileRestricting (evd,ev1) ->
13941404 raise (EvarSolvedOnTheFly (evd,ev1))
15841594 let aliases = lift_aliases k aliases in
15851595 (try
15861596 let ev = (evk,Array.map (lift k) argsv) in
1587 let evd,body = project_evar_on_evar conv_algo env !evdref aliases k ev' ev in
1597 let evd,body = project_evar_on_evar conv_algo env' !evdref aliases k ev' ev in
15881598 evdref := evd;
15891599 body
15901600 with
345345 | GHole (loc,_) -> PatVar (loc,na)
346346 | GRef (loc,ConstructRef cstr) ->
347347 PatCstr (loc,cstr,[],na)
348 | GApp (loc,GRef (_,ConstructRef cstr),l) ->
349 PatCstr (loc,cstr,List.map (cases_pattern_of_glob_constr Anonymous) l,na)
348 | GApp (loc,GRef (_,ConstructRef (ind,_ as cstr)),args) ->
349 let mib,_ = Global.lookup_inductive ind in
350 let nparams = mib.Declarations.mind_nparams in
351 if nparams > List.length args then
352 user_err_loc (loc,"",Pp.str "Invalid notation for pattern.");
353 let params,args = list_chop nparams args in
354 List.iter (function GHole _ -> ()
355 | _ -> user_err_loc (loc,"",Pp.str"Invalid notation for pattern."))
356 params;
357 let args = List.map (cases_pattern_of_glob_constr Anonymous) args in
358 PatCstr (loc,cstr,args,na)
359 | _ -> raise Not_found
360
361 let rec cases_pattern_of_glob_constr na = function
362 | GVar (loc,id) when na<>Anonymous ->
363 (* Unable to manage the presence of both an alias and a variable *)
364 raise Not_found
365 | GVar (loc,id) -> PatVar (loc,Name id)
366 | GHole (loc,_) -> PatVar (loc,na)
367 | GRef (loc,ConstructRef cstr) ->
368 PatCstr (loc,cstr,[],na)
369 | GApp (loc,GRef (_,ConstructRef (ind,_ as cstr)),args) ->
370 let mib,_ = Global.lookup_inductive ind in
371 let nparams = mib.Declarations.mind_nparams in
372 if nparams > List.length args then
373 user_err_loc (loc,"",Pp.str "Invalid notation for pattern.");
374 let params,args = list_chop nparams args in
375 List.iter (function GHole _ -> ()
376 | _ -> user_err_loc (loc,"",Pp.str"Invalid notation for pattern."))
377 params;
378 let args = List.map (cases_pattern_of_glob_constr Anonymous) args in
379 PatCstr (loc,cstr,args,na)
350380 | _ -> raise Not_found
351381
352382 (* Turn a closed cases pattern into a glob_constr *)
4040 let (evd,s) = Evarutil.define_evar_as_sort !evdref ev in
4141 evdref := evd; { utj_val = j.uj_val; utj_type = s }
4242 | _ -> error_not_type env j
43
44 let e_assumption_of_judgment env evdref j =
45 try (e_type_judgment env evdref j).utj_val
46 with TypeError _ ->
47 error_assumption env j
4348
4449 let e_judge_of_apply env evdref funj argjv =
4550 let rec apply_rec n typ = function
149154 | Evar ev ->
150155 let ty = Evd.existential_type !evdref ev in
151156 let jty = execute env evdref (whd_evar !evdref ty) in
152 let jty = assumption_of_judgment env jty in
157 let jty = e_assumption_of_judgment env evdref jty in
153158 { uj_val = cstr; uj_type = jty }
154159
155160 | Rel n ->
242247
243248 and execute_recdef env evdref (names,lar,vdef) =
244249 let larj = execute_array env evdref lar in
245 let lara = Array.map (assumption_of_judgment env) larj in
250 let lara = Array.map (e_assumption_of_judgment env evdref) larj in
246251 let env1 = push_rec_types (names,lara,vdef) env in
247252 let vdefj = execute_array env1 evdref vdef in
248253 let vdefv = Array.map j_val vdefj in
197197 (* (and activated for apply, rewrite but not auto since Feb 2008 for 8.2) *)
198198
199199 modulo_delta : Names.transparent_state;
200 (* This controls which constant are unfoldable; this is on for apply *)
200 (* This controls which constants are unfoldable; this is on for apply *)
201201 (* (but not simple apply) since Feb 2008 for 8.2 *)
202202
203203 modulo_delta_types : Names.transparent_state;
204
205 modulo_delta_in_merge : Names.transparent_state option;
206 (* This controls whether unfoldability is different when trying to unify *)
207 (* several instances of the same metavariable *)
208 (* Typical situation is when we give a pattern to be matched *)
209 (* syntactically against a subterm but we want the metas of the *)
210 (* pattern to be modulo convertibility *)
204211
205212 check_applied_meta_types : bool;
206213 (* This controls whether meta's applied to arguments have their *)
239246 }
240247
241248 (* Default flag for unifying a type against a type (e.g. apply) *)
242 (* We set all conversion flags *)
249 (* We set all conversion flags (no flag should be modified anymore) *)
243250 let default_unify_flags = {
244251 modulo_conv_on_closed_terms = Some full_transparent_state;
245252 use_metas_eagerly_in_conv_on_closed_terms = true;
246253 modulo_delta = full_transparent_state;
247254 modulo_delta_types = full_transparent_state;
255 modulo_delta_in_merge = None;
248256 check_applied_meta_types = true;
249257 resolve_evars = false;
250258 use_pattern_unification = true;
257265 (* in fact useless when not used in w_unify_to_subterm_list *)
258266 }
259267
268 let set_merge_flags flags =
269 match flags.modulo_delta_in_merge with
270 | None -> flags
271 | Some ts ->
272 { flags with modulo_delta = ts; modulo_conv_on_closed_terms = Some ts }
273
260274 (* Default flag for the "simple apply" version of unification of a *)
261275 (* type against a type (e.g. apply) *)
262276 (* We set only the flags available at the time the new "apply" extends *)
263277 (* out of "simple apply" *)
264 let default_no_delta_unify_flags = {
265 modulo_conv_on_closed_terms = Some full_transparent_state;
266 use_metas_eagerly_in_conv_on_closed_terms = true;
278 let default_no_delta_unify_flags = { default_unify_flags with
267279 modulo_delta = empty_transparent_state;
268 modulo_delta_types = full_transparent_state;
269280 check_applied_meta_types = false;
270 resolve_evars = false;
271281 use_pattern_unification = false;
272282 use_meta_bound_pattern_unification = true;
273 frozen_evars = ExistentialSet.empty;
274 restrict_conv_on_strict_subterms = false;
275283 modulo_betaiota = false;
276 modulo_eta = true;
277 allow_K_in_toplevel_higher_order_unification = false
278284 }
279285
280286 (* Default flags for looking for subterms in elimination tactics *)
282288 (* allow_K) because only closed terms are involved in *)
283289 (* induction/destruct/case/elim and w_unify_to_subterm_list does not *)
284290 (* call w_unify for induction/destruct/case/elim (13/6/2011) *)
285 let elim_flags = {
286 modulo_conv_on_closed_terms = Some full_transparent_state;
287 use_metas_eagerly_in_conv_on_closed_terms = true;
288 modulo_delta = full_transparent_state;
289 modulo_delta_types = full_transparent_state;
290 check_applied_meta_types = true;
291 resolve_evars = false;
292 use_pattern_unification = true;
293 use_meta_bound_pattern_unification = true;
294 frozen_evars = ExistentialSet.empty;
291 let elim_flags = { default_unify_flags with
295292 restrict_conv_on_strict_subterms = false; (* ? *)
296293 modulo_betaiota = false;
297 modulo_eta = true;
298294 allow_K_in_toplevel_higher_order_unification = true
299295 }
300296
301 let elim_no_delta_flags = {
302 modulo_conv_on_closed_terms = Some full_transparent_state;
303 use_metas_eagerly_in_conv_on_closed_terms = true;
297 let elim_no_delta_flags = { elim_flags with
304298 modulo_delta = empty_transparent_state;
305 modulo_delta_types = full_transparent_state;
306299 check_applied_meta_types = false;
307 resolve_evars = false;
308300 use_pattern_unification = false;
309 use_meta_bound_pattern_unification = true;
310 frozen_evars = ExistentialSet.empty;
311 restrict_conv_on_strict_subterms = false; (* ? *)
312 modulo_betaiota = false;
313 modulo_eta = true;
314 allow_K_in_toplevel_higher_order_unification = true
315301 }
316302
317303 let set_no_head_reduction flags =
864850 if Evd.is_defined evd evk then
865851 let v = Evd.existential_value evd ev in
866852 let (evd,metas',evars'') =
867 unify_0 curenv evd CONV flags rhs v in
853 unify_0 curenv evd CONV (set_merge_flags flags) rhs v in
868854 w_merge_rec evd (metas'@metas) (evars''@evars') eqns
869855 else begin
870856 (* This can make rhs' ill-typed if metas are *)
942928 let sp_env = Global.env_of_context ev.evar_hyps in
943929 let (evd', c) = applyHead sp_env evd nargs hdc in
944930 let (evd'',mc,ec) =
945 unify_0 sp_env evd' CUMUL flags
931 unify_0 sp_env evd' CUMUL (set_merge_flags flags)
946932 (get_type_of sp_env evd' c) ev.evar_concl in
947933 let evd''' = w_merge_rec evd'' mc ec [] in
948934 if evd' == evd'''
1414 use_metas_eagerly_in_conv_on_closed_terms : bool;
1515 modulo_delta : Names.transparent_state;
1616 modulo_delta_types : Names.transparent_state;
17 modulo_delta_in_merge : Names.transparent_state option;
1718 check_applied_meta_types : bool;
1819 resolve_evars : bool;
1920 use_pattern_unification : bool;
104104 use_metas_eagerly_in_conv_on_closed_terms = false;
105105 modulo_delta = empty_transparent_state;
106106 modulo_delta_types = full_transparent_state;
107 modulo_delta_in_merge = None;
107108 check_applied_meta_types = false;
108109 resolve_evars = false;
109110 use_pattern_unification = false;
6161
6262 let start_proof id str hyps c ?init_tac ?compute_guard hook =
6363 let goals = [ (Global.env_of_context hyps , c) ] in
64 let init_tac = Option.map Proofview.V82.tactic init_tac in
6564 Proof_global.start_proof id str goals ?compute_guard hook;
66 try Option.iter Proof_global.run_tactic init_tac
65 let tac = match init_tac with
66 | Some tac -> Proofview.V82.tactic tac
67 | None -> Proofview.tclUNIT ()
68 in
69 try Proof_global.run_tactic tac
6770 with e -> Proof_global.discard_current (); raise e
6871
6972 let restart_proof () = undo_todepth 1
6262
6363 let is_ocaml4 = Coq_config.caml_version.[0] <> '3'
6464
65 (* Since the .cma are given with their relative paths (e.g. "lib/clib.cma"),
66 we only need to include directories mentionned in the temp main ml file
67 below (for accessing the corresponding .cmi). *)
68
6569 let src_dirs =
66 [ []; ["kernel";"byterun"]; [ "config" ]; [ "toplevel" ] ]
70 [ []; ["lib"]; ["toplevel"]; ["kernel";"byterun"]; ]
6771
6872 let includes () =
69 (if !Flags.boot then [] (* the include flags are given on the cmdline *)
70 else
71 let coqlib = Envars.coqlib () in
72 let mkdir d = "\"" ^ List.fold_left Filename.concat coqlib d ^ "\"" in
73 let camlp4incl = ["-I"; "\"" ^ Envars.camlp4lib () ^ "\""] in
74 List.fold_right (fun d l -> "-I" :: mkdir d :: l) src_dirs camlp4incl)
73 let coqlib = if !Flags.boot then "." else Envars.coqlib () in
74 let mkdir d = "\"" ^ List.fold_left Filename.concat coqlib d ^ "\"" in
75 (List.fold_right (fun d l -> "-I" :: mkdir d :: l) src_dirs [])
76 @ ["-I"; "\"" ^ Envars.camlp4lib () ^ "\""]
7577 @ (if is_ocaml4 then ["-I"; "+compiler-libs"] else [])
7678
7779 (* Transform bytecode object file names in native object file names *)
241243
242244 (* create a temporary main file to link *)
243245 let create_tmp_main_file modules =
244 let main_name = Filename.temp_file "coqmain" ".ml" in
245 let oc = open_out main_name in
246 let main_name,oc = Filename.open_temp_file "coqmain" ".ml" in
246247 try
247248 (* Add the pre-linked modules *)
248249 output_string oc "List.iter Mltop.add_known_module [\"";
289290 []
290291 in
291292 (* the list of the loaded modules *)
292 let main_file = Filename.quote (create_tmp_main_file modules) in
293 let main_file = create_tmp_main_file modules in
293294 try
294 let args =
295 options @ (includes ()) @ copts @ tolink @ dynlink @ [ main_file ] in
295 let args = options @ includes () @ copts @ tolink @ dynlink in
296 let args = args @ [ Filename.quote main_file ] in
296297 (* add topstart.cmo explicitly because we shunted ocamlmktop wrapper *)
297298 let args = if !top then args @ [ "topstart.cmo" ] else args in
298299 (* Now, with the .cma, we MUST use the -linkall option *)
10191019 use_metas_eagerly_in_conv_on_closed_terms = false;
10201020 modulo_delta = empty_transparent_state;
10211021 modulo_delta_types = full_transparent_state;
1022 modulo_delta_in_merge = None;
10221023 check_applied_meta_types = false;
10231024 resolve_evars = true;
10241025 use_pattern_unification = false;
7676 use_metas_eagerly_in_conv_on_closed_terms = true;
7777 modulo_delta = var_full_transparent_state;
7878 modulo_delta_types = full_transparent_state;
79 modulo_delta_in_merge = None;
7980 check_applied_meta_types = false;
8081 resolve_evars = false;
8182 use_pattern_unification = true;
8686 Unification.use_metas_eagerly_in_conv_on_closed_terms = true;
8787 Unification.modulo_delta = empty_transparent_state;
8888 Unification.modulo_delta_types = empty_transparent_state;
89 Unification.modulo_delta_in_merge = None;
8990 Unification.check_applied_meta_types = true;
9091 Unification.resolve_evars = true;
9192 Unification.use_pattern_unification = true;
154155
155156 Unification.modulo_delta = empty_transparent_state;
156157 Unification.modulo_delta_types = full_transparent_state;
158 Unification.modulo_delta_in_merge = None;
157159 Unification.check_applied_meta_types = true;
158160 Unification.resolve_evars = false;
159161 Unification.use_pattern_unification = true;
193193 | None,false -> str "in" ++ spc () ++ str "*" ++ spc () ++ str "|-"
194194 | Some l,_ ->
195195 str "in" ++
196 Util.prlist (fun id -> spc () ++ pr_id id) l ++
196 spc () ++ Util.prlist_with_sep Util.pr_comma pr_id l ++
197197 match concl with
198198 | true -> spc () ++ str "|-" ++ spc () ++ str "*"
199199 | _ -> mt ()
150150 | Ind ind ->
151151 let car = mis_constr_nargs ind in
152152 let (mib,mip) = Global.lookup_inductive ind in
153 if array_for_all (fun ar -> ar = 1) car &&
154 not (mis_is_recursive (ind,mib,mip))
153 if array_for_all (fun ar -> ar = 1) car
154 && not (mis_is_recursive (ind,mib,mip))
155 && (mip.mind_nrealargs = 0)
155156 then
156157 if strict then
157158 if test_strict_disjunction mib.mind_nparams mip.mind_nf_lc then
293293 Unification.use_metas_eagerly_in_conv_on_closed_terms = true;
294294 Unification.modulo_delta = empty_transparent_state;
295295 Unification.modulo_delta_types = full_transparent_state;
296 Unification.modulo_delta_in_merge = None;
296297 Unification.check_applied_meta_types = true;
297298 Unification.resolve_evars = true;
298299 Unification.use_pattern_unification = true;
304305 Unification.allow_K_in_toplevel_higher_order_unification = true
305306 }
306307
307 let rewrite2_unif_flags =
308 let rewrite2_unif_flags =
308309 { Unification.modulo_conv_on_closed_terms = Some conv_transparent_state;
309310 Unification.use_metas_eagerly_in_conv_on_closed_terms = true;
310311 Unification.modulo_delta = empty_transparent_state;
311312 Unification.modulo_delta_types = conv_transparent_state;
313 Unification.modulo_delta_in_merge = None;
312314 Unification.check_applied_meta_types = true;
313315 Unification.resolve_evars = true;
314316 Unification.use_pattern_unification = true;
326328 Unification.use_metas_eagerly_in_conv_on_closed_terms = true;
327329 Unification.modulo_delta = ts;
328330 Unification.modulo_delta_types = ts;
331 Unification.modulo_delta_in_merge = None;
329332 Unification.check_applied_meta_types = true;
330333 Unification.resolve_evars = true;
331334 Unification.use_pattern_unification = true;
16891689 use_metas_eagerly_in_conv_on_closed_terms = false;
16901690 modulo_delta = empty_transparent_state;
16911691 modulo_delta_types = full_transparent_state;
1692 modulo_delta_in_merge = Some full_transparent_state;
16921693 check_applied_meta_types = true;
16931694 resolve_evars = false;
16941695 use_pattern_unification = false;
126126 : nat
127127 fun _ : nat => 9
128128 : nat -> nat
129 Identifier 'ONE' now a keyword
130 fun (x : nat) (p : x = x) => match p with
131 | ONE => ONE
132 end = p
133 : forall x : nat, x = x -> Prop
134 fun (x : nat) (p : x = x) => match p with
135 | 1 => 1
136 end = p
137 : forall x : nat, x = x -> Prop
261261
262262 Check (foo 9).
263263 Check (fun _ : nat => 9).
264
265 (* Checking parsing and printing of numerical and non-numerical notations for eq_refl *)
266
267 (* This notation was not correctly printed until Pierre B.'s
268 improvements to the interpretation of patterns *)
269
270 Notation "'ONE'" := eq_refl.
271 Check fun (x:nat) (p : x=x) => match p with ONE => ONE end = p.
272
273 (* This one used to failed at parsing until now *)
274
275 Notation "1" := eq_refl.
276 Check fun (x:nat) (p : x=x) => match p with 1 => 1 end = p.
18641864 | Z0 => true
18651865 | _ => false
18661866 end).
1867
1868 (* Check that types with unknown sort, as A below, are not fatal to
1869 the pattern-matching compilation *)
1870
1871 Definition transport {A} (P : A->Type) {x y : A} (p : x=y) (u : P x) : P y :=
1872 match p with eq_refl => u end.
0 (* This used to fail in 8.0pl1 *)
1
02 Goal forall n, n+n=0->0=n+n.
13 intros.
4 set n in * |-.
5 Abort.
26
3 (* This used to fail in 8.0pl1 *)
4 set n in * |-.
7 (* This works from 8.4pl1, since merging of different instances of the
8 same metavariable in a pattern is done modulo conversion *)
9
10 Notation "p .+1" := (S p) (at level 1, left associativity, format "p .+1").
11
12 Goal forall (f:forall n, n=0 -> Prop) n (H:(n+n).+1=0), f (n.+1+n) H.
13 intros.
14 set (f _ _).
15 Abort.
516
617
718
3434 Local Open Scope pair_scope.
3535 Local Open Scope lazy_bool_scope.
3636 Local Open Scope Int_scope.
37 Local Notation int := I.t.
3738
3839 Definition key := X.t.
3940 Hint Transparent key.
4343
4444 Module Ops (Import I:Int)(X:OrderedType) <: MSetInterface.Ops X.
4545 Local Open Scope Int_scope.
46 Local Notation int := I.t.
4647
4748 (** ** Generic trees instantiated with integer height *)
4849
146146 Definition le_lteq := lt_eq_cases.
147147
148148 Module Private_OrderTac.
149 Module Elts <: TotalOrder.
150 Definition t := t.
151 Definition eq := eq.
152 Definition lt := lt.
153 Definition le := le.
149 Module IsTotal.
154150 Definition eq_equiv := eq_equiv.
155151 Definition lt_strorder := lt_strorder.
156152 Definition lt_compat := lt_compat.
157153 Definition lt_total := lt_total.
158154 Definition le_lteq := le_lteq.
159 End Elts.
160 Module Tac := !MakeOrderTac Elts.
155 End IsTotal.
156 Module Tac := !MakeOrderTac NZ IsTotal.
161157 End Private_OrderTac.
162158 Ltac order := Private_OrderTac.Tac.order.
163159
4141 Bind Scope bigQ_scope with t t_.
4242 Include !QProperties <+ HasEqBool2Dec
4343 <+ !MinMaxLogicalProperties <+ !MinMaxDecProperties.
44 Ltac order := Private_Tac.order.
4445 End BigQ.
4546
4647 (** Notations about [BigQ] *)
143144
144145 (** [BigQ] can also benefit from an "order" tactic *)
145146
146 Module BigQ_Order := !OrdersTac.MakeOrderTac BigQ.
147 Ltac bigQ_order := BigQ_Order.order.
147 Ltac bigQ_order := BigQ.order.
148148
149149 Section TestOrder.
150150 Let test : forall x y : bigQ, x<=y -> y<=x -> x==y.
14841484 (** We hence obtain all the generic properties of [min] and [max]. *)
14851485
14861486 Include UsualMinMaxLogicalProperties <+ UsualMinMaxDecProperties.
1487
1488 Ltac order := Private_Tac.order.
14871489
14881490 (** Minimum, maximum and constant one *)
14891491
3939 Definition max := gmax O.compare.
4040 Definition min := gmin O.compare.
4141
42 Lemma ge_not_lt : forall x y, y<=x -> x<y -> False.
42 Lemma ge_not_lt x y : y<=x -> x<y -> False.
4343 Proof.
44 intros x y H H'.
44 intros H H'.
4545 apply (StrictOrder_Irreflexive x).
4646 rewrite le_lteq in *; destruct H as [H|H].
4747 transitivity y; auto.
4848 rewrite H in H'; auto.
4949 Qed.
5050
51 Lemma max_l : forall x y, y<=x -> max x y == x.
51 Lemma max_l x y : y<=x -> max x y == x.
5252 Proof.
5353 intros. unfold max, gmax. case compare_spec; auto with relations.
5454 intros; elim (ge_not_lt x y); auto.
5555 Qed.
5656
57 Lemma max_r : forall x y, x<=y -> max x y == y.
57 Lemma max_r x y : x<=y -> max x y == y.
5858 Proof.
5959 intros. unfold max, gmax. case compare_spec; auto with relations.
6060 intros; elim (ge_not_lt y x); auto.
6161 Qed.
6262
63 Lemma min_l : forall x y, x<=y -> min x y == x.
63 Lemma min_l x y : x<=y -> min x y == x.
6464 Proof.
6565 intros. unfold min, gmin. case compare_spec; auto with relations.
6666 intros; elim (ge_not_lt y x); auto.
6767 Qed.
6868
69 Lemma min_r : forall x y, y<=x -> min x y == y.
69 Lemma min_r x y : y<=x -> min x y == y.
7070 Proof.
7171 intros. unfold min, gmin. case compare_spec; auto with relations.
7272 intros; elim (ge_not_lt x y); auto.
7575 End GenericMinMax.
7676
7777
78 (** ** Consequences of the minimalist interface: facts about [max]. *)
79
80 Module MaxLogicalProperties (Import O:TotalOrder')(Import M:HasMax O).
81 Module Import Private_Tac := !MakeOrderTac O.
78 (** ** Consequences of the minimalist interface: facts about [max] and [min]. *)
79
80 Module MinMaxLogicalProperties (Import O:TotalOrder')(Import M:HasMinMax O).
81 Module Import Private_Tac := !MakeOrderTac O O.
8282
8383 (** An alternative caracterisation of [max], equivalent to
8484 [max_l /\ max_r] *)
8585
86 Lemma max_spec : forall n m,
87 (n < m /\ max n m == m) \/ (m <= n /\ max n m == n).
88 Proof.
89 intros n m.
86 Lemma max_spec n m :
87 (n < m /\ max n m == m) \/ (m <= n /\ max n m == n).
88 Proof.
9089 destruct (lt_total n m); [left|right].
91 split; auto. apply max_r. rewrite le_lteq; auto.
92 assert (m <= n) by (rewrite le_lteq; intuition).
93 split; auto. apply max_l; auto.
90 - split; auto. apply max_r. rewrite le_lteq; auto.
91 - assert (m <= n) by (rewrite le_lteq; intuition).
92 split; auto. now apply max_l.
9493 Qed.
9594
9695 (** A more symmetric version of [max_spec], based only on [le].
9796 Beware that left and right alternatives overlap. *)
9897
99 Lemma max_spec_le : forall n m,
98 Lemma max_spec_le n m :
10099 (n <= m /\ max n m == m) \/ (m <= n /\ max n m == n).
101100 Proof.
102 intros. destruct (max_spec n m); [left|right]; intuition; order.
101 destruct (max_spec n m); [left|right]; intuition; order.
103102 Qed.
104103
105104 Instance : Proper (eq==>eq==>iff) le.
107106
108107 Instance max_compat : Proper (eq==>eq==>eq) max.
109108 Proof.
110 intros x x' Hx y y' Hy.
111 assert (H1 := max_spec x y). assert (H2 := max_spec x' y').
112 set (m := max x y) in *; set (m' := max x' y') in *; clearbody m m'.
113 rewrite <- Hx, <- Hy in *.
114 destruct (lt_total x y); intuition order.
115 Qed.
116
109 intros x x' Hx y y' Hy.
110 assert (H1 := max_spec x y). assert (H2 := max_spec x' y').
111 set (m := max x y) in *; set (m' := max x' y') in *; clearbody m m'.
112 rewrite <- Hx, <- Hy in *.
113 destruct (lt_total x y); intuition order.
114 Qed.
117115
118116 (** A function satisfying the same specification is equal to [max]. *)
119117
120 Lemma max_unicity : forall n m p,
121 ((n < m /\ p == m) \/ (m <= n /\ p == n)) -> p == max n m.
122 Proof.
123 intros. assert (Hm := max_spec n m).
118 Lemma max_unicity n m p :
119 ((n < m /\ p == m) \/ (m <= n /\ p == n)) -> p == max n m.
120 Proof.
121 assert (Hm := max_spec n m).
124122 destruct (lt_total n m); intuition; order.
125123 Qed.
126124
127 Lemma max_unicity_ext : forall f,
128 (forall n m, (n < m /\ f n m == m) \/ (m <= n /\ f n m == n)) ->
125 Lemma max_unicity_ext f :
126 (forall n m, (n < m /\ f n m == m) \/ (m <= n /\ f n m == n)) ->
129127 (forall n m, f n m == max n m).
130128 Proof.
131129 intros. apply max_unicity; auto.
133131
134132 (** [max] commutes with monotone functions. *)
135133
136 Lemma max_mono: forall f,
134 Lemma max_mono f :
137135 (Proper (eq ==> eq) f) ->
138136 (Proper (le ==> le) f) ->
139137 forall x y, max (f x) (f y) == f (max x y).
140138 Proof.
141 intros f Eqf Lef x y.
139 intros Eqf Lef x y.
142140 destruct (max_spec x y) as [(H,E)|(H,E)]; rewrite E;
143141 destruct (max_spec (f x) (f y)) as [(H',E')|(H',E')]; auto.
144142 assert (f x <= f y) by (apply Lef; order). order.
147145
148146 (** *** Semi-lattice algebraic properties of [max] *)
149147
150 Lemma max_id : forall n, max n n == n.
151 Proof.
152 intros. destruct (max_spec n n); intuition.
148 Lemma max_id n : max n n == n.
149 Proof.
150 apply max_l; order.
153151 Qed.
154152
155153 Notation max_idempotent := max_id (only parsing).
156154
157 Lemma max_assoc : forall m n p, max m (max n p) == max (max m n) p.
158 Proof.
159 intros.
160 destruct (max_spec n p) as [(H,Eq)|(H,Eq)]; rewrite Eq.
161 destruct (max_spec m n) as [(H',Eq')|(H',Eq')]; rewrite Eq'.
162 destruct (max_spec m p); intuition; order. order.
163 destruct (max_spec m n) as [(H',Eq')|(H',Eq')]; rewrite Eq'. order.
164 destruct (max_spec m p); intuition; order.
165 Qed.
166
167 Lemma max_comm : forall n m, max n m == max m n.
168 Proof.
169 intros.
170 destruct (max_spec n m) as [(H,Eq)|(H,Eq)]; rewrite Eq.
171 destruct (max_spec m n) as [(H',Eq')|(H',Eq')]; rewrite Eq'; order.
172 destruct (max_spec m n) as [(H',Eq')|(H',Eq')]; rewrite Eq'; order.
173 Qed.
155 Lemma max_assoc m n p : max m (max n p) == max (max m n) p.
156 Proof.
157 destruct (max_spec n p) as [(H,E)|(H,E)]; rewrite E;
158 destruct (max_spec m n) as [(H',E')|(H',E')]; rewrite E', ?E; try easy.
159 - apply max_r; order.
160 - symmetry. apply max_l; order.
161 Qed.
162
163 Lemma max_comm n m : max n m == max m n.
164 Proof.
165 destruct (max_spec m n) as [(H,E)|(H,E)]; rewrite E;
166 (apply max_r || apply max_l); order.
167 Qed.
168
169 Ltac solve_max :=
170 match goal with |- context [max ?n ?m] =>
171 destruct (max_spec n m); intuition; order
172 end.
174173
175174 (** *** Least-upper bound properties of [max] *)
176175
177 Lemma le_max_l : forall n m, n <= max n m.
178 Proof.
179 intros; destruct (max_spec n m); intuition; order.
180 Qed.
181
182 Lemma le_max_r : forall n m, m <= max n m.
183 Proof.
184 intros; destruct (max_spec n m); intuition; order.
185 Qed.
186
187 Lemma max_l_iff : forall n m, max n m == n <-> m <= n.
188 Proof.
189 split. intro H; rewrite <- H. apply le_max_r. apply max_l.
190 Qed.
191
192 Lemma max_r_iff : forall n m, max n m == m <-> n <= m.
193 Proof.
194 split. intro H; rewrite <- H. apply le_max_l. apply max_r.
195 Qed.
196
197 Lemma max_le : forall n m p, p <= max n m -> p <= n \/ p <= m.
198 Proof.
199 intros n m p H; destruct (max_spec n m);
200 [right|left]; intuition; order.
201 Qed.
202
203 Lemma max_le_iff : forall n m p, p <= max n m <-> p <= n \/ p <= m.
204 Proof.
205 intros. split. apply max_le.
206 destruct (max_spec n m); intuition; order.
207 Qed.
208
209 Lemma max_lt_iff : forall n m p, p < max n m <-> p < n \/ p < m.
210 Proof.
211 intros. destruct (max_spec n m); intuition;
176 Lemma le_max_l n m : n <= max n m.
177 Proof. solve_max. Qed.
178
179 Lemma le_max_r n m : m <= max n m.
180 Proof. solve_max. Qed.
181
182 Lemma max_l_iff n m : max n m == n <-> m <= n.
183 Proof. solve_max. Qed.
184
185 Lemma max_r_iff n m : max n m == m <-> n <= m.
186 Proof. solve_max. Qed.
187
188 Lemma max_le n m p : p <= max n m -> p <= n \/ p <= m.
189 Proof.
190 destruct (max_spec n m); [right|left]; intuition; order.
191 Qed.
192
193 Lemma max_le_iff n m p : p <= max n m <-> p <= n \/ p <= m.
194 Proof. split. apply max_le. solve_max. Qed.
195
196 Lemma max_lt_iff n m p : p < max n m <-> p < n \/ p < m.
197 Proof.
198 destruct (max_spec n m); intuition;
212199 order || (right; order) || (left; order).
213200 Qed.
214201
215 Lemma max_lub_l : forall n m p, max n m <= p -> n <= p.
216 Proof.
217 intros; destruct (max_spec n m); intuition; order.
218 Qed.
219
220 Lemma max_lub_r : forall n m p, max n m <= p -> m <= p.
221 Proof.
222 intros; destruct (max_spec n m); intuition; order.
223 Qed.
224
225 Lemma max_lub : forall n m p, n <= p -> m <= p -> max n m <= p.
226 Proof.
227 intros; destruct (max_spec n m); intuition; order.
228 Qed.
229
230 Lemma max_lub_iff : forall n m p, max n m <= p <-> n <= p /\ m <= p.
231 Proof.
232 intros; destruct (max_spec n m); intuition; order.
233 Qed.
234
235 Lemma max_lub_lt : forall n m p, n < p -> m < p -> max n m < p.
236 Proof.
237 intros; destruct (max_spec n m); intuition; order.
238 Qed.
239
240 Lemma max_lub_lt_iff : forall n m p, max n m < p <-> n < p /\ m < p.
241 Proof.
242 intros; destruct (max_spec n m); intuition; order.
243 Qed.
244
245 Lemma max_le_compat_l : forall n m p, n <= m -> max p n <= max p m.
246 Proof.
247 intros.
248 destruct (max_spec p n) as [(LT,E)|(LE,E)]; rewrite E.
249 assert (LE' := le_max_r p m). order.
250 apply le_max_l.
251 Qed.
252
253 Lemma max_le_compat_r : forall n m p, n <= m -> max n p <= max m p.
254 Proof.
255 intros. rewrite (max_comm n p), (max_comm m p).
256 auto using max_le_compat_l.
257 Qed.
258
259 Lemma max_le_compat : forall n m p q, n <= m -> p <= q ->
260 max n p <= max m q.
261 Proof.
262 intros n m p q Hnm Hpq.
202 Lemma max_lub_l n m p : max n m <= p -> n <= p.
203 Proof. solve_max. Qed.
204
205 Lemma max_lub_r n m p : max n m <= p -> m <= p.
206 Proof. solve_max. Qed.
207
208 Lemma max_lub n m p : n <= p -> m <= p -> max n m <= p.
209 Proof. solve_max. Qed.
210
211 Lemma max_lub_iff n m p : max n m <= p <-> n <= p /\ m <= p.
212 Proof. solve_max. Qed.
213
214 Lemma max_lub_lt n m p : n < p -> m < p -> max n m < p.
215 Proof. solve_max. Qed.
216
217 Lemma max_lub_lt_iff n m p : max n m < p <-> n < p /\ m < p.
218 Proof. solve_max. Qed.
219
220 Lemma max_le_compat_l n m p : n <= m -> max p n <= max p m.
221 Proof. intros. apply max_lub_iff. solve_max. Qed.
222
223 Lemma max_le_compat_r n m p : n <= m -> max n p <= max m p.
224 Proof. intros. apply max_lub_iff. solve_max. Qed.
225
226 Lemma max_le_compat n m p q : n <= m -> p <= q -> max n p <= max m q.
227 Proof.
228 intros Hnm Hpq.
263229 assert (LE := max_le_compat_l _ _ m Hpq).
264230 assert (LE' := max_le_compat_r _ _ p Hnm).
265231 order.
266232 Qed.
267233
268 End MaxLogicalProperties.
269
270
271 (** ** Properties concernant [min], then both [min] and [max].
272
273 To avoid too much code duplication, we exploit that [min] can be
274 seen as a [max] of the reversed order.
275 *)
276
277 Module MinMaxLogicalProperties (Import O:TotalOrder')(Import M:HasMinMax O).
278 Include MaxLogicalProperties O M.
279 Import Private_Tac.
280
281 Module Import Private_Rev.
282 Module ORev := TotalOrderRev O.
283 Module MRev <: HasMax ORev.
284 Definition max x y := M.min y x.
285 Definition max_l x y := M.min_r y x.
286 Definition max_r x y := M.min_l y x.
287 End MRev.
288 Module MPRev := MaxLogicalProperties ORev MRev.
289 End Private_Rev.
234 (** Properties of [min] *)
235
236 Lemma min_spec n m :
237 (n < m /\ min n m == n) \/ (m <= n /\ min n m == m).
238 Proof.
239 destruct (lt_total n m); [left|right].
240 - split; auto. apply min_l. rewrite le_lteq; auto.
241 - assert (m <= n) by (rewrite le_lteq; intuition).
242 split; auto. now apply min_r.
243 Qed.
244
245 Lemma min_spec_le n m :
246 (n <= m /\ min n m == n) \/ (m <= n /\ min n m == m).
247 Proof.
248 destruct (min_spec n m); [left|right]; intuition; order.
249 Qed.
290250
291251 Instance min_compat : Proper (eq==>eq==>eq) min.
292 Proof. intros x x' Hx y y' Hy. apply MPRev.max_compat; assumption. Qed.
293
294 Lemma min_spec : forall n m,
295 (n < m /\ min n m == n) \/ (m <= n /\ min n m == m).
296 Proof. intros. exact (MPRev.max_spec m n). Qed.
297
298 Lemma min_spec_le : forall n m,
299 (n <= m /\ min n m == n) \/ (m <= n /\ min n m == m).
300 Proof. intros. exact (MPRev.max_spec_le m n). Qed.
301
302 Lemma min_mono: forall f,
252 Proof.
253 intros x x' Hx y y' Hy.
254 assert (H1 := min_spec x y). assert (H2 := min_spec x' y').
255 set (m := min x y) in *; set (m' := min x' y') in *; clearbody m m'.
256 rewrite <- Hx, <- Hy in *.
257 destruct (lt_total x y); intuition order.
258 Qed.
259
260 Lemma min_unicity n m p :
261 ((n < m /\ p == n) \/ (m <= n /\ p == m)) -> p == min n m.
262 Proof.
263 assert (Hm := min_spec n m).
264 destruct (lt_total n m); intuition; order.
265 Qed.
266
267 Lemma min_unicity_ext f :
268 (forall n m, (n < m /\ f n m == n) \/ (m <= n /\ f n m == m)) ->
269 (forall n m, f n m == min n m).
270 Proof.
271 intros. apply min_unicity; auto.
272 Qed.
273
274 Lemma min_mono f :
303275 (Proper (eq ==> eq) f) ->
304276 (Proper (le ==> le) f) ->
305277 forall x y, min (f x) (f y) == f (min x y).
306278 Proof.
307 intros. apply MPRev.max_mono; auto. compute in *; eauto.
308 Qed.
309
310 Lemma min_unicity : forall n m p,
311 ((n < m /\ p == n) \/ (m <= n /\ p == m)) -> p == min n m.
312 Proof. intros n m p. apply MPRev.max_unicity. Qed.
313
314 Lemma min_unicity_ext : forall f,
315 (forall n m, (n < m /\ f n m == n) \/ (m <= n /\ f n m == m)) ->
316 (forall n m, f n m == min n m).
317 Proof. intros f H n m. apply MPRev.max_unicity, H; auto. Qed.
318
319 Lemma min_id : forall n, min n n == n.
320 Proof. intros. exact (MPRev.max_id n). Qed.
279 intros Eqf Lef x y.
280 destruct (min_spec x y) as [(H,E)|(H,E)]; rewrite E;
281 destruct (min_spec (f x) (f y)) as [(H',E')|(H',E')]; auto.
282 assert (f x <= f y) by (apply Lef; order). order.
283 assert (f y <= f x) by (apply Lef; order). order.
284 Qed.
285
286 Lemma min_id n : min n n == n.
287 Proof.
288 apply min_l; order.
289 Qed.
321290
322291 Notation min_idempotent := min_id (only parsing).
323292
324 Lemma min_assoc : forall m n p, min m (min n p) == min (min m n) p.
325 Proof. intros. symmetry; apply MPRev.max_assoc. Qed.
326
327 Lemma min_comm : forall n m, min n m == min m n.
328 Proof. intros. exact (MPRev.max_comm m n). Qed.
329
330 Lemma le_min_r : forall n m, min n m <= m.
331 Proof. intros. exact (MPRev.le_max_l m n). Qed.
332
333 Lemma le_min_l : forall n m, min n m <= n.
334 Proof. intros. exact (MPRev.le_max_r m n). Qed.
335
336 Lemma min_l_iff : forall n m, min n m == n <-> n <= m.
337 Proof. intros n m. exact (MPRev.max_r_iff m n). Qed.
338
339 Lemma min_r_iff : forall n m, min n m == m <-> m <= n.
340 Proof. intros n m. exact (MPRev.max_l_iff m n). Qed.
341
342 Lemma min_le : forall n m p, min n m <= p -> n <= p \/ m <= p.
343 Proof. intros n m p H. destruct (MPRev.max_le _ _ _ H); auto. Qed.
344
345 Lemma min_le_iff : forall n m p, min n m <= p <-> n <= p \/ m <= p.
346 Proof. intros n m p. rewrite (MPRev.max_le_iff m n p); intuition. Qed.
347
348 Lemma min_lt_iff : forall n m p, min n m < p <-> n < p \/ m < p.
349 Proof. intros n m p. rewrite (MPRev.max_lt_iff m n p); intuition. Qed.
350
351 Lemma min_glb_l : forall n m p, p <= min n m -> p <= n.
352 Proof. intros n m. exact (MPRev.max_lub_r m n). Qed.
353
354 Lemma min_glb_r : forall n m p, p <= min n m -> p <= m.
355 Proof. intros n m. exact (MPRev.max_lub_l m n). Qed.
356
357 Lemma min_glb : forall n m p, p <= n -> p <= m -> p <= min n m.
358 Proof. intros. apply MPRev.max_lub; auto. Qed.
359
360 Lemma min_glb_iff : forall n m p, p <= min n m <-> p <= n /\ p <= m.
361 Proof. intros. rewrite (MPRev.max_lub_iff m n p); intuition. Qed.
362
363 Lemma min_glb_lt : forall n m p, p < n -> p < m -> p < min n m.
364 Proof. intros. apply MPRev.max_lub_lt; auto. Qed.
365
366 Lemma min_glb_lt_iff : forall n m p, p < min n m <-> p < n /\ p < m.
367 Proof. intros. rewrite (MPRev.max_lub_lt_iff m n p); intuition. Qed.
368
369 Lemma min_le_compat_l : forall n m p, n <= m -> min p n <= min p m.
370 Proof. intros n m. exact (MPRev.max_le_compat_r m n). Qed.
371
372 Lemma min_le_compat_r : forall n m p, n <= m -> min n p <= min m p.
373 Proof. intros n m. exact (MPRev.max_le_compat_l m n). Qed.
374
375 Lemma min_le_compat : forall n m p q, n <= m -> p <= q ->
293 Lemma min_assoc m n p : min m (min n p) == min (min m n) p.
294 Proof.
295 destruct (min_spec n p) as [(H,E)|(H,E)]; rewrite E;
296 destruct (min_spec m n) as [(H',E')|(H',E')]; rewrite E', ?E; try easy.
297 - symmetry. apply min_l; order.
298 - apply min_r; order.
299 Qed.
300
301 Lemma min_comm n m : min n m == min m n.
302 Proof.
303 destruct (min_spec m n) as [(H,E)|(H,E)]; rewrite E;
304 (apply min_r || apply min_l); order.
305 Qed.
306
307 Ltac solve_min :=
308 match goal with |- context [min ?n ?m] =>
309 destruct (min_spec n m); intuition; order
310 end.
311
312 Lemma le_min_r n m : min n m <= m.
313 Proof. solve_min. Qed.
314
315 Lemma le_min_l n m : min n m <= n.
316 Proof. solve_min. Qed.
317
318 Lemma min_l_iff n m : min n m == n <-> n <= m.
319 Proof. solve_min. Qed.
320
321 Lemma min_r_iff n m : min n m == m <-> m <= n.
322 Proof. solve_min. Qed.
323
324 Lemma min_le n m p : min n m <= p -> n <= p \/ m <= p.
325 Proof.
326 destruct (min_spec n m); [left|right]; intuition; order.
327 Qed.
328
329 Lemma min_le_iff n m p : min n m <= p <-> n <= p \/ m <= p.
330 Proof. split. apply min_le. solve_min. Qed.
331
332 Lemma min_lt_iff n m p : min n m < p <-> n < p \/ m < p.
333 Proof.
334 destruct (min_spec n m); intuition;
335 order || (right; order) || (left; order).
336 Qed.
337
338 Lemma min_glb_l n m p : p <= min n m -> p <= n.
339 Proof. solve_min. Qed.
340
341 Lemma min_glb_r n m p : p <= min n m -> p <= m.
342 Proof. solve_min. Qed.
343
344 Lemma min_glb n m p : p <= n -> p <= m -> p <= min n m.
345 Proof. solve_min. Qed.
346
347 Lemma min_glb_iff n m p : p <= min n m <-> p <= n /\ p <= m.
348 Proof. solve_min. Qed.
349
350 Lemma min_glb_lt n m p : p < n -> p < m -> p < min n m.
351 Proof. solve_min. Qed.
352
353 Lemma min_glb_lt_iff n m p : p < min n m <-> p < n /\ p < m.
354 Proof. solve_min. Qed.
355
356 Lemma min_le_compat_l n m p : n <= m -> min p n <= min p m.
357 Proof. intros. apply min_glb_iff. solve_min. Qed.
358
359 Lemma min_le_compat_r n m p : n <= m -> min n p <= min m p.
360 Proof. intros. apply min_glb_iff. solve_min. Qed.
361
362 Lemma min_le_compat n m p q : n <= m -> p <= q ->
376363 min n p <= min m q.
377 Proof. intros. apply MPRev.max_le_compat; auto. Qed.
378
364 Proof.
365 intros Hnm Hpq.
366 assert (LE := min_le_compat_l _ _ m Hpq).
367 assert (LE' := min_le_compat_r _ _ p Hnm).
368 order.
369 Qed.
379370
380371 (** *** Combined properties of min and max *)
381372
382 Lemma min_max_absorption : forall n m, max n (min n m) == n.
373 Lemma min_max_absorption n m : max n (min n m) == n.
383374 Proof.
384375 intros.
385376 destruct (min_spec n m) as [(C,E)|(C,E)]; rewrite E.
387378 destruct (max_spec n m); intuition; order.
388379 Qed.
389380
390 Lemma max_min_absorption : forall n m, min n (max n m) == n.
381 Lemma max_min_absorption n m : min n (max n m) == n.
391382 Proof.
392383 intros.
393384 destruct (max_spec n m) as [(C,E)|(C,E)]; rewrite E.
397388
398389 (** Distributivity *)
399390
400 Lemma max_min_distr : forall n m p,
391 Lemma max_min_distr n m p :
401392 max n (min m p) == min (max n m) (max n p).
402393 Proof.
403 intros. symmetry. apply min_mono.
394 symmetry. apply min_mono.
404395 eauto with *.
405396 repeat red; intros. apply max_le_compat_l; auto.
406397 Qed.
407398
408 Lemma min_max_distr : forall n m p,
399 Lemma min_max_distr n m p :
409400 min n (max m p) == max (min n m) (min n p).
410401 Proof.
411 intros. symmetry. apply max_mono.
402 symmetry. apply max_mono.
412403 eauto with *.
413404 repeat red; intros. apply min_le_compat_l; auto.
414405 Qed.
415406
416407 (** Modularity *)
417408
418 Lemma max_min_modular : forall n m p,
409 Lemma max_min_modular n m p :
419410 max n (min m (max n p)) == min (max n m) (max n p).
420411 Proof.
421 intros. rewrite <- max_min_distr.
412 rewrite <- max_min_distr.
422413 destruct (max_spec n p) as [(C,E)|(C,E)]; rewrite E; auto with *.
423414 destruct (min_spec m n) as [(C',E')|(C',E')]; rewrite E'.
424415 rewrite 2 max_l; try order. rewrite min_le_iff; auto.
425416 rewrite 2 max_l; try order. rewrite min_le_iff; auto.
426417 Qed.
427418
428 Lemma min_max_modular : forall n m p,
419 Lemma min_max_modular n m p :
429420 min n (max m (min n p)) == max (min n m) (min n p).
430421 Proof.
431422 intros. rewrite <- min_max_distr.
437428
438429 (** Disassociativity *)
439430
440 Lemma max_min_disassoc : forall n m p,
431 Lemma max_min_disassoc n m p :
441432 min n (max m p) <= max (min n m) p.
442433 Proof.
443434 intros. rewrite min_max_distr.
446437
447438 (** Anti-monotonicity swaps the role of [min] and [max] *)
448439
449 Lemma max_min_antimono : forall f,
440 Lemma max_min_antimono f :
450441 Proper (eq==>eq) f ->
451442 Proper (le==>inverse le) f ->
452443 forall x y, max (f x) (f y) == f (min x y).
453444 Proof.
454 intros f Eqf Lef x y.
445 intros Eqf Lef x y.
455446 destruct (min_spec x y) as [(H,E)|(H,E)]; rewrite E;
456447 destruct (max_spec (f x) (f y)) as [(H',E')|(H',E')]; auto.
457448 assert (f y <= f x) by (apply Lef; order). order.
458449 assert (f x <= f y) by (apply Lef; order). order.
459450 Qed.
460451
461 Lemma min_max_antimono : forall f,
452 Lemma min_max_antimono f :
462453 Proper (eq==>eq) f ->
463454 Proper (le==>inverse le) f ->
464455 forall x y, min (f x) (f y) == f (max x y).
465456 Proof.
466 intros f Eqf Lef x y.
457 intros Eqf Lef x y.
467458 destruct (max_spec x y) as [(H,E)|(H,E)]; rewrite E;
468459 destruct (min_spec (f x) (f y)) as [(H',E')|(H',E')]; auto.
469460 assert (f y <= f x) by (apply Lef; order). order.
479470
480471 (** Induction principles for [max]. *)
481472
482 Lemma max_case_strong : forall n m (P:t -> Type),
473 Lemma max_case_strong n m (P:t -> Type) :
483474 (forall x y, x==y -> P x -> P y) ->
484475 (m<=n -> P n) -> (n<=m -> P m) -> P (max n m).
485476 Proof.
486 intros n m P Compat Hl Hr.
477 intros Compat Hl Hr.
487478 destruct (CompSpec2Type (compare_spec n m)) as [EQ|LT|GT].
488479 assert (n<=m) by (rewrite le_lteq; auto).
489480 apply (Compat m), Hr; auto. symmetry; apply max_r; auto.
493484 apply (Compat n), Hl; auto. symmetry; apply max_l; auto.
494485 Defined.
495486
496 Lemma max_case : forall n m (P:t -> Type),
487 Lemma max_case n m (P:t -> Type) :
497488 (forall x y, x == y -> P x -> P y) ->
498489 P n -> P m -> P (max n m).
499490 Proof. intros. apply max_case_strong; auto. Defined.
500491
501492 (** [max] returns one of its arguments. *)
502493
503 Lemma max_dec : forall n m, {max n m == n} + {max n m == m}.
504 Proof.
505 intros n m. apply max_case; auto with relations.
494 Lemma max_dec n m : {max n m == n} + {max n m == m}.
495 Proof.
496 apply max_case; auto with relations.
506497 intros x y H [E|E]; [left|right]; rewrite <-H; auto.
507498 Defined.
508499
509500 (** Idem for [min] *)
510501
511 Lemma min_case_strong : forall n m (P:O.t -> Type),
502 Lemma min_case_strong n m (P:O.t -> Type) :
512503 (forall x y, x == y -> P x -> P y) ->
513504 (n<=m -> P n) -> (m<=n -> P m) -> P (min n m).
514505 Proof.
515 intros n m P Compat Hl Hr.
506 intros Compat Hl Hr.
516507 destruct (CompSpec2Type (compare_spec n m)) as [EQ|LT|GT].
517508 assert (n<=m) by (rewrite le_lteq; auto).
518509 apply (Compat n), Hl; auto. symmetry; apply min_l; auto.
522513 apply (Compat m), Hr; auto. symmetry; apply min_r; auto.
523514 Defined.
524515
525 Lemma min_case : forall n m (P:O.t -> Type),
516 Lemma min_case n m (P:O.t -> Type) :
526517 (forall x y, x == y -> P x -> P y) ->
527518 P n -> P m -> P (min n m).
528519 Proof. intros. apply min_case_strong; auto. Defined.
529520
530 Lemma min_dec : forall n m, {min n m == n} + {min n m == m}.
521 Lemma min_dec n m : {min n m == n} + {min n m == m}.
531522 Proof.
532523 intros. apply min_case; auto with relations.
533524 intros x y H [E|E]; [left|right]; rewrite <- E; auto with relations.
557548
558549 Include MinMaxLogicalProperties O M.
559550
560 Lemma max_monotone : forall f, Proper (le ==> le) f ->
551 Lemma max_monotone f : Proper (le ==> le) f ->
561552 forall x y, max (f x) (f y) = f (max x y).
562553 Proof. intros; apply max_mono; auto. congruence. Qed.
563554
564 Lemma min_monotone : forall f, Proper (le ==> le) f ->
555 Lemma min_monotone f : Proper (le ==> le) f ->
565556 forall x y, min (f x) (f y) = f (min x y).
566557 Proof. intros; apply min_mono; auto. congruence. Qed.
567558
568 Lemma min_max_antimonotone : forall f, Proper (le ==> inverse le) f ->
559 Lemma min_max_antimonotone f : Proper (le ==> inverse le) f ->
569560 forall x y, min (f x) (f y) = f (max x y).
570561 Proof. intros; apply min_max_antimono; auto. congruence. Qed.
571562
572 Lemma max_min_antimonotone : forall f, Proper (le ==> inverse le) f ->
563 Lemma max_min_antimonotone f : Proper (le ==> inverse le) f ->
573564 forall x y, max (f x) (f y) = f (min x y).
574565 Proof. intros; apply max_min_antimono; auto. congruence. Qed.
575566
107107 Lemma lt_total : forall x y, lt x y \/ eq x y \/ lt y x.
108108 Proof. intros; destruct (compare x y); auto. Qed.
109109
110 Module OrderElts <: Orders.TotalOrder.
111 Definition t := t.
112 Definition eq := eq.
113 Definition lt := lt.
114 Definition le x y := lt x y \/ eq x y.
115 Definition eq_equiv := eq_equiv.
116 Definition lt_strorder := lt_strorder.
117 Definition lt_compat := lt_compat.
118 Definition lt_total := lt_total.
119 Lemma le_lteq : forall x y, le x y <-> lt x y \/ eq x y.
120 Proof. unfold le; intuition. Qed.
121 End OrderElts.
122 Module OrderTac := !MakeOrderTac OrderElts.
110 Module TO.
111 Definition t := t.
112 Definition eq := eq.
113 Definition lt := lt.
114 Definition le x y := lt x y \/ eq x y.
115 End TO.
116 Module IsTO.
117 Definition eq_equiv := eq_equiv.
118 Definition lt_strorder := lt_strorder.
119 Definition lt_compat := lt_compat.
120 Definition lt_total := lt_total.
121 Lemma le_lteq x y : TO.le x y <-> lt x y \/ eq x y.
122 Proof. reflexivity. Qed.
123 End IsTO.
124 Module OrderTac := !MakeOrderTac TO IsTO.
123125 Ltac order := OrderTac.order.
124126
125127 Lemma le_eq x y z : ~lt x y -> eq y z -> ~lt x z. Proof. order. Qed.
3939 Local Infix "+" := trans_ord.
4040
4141
42 (** ** The requirements of the tactic : [TotalOrder].
43
44 [TotalOrder] contains an equivalence [eq],
45 a strict order [lt] total and compatible with [eq], and
46 a larger order [le] synonym for [lt\/eq].
42 (** ** The tactic requirements : a total order
43
44 We need :
45 - an equivalence [eq],
46 - a strict order [lt] total and compatible with [eq],
47 - a larger order [le] synonym for [lt\/eq].
48
49 This used to be provided here via a [TotalOrder], but
50 for technical reasons related to extraction, we now ask
51 for two sperate parts: relations in a [EqLtLe] + properties in
52 [IsTotalOrder]. Note that [TotalOrder = EqLtLe <+ IsTotalOrder]
4753 *)
4854
55 Module Type IsTotalOrder (O:EqLtLe) :=
56 IsEq O <+ IsStrOrder O <+ LeIsLtEq O <+ LtIsTotal O.
57
4958 (** ** Properties that will be used by the [order] tactic *)
5059
51 Module OrderFacts(Import O:TotalOrder').
60 Module OrderFacts (Import O:EqLtLe)(P:IsTotalOrder O).
61 Include EqLtLeNotation O.
5262
5363 (** Reflexivity rules *)
5464
5666 Proof. reflexivity. Qed.
5767
5868 Lemma le_refl : forall x, x<=x.
59 Proof. intros; rewrite le_lteq; right; reflexivity. Qed.
69 Proof. intros; rewrite P.le_lteq; right; reflexivity. Qed.
6070
6171 Lemma lt_irrefl : forall x, ~ x<x.
6272 Proof. intros; apply StrictOrder_Irreflexive. Qed.
6878
6979 Lemma le_antisym : forall x y, x<=y -> y<=x -> x==y.
7080 Proof.
71 intros x y; rewrite 2 le_lteq. intuition.
81 intros x y; rewrite 2 P.le_lteq. intuition.
7282 elim (StrictOrder_Irreflexive x); transitivity y; auto.
7383 Qed.
7484
8999
90100 Lemma trans : forall o o' x y z, #o x y -> #o' y z -> #(o+o') x z.
91101 Proof.
92 destruct o, o'; simpl; intros x y z; rewrite ?le_lteq; intuition;
102 destruct o, o'; simpl; intros x y z; rewrite ?P.le_lteq; intuition;
93103 subst_eqns; eauto using (StrictOrder_Transitive x y z) with *.
94104 Qed.
95105
113123
114124 Lemma not_neq_eq : forall x y, ~~x==y -> x==y.
115125 Proof.
116 intros x y H. destruct (lt_total x y) as [H'|[H'|H']]; auto;
126 intros x y H. destruct (P.lt_total x y) as [H'|[H'|H']]; auto;
117127 destruct H; intro H; rewrite H in H'; eapply lt_irrefl; eauto.
118128 Qed.
119129
120130 Lemma not_ge_lt : forall x y, ~y<=x -> x<y.
121131 Proof.
122 intros x y H. destruct (lt_total x y); auto.
123 destruct H. rewrite le_lteq. intuition.
132 intros x y H. destruct (P.lt_total x y); auto.
133 destruct H. rewrite P.le_lteq. intuition.
124134 Qed.
125135
126136 Lemma not_gt_le : forall x y, ~y<x -> x<=y.
127137 Proof.
128 intros x y H. rewrite le_lteq. generalize (lt_total x y); intuition.
138 intros x y H. rewrite P.le_lteq. generalize (P.lt_total x y); intuition.
129139 Qed.
130140
131141 Lemma le_neq_lt : forall x y, x<=y -> ~x==y -> x<y.
137147
138148 (** ** [MakeOrderTac] : The functor providing the order tactic. *)
139149
140 Module MakeOrderTac (Import O:TotalOrder').
141
142 Include OrderFacts O.
150 Module MakeOrderTac (Import O:EqLtLe)(P:IsTotalOrder O).
151 Include OrderFacts O P.
152 Include EqLtLeNotation O.
143153
144154 (** order_eq : replace x by y in all (in)equations hyps thanks
145155 to equality EQ (where eq has been hidden in order to avoid
256266
257267 Module OTF_to_OrderTac (OTF:OrderedTypeFull).
258268 Module TO := OTF_to_TotalOrder OTF.
259 Include !MakeOrderTac TO.
269 Include !MakeOrderTac OTF TO.
260270 End OTF_to_OrderTac.
261271
262272 Module OT_to_OrderTac (OT:OrderedType).
263273 Module OTF := OT_to_Full OT.
264274 Include !OTF_to_OrderTac OTF.
265275 End OT_to_OrderTac.
266
267 Module TotalOrderRev (O:TotalOrder) <: TotalOrder.
268
269 Definition t := O.t.
270 Definition eq := O.eq.
271 Definition lt := flip O.lt.
272 Definition le := flip O.le.
273 Include EqLtLeNotation.
274
275 (* No Instance syntax to avoid saturating the Equivalence tables *)
276 Definition eq_equiv := O.eq_equiv.
277
278 Instance lt_strorder: StrictOrder lt.
279 Proof. unfold lt; auto with *. Qed.
280 Instance lt_compat : Proper (eq==>eq==>iff) lt.
281 Proof. unfold lt; auto with *. Qed.
282
283 Lemma le_lteq : forall x y, x<=y <-> x<y \/ x==y.
284 Proof. intros; unfold le, lt, flip. rewrite O.le_lteq; intuition. Qed.
285
286 Lemma lt_total : forall x y, x<y \/ x==y \/ y<x.
287 Proof.
288 intros x y; unfold lt, eq, flip.
289 generalize (O.lt_total x y); intuition.
290 Qed.
291
292 End TotalOrderRev.
2323
2424 Parameter t : Set.
2525 Bind Scope Int_scope with t.
26
27 (** For compatibility *)
28 Definition int := t.
2926
3027 Parameter i2z : t -> Z.
3128
361358 Module Z_as_Int <: Int.
362359 Local Open Scope Z_scope.
363360 Definition t := Z.
364 Definition int := t.
365361 Definition _0 := 0.
366362 Definition _1 := 1.
367363 Definition _2 := 2.
374370 Definition gt_le_dec := Z_gt_le_dec.
375371 Definition ge_lt_dec := Z_ge_lt_dec.
376372 Definition eq_dec := Z.eq_dec.
377 Definition i2z : int -> Z := fun n => n.
373 Definition i2z : t -> Z := fun n => n.
378374 Lemma i2z_eq : forall n p, i2z n=i2z p -> n = p. Proof. auto. Qed.
379375 Lemma i2z_0 : i2z _0 = 0. Proof. auto. Qed.
380376 Lemma i2z_1 : i2z _1 = 1. Proof. auto. Qed.
221221 print "\n";
222222 end;
223223 print "install:";
224 if (not_empty cmxsfiles) then print "$(if ifeq '$(HASNATDYNLINK)' 'true',install-natdynlink)";
224 if (not_empty cmxsfiles) then print "$(if $(HASNATDYNLINK_OR_EMPTY),install-natdynlink)";
225225 print "\n";
226226 if not_empty vfiles then install_include_by_root "VOFILES" vfiles inc;
227227 if (not_empty cmofiles) then
290290 print "%.cmo: %.ml4\n\t$(CAMLC) $(ZDEBUG) $(ZFLAGS) $(PP) -impl $<\n\n";
291291 print "%.cmx: %.ml4\n\t$(CAMLOPTC) $(ZDEBUG) $(ZFLAGS) $(PP) -impl $<\n\n";
292292 print "%.ml4.d: %.ml4\n";
293 print "\t$(OCAMLDEP) -slash $(OCAMLLIBS) $(PP) -impl \"$<\" > \"$@\" || ( RV=$$?; rm -f \"$@\"; exit $${RV} )\n\n" in
293 print "\t$(COQDEP) -slash $(OCAMLLIBS) \"$<\" > \"$@\" || ( RV=$$?; rm -f \"$@\"; exit $${RV} )\n\n" in
294294 let ml_rules () =
295295 print "%.cmo: %.ml\n\t$(CAMLC) $(ZDEBUG) $(ZFLAGS) $<\n\n";
296296 print "%.cmx: %.ml\n\t$(CAMLOPTC) $(ZDEBUG) $(ZFLAGS) $<\n\n";
297297 print "%.ml.d: %.ml\n";
298298 print "\t$(OCAMLDEP) -slash $(OCAMLLIBS) \"$<\" > \"$@\" || ( RV=$$?; rm -f \"$@\"; exit $${RV} )\n\n" in
299299 let cmxs_rules () =
300 print "%.cmxs: %.cmxa\n\t$(CAMLOPTLINK) $(ZDEBUG) $(ZFLAGS) -linkall -shared -o $@ $<\n\n";
300301 print "%.cmxs: %.cmx\n\t$(CAMLOPTLINK) $(ZDEBUG) $(ZFLAGS) -shared -o $@ $<\n\n" in
301302 let mllib_rules () =
302303 print "%.cma: | %.mllib\n\t$(CAMLLINK) $(ZDEBUG) $(ZFLAGS) -a -o $@ $^\n\n";
303304 print "%.cmxa: | %.mllib\n\t$(CAMLOPTLINK) $(ZDEBUG) $(ZFLAGS) -a -o $@ $^\n\n";
304 print "%.cmxs: %.cmxa\n\t$(CAMLOPTLINK) $(ZDEBUG) $(ZFLAGS) -linkall -shared -o $@ $<\n\n";
305305 print "%.mllib.d: %.mllib\n";
306306 print "\t$(COQDEP) -slash $(COQLIBS) -c \"$<\" > \"$@\" || ( RV=$$?; rm -f \"$@\"; exit $${RV} )\n\n" in
307307 let mlpack_rules () =
410410 print "# DSTROOT to specify a prefix to install path.\n\n";
411411 print "# Here is a hack to make $(eval $(shell works:\n";
412412 print "define donewline\n\n\nendef\n";
413 print "includecmdwithout@ = $(eval $(subst @,$(donewline),$(shell { $(1) | tr '\\n' '@'; })))\n";
413 print "includecmdwithout@ = $(eval $(subst @,$(donewline),$(shell { $(1) | tr -d '\\r' | tr '\\n' '@'; })))\n";
414414 print "$(call includecmdwithout@,$(COQBIN)coqtop -config)\n\n"
415415
416416 let include_dirs (inc_i,inc_r) =
542542 print "CMXSFILES=$(CMXFILES:.cmx=.cmxs) $(CMXAFILES:.cmxa=.cmxs)\n";
543543 classify_files_by_root "CMXSFILES" (l1@l2) inc;
544544 end;
545 print "\n";
545 print "ifeq '$(HASNATDYNLINK)' 'true'\n";
546 print "HASNATDYNLINK_OR_EMPTY := yes\n";
547 print "else\n";
548 print "HASNATDYNLINK_OR_EMPTY :=\n";
549 print "endif\n\n";
546550 section "Definition of the toplevel targets.";
547551 print "all: ";
548552 if !some_vfile then print "$(VOFILES) ";
549553 if !some_mlfile || !some_ml4file || !some_mlpackfile then print "$(CMOFILES) ";
550554 if !some_mllibfile then print "$(CMAFILES) ";
551555 if !some_mlfile || !some_ml4file || !some_mllibfile || !some_mlpackfile
552 then print "$(if ifeq '$(HASNATDYNLINK)' 'true',$(CMXSFILES)) ";
556 then print "$(if $(HASNATDYNLINK_OR_EMPTY),$(CMXSFILES)) ";
553557 print_list "\\\n " other_targets; print "\n\n";
554558 if !some_mlifile then
555559 begin
0 (************************************************************************)
1 (* v * The Coq Proof Assistant / The Coq Development Team *)
2 (* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2012 *)
3 (* \VV/ **************************************************************)
4 (* // * This file is distributed under the terms of the *)
5 (* * GNU Lesser General Public License Version 2.1 *)
6 (************************************************************************)
7
8 (* coq-tex
9 * JCF, 16/1/98
10 * adapted from caml-tex (perl script written by Xavier Leroy)
11 *
12 * Perl isn't as portable as it pretends to be, and is quite difficult
13 * to read and maintain... Let us rewrite the stuff in Caml! *)
14
15 let linelen = ref 72
16 let output = ref ""
17 let output_specified = ref false
18 let image = ref ""
19 let cut_at_blanks = ref false
20 let verbose = ref false
21 let slanted = ref false
22 let hrule = ref false
23 let small = ref false
24 let boot = ref false
25
26 let coq_prompt = Str.regexp "Coq < "
27 let any_prompt = Str.regexp "^[A-Z0-9a-z_\\$']* < "
28
29 let remove_prompt s = Str.replace_first any_prompt "" s
30
31 (* First pass: extract the Coq phrases to evaluate from [texfile]
32 * and put them into the file [inputv] *)
33
34 let begin_coq = Str.regexp "\\\\begin{coq_\\(example\\|example\\*\\|example\\#\\|eval\\)}[ \t]*$"
35 let end_coq = Str.regexp "\\\\end{coq_\\(example\\|example\\*\\|example\\#\\|eval\\)}[ \t]*$"
36
37 let extract texfile inputv =
38 let chan_in = open_in texfile in
39 let chan_out = open_out inputv in
40 let rec inside () =
41 let s = input_line chan_in in
42 if Str.string_match end_coq s 0 then
43 outside ()
44 else begin
45 output_string chan_out (s ^ "\n");
46 inside ()
47 end
48 and outside () =
49 let s = input_line chan_in in
50 if Str.string_match begin_coq s 0 then
51 inside ()
52 else
53 outside ()
54 in
55 try
56 output_string chan_out
57 ("Set Printing Width " ^ (string_of_int !linelen) ^".\n");
58 outside ()
59 with End_of_file ->
60 begin close_in chan_in; close_out chan_out end
61
62 (* Second pass: insert the answers of Coq from [coq_output] into the
63 * TeX file [texfile]. The result goes in file [result]. *)
64
65 let begin_coq_example =
66 Str.regexp "\\\\begin{coq_\\(example\\|example\\*\\|example\\#\\)}[ \t]*$"
67 let begin_coq_eval = Str.regexp "\\\\begin{coq_eval}[ \t]*$"
68 let end_coq_example = Str.regexp "\\\\end{coq_\\(example\\|example\\*\\|example\\#\\)}[ \t]*$"
69 let end_coq_eval = Str.regexp "\\\\end{coq_eval}[ \t]*$"
70 let dot_end_line = Str.regexp "\\.[ \t]*\\((\\*.*\\*)\\)?[ \t]*$"
71
72 let has_match r s =
73 try let _ = Str.search_forward r s 0 in true with Not_found -> false
74
75 let percent = Str.regexp "%"
76 let bang = Str.regexp "!"
77 let expos = Str.regexp "^"
78
79 let tex_escaped s =
80 let dollar = "\\$" and backslash = "\\\\" and expon = "\\^" in
81 let delims = Str.regexp ("[_{}&%#" ^ dollar ^ backslash ^ expon ^"~ <>]") in
82 let adapt_delim = function
83 | "_" | "{" | "}" | "&" | "%" | "#" | "$" as c -> "\\"^c
84 | "\\" -> "{\\char'134}"
85 | "^" -> "{\\char'136}"
86 | "~" -> "{\\char'176}"
87 | " " -> "~"
88 | "<" -> "{<}"
89 | ">" -> "{>}"
90 | _ -> assert false
91 in
92 let adapt = function
93 | Str.Text s -> s
94 | Str.Delim s -> adapt_delim s
95 in
96 String.concat "" (List.map adapt (Str.full_split delims s))
97
98 let encapsule sl c_out s =
99 if sl then
100 Printf.fprintf c_out "\\texttt{\\textit{%s}}\\\\\n" (tex_escaped s)
101 else
102 Printf.fprintf c_out "\\texttt{%s}\\\\\n" (tex_escaped s)
103
104 let print_block c_out bl =
105 List.iter (fun s -> if s="" then () else encapsule !slanted c_out s) bl
106
107 let insert texfile coq_output result =
108 let c_tex = open_in texfile in
109 let c_coq = open_in coq_output in
110 let c_out = open_out result in
111 (* next_block k : this function reads the next block of Coq output
112 * removing the k leading prompts.
113 * it returns the block as a list of string) *)
114 let last_read = ref "" in
115 let next_block k =
116 if !last_read = "" then last_read := input_line c_coq;
117 (* skip k prompts *)
118 for i = 1 to k do
119 last_read := remove_prompt !last_read;
120 done;
121 (* read and return the following lines until a prompt is found *)
122 let rec read_lines () =
123 let s = input_line c_coq in
124 if Str.string_match any_prompt s 0 then begin
125 last_read := s; []
126 end else
127 s :: (read_lines ())
128 in
129 let first = !last_read in first :: (read_lines ())
130 in
131 (* we are just after \end{coq_...} block *)
132 let rec just_after () =
133 let s = input_line c_tex in
134 if Str.string_match begin_coq_example s 0 then begin
135 inside (Str.matched_group 1 s <> "example*")
136 (Str.matched_group 1 s <> "example#") 0 false
137 end
138 else begin
139 if !hrule then output_string c_out "\\hrulefill\\\\\n";
140 output_string c_out "\\end{flushleft}\n";
141 if !small then output_string c_out "\\end{small}\n";
142 if Str.string_match begin_coq_eval s 0 then
143 eval 0
144 else begin
145 output_string c_out (s ^ "\n");
146 outside ()
147 end
148 end
149 (* we are outside of a \begin{coq_...} ... \end{coq_...} block *)
150 and outside () =
151 let s = input_line c_tex in
152 if Str.string_match begin_coq_example s 0 then begin
153 if !small then output_string c_out "\\begin{small}\n";
154 output_string c_out "\\begin{flushleft}\n";
155 if !hrule then output_string c_out "\\hrulefill\\\\\n";
156 inside (Str.matched_group 1 s <> "example*")
157 (Str.matched_group 1 s <> "example#") 0 true
158 end else if Str.string_match begin_coq_eval s 0 then
159 eval 0
160 else begin
161 output_string c_out (s ^ "\n");
162 outside ()
163 end
164 (* we are inside a \begin{coq_example?} ... \end{coq_example?} block
165 * show_answers tells what kind of block it is
166 * k is the number of lines read until now *)
167 and inside show_answers show_questions k first_block =
168 let s = input_line c_tex in
169 if Str.string_match end_coq_example s 0 then begin
170 just_after ()
171 end else begin
172 if !verbose then Printf.printf "Coq < %s\n" s;
173 if (not first_block) & k=0 then output_string c_out "\\medskip\n";
174 if show_questions then encapsule false c_out ("Coq < " ^ s);
175 if has_match dot_end_line s then begin
176 let bl = next_block (succ k) in
177 if !verbose then List.iter print_endline bl;
178 if show_answers then print_block c_out bl;
179 inside show_answers show_questions 0 false
180 end else
181 inside show_answers show_questions (succ k) first_block
182 end
183 (* we are inside a \begin{coq_eval} ... \end{coq_eval} block
184 * k is the number of lines read until now *)
185 and eval k =
186 let s = input_line c_tex in
187 if Str.string_match end_coq_eval s 0 then
188 outside ()
189 else begin
190 if !verbose then Printf.printf "Coq < %s\n" s;
191 if has_match dot_end_line s then
192 let bl = next_block (succ k) in
193 if !verbose then List.iter print_endline bl;
194 eval 0
195 else
196 eval (succ k)
197 end
198 in
199 try
200 let _ = next_block 0 in (* to skip the Coq banner *)
201 let _ = next_block 0 in (* to skip the Coq answer to Set Printing Width *)
202 outside ()
203 with End_of_file -> begin
204 close_in c_tex;
205 close_in c_coq;
206 close_out c_out
207 end
208
209 (* Process of one TeX file *)
210
211 let rm f = try Sys.remove f with _ -> ()
212
213 let one_file texfile =
214 let inputv = Filename.temp_file "coq_tex" ".v" in
215 let coq_output = Filename.temp_file "coq_tex" ".coq_output"in
216 let result =
217 if !output_specified then
218 !output
219 else if Filename.check_suffix texfile ".tex" then
220 (Filename.chop_suffix texfile ".tex") ^ ".v.tex"
221 else
222 texfile ^ ".v.tex"
223 in
224 try
225 (* 1. extract Coq phrases *)
226 extract texfile inputv;
227 (* 2. run Coq on input *)
228 let _ = Sys.command (Printf.sprintf "%s < %s > %s 2>&1" !image inputv
229 coq_output)
230 in
231 (* 3. insert Coq output into original file *)
232 insert texfile coq_output result;
233 (* 4. clean up *)
234 rm inputv; rm coq_output
235 with e -> begin
236 rm inputv; rm coq_output;
237 raise e
238 end
239
240 (* Parsing of the command line, check of the Coq command and process
241 * of all the files in the command line, one by one *)
242
243 let files = ref []
244
245 let parse_cl () =
246 Arg.parse
247 [ "-o", Arg.String (fun s -> output_specified := true; output := s),
248 "output-file Specifiy the resulting LaTeX file";
249 "-n", Arg.Int (fun n -> linelen := n),
250 "line-width Set the line width";
251 "-image", Arg.String (fun s -> image := s),
252 "coq-image Use coq-image as Coq command";
253 "-w", Arg.Set cut_at_blanks,
254 " Try to cut lines at blanks";
255 "-v", Arg.Set verbose,
256 " Verbose mode (show Coq answers on stdout)";
257 "-sl", Arg.Set slanted,
258 " Coq answers in slanted font (only with LaTeX2e)";
259 "-hrule", Arg.Set hrule,
260 " Coq parts are written between 2 horizontal lines";
261 "-small", Arg.Set small,
262 " Coq parts are written in small font";
263 "-boot", Arg.Set boot,
264 " Launch coqtop with the -boot option"
265 ]
266 (fun s -> files := s :: !files)
267 "coq-tex [options] file ..."
268
269 let find_coqtop () =
270 let prog = Sys.executable_name in
271 try
272 let size = String.length prog in
273 let i = Str.search_backward (Str.regexp_string "coq-tex") prog (size-7) in
274 (String.sub prog 0 i)^"coqtop"^(String.sub prog (i+7) (size-i-7))
275 with Not_found -> begin
276 Printf.printf "Warning: preprocessing with default image \"coqtop\"\n";
277 "coqtop"
278 end
279
280 let main () =
281 parse_cl ();
282 if !image = "" then image := Filename.quote (find_coqtop ());
283 if !boot then image := !image ^ " -boot";
284 if Sys.command (!image ^ " -batch -silent") <> 0 then begin
285 Printf.printf "Error: ";
286 let _ = Sys.command (!image ^ " -batch") in
287 exit 1
288 end else begin
289 Printf.printf "Your version of coqtop seems OK\n";
290 flush stdout
291 end;
292 List.iter one_file (List.rev !files)
293
294 let _ = Printexc.catch main ()
+0
-290
tools/coq_tex.ml4 less more
0 (************************************************************************)
1 (* v * The Coq Proof Assistant / The Coq Development Team *)
2 (* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2012 *)
3 (* \VV/ **************************************************************)
4 (* // * This file is distributed under the terms of the *)
5 (* * GNU Lesser General Public License Version 2.1 *)
6 (************************************************************************)
7
8 (* coq-tex
9 * JCF, 16/1/98
10 * adapted from caml-tex (perl script written by Xavier Leroy)
11 *
12 * Perl isn't as portable as it pretends to be, and is quite difficult
13 * to read and maintain... Let us rewrite the stuff in Caml! *)
14
15 let _ =
16 match Sys.os_type with
17 | "Unix" -> ()
18 | _ -> begin
19 print_string "This program only runs under Unix !\n";
20 flush stdout;
21 exit 1
22 end
23
24 let linelen = ref 72
25 let output = ref ""
26 let output_specified = ref false
27 let image = ref ""
28 let cut_at_blanks = ref false
29 let verbose = ref false
30 let slanted = ref false
31 let hrule = ref false
32 let small = ref false
33
34 let coq_prompt = Str.regexp "Coq < "
35 let any_prompt = Str.regexp "^[A-Z0-9a-z_\\$']* < "
36
37 let remove_prompt s = Str.replace_first any_prompt "" s
38
39 (* First pass: extract the Coq phrases to evaluate from [texfile]
40 * and put them into the file [inputv] *)
41
42 let begin_coq = Str.regexp "\\\\begin{coq_\\(example\\|example\\*\\|example\\#\\|eval\\)}[ \t]*$"
43 let end_coq = Str.regexp "\\\\end{coq_\\(example\\|example\\*\\|example\\#\\|eval\\)}[ \t]*$"
44
45 let extract texfile inputv =
46 let chan_in = open_in texfile in
47 let chan_out = open_out inputv in
48 let rec inside () =
49 let s = input_line chan_in in
50 if Str.string_match end_coq s 0 then
51 outside ()
52 else begin
53 output_string chan_out (s ^ "\n");
54 inside ()
55 end
56 and outside () =
57 let s = input_line chan_in in
58 if Str.string_match begin_coq s 0 then
59 inside ()
60 else
61 outside ()
62 in
63 try
64 output_string chan_out
65 ("Set Printing Width " ^ (string_of_int !linelen) ^".\n");
66 outside ()
67 with End_of_file ->
68 begin close_in chan_in; close_out chan_out end
69
70 (* Second pass: insert the answers of Coq from [coq_output] into the
71 * TeX file [texfile]. The result goes in file [result]. *)
72
73 let begin_coq_example =
74 Str.regexp "\\\\begin{coq_\\(example\\|example\\*\\|example\\#\\)}[ \t]*$"
75 let begin_coq_eval = Str.regexp "\\\\begin{coq_eval}[ \t]*$"
76 let end_coq_example = Str.regexp "\\\\end{coq_\\(example\\|example\\*\\|example\\#\\)}[ \t]*$"
77 let end_coq_eval = Str.regexp "\\\\end{coq_eval}[ \t]*$"
78 let dot_end_line = Str.regexp "\\.[ \t]*\\((\\*.*\\*)\\)?[ \t]*$"
79
80 let has_match r s =
81 try let _ = Str.search_forward r s 0 in true with Not_found -> false
82
83 let percent = Str.regexp "%"
84 let bang = Str.regexp "!"
85 let expos = Str.regexp "^"
86
87 let tex_escaped s =
88 let rec trans = parser
89 | [< s1 = (parser
90 | [< ''_'|'$'|'{'|'}'|'&'|'%'|'#' as c >] ->
91 "\\" ^ (String.make 1 c)
92 | [< ''\\' >] -> "{\\char'134}"
93 | [< ''^' >] -> "{\\char'136}"
94 | [< ''~' >] -> "{\\char'176}"
95 | [< '' ' >] -> "~"
96 | [< ''<' >] -> "{<}"
97 | [< ''>' >] -> "{>}"
98 | [< 'c >] -> String.make 1 c);
99 s2 = trans >] -> s1 ^ s2
100 | [< >] -> ""
101 in
102 trans (Stream.of_string s)
103
104 let encapsule sl c_out s =
105 if sl then
106 Printf.fprintf c_out "\\texttt{\\textit{%s}}\\\\\n" (tex_escaped s)
107 else
108 Printf.fprintf c_out "\\texttt{%s}\\\\\n" (tex_escaped s)
109
110 let print_block c_out bl =
111 List.iter (fun s -> if s="" then () else encapsule !slanted c_out s) bl
112
113 let insert texfile coq_output result =
114 let c_tex = open_in texfile in
115 let c_coq = open_in coq_output in
116 let c_out = open_out result in
117 (* next_block k : this function reads the next block of Coq output
118 * removing the k leading prompts.
119 * it returns the block as a list of string) *)
120 let last_read = ref "" in
121 let next_block k =
122 if !last_read = "" then last_read := input_line c_coq;
123 (* skip k prompts *)
124 for i = 1 to k do
125 last_read := remove_prompt !last_read;
126 done;
127 (* read and return the following lines until a prompt is found *)
128 let rec read_lines () =
129 let s = input_line c_coq in
130 if Str.string_match any_prompt s 0 then begin
131 last_read := s; []
132 end else
133 s :: (read_lines ())
134 in
135 let first = !last_read in first :: (read_lines ())
136 in
137 (* we are just after \end{coq_...} block *)
138 let rec just_after () =
139 let s = input_line c_tex in
140 if Str.string_match begin_coq_example s 0 then begin
141 inside (Str.matched_group 1 s <> "example*")
142 (Str.matched_group 1 s <> "example#") 0 false
143 end
144 else begin
145 if !hrule then output_string c_out "\\hrulefill\\\\\n";
146 output_string c_out "\\end{flushleft}\n";
147 if !small then output_string c_out "\\end{small}\n";
148 if Str.string_match begin_coq_eval s 0 then
149 eval 0
150 else begin
151 output_string c_out (s ^ "\n");
152 outside ()
153 end
154 end
155 (* we are outside of a \begin{coq_...} ... \end{coq_...} block *)
156 and outside () =
157 let s = input_line c_tex in
158 if Str.string_match begin_coq_example s 0 then begin
159 if !small then output_string c_out "\\begin{small}\n";
160 output_string c_out "\\begin{flushleft}\n";
161 if !hrule then output_string c_out "\\hrulefill\\\\\n";
162 inside (Str.matched_group 1 s <> "example*")
163 (Str.matched_group 1 s <> "example#") 0 true
164 end else if Str.string_match begin_coq_eval s 0 then
165 eval 0
166 else begin
167 output_string c_out (s ^ "\n");
168 outside ()
169 end
170 (* we are inside a \begin{coq_example?} ... \end{coq_example?} block
171 * show_answers tells what kind of block it is
172 * k is the number of lines read until now *)
173 and inside show_answers show_questions k first_block =
174 let s = input_line c_tex in
175 if Str.string_match end_coq_example s 0 then begin
176 just_after ()
177 end else begin
178 if !verbose then Printf.printf "Coq < %s\n" s;
179 if (not first_block) & k=0 then output_string c_out "\\medskip\n";
180 if show_questions then encapsule false c_out ("Coq < " ^ s);
181 if has_match dot_end_line s then begin
182 let bl = next_block (succ k) in
183 if !verbose then List.iter print_endline bl;
184 if show_answers then print_block c_out bl;
185 inside show_answers show_questions 0 false
186 end else
187 inside show_answers show_questions (succ k) first_block
188 end
189 (* we are inside a \begin{coq_eval} ... \end{coq_eval} block
190 * k is the number of lines read until now *)
191 and eval k =
192 let s = input_line c_tex in
193 if Str.string_match end_coq_eval s 0 then
194 outside ()
195 else begin
196 if !verbose then Printf.printf "Coq < %s\n" s;
197 if has_match dot_end_line s then
198 let bl = next_block (succ k) in
199 if !verbose then List.iter print_endline bl;
200 eval 0
201 else
202 eval (succ k)
203 end
204 in
205 try
206 let _ = next_block 0 in (* to skip the Coq banner *)
207 let _ = next_block 0 in (* to skip the Coq answer to Set Printing Width *)
208 outside ()
209 with End_of_file -> begin
210 close_in c_tex;
211 close_in c_coq;
212 close_out c_out
213 end
214
215 (* Process of one TeX file *)
216
217 let rm f = try Sys.remove f with _ -> ()
218
219 let one_file texfile =
220 let inputv = Filename.temp_file "coq_tex" ".v" in
221 let coq_output = Filename.temp_file "coq_tex" ".coq_output"in
222 let result =
223 if !output_specified then
224 !output
225 else if Filename.check_suffix texfile ".tex" then
226 (Filename.chop_suffix texfile ".tex") ^ ".v.tex"
227 else
228 texfile ^ ".v.tex"
229 in
230 try
231 (* 1. extract Coq phrases *)
232 extract texfile inputv;
233 (* 2. run Coq on input *)
234 let _ = Sys.command (Printf.sprintf "%s < %s > %s 2>&1" !image inputv
235 coq_output)
236 in
237 (* 3. insert Coq output into original file *)
238 insert texfile coq_output result;
239 (* 4. clean up *)
240 rm inputv; rm coq_output
241 with e -> begin
242 rm inputv; rm coq_output;
243 raise e
244 end
245
246 (* Parsing of the command line, check of the Coq command and process
247 * of all the files in the command line, one by one *)
248
249 let files = ref []
250
251 let parse_cl () =
252 Arg.parse
253 [ "-o", Arg.String (fun s -> output_specified := true; output := s),
254 "output-file Specifiy the resulting LaTeX file";
255 "-n", Arg.Int (fun n -> linelen := n),
256 "line-width Set the line width";
257 "-image", Arg.String (fun s -> image := s),
258 "coq-image Use coq-image as Coq command";
259 "-w", Arg.Set cut_at_blanks,
260 " Try to cut lines at blanks";
261 "-v", Arg.Set verbose,
262 " Verbose mode (show Coq answers on stdout)";
263 "-sl", Arg.Set slanted,
264 " Coq answers in slanted font (only with LaTeX2e)";
265 "-hrule", Arg.Set hrule,
266 " Coq parts are written between 2 horizontal lines";
267 "-small", Arg.Set small,
268 " Coq parts are written in small font"
269 ]
270 (fun s -> files := s :: !files)
271 "coq-tex [options] file ..."
272
273 let main () =
274 parse_cl ();
275 if !image = "" then begin
276 Printf.printf "Warning: preprocessing with default image \"coqtop\"\n";
277 image := "coqtop"
278 end;
279 if Sys.command (!image ^ " -batch > /dev/null 2>&1") <> 0 then begin
280 Printf.printf "Error: ";
281 let _ = Sys.command (!image ^ " -batch") in
282 exit 1
283 end else begin
284 Printf.printf "Your version of coqtop seems OK\n";
285 flush stdout
286 end;
287 List.iter one_file (List.rev !files)
288
289 let _ = Printexc.catch main ()
287287 | (f,_) :: _ -> escape f
288288 | _ -> escape f
289289
290 let traite_fichier_Coq verbose f =
290 let rec traite_fichier_Coq verbose f =
291291 try
292292 let chan = open_in f in
293293 let buf = Lexing.from_channel chan in
346346 addQueue deja_vu_v [str];
347347 try
348348 let file_str = Hashtbl.find vKnown [str] in
349 printf " %s.v" (canonize file_str)
349 let canon = canonize file_str in
350 printf " %s.v" canon;
351 traite_fichier_Coq true (canon ^ ".v")
350352 with Not_found -> ()
351353 end
352354 | AddLoadPath _ | AddRecLoadPath _ -> (* TODO *) ()
3434 type index_entry =
3535 | Def of string * entry_type
3636 | Ref of coq_module * string * entry_type
37 | Mod of coq_module * string
3837
3938 let current_type : entry_type ref = ref Library
4039 let current_library = ref ""
4140 (** refers to the file being parsed *)
4241
43 (** [deftable] stores only definitions and is used to interpolate idents
44 inside comments, which are not globalized otherwise. *)
45
42 (** [deftable] stores only definitions and is used to build the index *)
4643 let deftable = Hashtbl.create 97
44
45 (** [byidtable] is used to interpolate idents inside comments, which are not
46 globalized otherwise. *)
47 let byidtable = Hashtbl.create 97
4748
4849 (** [reftable] stores references and definitions *)
4950 let reftable = Hashtbl.create 97
5859 else ""
5960
6061 let add_def loc1 loc2 ty sp id =
62 let fullid = full_ident sp id in
63 let def = Def (fullid, ty) in
6164 for loc = loc1 to loc2 do
62 Hashtbl.add reftable (!current_library, loc) (Def (full_ident sp id, ty))
65 Hashtbl.add reftable (!current_library, loc) def
6366 done;
64 Hashtbl.add deftable id (Def (full_ident sp id, ty))
67 Hashtbl.add deftable !current_library (fullid, ty);
68 Hashtbl.add byidtable id (!current_library, fullid, ty)
6569
6670 let add_ref m loc m' sp id ty =
71 let fullid = full_ident sp id in
6772 if Hashtbl.mem reftable (m, loc) then ()
68 else Hashtbl.add reftable (m, loc) (Ref (m', full_ident sp id, ty));
73 else Hashtbl.add reftable (m, loc) (Ref (m', fullid, ty));
6974 let idx = if id = "<>" then m' else id in
70 if Hashtbl.mem deftable idx then ()
71 else Hashtbl.add deftable idx (Ref (m', full_ident sp id, ty))
72
73 let add_mod m loc m' id =
74 Hashtbl.add reftable (m, loc) (Mod (m', id));
75 Hashtbl.add deftable m (Mod (m', id))
75 if Hashtbl.mem byidtable idx then ()
76 else Hashtbl.add byidtable idx (m', fullid, ty)
7677
7778 let find m l = Hashtbl.find reftable (m, l)
7879
79 let find_string m s = Hashtbl.find deftable s
80 let find_string m s = let (m,s,t) = Hashtbl.find byidtable s in Ref (m,s,t)
8081
8182 (*s Manipulating path prefixes *)
8283
288289 let l = try Hashtbl.find bt t with Not_found -> [] in
289290 Hashtbl.replace bt t ((s,m) :: l)
290291 in
291 let classify m e = match e with
292 | Def (s,t) -> add_g s m t; add_bt t s m
293 | Ref _ | Mod _ -> ()
294 in
292 let classify m (s,t) = (add_g s m t; add_bt t s m) in
295293 Hashtbl.iter classify deftable;
296294 Hashtbl.iter (fun id m -> add_g id m Library; add_bt Library id m) modules;
297295 { idx_name = "global";
3333 type index_entry =
3434 | Def of string * entry_type
3535 | Ref of coq_module * string * entry_type
36 | Mod of coq_module * string
3736
37 (* Find what symbol coqtop said is located at loc in the source file *)
3838 val find : coq_module -> loc -> index_entry
3939
40 (* Find what data is referred to by some string in some coq module *)
4041 val find_string : coq_module -> string -> index_entry
4142
4243 val add_module : coq_module -> unit
125125
126126 let token_tree_texmacs = ref (initialize_texmacs ())
127127
128 let token_tree_latex = ref Tokens.empty_ttree
129 let token_tree_html = ref Tokens.empty_ttree
130
128131 let initialize_tex_html () =
129132 let if_utf8 = if !Cdglobals.utf8 then fun x -> Some x else fun _ -> None in
130 List.fold_right (fun (s,l,l') (tt,tt') ->
133 let (tree_latex, tree_html) = List.fold_right (fun (s,l,l') (tt,tt') ->
131134 (Tokens.ttree_add tt s l,
132135 match l' with None -> tt' | Some l' -> Tokens.ttree_add tt' s l'))
133136 [ "*" , "\\ensuremath{\\times}", if_utf8 "×";
150153 "Π", "\\ensuremath{\\Pi}", if_utf8 "Π";
151154 "λ", "\\ensuremath{\\lambda}", if_utf8 "λ";
152155 (* "fun", "\\ensuremath{\\lambda}" ? *)
153 ] (Tokens.empty_ttree,Tokens.empty_ttree)
154
155 let token_tree_latex = ref (fst (initialize_tex_html ()))
156 let token_tree_html = ref (snd (initialize_tex_html ()))
156 ] (Tokens.empty_ttree,Tokens.empty_ttree) in
157 token_tree_latex := tree_latex;
158 token_tree_html := tree_html
157159
158160 let add_printing_token s (t1,t2) =
159161 (match t1 with None -> () | Some t1 ->
324326 let space = 0.5 *. (float n) in
325327 printf "\\coqdocindent{%2.2fem}\n" space
326328
327 let module_ref m s =
328 printf "\\coqdocmodule{%s}{%s}" m (escaped s)
329
330329 let ident_ref m fid typ s =
331330 let id = if fid <> "" then (m ^ "." ^ fid) else m in
332331 match find_module m with
355354 let reference s = function
356355 | Def (fullid,typ) ->
357356 defref (get_module false) fullid typ s
358 | Mod (m,s') when s = s' ->
359 module_ref m s
360357 | Ref (m,fullid,typ) ->
361358 ident_ref m fullid typ s
362 | Mod _ ->
363 printf "\\coqdocvar{%s}" (escaped s)
364359
365360 (*s The sublexer buffers symbol characters and attached
366361 uninterpreted ident and try to apply special translation such as,
388383 last_was_in := false
389384
390385 let initialize () =
386 initialize_tex_html ();
391387 Tokens.token_tree := token_tree_latex;
392388 Tokens.outfun := output_sublexer_string
393389
533529 end
534530
535531 let trailer () =
536 if !index && (get_module false) <> "Index" then
537 printf "</div>\n\n<div id=\"footer\">\n<hr/><a href=\"%s.html\">Index</a>" !index_name;
538 if !header_trailer then
539 if !footer_file_spec then
532 if !header_trailer && !footer_file_spec then
540533 let cin = Pervasives.open_in !footer_file in
541534 try
542535 while true do
544537 printf "%s\n" s
545538 done
546539 with End_of_file -> Pervasives.close_in cin
547 else
548 begin
549 printf "<hr/>This page has been generated by ";
550 printf "<a href=\"%s\">coqdoc</a>\n" Coq_config.wwwcoq;
551 printf "</div>\n\n</div>\n\n</body>\n</html>"
552 end
540 else
541 begin
542 if !index && (get_module false) <> "Index" then
543 printf "</div>\n\n<div id=\"footer\">\n<hr/><a href=\"%s.html\">Index</a>" !index_name;
544 printf "<hr/>This page has been generated by ";
545 printf "<a href=\"%s\">coqdoc</a>\n" Coq_config.wwwcoq;
546 printf "</div>\n\n</div>\n\n</body>\n</html>"
547 end
553548
554549 let start_module () =
555550 let ln = !lib_name in
619614 | Some n -> n
620615 | None -> addr)
621616
622 let module_ref m s =
623 match find_module m with
624 | Local ->
625 printf "<a class=\"modref\" href=\"%s.html\">%s</a>" m s
626 | External m when !externals ->
627 printf "<a class=\"modref\" href=\"%s.html\">%s</a>" m s
628 | External _ | Unknown ->
629 output_string s
630
631617 let ident_ref m fid typ s =
632618 match find_module m with
633619 | Local ->
644630 | Def (fullid,ty) ->
645631 printf "<a name=\"%s\">" fullid;
646632 printf "<span class=\"id\" type=\"%s\">%s</span></a>" (type_name ty) s
647 | Mod (m,s') when s = s' ->
648 module_ref m s
649633 | Ref (m,fullid,ty) ->
650634 ident_ref m fullid (type_name ty) s
651 | Mod _ ->
652 printf "<span class=\"id\" type=\"mod\">%s</span>" s
653635
654636 let output_sublexer_string doescape issymbchar tag s =
655637 let s = if doescape then escaped s else s in
666648 Tokens.output_tagged_symbol_char tag c
667649
668650 let initialize () =
651 initialize_tex_html();
669652 Tokens.token_tree := token_tree_html;
670653 Tokens.outfun := output_sublexer_string
671654
2020 Xml_utils.print_xml (snd !coqtop) xml_query;
2121 flush (snd !coqtop);
2222 let xml_answer = Xml_parser.parse p (Xml_parser.SChannel (fst !coqtop)) in
23 let res = Ide_intf.to_answer xml_answer in
23 let res = Ide_intf.to_answer xml_answer call in
2424 prerr_endline (Ide_intf.pr_full_value call res);
2525 match res with Interface.Fail _ -> exit 1 | _ -> ()
2626
4444 evars : unit -> evar list option;
4545 hints : unit -> (hint list * hint) option;
4646 status : unit -> status;
47 search : search_flags -> search_answer list;
47 search : search_flags -> string coq_object list;
4848 get_options : unit -> (option_name * option_state) list;
4949 set_options : (option_name * option_value) list -> unit;
5050 inloadpath : string -> bool;
6262 let evars : evar list option call = Evars
6363 let hints : (hint list * hint) option call = Hints
6464 let status : status call = Status
65 let search flags : search_answer list call = Search flags
65 let search flags : string coq_object list call = Search flags
6666 let get_options : (option_name * option_state) list call = GetOptions
6767 let set_options l : unit call = SetOptions l
6868 let inloadpath s : bool call = InLoadPath s
8080 | Evars -> Obj.magic (handler.evars () : evar list option)
8181 | Hints -> Obj.magic (handler.hints () : (hint list * hint) option)
8282 | Status -> Obj.magic (handler.status () : status)
83 | Search flags -> Obj.magic (handler.search flags : search_answer list)
83 | Search flags -> Obj.magic (handler.search flags : string coq_object list)
8484 | GetOptions -> Obj.magic (handler.get_options () : (option_name * option_state) list)
8585 | SetOptions opts -> Obj.magic (handler.set_options opts : unit)
8686 | InLoadPath s -> Obj.magic (handler.inloadpath s : bool)
129129
130130 (** Base types *)
131131
132 let of_unit () = Element ("unit", [], [])
133
134 let to_unit = function
135 | Element ("unit", [], []) -> ()
136 | _ -> raise Marshal_error
137
132138 let of_bool b =
133139 if b then constructor "bool" "true" []
134140 else constructor "bool" "false" []
165171 let of_int i = Element ("int", [], [PCData (string_of_int i)])
166172
167173 let to_int = function
168 | Element ("int", [], [PCData s]) -> int_of_string s
174 | Element ("int", [], [PCData s]) ->
175 (try int_of_string s with Failure _ -> raise Marshal_error)
169176 | _ -> raise Marshal_error
170177
171178 let of_pair f g (x, y) = Element ("pair", [], [f x; g y])
231238 | "include_blacklist" -> Include_Blacklist
232239 | _ -> raise Marshal_error)
233240
234 let of_search_answer ans =
235 let path = of_list of_string ans.search_answer_full_path in
236 let name = of_string ans.search_answer_base_name in
237 let tpe = of_string ans.search_answer_type in
238 Element ("search_answer", [], [path; name; tpe])
239
240 let to_search_answer = function
241 | Element ("search_answer", [], [path; name; tpe]) ->
242 let path = to_list to_string path in
243 let name = to_string name in
244 let tpe = to_string tpe in {
245 search_answer_full_path = path;
246 search_answer_base_name = name;
247 search_answer_type = tpe;
241 let of_coq_object f ans =
242 let prefix = of_list of_string ans.coq_object_prefix in
243 let qualid = of_list of_string ans.coq_object_qualid in
244 let obj = f ans.coq_object_object in
245 Element ("coq_object", [], [prefix; qualid; obj])
246
247 let to_coq_object f = function
248 | Element ("coq_object", [], [prefix; qualid; obj]) ->
249 let prefix = to_list to_string prefix in
250 let qualid = to_list to_string qualid in
251 let obj = f obj in {
252 coq_object_prefix = prefix;
253 coq_object_qualid = qualid;
254 coq_object_object = obj;
248255 }
249256 | _ -> raise Marshal_error
250257
411418 }
412419 | _ -> raise Marshal_error
413420
414 let of_hints =
415 let of_hint = of_list (of_pair of_string of_string) in
416 of_option (of_pair (of_list of_hint) of_hint)
417
418 let of_answer (q : 'a call) (r : 'a value) =
419 let convert = match q with
420 | Interp _ -> Obj.magic (of_string : string -> xml)
421 | Rewind _ -> Obj.magic (of_int : int -> xml)
422 | Goal -> Obj.magic (of_option of_goals : goals option -> xml)
423 | Evars -> Obj.magic (of_option (of_list of_evar) : evar list option -> xml)
424 | Hints -> Obj.magic (of_hints : (hint list * hint) option -> xml)
425 | Status -> Obj.magic (of_status : status -> xml)
426 | Search _ -> Obj.magic (of_list of_search_answer : search_answer list -> xml)
427 | GetOptions -> Obj.magic (of_list (of_pair (of_list of_string) of_option_state) : (option_name * option_state) list -> xml)
428 | SetOptions _ -> Obj.magic (fun _ -> Element ("unit", [], []))
429 | InLoadPath _ -> Obj.magic (of_bool : bool -> xml)
430 | MkCases _ -> Obj.magic (of_list (of_list of_string) : string list list -> xml)
431 | Quit -> Obj.magic (fun _ -> Element ("unit", [], []))
432 | About -> Obj.magic (of_coq_info : coq_info -> xml)
433 in
434 of_value convert r
435
436 let to_answer xml =
437 let rec convert elt = match elt with
438 | Element (tpe, attrs, l) ->
439 begin match tpe with
440 | "unit" -> Obj.magic ()
441 | "string" -> Obj.magic (to_string elt : string)
442 | "int" -> Obj.magic (to_int elt : int)
443 | "status" -> Obj.magic (to_status elt : status)
444 | "bool" -> Obj.magic (to_bool elt : bool)
445 | "list" -> Obj.magic (to_list convert elt : 'a list)
446 | "option" -> Obj.magic (to_option convert elt : 'a option)
447 | "pair" -> Obj.magic (to_pair convert convert elt : ('a * 'b))
448 | "goals" -> Obj.magic (to_goals elt : goals)
449 | "evar" -> Obj.magic (to_evar elt : evar)
450 | "option_value" -> Obj.magic (to_option_value elt : option_value)
451 | "option_state" -> Obj.magic (to_option_state elt : option_state)
452 | "coq_info" -> Obj.magic (to_coq_info elt : coq_info)
453 | "search_answer" -> Obj.magic (to_search_answer elt : search_answer)
454 | _ -> raise Marshal_error
455 end
456 | _ -> raise Marshal_error
457 in
458 to_value convert xml
421 (** Conversions between ['a value] and xml answers
422
423 When decoding an xml answer, we dynamically check that it is compatible
424 with the original call. For that we now rely on the fact that all
425 sub-fonctions [to_xxx : xml -> xxx] check that the current xml element
426 is "xxx", and raise [Marshal_error] if anything goes wrong.
427 *)
428
429 type value_type =
430 | Unit | String | Int | Bool | Goals | Evar | State | Option_state | Coq_info
431 | Option of value_type
432 | List of value_type
433 | Coq_object of value_type
434 | Pair of value_type * value_type
435
436 let hint = List (Pair (String, String))
437 let option_name = List String
438
439 let expected_answer_type = function
440 | Interp _ -> String
441 | Rewind _ -> Int
442 | Goal -> Option Goals
443 | Evars -> Option (List Evar)
444 | Hints -> Option (Pair (List hint, hint))
445 | Status -> State
446 | Search _ -> List (Coq_object String)
447 | GetOptions -> List (Pair (option_name, Option_state))
448 | SetOptions _ -> Unit
449 | InLoadPath _ -> Bool
450 | MkCases _ -> List (List String)
451 | Quit -> Unit
452 | About -> Coq_info
453
454 let of_answer (q : 'a call) (r : 'a value) : xml =
455 let rec convert ty : 'a -> xml = match ty with
456 | Unit -> Obj.magic of_unit
457 | Bool -> Obj.magic of_bool
458 | String -> Obj.magic of_string
459 | Int -> Obj.magic of_int
460 | State -> Obj.magic of_status
461 | Option_state -> Obj.magic of_option_state
462 | Coq_info -> Obj.magic of_coq_info
463 | Goals -> Obj.magic of_goals
464 | Evar -> Obj.magic of_evar
465 | List t -> Obj.magic (of_list (convert t))
466 | Option t -> Obj.magic (of_option (convert t))
467 | Coq_object t -> Obj.magic (of_coq_object (convert t))
468 | Pair (t1,t2) -> Obj.magic (of_pair (convert t1) (convert t2))
469 in
470 of_value (convert (expected_answer_type q)) r
471
472 let to_answer xml (c : 'a call) : 'a value =
473 let rec convert ty : xml -> 'a = match ty with
474 | Unit -> Obj.magic to_unit
475 | Bool -> Obj.magic to_bool
476 | String -> Obj.magic to_string
477 | Int -> Obj.magic to_int
478 | State -> Obj.magic to_status
479 | Option_state -> Obj.magic to_option_state
480 | Coq_info -> Obj.magic to_coq_info
481 | Goals -> Obj.magic to_goals
482 | Evar -> Obj.magic to_evar
483 | List t -> Obj.magic (to_list (convert t))
484 | Option t -> Obj.magic (to_option (convert t))
485 | Coq_object t -> Obj.magic (to_coq_object (convert t))
486 | Pair (t1,t2) -> Obj.magic (to_pair (convert t1) (convert t2))
487 in
488 to_value (convert (expected_answer_type c)) xml
459489
460490 (** * Debug printing *)
461491
7676 evars : unit -> evar list option;
7777 hints : unit -> (hint list * hint) option;
7878 status : unit -> status;
79 search : search_flags -> search_answer list;
79 search : search_flags -> string coq_object list;
8080 get_options : unit -> (option_name * option_state) list;
8181 set_options : (option_name * option_value) list -> unit;
8282 inloadpath : string -> bool;
103103 val to_call : xml -> 'a call
104104
105105 val of_answer : 'a call -> 'a value -> xml
106 val to_answer : xml -> 'a value
106 val to_answer : xml -> 'a call -> 'a value
107107
108108 (** * Debug printing *)
109109
126126 let id_s = Names.string_of_id id in
127127 let type_s = string_of_ppcmds (pr_ltype_env env ast) in
128128 [
129 ("clear "^id_s),("clear "^id_s^".\n");
130 ("apply "^id_s),("apply "^id_s^".\n");
131 ("exact "^id_s),("exact "^id_s^".\n");
132 ("generalize "^id_s),("generalize "^id_s^".\n");
133 ("absurd <"^id_s^">"),("absurd "^type_s^".\n")
129 ("clear "^id_s),("clear "^id_s^".");
130 ("apply "^id_s),("apply "^id_s^".");
131 ("exact "^id_s),("exact "^id_s^".");
132 ("generalize "^id_s),("generalize "^id_s^".");
133 ("absurd <"^id_s^">"),("absurd "^type_s^".")
134134 ] @ [
135 ("discriminate "^id_s),("discriminate "^id_s^".\n");
136 ("injection "^id_s),("injection "^id_s^".\n")
135 ("discriminate "^id_s),("discriminate "^id_s^".");
136 ("injection "^id_s),("injection "^id_s^".")
137137 ] @ [
138 ("rewrite "^id_s),("rewrite "^id_s^".\n");
139 ("rewrite <- "^id_s),("rewrite <- "^id_s^".\n")
138 ("rewrite "^id_s),("rewrite "^id_s^".");
139 ("rewrite <- "^id_s),("rewrite <- "^id_s^".")
140140 ] @ [
141 ("elim "^id_s), ("elim "^id_s^".\n");
142 ("inversion "^id_s), ("inversion "^id_s^".\n");
143 ("inversion clear "^id_s), ("inversion_clear "^id_s^".\n")
141 ("elim "^id_s), ("elim "^id_s^".");
142 ("inversion "^id_s), ("inversion "^id_s^".");
143 ("inversion clear "^id_s), ("inversion_clear "^id_s^".")
144144 ]
145145
146146 let concl_next_tac sigma concl =
147 let expand s = (s,s^".\n") in
147 let expand s = (s,s^".") in
148148 List.map expand ([
149149 "intro";
150150 "intros";
311311 in
312312 let ans = ref [] in
313313 let print_function ref env constr =
314 let name = Names.string_of_id (Nametab.basename_of_global ref) in
315 let make_path = Names.string_of_id in
316 let path =
317 List.rev_map make_path (Names.repr_dirpath (Nametab.dirpath_of_global ref))
318 in
319 let answer = {
320 Interface.search_answer_full_path = path;
321 Interface.search_answer_base_name = name;
322 Interface.search_answer_type = string_of_ppcmds (pr_lconstr_env env constr);
323 } in
314 let fullpath = repr_dirpath (Nametab.dirpath_of_global ref) in
315 let qualid = Nametab.shortest_qualid_of_global Idset.empty ref in
316 let (shortpath, basename) = Libnames.repr_qualid qualid in
317 let shortpath = repr_dirpath shortpath in
318 (* [shortpath] is a suffix of [fullpath] and we're looking for the missing
319 prefix *)
320 let rec prefix full short accu = match full, short with
321 | _, [] ->
322 let full = List.rev_map string_of_id full in
323 (full, accu)
324 | _ :: full, m :: short ->
325 prefix full short (string_of_id m :: accu)
326 | _ -> assert false
327 in
328 let (prefix, qualid) = prefix fullpath shortpath [string_of_id basename] in
329 let answer = {
330 Interface.coq_object_prefix = prefix;
331 Interface.coq_object_qualid = qualid;
332 Interface.coq_object_object = string_of_ppcmds (pr_lconstr_env env constr);
333 } in
324334 ans := answer :: !ans;
325335 in
326336 let () = Search.gen_filtered_search filter_function print_function in
431441 let () = pr_debug ("--> " ^ Ide_intf.pr_full_value q r) in
432442 Ide_intf.of_answer q r
433443 with
444 | Xml_parser.Error (Xml_parser.Empty, _) ->
445 pr_debug ("End of input, exiting");
446 exit 0
434447 | Xml_parser.Error (err, loc) ->
435448 let msg = "Syntax error in query: " ^ Xml_parser.error_msg err in
436449 fail msg
8585 the flag should be negated. *)
8686 type search_flags = (search_constraint * bool) list
8787
88 type search_answer = {
89 search_answer_full_path : string list;
90 search_answer_base_name : string;
91 search_answer_type : string;
88 (** A named object in Coq. [coq_object_qualid] is the shortest path defined for
89 the user. [coq_object_prefix] is the missing part to recover the fully
90 qualified name, i.e [fully_qualified = coq_object_prefix + coq_object_qualid].
91 [coq_object_object] is the actual content of the object. *)
92 type 'a coq_object = {
93 coq_object_prefix : string list;
94 coq_object_qualid : string list;
95 coq_object_object : 'a;
9296 }
9397
9498 type coq_info = {
207207 str "| " ++ hov 1 (prlist_with_sep spc str l) ++ str " =>"
208208 in
209209 msg (v 1 (str "match # with" ++ fnl () ++
210 prlist_with_sep fnl pr_branch patterns ++ fnl ()))
210 prlist_with_sep fnl pr_branch patterns ++ fnl () ++ str "end" ++ fnl ()))
211211
212212 (* "Print" commands *)
213213