{"id":15168755,"url":"https://github.com/lpcic/coq-elpi","last_synced_at":"2026-03-06T00:07:48.099Z","repository":{"id":37773898,"uuid":"85685354","full_name":"LPCIC/coq-elpi","owner":"LPCIC","description":"Coq plugin embedding elpi","archived":false,"fork":false,"pushed_at":"2025-04-11T16:32:57.000Z","size":10878,"stargazers_count":163,"open_issues_count":80,"forks_count":58,"subscribers_count":7,"default_branch":"master","last_synced_at":"2025-04-12T19:48:12.196Z","etag":null,"topics":["coq","extension-language","lambda-prolog","metaprogramming","scripting"],"latest_commit_sha":null,"homepage":null,"language":"Coq","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"lgpl-2.1","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/LPCIC.png","metadata":{"files":{"readme":"README.md","changelog":"Changelog.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2017-03-21T09:53:39.000Z","updated_at":"2025-04-11T16:25:28.000Z","dependencies_parsed_at":"2023-10-14T19:39:07.703Z","dependency_job_id":"d58e6bff-edd4-4ead-83ee-c0df86c6b59d","html_url":"https://github.com/LPCIC/coq-elpi","commit_stats":{"total_commits":2672,"total_committers":48,"mean_commits":"55.666666666666664","dds":0.5958083832335329,"last_synced_commit":"335867ab3e584abe06f296517cfe253fa6d8ad91"},"previous_names":[],"tags_count":73,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LPCIC%2Fcoq-elpi","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LPCIC%2Fcoq-elpi/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LPCIC%2Fcoq-elpi/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LPCIC%2Fcoq-elpi/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/LPCIC","download_url":"https://codeload.github.com/LPCIC/coq-elpi/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248625498,"owners_count":21135513,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["coq","extension-language","lambda-prolog","metaprogramming","scripting"],"created_at":"2024-09-27T06:41:31.241Z","updated_at":"2026-03-06T00:07:48.088Z","avatar_url":"https://github.com/LPCIC.png","language":"Coq","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![CI](https://github.com/LPCIC/coq-elpi/actions/workflows/ci.yml/badge.svg)](https://github.com/LPCIC/coq-elpi/actions/workflows/ci.yml)\n[![Nix 9.0](https://github.com/LPCIC/coq-elpi/actions/workflows/nix-action-rocq-9.0.yml/badge.svg)](https://github.com/LPCIC/coq-elpi/actions/workflows/nix-action-rocq-9.0.yml)\n[![Nix 9.1](https://github.com/LPCIC/coq-elpi/actions/workflows/nix-action-rocq-9.1.yml/badge.svg)](https://github.com/LPCIC/coq-elpi/actions/workflows/nix-action-rocq-9.1.yml)\n[![Nix 9.1](https://github.com/LPCIC/coq-elpi/actions/workflows/nix-action-rocq-9.2.yml/badge.svg)](https://github.com/LPCIC/coq-elpi/actions/workflows/nix-action-rocq-9.2.yml)\n[![Nix master](https://github.com/LPCIC/coq-elpi/actions/workflows/nix-action-coq-master.yml/badge.svg)](https://github.com/LPCIC/coq-elpi/actions/workflows/nix-action-coq-master.yml)\n[![DOC](https://github.com/LPCIC/coq-elpi/actions/workflows/doc.yml/badge.svg)](https://github.com/LPCIC/coq-elpi/actions/workflows/doc.yml)\n[![project chat](https://img.shields.io/badge/zulip-join_chat-brightgreen.svg)](https://coq.zulipchat.com/#narrow/stream/253928-Elpi-users.20.26.20devs)\n\u003cimg align=\"right\" src=\"https://github.com/LPCIC/coq-elpi/raw/master/etc/logo.png\" alt=\"Coq-Elpi logo\" width=\"25%\" /\u003e\n\n\u003ch1 tabindex=\"-1\" class=\"heading-element\" dir=\"auto\" style=\"width: 60%\"\u003eCoq-Elpi\u003c/h1\u003e\n\n[Coq](https://github.com/coq/coq) plugin embedding [Elpi](https://github.com/LPCIC/elpi).\n\n## What is Elpi\n[Elpi](https://github.com/LPCIC/elpi) provides an easy-to-embed implementation\nof a dialect of λProlog, a programming language well suited to manipulate\nabstract syntax trees containing binders and unification variables.\n\n## What is Coq-Elpi\nCoq-Elpi provides a Coq plugin that lets one define new commands and tactics in\nElpi. For that purpose it provides an embedding of Coq's terms into λProlog\nusing the Higher-Order Abstract Syntax approach\n([HOAS](https://en.wikipedia.org/wiki/Higher-order_abstract_syntax)). It also\nexports to Elpi a comprehensive set of Coq's primitives, so that one can\nprint a message, access the environment of theorems and data types, define a\nnew constant, declare implicit arguments, type classes instances, and so on.\nFor convenience it also provides quotations and anti-quotations for Coq's\nsyntax, so that one can write `{{ nat -\u003e lp:X }}` in the middle of a λProlog\nprogram instead of the equivalent AST.\n\n## What is the purpose of all that\nIn the short term, provide an extension language for Coq well suited to\nmanipulate terms containing binders. One can already use Elpi to implement\ncommands and tactics.\nAs ongoing research we are\nlooking forward to express algorithms like higher order unification and type\ninference, and to provide an alternative elaborator for Coq.\n\n## Installation\n\nThe simplest way is to use [OPAM](http://opam.ocaml.org/) and type\n```\nopam repo add coq-released https://coq.inria.fr/opam/released\nopam install rocq-elpi\n```\n\n### Editor Setup\n\nThe recommended user interface is [VSCoq](https://github.com/coq-community/vscoq/).\nWe provide an [extension for vscode](https://github.com/LPCIC/coq-elpi-lang) in the\nmarket place, just look for Coq Elpi. The extension provides syntax hilighting\nfor both languages even when they are nested via quotations and antiquotations.\n\n\u003cdetails\u003e\u003csummary\u003eOther editors (click to expand)\u003c/summary\u003e\u003cp\u003e\n\nAt the time of writing Proof General does not handle quotations correctly, see ProofGeneral/PG#437.\nIn particular `Elpi Accumulate lp:{{ .... }}.` is used in tutorials to mix Coq and Elpi code\nwithout escaping. Coq-Elpi also accepts `Elpi Accumulate \" .... \".` but strings part of the\nElpi code needs to be escaped. Finally, for non-tutorial material, one can always put\nthe code in an external file declared with `From some.load.path Extra Dependency \"filename\" as f.`\nand use `Elpi Accumulate File f.`.\n\nCoqIDE does handle quotations. The installation process puts\n[coq-elpi.lang](etc/coq-elpi.lang)\nin a place where CoqIDE can find it.  Then you can select `coq-elpi`\nfrom the menu `Edit -\u003e Preferences -\u003e Colors`.\n\nFor Vim users, [Coqtail](https://github.com/whonore/Coqtail) provides syntax\nhighlighting and handles quotations.\n\n\u003c/p\u003e\u003c/details\u003e\n\n\u003cdetails\u003e\u003csummary\u003eDevelopment version (click to expand)\u003c/summary\u003e\u003cp\u003e\n\nTo install the development version one can type\n```\nopam pin add rocq-elpi https://github.com/LPCIC/coq-elpi.git\n```\nOne can also clone this repository and type `make`, but check you have\nall the dependencies installed first (see [rocq-elpi.opam](rocq-elpi.opam)).\n\nWe recommend to look at the [CI setup](.github/workflows) for\nocaml versions being tested. Also, we recommend to install `dot-merlin-reader`\nand `ocaml-lsp-server` (version 1.15).\n\n\u003c/p\u003e\u003c/details\u003e\n\n## Documentation\n\n### Tutorials\n\n- [The Elpi programming language](https://lpcic.github.io/coq-elpi/tutorial_elpi_lang.html) is an Elpi\n  tutorial, there is nothing Coq specific in there even if the tutorial uses Coq\n  to step trough the various examples. If you never heard of λProlog or HOAS\n  based languages (like Twelf or Beluga) then you are strongly encouraged to\n  read this tutorial and have a look at\n  [λProlog's home page](http://www.lix.polytechnique.fr/Labo/Dale.Miller/lProlog/)\n  for additional documentation. Even if you are familiar with λProlog or HOAS it\n  may be worth reading the last sections since they focus on Elpi specific\n  features. Last but not least it covers common pitfalls for people with a\n  background in functional programming and the tracing mechanisms (useful for\n  debugging).\n- [HOAS of Coq terms](https://lpcic.github.io/coq-elpi/tutorial_coq_elpi_HOAS.html) focuses on how\n  Coq terms are represented in Elpi, how to inspect them and call Coq APIs under\n  a context of binders, and finally how holes (\"evars\" in Coq slang) are\n  represented. It assumes the reader is familiar with Elpi.\n- [Writing commands in Elpi](https://lpcic.github.io/coq-elpi/tutorial_coq_elpi_command.html) focuses on how to\n  write commands, in particular how to store a state across calls via so called\n  DBs and how to handled command arguments. It assumes the reader is familiar\n  with Elpi and the HOAS of Coq terms.\n- [Writing tactics in Elpi](https://lpcic.github.io/coq-elpi/tutorial_coq_elpi_tactic.html) describes how goals\n  and tactics are represented, how to handle tactic arguments and finally how\n  to define tactic notations. It assumes the reader is familiar with Elpi and\n  the HOAS of Coq terms.\n- [Elpi: rule-based meta-language for Rocq](https://www.youtube.com/watch?v=XjkpA5rVxkM)\n  video recording of the keynote at CoqPL25 ([slides \u0026 demo files](https://www-sop.inria.fr/members/Enrico.Tassi/coqpl2025/)).\n- [Coq-Elpi in 20 minutes](https://youtu.be/m60rHnvCJ2o)\n  video recording of a talk given at the Coq Users and Developers Workshop 2020.\n\n### Small examples (proofs of concept)\n\n- [reification](examples/example_reflexive_tactic.v) is the typical use\n  case for meta programs: reading the syntax of terms into an inductive\n  representing a sub language on which some decision procedure can be\n  implemented\n- [data bases](examples/example_data_base.v) shows how Elpi programs\n  can store data and reuse it across multiple runs\n- [record expansion](examples/example_record_expansion.v) sketches a\n  program to unpack records in a definition: it  replaces an abstraction over a\n  records with abstractions over all of its components\n- [record to sigma](examples/example_record_to_sigma.v) sketches a\n  program that de-sugars a record type to iterated sigma types\n- [fuzzer](examples/example_fuzzer.v) sketches a\n  program to alter an inductive type while preserving its well typedness. It\n  makes nothing useful per se, but shows how to map a term and call the type\n  checker deep inside it.\n- [tactics](examples/example_curry_howard_tactics.v) show how to create\n  simple tactics by using (proof) terms and the elaborator of Coq\n- [generalize](examples/example_generalize.v) show how to abstract\n  subterms out (one way to skin the cat, there are many)\n- [abs_evars](examples/example_abs_evars.v) show how to close a term\n  containing holes (evars) with binders\n- [record import](examples/example_import_projections.v) gives short names\n  to record projections applied to the given record instance.\n- [reduction surgery](examples/example_reduction_surgery.v) implements\n  a tactic fine tuning cbv with a list of allowed unfoldings taken from a\n  module.\n- [open terms](examples/example_open_terms.v) implements\n  a tactic like `replace` that receives terms containing free variables, i.e.\n  variables bound in the goal but not in the proof context.\n- [builtins](examples/example_plugin/) adds builtin predicates\n  (hence implemented in OCaml) to Elpi via a Rocq plugin\n\n### Applications written in Coq-Elpi\n\n- [Derive](apps/derive/examples/usage.v) shows how to \n  obtain proved equality tests and a few extra gadgets out of\n  inductive type declarations. See the [README](apps/derive/README.md)\n  for the list of derivations. It comes bundled with Coq-Elpi.\n- [Locker](apps/locker) lets one hide the computational contents of definitions\n  via modules or opaque locks. It comes bundled with Coq-Elpi.\n- [Hierarchy Builder](https://github.com/math-comp/hierarchy-builder) is a\n  Coq extension to declare hierarchies of algebraic structures.\n- [Algebra Tactics](https://github.com/math-comp/algebra-tactics/) is a \n  port of the `ring` and `field` tactics to the Mathematical Components\n  library.\n- [Trakt](https://github.com/ecranceMERCE/trakt) is a generic goal\n  preprocessing tool for proof automation tactics in Coq.\n- [Namespace Emulation System](apps/NES/examples/usage_NES.v) implements\n  most of the features of namespaces (on top of Coq's modules).\n- [Dx](https://gitlab.univ-lille.fr/samuel.hym/dx) uses elpi to generate\n  an intermediate representation of Coq terms, to be later tranformed into\n  C.\n- [Coercion](apps/coercion) enable to program coercions in Elpi.\n  It comes bundled with Coq-Elpi.\n- [Record builder](apps/rbuild) implements fancy record build/update syntax.\n  It comes bundled with Coq-Elpi.\n\n### Quick Reference\n\nIn order to load Coq-Elpi use `From elpi Require Import elpi`.\n\n#### Vernacular commands\n\n\u003cdetails\u003e\u003csummary\u003e(click to expand)\u003c/summary\u003e\n\n- `Elpi Command \u003cqname\u003e` creates command named `\u003cqname\u003e` containing the preamble\n  [elpi-command](elpi/elpi-command-template.elpi).\n- `Elpi Tactic \u003cqname\u003e` creates a tactic `\u003cqname\u003e` containing the preamble\n  [elpi-tactic](elpi/elpi-tactic-template.elpi).\n- `Elpi Db \u003cdbname\u003e \u003ccode\u003e` creates a Db (a program that is accumulated into\n  other programs). `\u003ccode\u003e` is the initial contents of the Db, including the\n  type declaration of its constituting predicates.\n  It understands the `#[phase]` attribute, see [synterp-vs-interp](README.md#separation-of-parsing-from-execution-of-vernacular-commands).\n- `Elpi Program \u003cqname\u003e \u003ccode\u003e` lower level primitive letting one crate a\n  command/tactic with a custom preamble `\u003ccode\u003e`.\n- `From some.load.path Extra Dependency \u003cfilename\u003e as \u003cfname\u003e` declares `\u003cfname\u003e`\n   as a piece of code that can be accumulated via `Elpi Accumulate File`.\n   The content is given in the external file `\u003cfilename\u003e` to be found in\n   the Coq load path `some.load.path`.\n- `Elpi File \u003cfname\u003e \u003ccode\u003e.` declares `\u003cfname\u003e`\n   as a piece of code that can be accumulated via `Elpi Accumulate File`.\n   This time the code is given in the .v file.\n   It understands the `#[phase]` attribute, see [synterp-vs-interp](README.md#separation-of-parsing-from-execution-of-vernacular-commands).\n- `Elpi Accumulate [\u003cdbname\u003e|\u003cqname\u003e] [\u003ccode\u003e|File [Signature] \u003cfname\u003e|Db [Header] \u003cdbname\u003e]`\n  adds code to the current program (or `\u003cdbname\u003e` or `\u003cqname\u003e` if specified).\n  The code can be verbatim, from a file or a Db.\n  File names `\u003cfname\u003e` must have been previously declared with\n  `Extra Dependency` or `Elpi File`.\n  Accumulating `File Signature \u003cfname\u003e` only adds the signautre declarations\n  (kinds, types, modes, type abbreviations) from `\u003cfname\u003e` skipping the code\n  (clauses/rules).\n  Accumulating `Db Header \u003cdbname\u003e`, instead of `Db \u003cdbname\u003e`, accumulates\n  only the first chunk of code associated with Db, typically the type\n  declaration of the predicates that live in the Db. When defining a command\n  or tactic it can be useful to first accumulate the Db header, then some\n  code (possibly calling the predicate living in the Db), and finally\n  accumulating the (full) Db.\n  Note that when a command is executed it may need to be (partially)\n  recompiled, e.g. if the Db was updated. In this case all the code accumulated\n  after the Db (but not after its header) may need to be recompiled. Hence\n  we recommend to accumulate Dbs last.\n  It understands the `#[skip=\"rex\"]` and `#[only=\"rex\"]` which make the command\n  a no op if the Coq version is matched (or not) by the given regular expression.\n  It understands the `#[phase]` attribute, see [synterp-vs-interp](README.md#separation-of-parsing-from-execution-of-vernacular-commands).\n  It understands the `#[local]`, `#[global]`, and `#[superglobal]` scope attributes,\n  although only when accumulating to a `\u003cdbname\u003e` (all accumulations to a program\n  are `#[superglobal]`). Default accumulation to db is the equivalent of `#[export]`.\n  See the Coq reference manual for the meaning of these scopes.\n- `Elpi Typecheck [\u003cqname\u003e]` typechecks the current program (or `\u003cqname\u003e` if\n  specified).\n  It understands the `#[phase]` attribute, see [synterp-vs-interp](README.md#separation-of-parsing-from-execution-of-vernacular-commands)\n- `Elpi Debug \u003cstring\u003e` sets the variable `\u003cstring\u003e`, relevant for conditional\n  clause compilation (the `:if VARIABLE` clause attribute).\n  It understands the `#[phase]` attribute, see [synterp-vs-interp](README.md#separation-of-parsing-from-execution-of-vernacular-commands)\n- `Elpi Trace [[\u003cstart\u003e \u003cstop\u003e] \u003cpredicate-filter\u003e*|Off]` enable/disable\n  tracing, eventually limiting it to a specific range of execution steps or\n  predicate names.\n  It understands the `#[phase]` attribute, see [synterp-vs-interp](README.md#separation-of-parsing-from-execution-of-vernacular-commands)\n- `Elpi Trace Browser` enable/disable\n  tracing for Elpi's [trace browser]().\n- `Elpi Bound Steps \u003cnumber\u003e` limits the number of steps an Elpi program can\n  make.\n- `Elpi Print \u003cqname\u003e [\u003cstring\u003e \u003cfilter\u003e*]` prints the program `\u003cqname\u003e` to \n  a text file called `\u003cqname\u003e.txt` (or `\u003cstring\u003e` if provided) filtering out\n  clauses whose file or clause-name matches `\u003cfilter\u003e`.\n  It understands the `#[phase]` attribute, see [synterp-vs-interp](README.md#separation-of-parsing-from-execution-of-vernacular-commands)\n\nwhere:\n\n- `\u003cqname\u003e` is a qualified Coq name, e.g. `derive.eq` or `my_program`.\n- `\u003cdbname\u003e` is like `\u003cqname\u003e` but lives in a different namespace. By convention\n  `\u003cdbname\u003e` ends in `.db`, e.g. `derive.eq.db`.\n- `\u003ccode\u003e` is verbatim Elpi code, either `lp:{{ ... }}` or `\" ... \"` (in the\n  latter case, strings delimiters need to be escaped following Coq rules, e.g.\n  `lp:{{ coq.say \"hello!\" }}` becomes `\" coq.say \"\"hello!\"\" \"`).\n- `\u003cfilename\u003e` is a string containing the path of an external file, e.g.\n  `\"this_file.elpi\"`.\n- `\u003cfname\u003e` is a qualified Coq name, eg `foo.elpi` (note that `Extra Dependency`\n  only allows simple identifiers).\n- `\u003cstart\u003e` and `\u003cstop\u003e` are numbers, e.g. `17 24`.\n- `\u003cpredicate-filter\u003e` is a regexp against which the predicate name is matched,\n  e.g. `\"derive.*\"`.\n\n\u003c/p\u003e\u003c/details\u003e\n\n#### Separation of parsing from execution of vernacular commands\n\n\u003cdetails\u003e\u003csummary\u003e(click to expand)\u003c/summary\u003e\n\nSince version 8.18 Coq has separate parsing and execution phases,\nrespectively called synterp and interp.\n\nSince Coq has an extensible grammar the parsing phase is not entirely\nperformed by the parser: after parsing one sentence Coq evaluates its\nsynterp action. The synterp actions of a command like `Import A.` are\nthe subset of its effect which affect parsing, like enabling a notation.\nLater, during the execution phase Coq evaluates the its\ninterp action, which includes effects like putting lemma names in scope or\nenables type class instances etc.\n\nBeing able to parse an entire document quickly,\nwithout actually executing any sentence, is important for developing reactive\nuser interfaces, but requires some extra work when defining new commands,\nin particular to separate their synterp actions from their interp ones.\nEach command defined with Coq-Elpi is split into two programs,\none running during the parsing phase and the other one during the execution\nphase.\n\n##### Declaration of synterp actions\n\nEach `Elpi Command` internally declares two programs with the same name.\nOne to be run while the Coq document is parsed, the synterp-command,\nand the other one while it is executed, the interp command.\n`Elpi Accumulate`, by default, adds code to the interp-command.\nThe `#[phase]` attribute can be used to accumulate code to the synterp-command\nor to both commands. `Elpi Typecheck` checks both commands.\n\nEach `Elpi Db` internally declares one db, by default for the interp phase.\nThe `#[phase]` attribute can be used crate a database for the synterp phase,\nor for both phases. Note that databases for the two phases are distinct, no\ndata is shared among them. In particular the `coq.elpi.accumulate*` API exists\nin both phases and only acts on data bases for the current phase.\n\n##### The alignment of phases\n\nAll synterp actions, i.e. calls to APIs dealing with modules and sections\nlike begin/end-module or import/export, have to happen at *both* synterp and\ninterp time and *in the same order*.\n\nIn order to do so, the synterp-command may need to communicate data to the\ncorresponding interp-command. There are two ways for doing so.\n\nThe first one is to use, as the main entry points, the following ones:\n```\npred main-synterp i:list argument, o:any.\npred main-interp i:list argument, i:any.\n```\nUnlike `main` the former outputs a datum while the latter receives it in input.\nDuring the synterp phase the API `coq.synterp-actions` lists the actions\nperformed so far. An excerpt from the [coq-builtin-synterp](builtin-doc/coq-builtin-synterp.elpi) file:\n```\n% Action executed during the parsing phase (aka synterp)\nkind synterp-action type.\ntype begin-module id -\u003e synterp-action.\ntype end-module modpath -\u003e synterp-action.\n```\nThe synterp-command can output data of that type, but also any other data it\nwishes.\n\nThe second way to communicate data is implicit, but limited to synterp actions.\nSuch synterp actions can be recorded into (nested) groups whose structure is\ndeclared using well-bracketed calls to predicates `coq.begin-synterp-group`\nand `coq.end-synterp-group` in the synterp phase. In the interp phase, one can\nthen use predicate `coq.replay-synterp-action-group` to replay all the synterp\nactions of the group with the given name at once.\n\nIn the case where one wishes to interleave code between the actions of a given\ngroup, it is also possible to match the synterp group structure at interp, via\n`coq.begin-synterp-group` and `coq.end-synterp-group`. Individual actions that\nare contained in the group then need to be replayed individually.\n\nOne can use `coq.replay-next-synterp-actions` to replay all synterp actions\nuntil the next beginning/end of a synterp group. However, this is discouraged\nin favour of using groups explicitly, as this is more modular. Code that used\nto rely on the now-removed `coq.replay-all-missing-synterp-actions` predicate\ncan rely on `coq.replay-next-synterp-actions` instead, but this is discouraged\nin favour of using groups explicitly)\n\n##### Syntax of the `#[phase]` attribute\n\n- `#[phase=\"ph\"]` where `\"ph\"` can be `\"parsing\"`,\n  `\"execution\"` or `\"both\"`\n- `#[synterp]` is a shorthand for `#[phase=\"parsing\"]`\n- `#[interp]` is a shorthand for `#[phase=\"execution]`\n\n\u003c/p\u003e\u003c/details\u003e\n\n#### Invocation of Elpi code\n\n\u003cdetails\u003e\u003csummary\u003e(click to expand)\u003c/summary\u003e\n\n- `Elpi \u003cqname\u003e \u003cargument\u003e*.` invokes the `main` predicate of the `\u003cqname\u003e`\n  program passing a possible empty list of arguments. This is how you invoke a\n  command.\n- `elpi \u003cqname\u003e \u003cargument\u003e*.` invokes the `solve` predicate of the `\u003cqname\u003e`\n  program passing a possible empty list of arguments and the current goal. This\n  is how you invoke a tactic.\n\n- `Elpi Export \u003cqname\u003e [As \u003cother-qname\u003e]` makes it possible to invoke\n  command `\u003cqname\u003e` (or `\u003cother-qname\u003e` if given) without\n  the `Elpi` prefix or invoke tactic `\u003cqname\u003e` in the middle of a term just\n  writing `\u003cqname\u003e args` instead of `ltac:(elpi \u003cqname\u003e args)`. Note that in\n  the case of tactics, all arguments are considered to be terms.\n  Moreover, remember that one can use `Tactic Notation` to give the tactic a\n  better syntax and a shorter name when used in the middle of a proof script.\n  Commands can declare the behavior of starting/ending a proof by, respectively,\n  using `#[proof=\"begin\"] Elpi Export ..` and `#[proof=\"end\"] Elpi Export ..`.\n  Starting the proof can depend on the presence of an attribute, for example\n  `#[proof(begin_if=\"interactive\")] Elpi Export foo` will make\n  `foo` not open a proof, while `#[interactive] foo` will open a proof.\n  See also the `main-interp-proof` and `main-interp-qed` entry points in\n  [coq-builtin](builtin-doc/coq-builtin.elpi).\n\nwhere `\u003cargument\u003e` can be:\n\n- a number, e.g. `3`, represented in Elpi as `(int 3)`\n- a string, e.g. `\"foo\"` or `bar.baz`,  represented in Elpi as `(str \"foo\")` and\n  `(str \"bar.baz\")`. Coq keywords and symbols are recognized as strings,\n  eg `=\u003e` requires no quotes. Quotes are necessary if the string contains\n  a space or a character that is not accepted for qualified identifiers or\n  if the string is `Definition`, `Axiom`, `Record`, `Structure`, `Inductive`,\n  `CoInductive`, `Variant` or `Context`.\n- a term, e.g. `(3)` or `(f x)`, represented in Elpi as `(trm ...)`. Note that\n  terms always require parentheses, that is `3` is a number while `(3)` is a Coq\n  term and depending on the context could be a natural number\n  (i.e. `S (S (S O))`) or a `Z` or ... See also the section Terms as arguments\n  down below, and the syntax for Ltac variables down below.\n\nCommands also accept the following arguments (the syntax is as close as possible\nto the Coq one: [...] means optional, * means 0 or more). See the `argument`\ndata type in `coq-builtin.elpi` for their HOAS encoding. See also the section\nTerms as arguments down below.\n\n- `Definition` _name_ _binder_* [`:` _term_] `:=` _term_\n- `Axiom` _name_ `:` _term_\n- [ `Record` | `Structure` ] _name_ _binder_* [`:` _sort_] `:=` [_name_] `{` _name_ `:` _term_ `;` * `}`\n- [ `Inductive` | `CoInductive` | `Variant` ] _name_ _binder_* [`|` _binder_*] [`:` _term_] `:=` `|` _name_ _binder_* `:` _term_ *\n- `Context` _binder_*\n\n##### Ltac Variables\n\nTactics also accept Ltac variables as follows:\n- `ltac_string:(v)` (for `v` of type `string` or `ident`)\n- `ltac_int:(v)` (for `v` of type `int` or `integer`)\n- `ltac_term:(v)` (for `v` of type `constr` or `open_constr` or `uconstr` or `hyp`)\n- `ltac_open_term:(v)` (for `v` of type `uconstr`)\n- `ltac_(string|int|term|open_term)_list:(v)` (for `v` of type `list` of ...)\n- `ltac_tactic:(t)` (for `t` of type `tactic_expr`)\n- `ltac_attributes:(v)` (for `v` of type `attributes`)\nFor example:\n```coq\nTactic Notation \"tac\" string(X) ident(Y) int(Z) hyp(T) constr_list(L) simple_intropattern_list(P) uconstr(U) :=\n  elpi tac ltac_string:(X) ltac_string:(Y) ltac_int:(Z) ltac_term:(T) ltac_term_list:(L) ltac_tactic:(intros P) ltac_open_term:(U).\n```\nlets one write `tac \"a\" b 3 H t1 t2 t3 [|m]` in any Ltac context.\nArguments are first interpreted by Ltac according to the types declared\nin the tactic notation and then injected in the corresponding Elpi argument.\nFor example `H` must be an existing hypothesis, since it is typed with\nthe `hyp` Ltac type, but in Elpi it will appear as a term, eg `trm c0`.\nSimilarly `t1`, `t2` and `t3` are checked to be well typed and to contain no\nunresolved implicit arguments, since this is what the `constr` Ltac type means\nIf they were typed as `open_constr` or `uconstr`, the last or both checks would\nbe respectively skipped. In any case they are passed to the Elpi code as `trm ...`.\nBoth `\"a\"` and `b` are passed to Elpi as `str ...`.\nArgument `U` flagged as `ltac_open_term` can mention free variables. The Elpi\ntactic receives `open-trm N F` where `N` is the number of free variables in `U`\nand `F` is `fun x1 =\u003e ... fun xN =\u003e U`.\nFinally, `ltac_term:(T)` and `(T)` are *not* synonyms: but the former must be used\nwhen defining tactic notations, the latter when invoking elpi tactics directly.\n``` `(T)``` can be used to pass an open term to `elpi tactic ...`.\n\n##### Attributes\n\nAttributes are supported in both commands and tactics. Examples:\n- `#[ att ] Elpi cmd`\n- `#[ att ] cmd` for a command `cmd` exported via `Elpi Export cmd`\n- `#[ att ] elpi tac`\n- `Tactic Notation ... attributes(A) ... := ltac_attributes:(A) elpi tac`.\n  Due to a parsing conflict in Coq grammar, at the time of writing this code:\n  ```coq\n  Tactic Notation \"#[\" attributes(A) \"]\" \"tac\" :=\n    ltac_attributes:(A) elpi tac.\n  ``` \n  has the following limitation:\n  - `#[ att ] tac.` does not parse\n  - `(#[ att ] tac).` works\n  - `idtac; #[ att ] tac.` works\n\n##### Terms as arguments\n\nSince version 1.15, terms passed to Elpi commands code via `(term)` or via a\ndeclaration (like `Record`, `Inductive` ...) are in elaborated format by\ndefault. This means that all Coq notational facilities are available, like\ndeep pattern matching, or tactics in terms.\nOne can use the attribute `#[arguments(raw)]` to declare a command which instead\ntakes arguments in raw format. In that case, notations are unfolded,\nimplicit arguments are expanded (holes `_` are added) and lexical analysis is\nperformed (global names and bound names are identified, holes are applied\nto bound names in scope), but deep pattern matching or tactics in terms are not\nsupported, and in particular type checking/inference is not performed.\nOnce can use the `coq.typecheck` or `coq.elaborate-skeleton` APIs\nto fill in implicit arguments and insert coercions on raw terms.\n\nTerms passed to Elpi tactics via tactic notations can be forced to be elaborated\nbeforehand by declaring the parameters to be of type `constr` or `open_constr`.\nArguments of type `uconstr` are passed raw.\n\n##### Testing/debugging:\n\n- `Elpi Query [\u003cqname\u003e] \u003ccode\u003e` runs `\u003ccode\u003e` in the current program (or in\n  `\u003cqname\u003e` if specified).\n- `Elpi Query [\u003cqname\u003e] \u003csynterp-code\u003e \u003cinterp-code\u003e` runs\n  `\u003csynterp-code\u003e` in the current (synterp) program (or in\n`\u003cqname\u003e` if specified) and `\u003cinterp-code\u003e` in the current program (or `\u003cqname\u003e`).\n- `elpi query [\u003cqname\u003e] \u003cstring\u003e \u003cargument\u003e*` runs the `\u003cstring\u003e` predicate\n  (that must have the same signature of the default predicate `solve`).\n\n\u003c/p\u003e\u003c/details\u003e\n\n#### Supported features of Gallina (core calculus of Coq)\n\n\u003cdetails\u003e\u003csummary\u003e(click to expand)\u003c/summary\u003e\n\n- [x] functional core (fun, forall, match, application, let-in, sorts)\n- [x] evars (unification variables)\n- [x] single Inductive and CoInductive types (including parameters, non-uniform\n      parameters, indexes)\n- [ ] mutual Inductive and CoInductive types\n- [x] fixpoints\n- [ ] mutual fixpoints\n- [ ] cofixpoints\n- [x] primitive records\n- [x] primitive projections\n- [x] primitive integers\n- [x] primitive floats\n- [ ] primitive arrays\n- [x] universe polymorphism\n- [x] modules\n- [x] module types\n- [x] functor application\n- [x] functor definition\n\n\u003c/p\u003e\u003c/details\u003e\n\n#### Supported features of Gallina's extensions (extra logical features, APIs)\n\n\u003cdetails\u003e\u003csummary\u003e(click to expand)\u003c/summary\u003e\n\nChecked boxes are available, unchecked boxes are planned, missing items are not\nplanned. This is a high level list, for the details\nsee [coq-builtin](builtin-doc/coq-builtin.elpi).\n\n- [x] i/o: messages, warnings, errors, Coq version\n- [x] logical environment: read, write, locate\n  + [x] dependencies between objects\n- [x] type classes database: read, write\n  + [ ] take over resolution\n- [x] canonical structures database: read, write\n  + [ ] take over resolution\n- [x] coercions database: read, write\n- [x] sections: open, close\n- [x] scope management: import, export\n- [x] hints: mode, opaque, resolve, strategy\n- [x] arguments: implicit, name, scope, simpl\n- [x] abbreviations: read, write, locate\n- [x] typing and elaboration\n- [x] unification\n- [x] reduction: `lazy`, `cbv`, `vm`, `native`\n  - [x] flags for `lazy` and `cbv`\n- [x] ltac1: bridge to call ltac1 code, mono and multi-goal tactics\n- [x] option system: get, set, add\n- [x] pretty printer: boxes, printing width\n- [x] attributes: read\n\n\u003c/p\u003e\u003c/details\u003e\n\n#### Relevant files\n\n- [coq-builtin](builtin-doc/coq-builtin.elpi) documents the HOAS encoding of Coq terms\n  and the API to access Coq\n- [coq-builtin-synterp](builtin-doc/coq-builtin-synterp.elpi) documents APIs to interact with Coq at parsing time\n- [elpi-buitin](builtin-doc/elpi-builtin.elpi) documents Elpi's standard library, you may\n  look here for list processing code\n- [coq-lib](elpi/coq-lib.elpi) provides some utilities to manipulate Coq terms;\n  it is an addendum to coq-builtin\n- [elpi-command-template](elpi/elpi-command-template.elpi) provides the pre-loaded code for `Elpi Command` (execution phase) and `Elpi Tactic`\n- [elpi-command-template-synterp](elpi/elpi-command-template-synterp.elpi) provides the pre-loaded code for `Elpi Command` (parsing phase)\n- [elpi-tactic-template](elpi/elpi-tactic-template.elpi) provides the pre-loaded code for `Elpi Tactic` (note tactics also load [elpi-command-template](elpi/elpi-command-template.elpi))\n\n#### Organization of the repository\n\nThe code of the Coq plugin is at the root of the repository in the [src](src/),\n[elpi](elpi/) and [theories](theories/) directories.\n\nThe [apps](apps/) directory contains client applications written in Coq-Elpi.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flpcic%2Fcoq-elpi","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flpcic%2Fcoq-elpi","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flpcic%2Fcoq-elpi/lists"}