Repository navigation
Conversation
There was a problem hiding this comment.
🟡 Changes recommended
The legacy Docker CI still targets Coq 8.15 and cannot validate the newly required Rocq/Dune toolchain.
1 open finding
What changed in this PR
Makes choice trees universe-polymorphic, removes disabled universe checking, updates affected proofs, and migrates builds to Rocq/Dune syntax.
Changes:
- Separates event, branch, result, and tree-carrier universes.
- Repairs interpreter, recursion, equivalence, and example proofs.
- Migrates Dune stanzas to Rocq.
| File | Description |
|---|---|
README.md |
Documents enabled universe checking. |
dune-project |
Requires Dune 3.24 and Rocq 0.11. |
theories/dune |
Migrates the main theory to Rocq. |
theories/Core/CTreeDefinitions.v |
Makes core trees and atomic operations universe-polymorphic. |
theories/Core/Index.v |
Enables universe polymorphism. |
theories/Core/Utils.v |
Generalizes trigger and branch classes. |
theories/Eq/Epsilon.v |
Enables universe polymorphism. |
theories/Eq/Equ.v |
Adds polymorphic atomic equations and repairs proofs. |
theories/Eq/IterFacts.v |
Enables universe polymorphism. |
theories/Eq/SBisim.v |
Repairs strong bisimulation proofs. |
theories/Eq/SBisimAlt.v |
Enables universe polymorphism. |
theories/Eq/SSim.v |
Repairs simulation proofs. |
theories/Eq/SSimAlt.v |
Repairs alternate simulation proofs. |
theories/Eq/Shallow.v |
Enables universe polymorphism. |
theories/Eq/Trace.v |
Adds rewriting support for trace heads. |
theories/Eq/Trans.v |
Separates transition-label universes and updates proofs. |
theories/Eq/Visible.v |
Enables universe polymorphism. |
theories/Eq/WBisim.v |
Updates converse notation for Rocq compatibility. |
theories/Interp/Fold.v |
Generalizes fold and interpreter signatures. |
theories/Interp/FoldCTree.v |
Makes tree interpreters universe-polymorphic. |
theories/Interp/FoldStateT.v |
Generalizes state interpreters and repairs equations. |
theories/Interp/ITree.v |
Generalizes interaction-tree embedding. |
theories/Interp/Internalize.v |
Separates source and destination universes. |
theories/Interp/Recursion.v |
Generalizes recursive interpreters and calls. |
theories/Interp/RecursionFacts.v |
Updates recursion equivalence proofs. |
theories/Interp/Refine.v |
Repairs refinement proofs under universe checking. |
theories/Misc/Head.v |
Generalizes head actions. |
theories/Misc/Pure.v |
Makes purity predicates polymorphic. |
examples/AltBisim/dune |
Migrates the example theory to Rocq. |
examples/CCS/Denotation.v |
Generalizes CCS trees and repairs transition proofs. |
examples/CCS/OpDenot.v |
Removes disabled universe checking. |
examples/CCS/dune |
Migrates the CCS theory to Rocq. |
examples/Coffee/coffeeCTree.v |
Updates transition-based example proofs. |
examples/Coffee/dune |
Migrates the Coffee theory to Rocq. |
examples/ImpBr/ImpBr.v |
Generalizes computation universes and notation. |
examples/ImpBr/dune |
Migrates the ImpBr theory to Rocq. |
examples/SimpleSim/SimExample.v |
Updates trigger equation rewrites. |
examples/SimpleSim/dune |
Migrates the simulation theory to Rocq. |
examples/Yield/Lang.v |
Generalizes semantic interpreters and proofs. |
examples/Yield/Par.v |
Separates scheduler tree universes. |
examples/Yield/Util.v |
Generalizes vector-tree utilities. |
examples/Yield/dune |
Migrates Yield and adds Equations. |
tests/ImpBrTest/ImpBrEx/ImpBrEx.v |
Removes disabled universe checking. |
tests/ImpBrTest/ImpBrEx/dune |
Migrates the test theory to Rocq. |
tests/ImpBrTest/extracted/Extract.v |
Removes disabled universe checking. |
tests/ImpBrTest/extracted/dune |
Migrates extraction to Rocq. |
🧠 Review effort: Balanced
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
|
Hey Lef, hope you are doing great on your side! That's interesting, I had luck with Claude diagnosing a similar issue in a development, trying at some point for ctrees was in the back of my mind. Thanks for giving it a shot!! In the other library I tried it I was quite happy to get the problem boiled down to a single specific definition for which an alternate definition relaxed constraints. Here things are a lot more complex visibly. From a quick glance:
That's both satisfying and frustrating! Did it produce some kind of summary explanation by any chance to get a better sense of what is going on? Thanks again! |
| Section ctree. | ||
|
|
||
| Context {E : Type -> Type} {B : Type -> Type} {R : Type}. | ||
| Universe e b. |
There was a problem hiding this comment.
Need to understand if and why this manual pinning of the universes is necessary.
There was a problem hiding this comment.
The names tie VisF/BrF response types to the E/B domains without tying those domains together.
| End CTree. | ||
|
|
||
| Section AtomicTrees. | ||
| Universes d q. |
There was a problem hiding this comment.
It's even more mystifying to me in this section. It doesn't seem to explicitly tie any specific universes together, why not let universe polymorphism run its course?
There was a problem hiding this comment.
These preserve independently instantiable constructor carriers; the regression checks strictly larger carriers (i < ri < qi) and bind across different carrier universes.
|
|
||
| #[global] Instance MonadTrigger_ctree {E F B} `{E -< F} : MonadTrigger E (ctree F B) := | ||
| fun _ e => trigger e. | ||
| #[global] Instance MonadTrigger_ctree@{d q +} {E : Type -> Type} {F : Type -> Type} {B} |
There was a problem hiding this comment.
Need to check what is this + notation. Is it just to name the two first universes but let the others be handled normally? Unsure.
There was a problem hiding this comment.
Yes: + lets Rocq infer the remaining universes, while d and q name the carrier levels rather than fixing concrete universe values.
|
|
||
| Polymorphic Class MonadTrigger (E : Type -> Type) (M : Type -> Type) : Type := | ||
| mtrigger : forall {X}, E X -> M X. | ||
| Polymorphic Class MonadTrigger@{ei +} |
There was a problem hiding this comment.
Ah here I maybe (emphasis on maybe) understand better: the input of E and the type on which we quantify can indeed be enforced to be equal, that sounds reasonable.
There was a problem hiding this comment.
Exactly: mtrigger quantifies over the same response universe as E’s domain, and mbr does the analogous thing for branches.
| rewrite <- x in EQu. | ||
| dependent destruction EQu. | ||
| rewrite <- x. eauto. | ||
| rewrite <- x. |
There was a problem hiding this comment.
But surely we don't have to carefully not call eauto in some contexts just to please the universes? That would simply not be sustainable.
There was a problem hiding this comment.
Agreed; I restored the original eauto proof, which compiles with universe checking enabled.
| Proof. | ||
| intros R t u EQ; inv EQ. | ||
| apply Equ_clos with u' t'; intuition. | ||
| apply Equ_clos with u' t'; intuition; symmetry; assumption. |
There was a problem hiding this comment.
It really seems to hate intuition. Why?
There was a problem hiding this comment.
There was no need to avoid it here; I restored the original intuition proof and checked it with universe checking enabled.
| (CTree.trigger e : @ctree@{_ _ _ _ d q} E B X) = Vis e (fun x => Ret x). | ||
| Proof. reflexivity. Qed. | ||
|
|
||
| Lemma bind_trigger {X Y} |
There was a problem hiding this comment.
It also seems to avoid using the monad type class. That makes sense as it probably tried to find a repo-local solution when fundamentally it's a cross repo one.
There was a problem hiding this comment.
The Monad instance remains; this lemma exposes different input/output tree universes, whereas ExtLib’s bind uses a single M.
Keep required universe boundaries, restore existing proof structure, and retain only necessary polymorphism. Remove the unused trace instance and use native converse notation in WBisim. Validated on Rocq 9.3.0 with OCaml 5.4.1 and Dune 3.24.2: full build, UniverseCheck, kernel recheck, focused source probes, and ImpBr consumer. Rocq 9.0 and 9.2 CI remain required.
Align Nix with the passing Docker toolchain and pin coinduction v1.22 and relation-algebra v1.9.1. Update the declared compiler minimum and README to Rocq 9.2. The former Rocq 9.0 dependency combination fails a universe-checked RelationAlgebra/ITree facts import without loading any CTree code. The repaired dependency import and exact Nix package build pass locally; the Rocq 9.3 build, UniverseCheck, and ImpBr consumer also pass.
|
Hey Yannick, thanks for the careful review! You were right that the first pass mixed the universe fix with a lot of unnecessary churn. I’ve pushed 1b688f3, reverting those proof rewrites—including the eauto, intuition, and relational-algebra changes—restoring InterpFacts and ~> notation, and removing redundant polymorphism settings. The remaining annotations keep event/branch response domains and tree-carrier universes separate, including across bind and interpretation. I also added a regression with strict universe inequalities to check that these boundaries really stay independent, rather than just making the examples compile. The full build, kernel recheck, and ImpBr example pass locally on Rocq 9.3 and should pass on the CI as well. I bumped the versions of Rocq and dune, might as well. |


Hey folks! I hope all is well since we last talked. I was evaluating the performance of LLMs on hard proof engineering tasks and I decided to try resolving the "Unset Universe Check" issue which has been
with ctrees for several years. This PR removes the universe-checking workarounds by fixing the underlying constraints, particularly where event and branch response universes were tied to tree carriers.
It also updates the build for Rocq/Dune and repairs the affected interpreters and example proofs, restoring the usual trigger and bind equations. Existing declarations and notation are preserved; no new
axioms or admitted proofs were added.
I checked the full build on Rocq 9.3.0, feel free to review and comment.