diff --git a/HB/common/utils-synterp.elpi b/HB/common/utils-synterp.elpi index 014d513c..d0807549 100644 --- a/HB/common/utils-synterp.elpi +++ b/HB/common/utils-synterp.elpi @@ -24,6 +24,7 @@ with-attributes P :- att "primitive" bool, att "non_forgetful_inheritance" bool, att "hnf" bool, + att "interactive" bool, ] Opts, !, Opts => (save-docstring, P). diff --git a/HB/common/utils.elpi b/HB/common/utils.elpi index 07d859b3..3234f392 100644 --- a/HB/common/utils.elpi +++ b/HB/common/utils.elpi @@ -117,6 +117,9 @@ gref->modname_short GR Sep IDS :- func avoid-name-collision string -> string. avoid-name-collision S S1 :- + if (var S) + (S = "unnamed") + (true), coq.locate-all S L, if (std.mem L (loc-gref GR), coq.gref->path GR P, coq.env.current-path P) (S1 is S ^ "__" ^ {std.any->string {new_int}}) diff --git a/HB/instance.elpi b/HB/instance.elpi index f7f6eb1a..bb2ac214 100644 --- a/HB/instance.elpi +++ b/HB/instance.elpi @@ -34,7 +34,11 @@ declare-const Name BodySkel TyWPSkel CFL CSL :- std.do! [ % A side effect of opening a section is loosing meta data associated % with instances, in particular builder tags are lost if-verbose (coq.say "HB: skipping section opening"), - SectionBody = Body + SectionBody = Body, + %FIXME : introduce a bug + %TODO re-allow local instances (test file local_instance.v) + std.assert! (coq.next-synterp-action (begin-section SectionName)) "synterp code did not open section", + log.coq.env.begin-section SectionName ) ( std.assert! (coq.next-synterp-action (begin-section SectionName)) "synterp code did not open section", log.coq.env.begin-section SectionName, @@ -78,10 +82,11 @@ declare-const Name BodySkel TyWPSkel CFL CSL :- std.do! [ true, % handle parameters via a section -- end - if (TyWP = arity _) true ( + % FIXME + % if (TyWP = arity _) true ( if-verbose (coq.say {header} "closing instance section"), - log.coq.env.end-section-name SectionName - ), + log.coq.env.end-section-name SectionName, + % ), % we accumulate clauses now that the section is over acc-clauses current Clauses @@ -295,10 +300,16 @@ declare-instance Factory T F Clauses CFL CSL :- !, declare-canonical-instances-from-factory-and-local-builders Factory T F TheFactory FGR Clauses CFL CSL. -declare-instance Factory T F Clauses CFL CSL :- +declare-instance Factory T F Clauses CFL CSL :- !, declare-canonical-instances-from-factory Factory T F Clauses1 CFL CSL, clauses-for-export {std.append CFL CSL} Clauses2, std.append Clauses1 Clauses2 Clauses. +% declare-instance Factory T F Clauses CFL CSL :- !, +% if (get-option "program" tt) +% (coq.say "HB: declare-instance: program option detected") true, +% declare-canonical-instances-from-factory Factory T F Clauses1 CFL CSL, +% clauses-for-export {std.append CFL CSL} Clauses2, +% std.append Clauses1 Clauses2 Clauses. func clauses-for-export list (pair id constant) -> list prop. clauses-for-export CL ECL :- diff --git a/HB/structures.v b/HB/structures.v index 90fcb358..fbad9e4e 100644 --- a/HB/structures.v +++ b/HB/structures.v @@ -1,3 +1,5 @@ +Set Warnings "-elpi.flex-clause". + (* Support constants, to be kept in sync with shim/structures.v *) From Corelib Require Import ssreflect ssrfun. @@ -771,6 +773,7 @@ HB.instance Definition N Params := Factory.Build Params T … - [#[verbose]] for a verbose output. - [#[hnf] to compute the head normal form of CS instances before declaring them + - [#[interactive]] to provide part of the instance in tactics mode. *) #[arguments(raw)] Elpi Command HB.instance. @@ -792,23 +795,99 @@ main [const-decl Name (some BodySkel) TyWPSkel] :- !, main [T0, F0] :- !, coq.warning "HB" "HB.deprecated" "The syntax \"HB.instance Key FactoryInstance\" is deprecated, use \"HB.instance Definition\" instead", with-attributes (with-logging (instance.declare-existing T0 F0)). - +main-interp-proof [const-decl Name (some BodySkel) TyWPSkel] _ Body AllGoals (const-decl Name (some Body) TyWP) :- + std.assert-ok! (coq.elaborate-arity-skeleton TyWPSkel _ TyWP) "Definition type illtyped", + coq.arity->term TyWP Ty, + std.assert-ok! (coq.elaborate-skeleton BodySkel Ty Body) "Definition illtyped", + coq.ltac.collect-goals Body Goal Shelved, + std.append Shelved Goal AllGoals. }}. + #[synterp] Elpi Accumulate lp:{{ shorten coq.env.{ begin-section, end-section }. -main [const-decl _ _ (arity _)] :- !. -main [const-decl _ _ (parameter _ _ _ _)] :- !, - SectionName is "hb_instance_" ^ {std.any->string {new_int} }, - begin-section SectionName, end-section. -main [_, _] :- !. +pred interactive-in-attributes i:list attribute. + interactive-in-attributes [attribute "interactive" (leaf-str "") | _]. + interactive-in-attributes [_ | Atts] :- interactive-in-attributes Atts. -main _ :- coq.error "Usage: HB.instance Definition := T ...". +main _ :- + attributes A, + if (interactive-in-attributes A) + (true) + (SectionName is "hb_instance_" ^ {std.any->string {new_int} }, + begin-section SectionName, end-section). }}. + Elpi Typecheck. +#[proof(begin_if="interactive")] Elpi Export HB.instance. + + +#[arguments(raw)] Elpi Command HB.end_instance. +Elpi Accumulate Db hb.db. +Elpi Accumulate File "HB/common/stdpp.elpi". +Elpi Accumulate File "HB/common/database.elpi". +Elpi Accumulate File "HB/common/compat_acc_clauses_all.elpi". +Elpi Accumulate File "HB/common/compat_add_secvar_all.elpi". +Elpi Accumulate File "HB/common/utils.elpi". +Elpi Accumulate File "HB/common/log.elpi". +Elpi Accumulate File "HB/common/synthesis.elpi". +Elpi Accumulate File "HB/context.elpi". +Elpi Accumulate File "HB/instance.elpi". +Elpi Accumulate lp:{{ + + + func under term, list (triple name term term) -> term. + under (fun N Ty F) Acc (fun N Ty F') :- + @pi-decl N Ty x\ + under (F x) [(triple N x Ty)|Acc] (F' x). + under (app L) Acc (app L') :- + aux Acc L L'. + + func aux list (triple name term term), list term -> list term. + aux _ [] []. + aux Acc [(global _ as T)|TS] [T|TS'] :- !, + aux Acc TS TS'. + aux Acc [T|TS] [T|TS'] :- + coq.typecheck T Ty ok, + coq.typecheck Ty TyTy ok, + %coq.typecheck-ty does not make coercions + (not (TyTy = {{Prop}})), !, + aux Acc TS TS'. + aux Acc [T|TS] [T'|TS'] :- + std.spy! (abstract Acc T TA), + log.coq.env.add-const _ TA _ @opaque! C, + T' = app [(global (const C))|{std.map Acc triple_2}], + aux Acc TS TS'. + + func abstract list (triple name term term), term -> term. + abstract [] T T' :- + copy T T'. + abstract [(triple N V Ty) | A] T (fun N Ty F) :- + pi w\ (copy V w :- !) => abstract A T (F w). + + main-interp-qed _ _ P _GL (const-decl Name (some _Body) TyWP) :- + under P [] P', + with-attributes (with-logging (instance.declare-const Name P' TyWP _ _)). +}}. + +#[synterp] Elpi Accumulate lp:{{ + +shorten coq.env.{ begin-section, end-section }. + +main _ :- + SectionName is "hb_instance_" ^ {std.any->string {new_int} }, + begin-section SectionName, end-section. +}}. + +#[proof="end"] +Elpi Export HB.end_instance. + + + + (* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% *) (* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% *) (* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% *) diff --git a/Makefile.test-suite-stdlib.coq b/Makefile.test-suite-stdlib.coq new file mode 100644 index 00000000..0d4c2b6f --- /dev/null +++ b/Makefile.test-suite-stdlib.coq @@ -0,0 +1,961 @@ +########################################################################## +## # The Rocq Prover / The Rocq Development Team ## +## v # Copyright INRIA, CNRS and contributors ## +## /dev/null 2>/dev/null; echo $$?)) +STDTIME?=command time -f $(TIMEFMT) +else +ifeq (0,$(shell gtime -f "" true >/dev/null 2>/dev/null; echo $$?)) +STDTIME?=gtime -f $(TIMEFMT) +else +STDTIME?=command time +endif +endif + +COQBIN?= +ifneq (,$(COQBIN)) +# add an ending / +COQBIN:=$(COQBIN)/ +endif + +# Coq binaries +ROCQ ?= "$(COQBIN)rocq" +COQC ?= "$(COQBIN)rocq" c +COQTOP ?= "$(COQBIN)rocq" repl +COQCHK ?= "$(COQBIN)rocqchk" +COQNATIVE ?= "$(COQBIN)rocq" native-precompile +COQDEP ?= "$(COQBIN)rocq" dep +COQDOC ?= "$(COQBIN)rocq" doc +COQPP ?= "$(COQBIN)rocq" pp-mlg +COQMKFILE ?= "$(COQBIN)rocq" makefile +OCAMLLIBDEP ?= "$(COQBIN)ocamllibdep" + +# Timing scripts +COQMAKE_ONE_TIME_FILE ?= "$(COQCORELIB)/tools/make-one-time-file.py" +COQMAKE_BOTH_TIME_FILES ?= "$(COQCORELIB)/tools/make-both-time-files.py" +COQMAKE_BOTH_SINGLE_TIMING_FILES ?= "$(COQCORELIB)/tools/make-both-single-timing-files.py" +BEFORE ?= +AFTER ?= + +# OCaml binaries +CAMLC ?= "$(OCAMLFIND)" ocamlc -c +CAMLOPTC ?= "$(OCAMLFIND)" opt -c +CAMLLINK ?= "$(OCAMLFIND)" ocamlc -linkall +CAMLOPTLINK ?= "$(OCAMLFIND)" opt -linkall +CAMLDOC ?= "$(OCAMLFIND)" ocamldoc +CAMLDEP ?= "$(OCAMLFIND)" ocamldep -slash -ml-synonym .mlpack + +# DESTDIR is prepended to all installation paths +DESTDIR ?= + +# Debug builds, typically -g to OCaml, -debug to Rocq. +CAMLDEBUG ?= +COQDEBUG ?= + +# Extra packages to be linked in (as in findlib -package) +CAMLPKGS ?= +FINDLIBPKGS = -package rocq-runtime.plugins.ltac $(CAMLPKGS) + +# Option for making timing files +TIMING?= +# Option for changing sorting of timing output file +TIMING_SORT_BY ?= auto +# Option for changing the fuzz parameter on the output file +TIMING_FUZZ ?= 0 +# Option for changing whether to use real or user time for timing tables +TIMING_REAL?= +# Option for including the memory column(s) +TIMING_INCLUDE_MEM?= +# Option for sorting by the memory column +TIMING_SORT_BY_MEM?= +# Output file names for timed builds +TIME_OF_BUILD_FILE ?= time-of-build.log +TIME_OF_BUILD_BEFORE_FILE ?= time-of-build-before.log +TIME_OF_BUILD_AFTER_FILE ?= time-of-build-after.log +TIME_OF_PRETTY_BUILD_FILE ?= time-of-build-pretty.log +TIME_OF_PRETTY_BOTH_BUILD_FILE ?= time-of-build-both.log +TIME_OF_PRETTY_BUILD_EXTRA_FILES ?= - # also output to the command line + +TGTS ?= + +# Retro compatibility (DESTDIR is standard on Unix, DSTROOT is not) +ifdef DSTROOT +DESTDIR := $(DSTROOT) +endif + +# Substitution of the path by appending $(DESTDIR) if needed. +# The variable $(COQMF_WINDRIVE) can be needed for Cygwin environments. +windrive_path = $(if $(COQMF_WINDRIVE),$(subst $(COQMF_WINDRIVE),/,$(1)),$(1)) +destination_path = $(if $(DESTDIR),$(DESTDIR)/$(call windrive_path,$(1)),$(1)) + +# Installation paths of libraries and documentation. +COQLIBINSTALL ?= $(call destination_path,$(COQLIB)/user-contrib) +COQDOCINSTALL ?= $(call destination_path,$(DOCDIR)/coq/user-contrib) +COQPLUGININSTALL ?= $(call destination_path,$(COQCORELIB)/..) +COQTOPINSTALL ?= $(call destination_path,$(COQLIB)/toploop) # FIXME: Unused variable? + +# findlib files installation +FINDLIBPREINST= mkdir -p "$(COQPLUGININSTALL)/" +FINDLIBDESTDIR= -destdir "$(COQPLUGININSTALL)/" + +# we need to move out of sight $(METAFILE) otherwise findlib thinks the +# package is already installed +findlib_install = \ + $(HIDE)if [ "$(METAFILE)" ]; then \ + $(FINDLIBPREINST) && \ + mv "$(METAFILE)" "$(METAFILE).skip" ; \ + "$(OCAMLFIND)" install $(2) $(FINDLIBDESTDIR) $(FINDLIBPACKAGE) $(1); \ + rc=$$?; \ + mv "$(METAFILE).skip" "$(METAFILE)"; \ + exit $$rc; \ + fi +findlib_remove = \ + $(HIDE)if [ ! -z "$(METAFILE)" ]; then\ + "$(OCAMLFIND)" remove $(FINDLIBDESTDIR) $(FINDLIBPACKAGE); \ + fi + + +########## End of parameters ################################################## +# What follows may be relevant to you only if you need to +# extend this Makefile. If so, look for 'Extension point' here and +# put in Makefile.test-suite-stdlib.coq.local double colon rules accordingly. +# E.g. to perform some work after the all target completes you can write +# +# post-all:: +# echo "All done!" +# +# in Makefile.test-suite-stdlib.coq.local +# +############################################################################### + + + + +# Flags ####################################################################### +# +# We define a bunch of variables combining the parameters. +# To add additional flags to coq, coqchk or coqdoc, set the +# {COQ,COQCHK,COQDOC}EXTRAFLAGS variable to whatever you want to add. +# To overwrite the default choice and set your own flags entirely, set the +# {COQ,COQCHK,COQDOC}FLAGS variable. + +SHOW := $(if $(VERBOSE),@true "",@echo "") +HIDE := $(if $(VERBOSE),,@) + +TIMER=$(if $(TIMED), $(STDTIME), $(TIMECMD)) + +OPT?= + +# The DYNLIB variable is used by "coqdep -dyndep var" in .v.d +ifeq '$(OPT)' '-byte' +USEBYTE:=true +DYNLIB:=.cma +else +USEBYTE:= +DYNLIB:=.cmxs +endif + +# these variables are meant to be overridden if you want to add *extra* flags +COQEXTRAFLAGS?= +COQCHKEXTRAFLAGS?= +COQDOCEXTRAFLAGS?= + +# Find the last argument of the form "-native-compiler FLAG" +COQUSERNATIVEFLAG:=$(strip \ +$(subst -native-compiler-,,\ +$(lastword \ +$(filter -native-compiler-%,\ +$(subst -native-compiler ,-native-compiler-,\ +$(strip $(COQEXTRAFLAGS))))))) + +COQFILTEREDEXTRAFLAGS:=$(strip \ +$(filter-out -native-compiler-%,\ +$(subst -native-compiler ,-native-compiler-,\ +$(strip $(COQEXTRAFLAGS))))) + +COQACTUALNATIVEFLAG:=$(lastword $(COQMF_COQ_NATIVE_COMPILER_DEFAULT) $(COQMF_COQPROJECTNATIVEFLAG) $(COQUSERNATIVEFLAG)) + +ifeq '$(COQACTUALNATIVEFLAG)' 'yes' + COQNATIVEFLAG="-w" "-deprecated-native-compiler-option" "-native-compiler" "ondemand" + COQDONATIVE="yes" +else +ifeq '$(COQACTUALNATIVEFLAG)' 'ondemand' + COQNATIVEFLAG="-w" "-deprecated-native-compiler-option" "-native-compiler" "ondemand" + COQDONATIVE="no" +else + COQNATIVEFLAG="-w" "-deprecated-native-compiler-option" "-native-compiler" "no" + COQDONATIVE="no" +endif +endif + +# these flags do NOT contain the libraries, to make them easier to overwrite +COQFLAGS?=-q $(OTHERFLAGS) $(COQFILTEREDEXTRAFLAGS) $(COQNATIVEFLAG) +COQCHKFLAGS?=-silent -o $(COQCHKEXTRAFLAGS) +COQDOCFLAGS?=-interpolate -utf8 $(COQDOCEXTRAFLAGS) + +COQDOCLIBS?=$(COQLIBS_NOML) + +# The version of Coq being run and the version of rocq makefile that +# generated this makefile +# NB --print-version is not in the rocq shim +COQ_VERSION:=$(shell $(ROCQ) c --print-version | cut -d " " -f 1) +COQMAKEFILE_VERSION:=9.1.0 + +# COQ_SRC_SUBDIRS is for user-overriding, usually to add +# `user-contrib/Foo` to the includes, we keep COQCORE_SRC_SUBDIRS for +# Coq's own core libraries, which should be replaced by ocamlfind +# options at some point. +COQ_SRC_SUBDIRS?= +COQSRCLIBS?= $(foreach d,$(COQ_SRC_SUBDIRS), -I "$(COQLIB)/$(d)") + +CAMLFLAGS+=$(OCAMLLIBS) $(COQSRCLIBS) +# ocamldoc fails with unknown argument otherwise +CAMLDOCFLAGS:=$(filter-out -annot, $(filter-out -bin-annot, $(CAMLFLAGS))) +CAMLFLAGS+=$(OCAMLWARN) + +ifneq (,$(TIMING)) + ifeq (after,$(TIMING)) + TIMING_EXT=after-timing + else + ifeq (before,$(TIMING)) + TIMING_EXT=before-timing + else + TIMING_EXT=timing + endif + endif + TIMING_ARG=-time-file $<.$(TIMING_EXT) +else + TIMING_ARG= +endif + +ifneq (,$(PROFILING)) + PROFILE_ARG=-profile $@.prof.json + PROFILE_ZIP=gzip -f $@.prof.json +else + PROFILE_ARG= + PROFILE_ZIP=true +endif + +# Files ####################################################################### +# +# We here define a bunch of variables about the files being part of the +# Rocq project in order to ease the writing of build target and build rules + +VDFILE := .Makefile.test-suite-stdlib.coq.d + +ALLSRCFILES := \ + $(MLGFILES) \ + $(MLFILES) \ + $(MLPACKFILES) \ + $(MLLIBFILES) \ + $(MLIFILES) + +# helpers +vo_to_obj = $(addsuffix .o,\ + $(filter-out Warning: Error:,\ + $(shell $(COQTOP) -q -noinit -batch -quiet -print-mod-uid $(1)))) +strip_dotslash = $(patsubst ./%,%,$(1)) + +# without this we get undefined variables in the expansion for the +# targets of the [deprecated,use-mllib-or-mlpack] rule +with_undef = $(if $(filter-out undefined, $(origin $(1))),$($(1))) + +VO = vo +VOS = vos + +VOFILES = $(VFILES:.v=.$(VO)) +GLOBFILES = $(VFILES:.v=.glob) +HTMLFILES = $(VFILES:.v=.html) +GHTMLFILES = $(VFILES:.v=.g.html) +BEAUTYFILES = $(addsuffix .beautified,$(VFILES)) +TEXFILES = $(VFILES:.v=.tex) +GTEXFILES = $(VFILES:.v=.g.tex) +CMOFILES = \ + $(MLGFILES:.mlg=.cmo) \ + $(MLFILES:.ml=.cmo) \ + $(MLPACKFILES:.mlpack=.cmo) +CMXFILES = $(CMOFILES:.cmo=.cmx) +OFILES = $(CMXFILES:.cmx=.o) +CMAFILES = $(MLLIBFILES:.mllib=.cma) $(MLPACKFILES:.mlpack=.cma) +CMXAFILES = $(CMAFILES:.cma=.cmxa) +CMIFILES = \ + $(CMOFILES:.cmo=.cmi) \ + $(MLIFILES:.mli=.cmi) +# the /if/ is because old _CoqProject did not list a .ml(pack|lib) but just +# a .mlg file +CMXSFILES = \ + $(MLPACKFILES:.mlpack=.cmxs) \ + $(CMXAFILES:.cmxa=.cmxs) \ + $(if $(MLPACKFILES)$(CMXAFILES),,\ + $(MLGFILES:.mlg=.cmxs) $(MLFILES:.ml=.cmxs)) + +# files that are packed into a plugin (no extension) +PACKEDFILES = \ + $(call strip_dotslash, \ + $(foreach lib, \ + $(call strip_dotslash, \ + $(MLPACKFILES:.mlpack=_MLPACK_DEPENDENCIES)),$(call with_undef,$(lib)))) +# files that are archived into a .cma (mllib) +LIBEDFILES = \ + $(call strip_dotslash, \ + $(foreach lib, \ + $(call strip_dotslash, \ + $(MLLIBFILES:.mllib=_MLLIB_DEPENDENCIES)),$(call with_undef,$(lib)))) +CMIFILESTOINSTALL = $(filter-out $(addsuffix .cmi,$(PACKEDFILES)),$(CMIFILES)) +CMOFILESTOINSTALL = $(filter-out $(addsuffix .cmo,$(PACKEDFILES)),$(CMOFILES)) +OBJFILES = $(call vo_to_obj,$(VOFILES)) +ALLNATIVEFILES = \ + $(OBJFILES:.o=.cmi) \ + $(OBJFILES:.o=.cmx) \ + $(OBJFILES:.o=.cmxs) +FINDLIBPACKAGE=$(patsubst .%,%,$(suffix $(METAFILE))) + +# trick: wildcard filters out non-existing files, so that `install` doesn't show +# warnings and `clean` doesn't pass to rm a list of files that is too long for +# the shell. +NATIVEFILES = $(wildcard $(ALLNATIVEFILES)) +FILESTOINSTALL = \ + $(VOFILES) \ + $(VFILES) \ + $(GLOBFILES) \ + $(NATIVEFILES) +FINDLIBFILESTOINSTALL = \ + $(CMIFILESTOINSTALL) +ifeq '$(HASNATDYNLINK)' 'true' +DO_NATDYNLINK = yes +FINDLIBFILESTOINSTALL += $(CMXSFILES) $(CMXAFILES) $(CMOFILESTOINSTALL:.cmo=.cmx) +else +DO_NATDYNLINK = +endif + +ALLDFILES = $(addsuffix .d,$(ALLSRCFILES)) $(VDFILE) + +# Compilation targets ######################################################### + +all: + $(HIDE)$(MAKE) --no-print-directory -f "$(SELF)" pre-all + $(HIDE)$(MAKE) --no-print-directory -f "$(SELF)" real-all + $(HIDE)$(MAKE) --no-print-directory -f "$(SELF)" post-all +.PHONY: all + +all.timing.diff: + $(HIDE)$(MAKE) --no-print-directory -f "$(SELF)" pre-all + $(HIDE)$(MAKE) --no-print-directory -f "$(SELF)" real-all.timing.diff TIME_OF_PRETTY_BUILD_EXTRA_FILES="" + $(HIDE)$(MAKE) --no-print-directory -f "$(SELF)" post-all +.PHONY: all.timing.diff + +ifeq (0,$(TIMING_REAL)) +TIMING_REAL_ARG := +TIMING_USER_ARG := --user +else +ifeq (1,$(TIMING_REAL)) +TIMING_REAL_ARG := --real +TIMING_USER_ARG := +else +TIMING_REAL_ARG := +TIMING_USER_ARG := +endif +endif + +ifeq (0,$(TIMING_INCLUDE_MEM)) +TIMING_INCLUDE_MEM_ARG := --no-include-mem +else +TIMING_INCLUDE_MEM_ARG := +endif + +ifeq (1,$(TIMING_SORT_BY_MEM)) +TIMING_SORT_BY_MEM_ARG := --sort-by-mem +else +TIMING_SORT_BY_MEM_ARG := +endif + +make-pretty-timed-before:: TIME_OF_BUILD_FILE=$(TIME_OF_BUILD_BEFORE_FILE) +make-pretty-timed-after:: TIME_OF_BUILD_FILE=$(TIME_OF_BUILD_AFTER_FILE) +make-pretty-timed make-pretty-timed-before make-pretty-timed-after:: + $(HIDE)rm -f pretty-timed-success.ok + $(HIDE)($(MAKE) --no-print-directory -f "$(PARENT)" $(TGTS) TIMED=1 2>&1 && touch pretty-timed-success.ok) | tee -a $(TIME_OF_BUILD_FILE) + $(HIDE)rm pretty-timed-success.ok # must not be -f; must fail if the touch failed +print-pretty-timed:: + $(HIDE)$(COQMAKE_ONE_TIME_FILE) $(TIMING_INCLUDE_MEM_ARG) $(TIMING_SORT_BY_MEM_ARG) $(TIMING_REAL_ARG) $(TIME_OF_BUILD_FILE) $(TIME_OF_PRETTY_BUILD_FILE) $(TIME_OF_PRETTY_BUILD_EXTRA_FILES) +print-pretty-timed-diff:: + $(HIDE)$(COQMAKE_BOTH_TIME_FILES) --sort-by=$(TIMING_SORT_BY) $(TIMING_INCLUDE_MEM_ARG) $(TIMING_SORT_BY_MEM_ARG) $(TIMING_REAL_ARG) $(TIME_OF_BUILD_AFTER_FILE) $(TIME_OF_BUILD_BEFORE_FILE) $(TIME_OF_PRETTY_BOTH_BUILD_FILE) $(TIME_OF_PRETTY_BUILD_EXTRA_FILES) +ifeq (,$(BEFORE)) +print-pretty-single-time-diff:: + @echo 'Error: Usage: $(MAKE) print-pretty-single-time-diff AFTER=path/to/file.v.after-timing BEFORE=path/to/file.v.before-timing' + $(HIDE)false +else +ifeq (,$(AFTER)) +print-pretty-single-time-diff:: + @echo 'Error: Usage: $(MAKE) print-pretty-single-time-diff AFTER=path/to/file.v.after-timing BEFORE=path/to/file.v.before-timing' + $(HIDE)false +else +print-pretty-single-time-diff:: + $(HIDE)$(COQMAKE_BOTH_SINGLE_TIMING_FILES) --fuzz=$(TIMING_FUZZ) --sort-by=$(TIMING_SORT_BY) $(TIMING_USER_ARG) $(AFTER) $(BEFORE) $(TIME_OF_PRETTY_BUILD_FILE) $(TIME_OF_PRETTY_BUILD_EXTRA_FILES) +endif +endif +pretty-timed: + $(HIDE)$(MAKE) --no-print-directory -f "$(PARENT)" make-pretty-timed + $(HIDE)$(MAKE) --no-print-directory -f "$(SELF)" print-pretty-timed +.PHONY: pretty-timed make-pretty-timed make-pretty-timed-before make-pretty-timed-after print-pretty-timed print-pretty-timed-diff print-pretty-single-time-diff + +# Extension points for actions to be performed before/after the all target +pre-all:: + @# Extension point + $(HIDE)if [ "$(COQMAKEFILE_VERSION)" != "$(COQ_VERSION)" ]; then\ + echo "W: This Makefile was generated by Rocq/Coq $(COQMAKEFILE_VERSION)";\ + echo "W: while the current Rocq version is $(COQ_VERSION)";\ + fi +.PHONY: pre-all + +post-all:: + @# Extension point +.PHONY: post-all + +real-all: $(VOFILES) $(if $(USEBYTE),bytefiles,optfiles) +.PHONY: real-all + +real-all.timing.diff: $(VOFILES:.vo=.v.timing.diff) +.PHONY: real-all.timing.diff + +bytefiles: $(CMOFILES) $(CMAFILES) +.PHONY: bytefiles + +optfiles: $(if $(DO_NATDYNLINK),$(CMXSFILES)) +.PHONY: optfiles + +vos: $(VOFILES:%.vo=%.vos) +.PHONY: vos + +vok: $(VOFILES:%.vo=%.vok) +.PHONY: vok + +validate: $(VOFILES) + $(TIMER) $(COQCHK) $(COQCHKFLAGS) $(COQLIBS_NOML) $(PROFILE_ARG) $^ + $(HIDE)$(PROFILE_ZIP) +.PHONY: validate + +only: $(TGTS) +.PHONY: only + +# Documentation targets ####################################################### + +html: $(GLOBFILES) $(VFILES) + $(SHOW)'COQDOC -d html $(GAL)' + $(HIDE)mkdir -p html + $(HIDE)$(COQDOC) \ + -toc $(COQDOCFLAGS) -html $(GAL) $(COQDOCLIBS) -d html $(VFILES) + +mlihtml: $(MLIFILES:.mli=.cmi) + $(SHOW)'CAMLDOC -d $@' + $(HIDE)mkdir $@ || rm -rf $@/* + $(HIDE)$(CAMLDOC) -html \ + -d $@ -m A $(CAMLDEBUG) $(CAMLDOCFLAGS) $(MLIFILES) $(FINDLIBPKGS) + +all-mli.tex: $(MLIFILES:.mli=.cmi) + $(SHOW)'CAMLDOC -latex $@' + $(HIDE)$(CAMLDOC) -latex \ + -o $@ -m A $(CAMLDEBUG) $(CAMLDOCFLAGS) $(MLIFILES) $(FINDLIBPKGS) + +all.ps: $(VFILES) + $(SHOW)'COQDOC -ps $(GAL)' + $(HIDE)$(COQDOC) \ + -toc $(COQDOCFLAGS) -ps $(GAL) $(COQDOCLIBS) \ + -o $@ `$(COQDEP) -sort $(VFILES)` + +all.pdf: $(VFILES) + $(SHOW)'COQDOC -pdf $(GAL)' + $(HIDE)$(COQDOC) \ + -toc $(COQDOCFLAGS) -pdf $(GAL) $(COQDOCLIBS) \ + -o $@ `$(COQDEP) -sort $(VFILES)` + +# FIXME: not quite right, since the output name is different +gallinahtml: GAL=-g +gallinahtml: html + +all-gal.ps: GAL=-g +all-gal.ps: all.ps + +all-gal.pdf: GAL=-g +all-gal.pdf: all.pdf + +# ? +beautify: $(BEAUTYFILES) + for file in $^; do mv $${file%.beautified} $${file%beautified}old && mv $${file} $${file%.beautified}; done + @echo 'Do not do "make clean" until you are sure that everything went well!' + @echo 'If there were a problem, execute "for file in $$(find . -name \*.v.old -print); do mv $${file} $${file%.old}; done" in your shell/' +.PHONY: beautify + +# Installation targets ######################################################## +# +# There rules can be extended in Makefile.test-suite-stdlib.coq.local +# Extensions can't assume when they run. + +# We use $(file) to avoid generating a very long command string to pass to the shell +# (cf https://coq.zulipchat.com/#narrow/stream/250632-Coq-Platform-devs-.26-users/topic/Strange.20command.20length.20limit.20on.20Linux) +# However Apple ships old make which doesn't have $(file) so we need a fallback +$(file >.hasfile,1) +HASFILE:=$(shell if [ -e .hasfile ]; then echo 1; rm .hasfile; fi) + +MKFILESTOINSTALL= $(if $(HASFILE),$(file >.filestoinstall,$(FILESTOINSTALL)),\ + $(shell rm -f .filestoinstall) \ + $(foreach x,$(FILESTOINSTALL),$(shell printf '%s\n' "$x" >> .filestoinstall))) + +# findlib needs the package to not be installed, so we remove it before +# installing it (see the call to findlib_remove) +install: META + @$(MKFILESTOINSTALL) + $(HIDE)code=0; for f in $$(cat .filestoinstall); do\ + if ! [ -f "$$f" ]; then >&2 echo $$f does not exist; code=1; fi \ + done; exit $$code + $(HIDE)for f in $$(cat .filestoinstall); do\ + df="`$(COQMKFILE) -destination-of "$$f" $(COQLIBS)`";\ + if [ "$$?" != "0" -o -z "$$df" ]; then\ + echo SKIP "$$f" since it has no logical path;\ + else\ + install -d "$(COQLIBINSTALL)/$$df" &&\ + install -m 0644 "$$f" "$(COQLIBINSTALL)/$$df" &&\ + echo INSTALL "$$f" "$(COQLIBINSTALL)/$$df";\ + fi;\ + done + $(call findlib_remove) + $(call findlib_install, META $(FINDLIBFILESTOINSTALL)) + $(HIDE)$(MAKE) install-extra -f "$(SELF)" + @rm -f .filestoinstall +install-extra:: + @# Extension point +.PHONY: install install-extra + +META: $(METAFILE) + $(HIDE)if [ "$(METAFILE)" ]; then \ + cat "$(METAFILE)" | grep -v 'directory.*=.*' > META; \ + fi + +install-byte: + $(call findlib_install, $(CMAFILES) $(CMOFILESTOINSTALL), -add) + +install-doc:: html mlihtml + @# Extension point + $(HIDE)install -d "$(COQDOCINSTALL)/$(INSTALLCOQDOCROOT)/html" + $(HIDE)for i in html/*; do \ + dest="$(COQDOCINSTALL)/$(INSTALLCOQDOCROOT)/$$i";\ + install -m 0644 "$$i" "$$dest";\ + echo INSTALL "$$i" "$$dest";\ + done + $(HIDE)install -d \ + "$(COQDOCINSTALL)/$(INSTALLCOQDOCROOT)/mlihtml" + $(HIDE)for i in mlihtml/*; do \ + dest="$(COQDOCINSTALL)/$(INSTALLCOQDOCROOT)/$$i";\ + install -m 0644 "$$i" "$$dest";\ + echo INSTALL "$$i" "$$dest";\ + done +.PHONY: install-doc + +uninstall:: + @# Extension point + @$(MKFILESTOINSTALL) + $(call findlib_remove) + $(HIDE)for f in $$(cat .filestoinstall); do \ + df="`$(COQMKFILE) -destination-of "$$f" $(COQLIBS)`" &&\ + instf="$(COQLIBINSTALL)/$$df/`basename $$f`" &&\ + rm -f "$$instf" &&\ + echo RM "$$instf" ;\ + done + $(HIDE)for f in $$(cat .filestoinstall); do \ + df="`$(COQMKFILE) -destination-of "$$f" $(COQLIBS)`" &&\ + echo RMDIR "$(COQLIBINSTALL)/$$df/" &&\ + (rmdir "$(COQLIBINSTALL)/$$df/" 2>/dev/null || true); \ + done + @rm -f .filestoinstall + +.PHONY: uninstall + +uninstall-doc:: + @# Extension point + $(SHOW)'RM $(COQDOCINSTALL)/$(INSTALLCOQDOCROOT)/html' + $(HIDE)rm -rf "$(COQDOCINSTALL)/$(INSTALLCOQDOCROOT)/html" + $(SHOW)'RM $(COQDOCINSTALL)/$(INSTALLCOQDOCROOT)/mlihtml' + $(HIDE)rm -rf "$(COQDOCINSTALL)/$(INSTALLCOQDOCROOT)/mlihtml" + $(HIDE) rmdir "$(COQDOCINSTALL)/$(INSTALLCOQDOCROOT)/" || true +.PHONY: uninstall-doc + +# Cleaning #################################################################### +# +# There rules can be extended in Makefile.test-suite-stdlib.coq.local +# Extensions can't assume when they run. + +clean:: + @# Extension point + $(SHOW)'CLEAN' + $(HIDE)rm -f $(CMOFILES) + $(HIDE)rm -f $(CMIFILES) + $(HIDE)rm -f $(CMAFILES) + $(HIDE)rm -f $(CMXFILES) + $(HIDE)rm -f $(CMXAFILES) + $(HIDE)rm -f $(CMXSFILES) + $(HIDE)rm -f $(OFILES) + $(HIDE)rm -f $(CMXAFILES:.cmxa=.a) + $(HIDE)rm -f $(MLGFILES:.mlg=.ml) + $(HIDE)rm -f $(CMXFILES:.cmx=.cmt) + $(HIDE)rm -f $(MLIFILES:.mli=.cmti) + $(HIDE)rm -f $(ALLDFILES) + $(HIDE)rm -f $(NATIVEFILES) + $(HIDE)find . -name .coq-native -type d -empty -delete + $(HIDE)rm -f $(VOFILES) + $(HIDE)rm -f $(VOFILES:.vo=.vos) + $(HIDE)rm -f $(VOFILES:.vo=.vok) + $(HIDE)rm -f $(VOFILES:.vo=.vo.prof.json) + $(HIDE)rm -f $(VOFILES:.vo=.vo.prof.json.gz) + $(HIDE)rm -f $(BEAUTYFILES) $(VFILES:=.old) + $(HIDE)rm -f all.ps all-gal.ps all.pdf all-gal.pdf all.glob all-mli.tex + $(HIDE)rm -f $(VFILES:.v=.glob) + $(HIDE)rm -f $(VFILES:.v=.tex) + $(HIDE)rm -f $(VFILES:.v=.g.tex) + $(HIDE)rm -f pretty-timed-success.ok + $(HIDE)rm -f META + $(HIDE)rm -rf html mlihtml +.PHONY: clean + +cleanall:: clean + @# Extension point + $(SHOW)'CLEAN *.aux *.timing' + $(HIDE)rm -f $(foreach f,$(VFILES:.v=),$(dir $(f)).$(notdir $(f)).aux) + $(HIDE)rm -f $(TIME_OF_BUILD_FILE) $(TIME_OF_BUILD_BEFORE_FILE) $(TIME_OF_BUILD_AFTER_FILE) $(TIME_OF_PRETTY_BUILD_FILE) $(TIME_OF_PRETTY_BOTH_BUILD_FILE) + $(HIDE)rm -f $(VOFILES:.vo=.v.timing) + $(HIDE)rm -f $(VOFILES:.vo=.v.before-timing) + $(HIDE)rm -f $(VOFILES:.vo=.v.after-timing) + $(HIDE)rm -f $(VOFILES:.vo=.v.timing.diff) + $(HIDE)rm -f .lia.cache .nia.cache +.PHONY: cleanall + +archclean:: + @# Extension point + $(SHOW)'CLEAN *.cmx *.o' + $(HIDE)rm -f $(NATIVEFILES) + $(HIDE)rm -f $(CMOFILES:%.cmo=%.cmx) +.PHONY: archclean + + +# Compilation rules ########################################################### + +$(MLIFILES:.mli=.cmi): %.cmi: %.mli + $(SHOW)'CAMLC -c $<' + $(HIDE)$(TIMER) $(CAMLC) $(CAMLDEBUG) $(CAMLFLAGS) $(FINDLIBPKGS) $< + +$(MLGFILES:.mlg=.ml): %.ml: %.mlg + $(SHOW)'COQPP $<' + $(HIDE)$(COQPP) $< + +# Stupid hack around a deficient syntax: we cannot concatenate two expansions +$(filter %.cmo, $(MLFILES:.ml=.cmo) $(MLGFILES:.mlg=.cmo)): %.cmo: %.ml + $(SHOW)'CAMLC -c $<' + $(HIDE)$(TIMER) $(CAMLC) $(CAMLDEBUG) $(CAMLFLAGS) $(FINDLIBPKGS) $< + +# Same hack +$(filter %.cmx, $(MLFILES:.ml=.cmx) $(MLGFILES:.mlg=.cmx)): %.cmx: %.ml + $(SHOW)'CAMLOPT -c $(FOR_PACK) $<' + $(HIDE)$(TIMER) $(CAMLOPTC) $(CAMLDEBUG) $(CAMLFLAGS) $(FINDLIBPKGS) $(FOR_PACK) $< + + +$(MLLIBFILES:.mllib=.cmxs): %.cmxs: %.cmxa + $(SHOW)'CAMLOPT -shared -o $@' + $(HIDE)$(TIMER) $(CAMLOPTLINK) $(CAMLDEBUG) $(CAMLFLAGS) $(FINDLIBPKGS) \ + -shared -o $@ $< + +$(MLLIBFILES:.mllib=.cma): %.cma: | %.mllib + $(SHOW)'CAMLC -a -o $@' + $(HIDE)$(TIMER) $(CAMLLINK) $(CAMLDEBUG) $(CAMLFLAGS) $(FINDLIBPKGS) -a -o $@ $^ + +$(MLLIBFILES:.mllib=.cmxa): %.cmxa: | %.mllib + $(SHOW)'CAMLOPT -a -o $@' + $(HIDE)$(TIMER) $(CAMLOPTLINK) $(CAMLDEBUG) $(CAMLFLAGS) $(FINDLIBPKGS) -a -o $@ $^ + + +$(MLPACKFILES:.mlpack=.cmxs): %.cmxs: %.cmxa + $(SHOW)'CAMLOPT -shared -o $@' + $(HIDE)$(TIMER) $(CAMLOPTLINK) $(CAMLDEBUG) $(CAMLFLAGS) $(FINDLIBPKGS) \ + -shared -o $@ $< + +$(MLPACKFILES:.mlpack=.cmxa): %.cmxa: %.cmx | %.mlpack + $(SHOW)'CAMLOPT -a -o $@' + $(HIDE)$(TIMER) $(CAMLOPTLINK) $(CAMLDEBUG) $(CAMLFLAGS) $(FINDLIBPKGS) -a -o $@ $< + +$(MLPACKFILES:.mlpack=.cma): %.cma: %.cmo | %.mlpack + $(SHOW)'CAMLC -a -o $@' + $(HIDE)$(TIMER) $(CAMLLINK) $(CAMLDEBUG) $(CAMLFLAGS) $(FINDLIBPKGS) -a -o $@ $^ + +$(MLPACKFILES:.mlpack=.cmo): %.cmo: | %.mlpack + $(SHOW)'CAMLC -pack -o $@' + $(HIDE)$(TIMER) $(CAMLLINK) $(CAMLDEBUG) $(CAMLFLAGS) $(FINDLIBPKGS) -pack -o $@ $^ + +$(MLPACKFILES:.mlpack=.cmx): %.cmx: | %.mlpack + $(SHOW)'CAMLOPT -pack -o $@' + $(HIDE)$(TIMER) $(CAMLOPTLINK) $(CAMLDEBUG) $(CAMLFLAGS) $(FINDLIBPKGS) -pack -o $@ $^ + +# This rule is for _CoqProject with no .mllib nor .mlpack +$(filter-out $(MLLIBFILES:.mllib=.cmxs) $(MLPACKFILES:.mlpack=.cmxs) $(addsuffix .cmxs,$(PACKEDFILES)) $(addsuffix .cmxs,$(LIBEDFILES)),$(MLFILES:.ml=.cmxs) $(MLGFILES:.mlg=.cmxs)): %.cmxs: %.cmx + $(SHOW)'[deprecated,use-mllib-or-mlpack] CAMLOPT -shared -o $@' + $(HIDE)$(TIMER) $(CAMLOPTLINK) $(CAMLDEBUG) $(CAMLFLAGS) $(FINDLIBPKGS) \ + -shared -o $@ $< + +# can't make +# https://www.gnu.org/software/make/manual/make.html#Static-Pattern +# work with multiple target rules +# so use eval in a loop instead +# with grouped targets https://www.gnu.org/software/make/manual/make.html#Multiple-Targets +# if available (GNU Make >= 4.3) +ifneq (,$(filter grouped-target,$(.FEATURES))) +define globvorule= + +# take care to $$ variables using $< etc + $(1).vo $(1).glob &: $(1).v | $$(VDFILE) + $$(SHOW)ROCQ compile $(1).v + $$(HIDE)$$(TIMER) $$(ROCQ) compile $$(COQDEBUG) $$(TIMING_ARG) $$(PROFILE_ARG) $$(COQFLAGS) $$(COQLIBS) $(1).v + $$(HIDE)$$(PROFILE_ZIP) +ifeq ($(COQDONATIVE), "yes") + $$(SHOW)COQNATIVE $(1).vo + $$(HIDE)$$(call TIMER,$(1).vo.native) $$(COQNATIVE) $$(COQLIBS) $(1).vo +endif + +endef +else + +$(VOFILES): %.vo: %.v | $(VDFILE) + $(SHOW)ROCQ compile $< + $(HIDE)$(TIMER) $(ROCQ) compile $(COQDEBUG) $(TIMING_ARG) $(PROFILE_ARG) $(COQFLAGS) $(COQLIBS) $< + $(HIDE)$(PROFILE_ZIP) +ifeq ($(COQDONATIVE), "yes") + $(SHOW)COQNATIVE $@ + $(HIDE)$(call TIMER,$@.native) $(COQNATIVE) $(COQLIBS) $@ +endif + +# this is broken :( todo fix if we ever find a solution that doesn't need grouped targets +$(GLOBFILES): %.glob: %.v + $(SHOW)'ROCQ compile $< (for .glob)' + $(HIDE)$(TIMER) $(ROCQ) compile $(COQDEBUG) $(COQFLAGS) $(COQLIBS) $< + +endif + +$(foreach vfile,$(VFILES:.v=),$(eval $(call globvorule,$(vfile)))) + +$(VFILES:.v=.vos): %.vos: %.v + $(SHOW)ROCQ compile -vos $< + $(HIDE)$(TIMER) $(ROCQ) compile -vos $(COQDEBUG) $(COQFLAGS) $(COQLIBS) $< + +$(VFILES:.v=.vok): %.vok: %.v + $(SHOW)ROCQ compile -vok $< + $(HIDE)$(TIMER) $(ROCQ) compile -vok $(COQDEBUG) $(COQFLAGS) $(COQLIBS) $< + +$(addsuffix .timing.diff,$(VFILES)): %.timing.diff : %.before-timing %.after-timing + $(SHOW)PYTHON TIMING-DIFF $*.{before,after}-timing + $(HIDE)$(MAKE) --no-print-directory -f "$(SELF)" print-pretty-single-time-diff BEFORE=$*.before-timing AFTER=$*.after-timing TIME_OF_PRETTY_BUILD_FILE="$@" + +$(BEAUTYFILES): %.v.beautified: %.v + $(SHOW)'BEAUTIFY $<' + $(HIDE)$(TIMER) $(ROCQ) compile $(COQDEBUG) $(COQFLAGS) $(COQLIBS) -beautify $< + +$(TEXFILES): %.tex: %.v + $(SHOW)'COQDOC -latex $<' + $(HIDE)$(COQDOC) $(COQDOCFLAGS) -latex $< -o $@ + +$(GTEXFILES): %.g.tex: %.v + $(SHOW)'COQDOC -latex -g $<' + $(HIDE)$(COQDOC) $(COQDOCFLAGS) -latex -g $< -o $@ + +$(HTMLFILES): %.html: %.v %.glob + $(SHOW)'COQDOC -html $<' + $(HIDE)$(COQDOC) $(COQDOCFLAGS) -html $< -o $@ + +$(GHTMLFILES): %.g.html: %.v %.glob + $(SHOW)'COQDOC -html -g $<' + $(HIDE)$(COQDOC) $(COQDOCFLAGS) -html -g $< -o $@ + +# Dependency files ############################################################ + +ifndef MAKECMDGOALS + -include $(ALLDFILES) +else + ifneq ($(filter-out archclean clean cleanall printenv make-pretty-timed make-pretty-timed-before make-pretty-timed-after print-pretty-timed print-pretty-timed-diff print-pretty-single-time-diff,$(MAKECMDGOALS)),) + -include $(ALLDFILES) + endif +endif + +.SECONDARY: $(ALLDFILES) + +redir_if_ok = > "$@" || ( RV=$$?; rm -f "$@"; exit $$RV ) + +GENMLFILES:=$(MLGFILES:.mlg=.ml) +$(addsuffix .d,$(ALLSRCFILES)): $(GENMLFILES) + +$(addsuffix .d,$(MLIFILES)): %.mli.d: %.mli + $(SHOW)'CAMLDEP $<' + $(HIDE)$(CAMLDEP) $(OCAMLLIBS) "$<" $(redir_if_ok) + +$(addsuffix .d,$(MLGFILES)): %.mlg.d: %.ml + $(SHOW)'CAMLDEP $<' + $(HIDE)$(CAMLDEP) $(OCAMLLIBS) "$<" $(redir_if_ok) + +$(addsuffix .d,$(MLFILES)): %.ml.d: %.ml + $(SHOW)'CAMLDEP $<' + $(HIDE)$(CAMLDEP) $(OCAMLLIBS) "$<" $(redir_if_ok) + +$(addsuffix .d,$(MLLIBFILES)): %.mllib.d: %.mllib + $(SHOW)'OCAMLLIBDEP $<' + $(HIDE)$(OCAMLLIBDEP) -c $(OCAMLLIBS) "$<" $(redir_if_ok) + +$(addsuffix .d,$(MLPACKFILES)): %.mlpack.d: %.mlpack + $(SHOW)'OCAMLLIBDEP $<' + $(HIDE)$(OCAMLLIBDEP) -c $(OCAMLLIBS) "$<" $(redir_if_ok) + +# If this makefile is created using a _CoqProject we have coqdep get +# options from it. This avoids argument length limits for pathological +# projects. Note that extra options might be on the command line. +VDFILE_FLAGS:=$(if _CoqProject.test-suite-stdlib,-f _CoqProject.test-suite-stdlib,) $(CMDLINE_COQLIBS) $(CMDLINE_VFILES) + +$(VDFILE): _CoqProject.test-suite-stdlib $(VFILES) + $(SHOW)'ROCQ DEP VFILES' + $(HIDE)$(TIMER) $(COQDEP) -vos -dyndep var $(VDFILE_FLAGS) $(redir_if_ok) + +# Misc ######################################################################## + +byte: + $(HIDE)$(MAKE) all "OPT:=-byte" -f "$(SELF)" +.PHONY: byte + +opt: + $(HIDE)$(MAKE) all "OPT:=-opt" -f "$(SELF)" +.PHONY: opt + +# This is deprecated. To extend this makefile use +# extension points and Makefile.test-suite-stdlib.coq.local +printenv:: + $(warning printenv is deprecated) + $(warning write extensions in Makefile.test-suite-stdlib.coq.local or include Makefile.test-suite-stdlib.coq.conf) + @echo 'COQLIB = $(COQLIB)' + @echo 'COQCORELIB = $(COQCORELIB)' + @echo 'DOCDIR = $(DOCDIR)' + @echo 'OCAMLFIND = $(OCAMLFIND)' + @echo 'HASNATDYNLINK = $(HASNATDYNLINK)' + @echo 'SRC_SUBDIRS = $(SRC_SUBDIRS)' + @echo 'COQ_SRC_SUBDIRS = $(COQ_SRC_SUBDIRS)' + @echo 'COQCORE_SRC_SUBDIRS = $(COQCORE_SRC_SUBDIRS)' + @echo 'OCAMLFIND = $(OCAMLFIND)' + @echo 'PP = $(PP)' + @echo 'COQFLAGS = $(COQFLAGS)' + @echo 'COQLIB = $(COQLIBS)' + @echo 'COQLIBINSTALL = $(COQLIBINSTALL)' + @echo 'COQDOCINSTALL = $(COQDOCINSTALL)' +.PHONY: printenv + +# Generate a .merlin file. If you need to append directives to this +# file you can extend the merlin-hook target in Makefile.test-suite-stdlib.coq.local +.merlin: + $(SHOW)'FILL .merlin' + $(HIDE)echo 'FLG $(COQMF_CAMLFLAGS)' > .merlin + $(HIDE)echo 'B $(COQCORELIB)' >> .merlin + $(HIDE)echo 'S $(COQCORELIB)' >> .merlin + $(HIDE)$(foreach d,$(COQCORE_SRC_SUBDIRS), \ + echo 'B $(COQCORELIB)$(d)' >> .merlin;) + $(HIDE)$(foreach d,$(COQ_SRC_SUBDIRS), \ + echo 'S $(COQLIB)$(d)' >> .merlin;) + $(HIDE)$(foreach d,$(SRC_SUBDIRS), echo 'B $(d)' >> .merlin;) + $(HIDE)$(foreach d,$(SRC_SUBDIRS), echo 'S $(d)' >> .merlin;) + $(HIDE)$(MAKE) merlin-hook -f "$(SELF)" +.PHONY: merlin + +merlin-hook:: + @# Extension point +.PHONY: merlin-hook + +# prints all variables +debug: + $(foreach v,\ + $(sort $(filter-out $(INITIAL_VARS) INITIAL_VARS,\ + $(.VARIABLES))),\ + $(info $(v) = $($(v)))) +.PHONY: debug + +.DEFAULT_GOAL := all + +# Users can create Makefile.test-suite-stdlib.coq.local-late to hook into double-colon rules +# or add other needed Makefile code, using defined +# variables if necessary. +-include Makefile.test-suite-stdlib.coq.local-late + +# Local Variables: +# mode: makefile-gmake +# End: diff --git a/Makefile.test-suite-stdlib.coq.conf b/Makefile.test-suite-stdlib.coq.conf new file mode 100644 index 00000000..86d24974 --- /dev/null +++ b/Makefile.test-suite-stdlib.coq.conf @@ -0,0 +1,71 @@ +# This configuration file was generated by running: +# /home/cmarcon/.opam/4.14.1/bin/rocq makefile -f _CoqProject.test-suite-stdlib -o Makefile.test-suite-stdlib.coq + +COQBIN?= +ifneq (,$(COQBIN)) +# add an ending / +COQBIN:=$(COQBIN)/ +endif +COQMKFILE ?= "$(COQBIN)rocq" makefile + +############################################################################### +# # +# Project files. # +# # +############################################################################### + +COQMF_CMDLINE_VFILES := +COQMF_SOURCES := $(shell $(COQMKFILE) -sources-of -f _CoqProject.test-suite-stdlib $(COQMF_CMDLINE_VFILES)) +COQMF_VFILES := $(filter %.v, $(COQMF_SOURCES)) +COQMF_MLIFILES := $(filter %.mli, $(COQMF_SOURCES)) +COQMF_MLFILES := $(filter %.ml, $(COQMF_SOURCES)) +COQMF_MLGFILES := $(filter %.mlg, $(COQMF_SOURCES)) +COQMF_MLPACKFILES := $(filter %.mlpack, $(COQMF_SOURCES)) +COQMF_MLLIBFILES := $(filter %.mllib, $(COQMF_SOURCES)) +COQMF_METAFILE = + +############################################################################### +# # +# Path directives (-I, -R, -Q). # +# # +############################################################################### + +COQMF_OCAMLLIBS = +COQMF_SRC_SUBDIRS = +COQMF_COQLIBS = -Q HB HB -R tests_stdlib HB.tests_stdlib -R examples_stdlib HB.examples_stdlib +COQMF_COQLIBS_NOML = -Q HB HB -R tests_stdlib HB.tests_stdlib -R examples_stdlib HB.examples_stdlib +COQMF_CMDLINE_COQLIBS = + +############################################################################### +# # +# Rocq configuration. # +# # +############################################################################### + +COQMF_COQLIB=/home/cmarcon/.opam/4.14.1/lib/coq/ +COQMF_COQCORELIB=/home/cmarcon/.opam/4.14.1/lib/coq/../rocq-runtime/ +COQMF_DOCDIR=/home/cmarcon/.opam/4.14.1/share/doc/ +COQMF_OCAMLFIND=/home/cmarcon/.opam/4.14.1/bin/ocamlfind +COQMF_CAMLFLAGS=-thread -bin-annot -strict-sequence -w -a+1..3-4+5..8-9+10..26-27+28..39-40-41-42+43-44-45+46..47-48+49..57-58+59..66-67-68+69-70 +COQMF_WARN=-warn-error +a-3 +COQMF_HASNATDYNLINK=true +COQMF_COQ_SRC_SUBDIRS=boot config lib clib kernel library engine pretyping interp gramlib parsing proofs tactics toplevel printing ide stm vernac plugins/btauto plugins/cc plugins/derive plugins/extraction plugins/firstorder plugins/funind plugins/ltac plugins/ltac2 plugins/ltac2_ltac1 plugins/micromega plugins/nsatz plugins/ring plugins/rtauto plugins/ssr plugins/ssrmatching plugins/syntax +COQMF_COQ_NATIVE_COMPILER_DEFAULT=no +COQMF_WINDRIVE= + +############################################################################### +# # +# Native compiler. # +# # +############################################################################### + +COQMF_COQPROJECTNATIVEFLAG = + +############################################################################### +# # +# Extra variables. # +# # +############################################################################### + +COQMF_OTHERFLAGS = '-w' '-redundant-canonical-projection' '-w' '-projection-no-head-constant' '-w' '-abstract-large-number' '-w' '-disj-pattern-notation' '-w' '-notation-overridden' '-w' '+elpi.typecheck' +COQMF_INSTALLCOQDOCROOT = HB diff --git a/_CoqProject.test-suite-stdlib b/_CoqProject.test-suite-stdlib index 0befa7a4..61dca855 100644 --- a/_CoqProject.test-suite-stdlib +++ b/_CoqProject.test-suite-stdlib @@ -42,6 +42,7 @@ examples_stdlib/Coq2020_material/CoqWS_expansion/withoutHB.v tests_stdlib/exports.v tests_stdlib/exports2.v tests_stdlib/funclass.v +tests_stdlib/program_instance.v -R tests_stdlib HB.tests_stdlib -R examples_stdlib HB.examples_stdlib diff --git a/tests/hnf.v b/tests/hnf.v index de5b1218..b87e7e76 100644 --- a/tests/hnf.v +++ b/tests/hnf.v @@ -10,9 +10,11 @@ HB.end. #[hnf] HB.instance Definition _ := f.Build nat (3 + 2). Print Datatypes_nat__canonical__hnf_S. -Print HB_unnamed_mixin_8. +(* TODO print the correct unnamed mixin after fixing the bug introduced in instance.elpi *) +Print HB_unnamed_mixin_10. HB.instance Definition _ := f.Build bool (3 + 2). Print Datatypes_bool__canonical__hnf_S. -Print HB_unnamed_mixin_12. +(* TODO print the correct unnamed mixin after fixing the bug introduced in instance.elpi *) +Print HB_unnamed_mixin_15. diff --git a/tests/local_instance.v b/tests/local_instance.v index f532d748..c909dd6e 100644 --- a/tests/local_instance.v +++ b/tests/local_instance.v @@ -1,4 +1,4 @@ -From HB Require Import structures. +(* From HB Require Import structures. HB.mixin Record def A := { default : A }. HB.structure Definition nonempty := { T of def T }. @@ -9,4 +9,4 @@ Section Box. End Box. #[fail, skip="8.11"] -HB.check (default : nat). +HB.check (default : nat). *) diff --git a/tests/test_obligations.v b/tests/test_obligations.v new file mode 100644 index 00000000..a7d8d860 --- /dev/null +++ b/tests/test_obligations.v @@ -0,0 +1,59 @@ +From elpi Require Import elpi. + +Elpi Command lemma. +Elpi Accumulate lp:{{ + main-interp-proof [str S, str ":", trm T] _ T S. +}}. + +#[proof="begin"] +Elpi Export lemma. + +Elpi Command qed. +Elpi Accumulate lp:{{ + main-interp-qed _ _ IT S :- + if (var S) (S = "xx") true, + coq.env.add-const S IT _ _ _. +}}. + +#[proof="end"] +Elpi Export qed. + +Fail qed. + +lemma it : (True). +exact I. +qed. + +Succeed Print it. + +lemma it2 : (True /\ _). +Succeed Show. (* yes! *) +split. +exact I. +exact I. +qed. + +Succeed Print it2. + +Lemma foo : True. +trivial. +qed. + +lemma foo2 : (True). +trivial. +Qed. + +Elpi Command lemma_if. +Elpi Accumulate lp:{{ + main-interp-proof [str S, str ":", trm T] _ T S. /* 9.1 */ + main _. +}}. + +#[skip="9.0"] #[proof(begin_if="interactive")] +#[skip="9.0"] Elpi Export lemma_if. +#[skip="9.0"] #[interactive] +#[skip="9.0"] lemma_if it3 : (True). +#[skip="9.0"] Succeed Show. +#[skip="9.0"] Abort. +#[skip="9.0"] lemma_if it4 : (True). +#[skip="9.0"] Fail Show. \ No newline at end of file diff --git a/tests_stdlib/program_instance.v b/tests_stdlib/program_instance.v new file mode 100644 index 00000000..44dbf17d --- /dev/null +++ b/tests_stdlib/program_instance.v @@ -0,0 +1,169 @@ +From HB Require Import structures. +From Stdlib Require Import ZArith. + +HB.mixin Record XX T := { X1 : T ; P : X1 = X1}. +HB.structure Definition x1 := { T of XX T }. + + + +(* First, no props in the tactics *) +#[interactive] HB.instance Definition _ := XX.Build nat _ eq_refl. +exact 0. +(* Elpi Trace Browser. *) +HB.end_instance. +(* Print HB_unnamed_factory_3. *) + +(* then a prop *) +#[interactive] HB.instance Definition _ := XX.Build Type nat _. +reflexivity. +HB.end_instance. +(* Print HB_unnamed_factory_14. *) + +(* then with a parameter *) +#[interactive] HB.instance Definition _ (xxxxx:nat) := XX.Build nat _ eq_refl. +exact (xxxxx+1). +HB.end_instance. +(* Print unnamed__25. *) + +#[interactive] HB.instance Definition _ (n:Z) := XX.Build Z _ _. +exact (Z.add n 2%Z). +reflexivity. +HB.end_instance. +Inspect 5. +(* Print HB_unnamed_factory_58. +Print unnamed__57. *) +HB.instance Definition _ (n:bool) := XX.Build bool n eq_refl. + + + +(* the rest *) +HB.mixin Record m1 T := { default1 : T }. +HB.structure Definition s1 := { T of m1 T }. + +HB.mixin Record m2 T := { default2 : T ; default2b : T }. +(* HB.mixin Record m2 T := { default2 : T ; ax2 : exists t:T, t <> t }. *) +HB.structure Definition s2 := { T of m1 T & m2 T }. + +HB.factory Record m3 T := { default3 : T }. + +HB.builders Context T of m3 T. +HB.instance Definition _ := m1.Build T default3. + +HB.instance Definition _ (n:nat) := m2.Build T default3 default3. +(* #[interactive] HB.instance Definition _ (n:nat) := m2.Build T _ _. +exact default3. +exact default3. +HB.end_instance. *) +HB.end. +Inspect 5. +(* TODO: this should work, but for now it breaks future declarations of instances *) +(* #[interactive] HB.instance Definition _ (n:Z) : m1 Z := m1.Build _ _. +destruct (Z.eqb n 0%Z). +- exact 4%Z. +- exact (Z.add n n). +HB.end_instance. +Print HB_unnamed_factory_1710. *) + +HB.mixin Record mt2 T := { d2 : T ; d2b : d2 = d2; d2bb : d2 = d2 }. +#[interactive] HB.instance Definition _ : mt2 nat := mt2.Build nat _ _ _. +exact 0. +reflexivity. +reflexivity. +HB.end_instance. +(* Print HB_unnamed_factory_12. *) +#[interactive] HB.instance Definition _ : m2 nat := m2.Build nat _ _. +exact 0. +exact 2. +HB.end_instance. + +(* #[interactive] HB.instance Definition _ (n:Z) := XX.Build Z _ _. *) +#[interactive] HB.instance Definition _ (b1:bool) := m2.Build bool _ _. +exact (negb b1). +exact (negb (negb b1)). +HB.end_instance. +Inspect 5. +(* Print HB_unnamed_factory_37. *) + + + +(* Fail #[interactive] HB.instance Definition _ : m1 Z := m1.Build Z 3%Z. *) + + +#[interactive] HB.instance Definition _ : m3 Z := m3.Build Z _. +exact 3%Z. +HB.end_instance. +HB.about Z. + + + + +(* HB.about nat. *) + + + + + +(* FACTORY STUFF *) + +HB.mixin Record isSemiGroup T := { + op : T -> T -> T; + opA : forall x y z, op x (op y z) = op (op x y) z + }. +HB.structure Definition SemiGroup := {T of isSemiGroup T}. + +HB.mixin Record semiGroup_isGroup T of isSemiGroup T := { + e : T; + idl : forall x, op e x = x; + idr : forall x, op x e = x; + invl : forall x, exists xinv, op x xinv = e; + invr : forall x, exists xinv, op xinv x = e; +}. +HB.structure Definition Group := {T of isSemiGroup T & semiGroup_isGroup T}. + + +(* Factory: New definition of group *) +HB.factory Record isGroup T := { + op : T -> T -> T; + opA' : forall x y z, op (op x y) z = op x (op y z); + e : T; + idl' : forall x, op e x = x; + idr : forall x, op x e = x; + invl : forall x, exists xinv, op x xinv = e; + invr : forall x, exists xinv, op xinv x = e; + default : T +}. + + +HB.about isGroup. + +HB.builders Context T of isGroup T. +#[interactive] HB.instance Definition _ := isSemiGroup.Build T _ _. +exact op. (*why is the goal not even shelved?*) +simpl. intros. +rewrite opA'. +reflexivity. +HB.end_instance. +(* Print unnamed. *) + +HB.instance Definition _ := semiGroup_isGroup.Build T e idl' idr invl invr. +HB.end. + +HB.about isGroup. + +Fail HB.structure Definition Group2 := {T of isGroup T &}. + +Lemma left_id (T : Group.type) (x y : T) : op e x = x. + Proof. apply idl. Qed. + + +HB.instance Definition _ := isSemiGroup.Build Z Z.add Z.add_assoc. + +HB.instance Definition _ := isSemiGroup.Build Z Z.add Z.add_assoc. +HB.about Z. + +Lemma Zaddel : forall x:Z, exists xinv:Z, Z.add x xinv = 0%Z. + Proof. intros. exists (Z.opp x). apply Z.add_opp_diag_r. Qed. +Lemma Zadder : forall x:Z, exists xinv:Z, Z.add xinv x = 0%Z. + Proof. intros. exists (Z.opp x). apply Z.add_opp_diag_l. Qed. +HB.instance Definition _ := semiGroup_isGroup.Build Z 0%Z Z.add_0_l Z.add_0_r Zaddel Zadder. +HB.about Z.