Skip to content

Define the category of LTSs#391

Open
ayberkt wants to merge 12 commits intoleanprover:mainfrom
ayberkt:main
Open

Define the category of LTSs#391
ayberkt wants to merge 12 commits intoleanprover:mainfrom
ayberkt:main

Conversation

@ayberkt
Copy link

@ayberkt ayberkt commented Mar 2, 2026

This PR resolves #387.

variable (lts₁ : LTS State₁ Label₁)
variable (lts₂ : LTS State₂ Label₂)
variable (lts₃ : LTS State₃ Label₃)

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From what I see below, you don't need these lts variables that much? Consider removing them maybe?


@[expose] public section

variable {State Label State₃ Label₃ State₁ State₂ Label₁ Label₂ : Type}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Type is too restrictive here, you want each type to be in its own universe to state the definitions below more generally. I suggest uᵢ for the States and vᵢ for the labels.


/-- A morphism between two labelled transition systems, consisting of a function on states, a
function on labels, and a proof that transitions are preserved. -/
structure LTSMorphism (lts₁ : LTS State₁ Label₁) (lts₂ : LTS State₂ Label₂) : Type where
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The resulting type should live in the max of the universes of the params.

/-- A morphism between two labelled transition systems, consisting of a function on states, a
function on labels, and a proof that transitions are preserved. -/
structure LTSMorphism (lts₁ : LTS State₁ Label₁) (lts₂ : LTS State₂ Label₂) : Type where
toFun : State₁ → State₂
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm a bit confused by the names. I suggest: stateMap, labelMap, and labelMap_tr.

function on labels, and a proof that transitions are preserved. -/
structure LTSMorphism (lts₁ : LTS State₁ Label₁) (lts₂ : LTS State₂ Label₂) : Type where
toFun : State₁ → State₂
labelMap : Label₁ → Label₂
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reading from the reference you provided on Zulip, this function is supposed to be partial. Is it a conscious decision to make it total here?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point. I wasn’t sure about this. I’ve definitely seen it defined like this elsewhere, but it might be better to stick with the definitions from the Winskel and Nielsen reference as it is quite standard. I will update the definition.

I am also looking at Daniel Mroz’s PhD thesis and the category of LTSs there is over a fixed label set.

Copy link
Collaborator

@chenson2018 chenson2018 Mar 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is common in category theory formalization to have some encoding of partial functions though dependent types, so I wasn't particularly surprised by this definition. Please see my reviews below however, I believe these definitions have a more fundamental problem.

variable (lts₃ : LTS State₃ Label₃)

/-!
# Category of Labelled Transition Systems
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be good to add a reference.

@fmontesi
Copy link
Collaborator

fmontesi commented Mar 3, 2026

Not urgent, but please fix the title of the PR at some point to start with the required feat: prefix, or CI won't let us merge this.

Comment on lines +36 to +40
def LTS.Morphism.id (lts : LTS State Label) : LTS.Morphism lts lts :=
{ toFun := _root_.id
, labelMap := _root_.id
, fun_preserves_transitions := fun _ _ _ h => h
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A couple of style points:

  • you can use where with def as well for better readability
  • please eliminate the extra whitespace here and everywhere else. I personally like it too aesthetically, but we prioritize the uniformity of the Mathlib style.
  • For fun_preserves_transitions move parameters to the left for clarity

All together this gives:

Suggested change
def LTS.Morphism.id (lts : LTS State Label) : LTS.Morphism lts lts :=
{ toFun := _root_.id
, labelMap := _root_.id
, fun_preserves_transitions := fun _ _ _ h => h
}
def LTS.Morphism.id (lts : LTS State Label) : LTS.Morphism lts lts where
toFun := _root_.id
labelMap := _root_.id
fun_preserves_transitions _ _ _ h := h


/-- A morphism between two labelled transition systems, consisting of a function on states, a
function on labels, and a proof that transitions are preserved. -/
structure LTS.Morphism (lts₁ : LTS State₁ Label₁) (lts₂ : LTS State₂ Label₂) : Type where
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

More significantly this needs to follow suit with Mathlib's concrete categories such as AddMonCat, AlgCat, GrpCat, etc. As I describe below, I think you end up formalizing a definition different from what you are intending.

I would expect this structure to follow their naming and to similarly bundle a separately defined type of LTS homomorphism.

Comment on lines +30 to +33
fun_preserves_transitions : (s s' : State₁)
→ (l : Label₁)
→ lts₁.Tr s l s'
→ lts₂.Tr (toFun s) (labelMap l) (toFun s')
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Style-wise this should go mostly on one line

Suggested change
fun_preserves_transitions : (s s' : State₁)
→ (l : Label₁)
→ lts₁.Tr s l s'
→ lts₂.Tr (toFun s) (labelMap l) (toFun s')
fun_preserves_transitions (s s' : State₁) (l : Label₁) :
lts₁.Tr s l s' → lts₂.Tr (toFun s) (labelMap l) (toFun s')

/-! ## LTSs and LTS morphisms form a category -/

/-- `LTS.Morphism` provides a category structure on the `LTS` type. -/
instance {State Label : Type} : CategoryTheory.CategoryStruct (LTS State Label) where
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You shouldn't define this separately from the Category instance.

comp {lts₁} {lts₂} {lts₃} := LTS.Morphism.comp lts₁ lts₂ lts₃

/-- Proof that the above structure actually forms a category. -/
instance {State Label : Type} : CategoryTheory.Category (LTS State Label) where
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You'll see in the examples I link above that they would define a fully bundled equivalent

structure LTSCat where
  State : Type u
  Label : Type v
  str : LTS State Label

Otherwise, we aren't talking about the category of LTSs where morphisms are between LTS with different states/labels, because a polymorphic instance like this is defining a category for each state/label type.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might be best also to go ahead and have the module structure match up as Cslib/Foundations/Semantics/LTS/LTSCat/Basic.lean since it looks like you have immediate plans to extend this further.


/- Remark: I do not like the name 'bundled LTS'; and LTS is already the bundled notion. The name
`LTS` for the transition relation on a fixed set of states and labels is what is confusing here.
I propose to change that to `LTS-Structure` and call the above `LTS`.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I hope not. LTS is used in many, many places already. We should keep its short name.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rest assured we will not change this name. As I say above, in alignment with Mathlib it should be LTSCat. (And will not affect any of your existing work)

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also

LTS is already the bundled notion

makes me think we have a mismatch in terminology that might be a Lean colloquialism. Could you clarify what you mean by this @ayberkt?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Define the category of LTSs

4 participants