High level commands to declare a hierarchy based on packed classes
104
stars
1,276
commits
Rocq Prover
primary language
Jul 24, 2026
updated
Hierarchy Builder (HB) provides high level commands to declare a hierarchy of algebraic structure (or interfaces if you prefer the glossary of computer science) for the Coq system.
Given a structure one can develop its theory, and that theory becomes automatically applicable to all the examples of the structure. One can also declare alternative interfaces, for convenience or backward compatibility, and provide glue code linking these interfaces to the structures part of the hierarchy.
HB commands compile down to Coq modules, sections, records, coercions, canonical structure instances and notations following the packed classes discipline which is at the core of the Mathematical Components library. All that complexity is hidden behind a few concepts and a few declarative Coq commands.
From HB Require Import structures.
From Coq Require Import ssreflect ZArith.
HB.mixin Record IsAddComoid A := {
zero : A;
add : A -> A -> A;
addrA : forall x y z, add x (add y z) = add (add x y) z;
addrC : forall x y, add x y = add y x;
add0r : forall x, add zero x = x;
}.
HB.structure Definition AddComoid := { A of IsAddComoid A }.
Notation "0" := zero.
Infix "+" := add.
Check forall (M : AddComoid.type) (x : M), x + x = 0.
This is all we need to do in order to declare the AddComoid structure
and write statements in its signature.
We proceed by declaring how to obtain an Abelian group out of the additive, commutative, monoid.
HB.mixin Record IsAbelianGrp A of IsAddComoid A := {
opp : A -> A;
addNr : forall x, opp x + x = 0;
}.
HB.structure Definition AbelianGrp := { A of IsAbelianGrp A & IsAddComoid A }.
Notation "- x" := (opp x).
Abelian groups feature the operations and properties given by the
IsAbelianGrp mixin (and its dependency IsAddComoid).
Lemma example (G : AbelianGrp.type) (x : G) : x + (- x) = - 0.
Proof. by rewrite addrC addNr -[LHS](addNr zero) addrC add0r. Qed.
We proceed by showing that Z is an example of both structures, and use
the lemma just proved on a statement about Z.
HB.instance Definition Z_CoMoid :=
IsAddComoid.Build Z 0%Z Z.add Z.add_assoc Z.add_comm Z.add_0_l.
HB.instance Definition Z_AbGrp :=
IsAbelianGrp.Build Z Z.opp Z.add_opp_diag_l.
Lemma example2 (x : Z) : x + (- x) = - 0.
Proof. by rewrite example. Qed.
For a tutorial, see the platform docs.
This paper describes the language in details, and the corresponding talk is available on youtube. The wiki gathers some tricks and FAQs. If you want to work on the implementation of HB, this recorded hacking session may be relevant to you.
opam repo add rocq-released https://rocq-prover.org/opam/released
opam install rocq-hierarchy-builder
rocqPackages_9_X.hierarchy-builder e.g.
via nix-shell -p rocq_9_0 -p rocqPackages_9_0.hierarchy-builder
a mixin is a bare bone building block of the hierarchy, it packs operations and axioms.
a factory is a package of operations and properties that is elaborated by HB to one or more mixin. A mixin is hence a trivial factory.
a structure is declared by attaching zero or more factories to a type.
a builder is a user provided piece of code capable of building one or more mixins from a factory.
an instance is an example of a structure: it provides all operation and fulfills all axioms.
HB core commands:
HB.mixin declares a mixin,HB.structure declares a structure,HB.factory declares a factory,HB.builders and HB.end declare a set of builders,HB.instance declares a structure instance,HB.declare declares a context with parameters, key and mixins.HB.saturate reconsiders all mixin instances to see if some newly declared
structure can be inhabitedHB core tactic-in-term:
HB.pack to synthesize a structure instance in the middle of a term.HB utility commands:
HB.export exports a module and schedules it for re-exportHB.reexport exports all modules, instances and constants scheduled for
re-exportHB.lock locks a definition behind an opaque symbol and an unfolding
equation using Coq module systemHB queries:
HB.about is similar to About but prints more info on HB structures, like
the known instances and where they are declaredHB.locate is similar to Locate, prints file name and line of any global
constant synthesized by HBHB.graph prints the structure hierarchy to a dot fileHB.howto prints sequences of factories to equip a type with a given structureHB debug commands:
HB.status dumps the contents of the hierarchy (debug purposes)HB.check is similar to Check (testing purposes)The documentation of all commands can be found in the comments of
structures.v, search for Elpi Command and you will
find them. All commands can be prefixed with the attribute #[verbose]
to get an idea of what they are doing.
For debugging and teaching purposes, passing the attributes
#[log] or #[log(raw)] to a HB command prints Coq commands which are
almost equivalent to its effect. Hence, copy-pasting the displayed commands into
your source file is not expected to work, and we strongly recommend
against it.
Rocq Prover
49.6%
Prolog
46.8%
Nix
2.4%
Makefile
1.2%
High level commands to declare a hierarchy based on packed classes
104
stars
1,276
commits
Rocq Prover
primary language
Jul 24, 2026
updated
Hierarchy Builder (HB) provides high level commands to declare a hierarchy of algebraic structure (or interfaces if you prefer the glossary of computer science) for the Coq system.
Given a structure one can develop its theory, and that theory becomes automatically applicable to all the examples of the structure. One can also declare alternative interfaces, for convenience or backward compatibility, and provide glue code linking these interfaces to the structures part of the hierarchy.
HB commands compile down to Coq modules, sections, records, coercions, canonical structure instances and notations following the packed classes discipline which is at the core of the Mathematical Components library. All that complexity is hidden behind a few concepts and a few declarative Coq commands.
From HB Require Import structures.
From Coq Require Import ssreflect ZArith.
HB.mixin Record IsAddComoid A := {
zero : A;
add : A -> A -> A;
addrA : forall x y z, add x (add y z) = add (add x y) z;
addrC : forall x y, add x y = add y x;
add0r : forall x, add zero x = x;
}.
HB.structure Definition AddComoid := { A of IsAddComoid A }.
Notation "0" := zero.
Infix "+" := add.
Check forall (M : AddComoid.type) (x : M), x + x = 0.
This is all we need to do in order to declare the AddComoid structure
and write statements in its signature.
We proceed by declaring how to obtain an Abelian group out of the additive, commutative, monoid.
HB.mixin Record IsAbelianGrp A of IsAddComoid A := {
opp : A -> A;
addNr : forall x, opp x + x = 0;
}.
HB.structure Definition AbelianGrp := { A of IsAbelianGrp A & IsAddComoid A }.
Notation "- x" := (opp x).
Abelian groups feature the operations and properties given by the
IsAbelianGrp mixin (and its dependency IsAddComoid).
Lemma example (G : AbelianGrp.type) (x : G) : x + (- x) = - 0.
Proof. by rewrite addrC addNr -[LHS](addNr zero) addrC add0r. Qed.
We proceed by showing that Z is an example of both structures, and use
the lemma just proved on a statement about Z.
HB.instance Definition Z_CoMoid :=
IsAddComoid.Build Z 0%Z Z.add Z.add_assoc Z.add_comm Z.add_0_l.
HB.instance Definition Z_AbGrp :=
IsAbelianGrp.Build Z Z.opp Z.add_opp_diag_l.
Lemma example2 (x : Z) : x + (- x) = - 0.
Proof. by rewrite example. Qed.
For a tutorial, see the platform docs.
This paper describes the language in details, and the corresponding talk is available on youtube. The wiki gathers some tricks and FAQs. If you want to work on the implementation of HB, this recorded hacking session may be relevant to you.
opam repo add rocq-released https://rocq-prover.org/opam/released
opam install rocq-hierarchy-builder
rocqPackages_9_X.hierarchy-builder e.g.
via nix-shell -p rocq_9_0 -p rocqPackages_9_0.hierarchy-builder
a mixin is a bare bone building block of the hierarchy, it packs operations and axioms.
a factory is a package of operations and properties that is elaborated by HB to one or more mixin. A mixin is hence a trivial factory.
a structure is declared by attaching zero or more factories to a type.
a builder is a user provided piece of code capable of building one or more mixins from a factory.
an instance is an example of a structure: it provides all operation and fulfills all axioms.
HB core commands:
HB.mixin declares a mixin,HB.structure declares a structure,HB.factory declares a factory,HB.builders and HB.end declare a set of builders,HB.instance declares a structure instance,HB.declare declares a context with parameters, key and mixins.HB.saturate reconsiders all mixin instances to see if some newly declared
structure can be inhabitedHB core tactic-in-term:
HB.pack to synthesize a structure instance in the middle of a term.HB utility commands:
HB.export exports a module and schedules it for re-exportHB.reexport exports all modules, instances and constants scheduled for
re-exportHB.lock locks a definition behind an opaque symbol and an unfolding
equation using Coq module systemHB queries:
HB.about is similar to About but prints more info on HB structures, like
the known instances and where they are declaredHB.locate is similar to Locate, prints file name and line of any global
constant synthesized by HBHB.graph prints the structure hierarchy to a dot fileHB.howto prints sequences of factories to equip a type with a given structureHB debug commands:
HB.status dumps the contents of the hierarchy (debug purposes)HB.check is similar to Check (testing purposes)The documentation of all commands can be found in the comments of
structures.v, search for Elpi Command and you will
find them. All commands can be prefixed with the attribute #[verbose]
to get an idea of what they are doing.
For debugging and teaching purposes, passing the attributes
#[log] or #[log(raw)] to a HB command prints Coq commands which are
almost equivalent to its effect. Hence, copy-pasting the displayed commands into
your source file is not expected to work, and we strongly recommend
against it.
Rocq Prover
49.6%
Prolog
46.8%
Nix
2.4%
Makefile
1.2%