Skip to content

Conversation

@CharlesCNorton
Copy link
Contributor

@CharlesCNorton CharlesCNorton commented Aug 10, 2025

Extracting SemiAdditive.v from additive categories work per PR #2304 review as part of general formalization for #2288

Provides:

  • SemiAdditiveCategory: Class with just cat, zero object, and biproducts
  • Derives IsCommutativeMonoid structure on morphisms using biproducts
  • Addition defined as: f + g = ∇ ∘ (f ⊕ g) ∘ Δ
  • Proves identity laws, commutativity, associativity from biproduct axioms
  • Bilinearity of composition (distributivity)

Note: The file is almost 1000 lines and requires refactoring, especially the associativity proof. @jdchristensen this was the only way I could get it to work - would very much appreciate help simplifying and identifying which helper lemmas can be removed. The associativity proof in particular requires many intermediate lemmas about how biproducts interact. It took me an entire week of 16 hour days to get here, but I assume there is a much more elegant method.

@CharlesCNorton
Copy link
Contributor Author

Also apologies if there are any nits I missed - I'll give it another lookover soon.

@CharlesCNorton
Copy link
Contributor Author

Refactored. File is about 20% shorter than before at 800 lines instead of 1000. Going through it again...

@CharlesCNorton
Copy link
Contributor Author

@jdchristensen In light of yesterday’s disastrous PR attempt, and out of respect for your time, I’d like to hold off on this PR for a few more weeks to ensure it’s truly shipshape. The rest of my contributions to Coq-HoTT will remain focused on the formalization.

@CharlesCNorton
Copy link
Contributor Author

We're now down to about half the length of the original PR. Continuing.

@jdchristensen
Copy link
Collaborator

@CharlesCNorton I haven't looked at this yet and will wait until you ok it. But I'll point out a couple of things that may help.

First, there's a trick for showing the a binary operation * is associative and commutative. You prove commutativity as expected, but instead of directly proving associativity, you prove the "twist" law: (x * y) * z <~> (z * y) * x (or some other variant). This is easier than proving associativity, because you can use the same function in both directions, and you only have to prove one composite is the identity (since that covers both composites, just as when you are proving symmetry). Associativity follows from these two. See baer_sum_twist and equiv_trijoin_twist' in the library.

The second thing that sometimes is helpful is to study the triple product x * y * z as its own operation, which is done for both the Baer sum and the join.

The Baer sum formalization should be particularly relevant, since it uses a lot about biproducts of abelian groups which should generalize to biproducts in any category.

@CharlesCNorton
Copy link
Contributor Author

@CharlesCNorton I haven't looked at this yet and will wait until you ok it. But I'll point out a couple of things that may help.

First, there's a trick for showing the a binary operation * is associative and commutative. You prove commutativity as expected, but instead of directly proving associativity, you prove the "twist" law: (x * y) * z <~> (z * y) * x (or some other variant). This is easier than proving associativity, because you can use the same function in both directions, and you only have to prove one composite is the identity (since that covers both composites, just as when you are proving symmetry). Associativity follows from these two. See baer_sum_twist and equiv_trijoin_twist' in the library.

The second thing that sometimes is helpful is to study the triple product x * y * z as its own operation, which is done for both the Baer sum and the join.

The Baer sum formalization should be particularly relevant, since it uses a lot about biproducts of abelian groups which should generalize to biproducts in any category.

Thank you very much!

@CharlesCNorton
Copy link
Contributor Author

@jdchristensen Ready for review! Was having a tough time implementing the twist, and so kept a more direct proof for associativity. Please let me know what you think. Happy to make any required changes. 👍

Copy link
Collaborator

@jdchristensen jdchristensen left a comment

Choose a reason for hiding this comment

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

I've only looked over the first 20% or so.

Comment on lines 39 to 42
(biproduct_coprod_mor (semiadditive_biproduct Y Y) Y
1%morphism 1%morphism
o biproduct_prod_mor (semiadditive_biproduct Y Y) X
f g)%morphism.
Copy link
Collaborator

Choose a reason for hiding this comment

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

This is verbose. Can you come up with a better way to express these morphisms, with some arguments implicit and provided via typeclass search? This comes up a lot in the file. (A similar thing appears in the ⊕ Notation.)


(** ** Biproduct characterization lemmas *)

Section BiproductCharacterization.
Copy link
Collaborator

Choose a reason for hiding this comment

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

It seems to me that the lemmas in the section only require a single Biproduct to exist, rather than a SemiAdditiveCategory structure, so they could be proved in Biproducts.v.


(** ** Swap morphism for biproducts *)

Section BiproductSwap.
Copy link
Collaborator

Choose a reason for hiding this comment

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

Again, some or all of this section probably belongs in Biproducts.v, since these results could be useful for a single biproduct object, even if you don't know you are in a semiadditive category.

Comment on lines 129 to 86
Definition biproduct_swap (A : object C)
: morphism C (A ⊕ A) (A ⊕ A)
Copy link
Collaborator

Choose a reason for hiding this comment

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

Why not [A ⊕ B -> B ⊕ A]? Then you are probably close to proving that biproducts are commutative.

Comment on lines 56 to 58
Lemma biproduct_zero_right_is_inl (Y Z : object C) (h : morphism C Z Y)
: biproduct_prod_mor (semiadditive_biproduct Y Y) Z h (zero_morphism Z Y)
= (Biproducts.inl (biproduct_data (semiadditive_biproduct Y Y)) o h)%morphism.
Copy link
Collaborator

Choose a reason for hiding this comment

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

This and the next lemma are ok, but I think the proof could be built out of a few more conceptual tools. In Biproducts.v, you could prove that Biproducts.inl = biproduct_prod_mor id zero (not typed precisely), which is a useful general fact. Then the third lemma in this section is a naturality result, which tells you that biproduct_prod_mor id zero o h = biproduct_prod_mor (id o h) (zero o h). Then you just use the properties of id and zero. Seems cleaner, and that result about inl is independently useful.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Also, I think one of the Ys can be changed to a fresh object Y', giving a slightly more general result.

Comment on lines 81 to 84
Lemma biproduct_comp_general (W X Y Z : object C)
(f : morphism C W X) (g : morphism C W Y) (h : morphism C Z W)
: (biproduct_prod_mor (semiadditive_biproduct X Y) W f g o h)%morphism
= biproduct_prod_mor (semiadditive_biproduct X Y) Z (f o h) (g o h).
Copy link
Collaborator

Choose a reason for hiding this comment

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

This is a naturality result, so that should be mentioned in the comment and in the name. (Also, this is a result that is just a fact about products, not biproducts. Really products (and coproducts) should have been studied on their own first, and then biproducts could make use of those results, but I think that's a refactoring for another time.)

@jdchristensen
Copy link
Collaborator

Was having a tough time implementing the twist, and so kept a more direct proof for associativity.

The examples where I've seen it used are for proving equivalences A * (B * C) <~> (A * B) * C, but here you are proving equalities, so maybe it's not as useful. For equalities, you just have to give a path in one direction and you are done. For equivalences, you have to give maps in both directions and then prove that both composites are the identity, and the twist saves you a factor of 2 of work, as the same map works in both directions and the same proof handles both composites.

That said, the proof of associativity still looks really long, and conceptually I don't see why it should be long. I wonder if what you are missing is the associativity of the biproduct itself (for which the twist approach would help). #2016 does this for wild categories using the twist approach (but doesn't get to addition of morphisms). Not sure if it would be worth trying this. It would certainly be a lot of work, but the idea is that instead of pushing through proofs, one tries to develop the basic tools that make later proofs easy. And knowing that biproducts are associative is one of the basic facts one would expect to have. Probably not worth it here, so just take this as an aside.

(This also suggests the idea of switching to wild categories. We have more about biproducts there, and they are also defined in terms of coproducts and products, so results are stated at the correct level of generality. But #2016 is still a work in progress, with @ThomatoTomato planning to reorganize things a bit.)

@CharlesCNorton
Copy link
Contributor Author

@jdchristensen Thanks for the review. Do you think I should switch to WildCat now or stick with the current approach? I suspect I know the answer, but wanted your opinion in case there's some utility in continuing.

@jdchristensen
Copy link
Collaborator

@jdchristensen Thanks for the review. Do you think I should switch to WildCat now or stick with the current approach? I suspect I know the answer, but wanted your opinion in case there's some utility in continuing.

I don't think there's an easy answer. If your current proofs just needed mild touch-ups, I'd lean towards just sticking with Categories, since the code has already been written and it might be quite a burden to rewrite it. But so far it seems that each file needs fairly substantial revisions, which makes me wonder if it wouldn't be that much extra work to switch to WildCat. The advantage of switching is that multiple people will be interested in using some of these results and may be able to contribute to review or even proofs. One disadvantage of switching (besides the fact that you already have code for Categories) is that dealing with the plethora of typeclasses used by WildCat can be a bit confusing.

Break semicolon and comma-chained tactics into individual lines
per code review feedback from @jdchristensen. Each tactic is now
on its own line, making proofs easier to step through interactively.
Make semiadditive_biproduct a typeclass instance (::) so Coq can
infer it automatically. Replace explicit (semiadditive_biproduct X Y)
arguments with _ throughout, reducing occurrences from 51 to 3.

Per code review feedback from @jdchristensen.
Remove incorrect indentation from morphism_addition_commutative
(was indented as if inside a Section). Remove trailing whitespace
throughout file.
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.

2 participants