Zulip Chat Archive
Stream: Is there code for X?
Topic: finite categories
Reid Barton (Feb 11 2022 at 01:02):
I'm interested in a particular finite category (it has 6 objects and a total of 17 morphisms) and verifying a fact about it, preferably by brute force. Is there a convenient way to write it down in such a way that I get fintype
instances for all the Hom-types?
Adam Topaz (Feb 11 2022 at 01:08):
docs#category_theory.fin_category is the first thing that I can think of
Adam Topaz (Feb 11 2022 at 01:11):
Well, you would have to provide the fintype
instances yourself. I don't know if derive
would work in your case.
Reid Barton (Feb 11 2022 at 05:54):
Right so my first, and perhaps only, question is in something like
import data.fintype.basic
import tactic.derive_fintype
inductive Ob
| A | B | C | D | E | F
open Ob
@[derive fintype] -- @[derive fintype]: inductive indices are not supported
inductive Hom : Ob → Ob → Type
| f : Hom A B
-- more constructors
is there a way to avoid manually writing an instance for Π (x y : Ob), fintype (Hom x y)
?
Mario Carneiro (Feb 11 2022 at 05:56):
Do you want it to compute?
Mario Carneiro (Feb 11 2022 at 05:56):
You could have a collection of inductives and use a def
to choose between them
Reid Barton (Feb 11 2022 at 05:58):
Well, what I want in the end is some way to automatically check associativity (and another similar condition which is relevant to my problem)
Reid Barton (Feb 11 2022 at 05:58):
I guess I don't really care whether it is dec_trivial
or a tactic that generates a proof with 100 cases
Mario Carneiro (Feb 11 2022 at 05:58):
I think that will be okay, although 6^3 is... :grimacing:
Mario Carneiro (Feb 11 2022 at 05:59):
I feel like this needs some kind of custom automation
David Wärn (Feb 11 2022 at 10:30):
Is it important that you get Π (x y : Ob), fintype (Hom x y)
as opposed to only fintype (Hom A A)
, fintype (Hom A B)
etc ? If not you could define Hom
by pattern matching.
Kyle Miller (Feb 11 2022 at 12:50):
Maybe you could use subtypes to get the fintype instances? I got this to work for a 2-object 4-morphism category.
import category_theory.fin_category
import tactic
open category_theory
@[derive [fintype, decidable_eq]]
inductive objs | a | b
@[derive [fintype, decidable_eq]]
inductive mors | a1 | f | g | b1
def s : mors → objs
| mors.a1 := objs.a
| mors.f := objs.a
| mors.g := objs.a
| mors.b1 := objs.b
def t : mors → objs
| mors.a1 := objs.a
| mors.f := objs.a
| mors.g := objs.b
| mors.b1 := objs.b
abbreviation mors' (x y : objs) : Type := {m : mors // s m = x ∧ t m = y}
example (x y : objs) : fintype (mors' x y) := infer_instance
instance : quiver objs := ⟨mors'⟩
def ids : Π (x : objs), mors' x x
| objs.a := ⟨mors.a1, by tidy⟩
| objs.b := ⟨mors.b1, by tidy⟩
def comp : mors → mors → option mors
| mors.a1 ψ := if s ψ = objs.a then some ψ else none
| ϕ mors.a1 := if t ϕ = objs.a then some ϕ else none
| mors.b1 ψ := if s ψ = objs.b then some ψ else none
| ϕ mors.b1 := if t ϕ = objs.b then some ϕ else none
| mors.f mors.f := some mors.a1
| mors.f mors.g := some mors.g
| _ _ := none
-- after this point, everything is generic and should work even after changing the above data
def comp' {x y z : objs} : mors' x y → mors' y z → mors' x z :=
begin
rintro ϕ ψ,
generalize hc : comp ϕ ψ = ρ,
cases ρ,
obtain ⟨ϕ, rfl, rfl⟩ := ϕ,
obtain ⟨ψ, h, rfl⟩ := ψ,
exfalso; cases ϕ; cases ψ; simp! at hc h; assumption,
use ρ,
obtain ⟨ϕ, rfl, rfl⟩ := ϕ,
obtain ⟨ψ, h, rfl⟩ := ψ,
cases ϕ; cases ψ; simp! at h hc; try { exfalso, assumption }; subst_vars; simp!,
end
instance : category objs :=
{ id := λ x, ids x,
comp := λ x y z ϕ ψ, comp' ϕ ψ,
id_comp' := λ x y ϕ, begin
obtain ⟨ϕ, rfl, rfl⟩ := ϕ,
cases ϕ; refl,
end,
comp_id' := λ x y ϕ, begin
obtain ⟨ϕ, rfl, rfl⟩ := ϕ,
cases ϕ; refl,
end,
assoc' := λ x y z w ϕ ψ ρ, begin
obtain ⟨ϕ, rfl, rfl⟩ := ϕ,
obtain ⟨ψ, h, rfl⟩ := ψ,
obtain ⟨ρ, h', rfl⟩ := ρ,
cases ϕ; cases ψ; simp! at h; try { exfalso, exact h }; cases ρ; simp! at h'; try { exfalso, exact h' }; refl,
end }
Kyle Miller (Feb 11 2022 at 13:03):
But if it would work to case bash for your other condition (rather than needing fintype
instances), this works fine for proving it's a category (after needing to alter how composition works to appease the equation compiler) and is significantly faster:
import category_theory.fin_category
import tactic
open category_theory
@[derive [fintype, decidable_eq]]
inductive objs | a | b
@[derive [decidable_eq]]
inductive mors : objs → objs → Type
| a1 : mors objs.a objs.a
| f : mors objs.a objs.a
| g : mors objs.a objs.b
| b1 : mors objs.b objs.b
instance : quiver objs := ⟨mors⟩
def ids : Π (x : objs), mors x x
| objs.a := mors.a1
| objs.b := mors.b1
def comp : Π {x y z}, mors x y → mors y z → mors x z
| _ _ _ mors.a1 ψ := ψ
| _ _ _ mors.f mors.a1 := mors.f
| _ _ _ mors.b1 ψ := ψ
| _ _ _ mors.g mors.b1 := mors.g
| _ _ _ mors.f mors.f := mors.a1
| _ _ _ mors.f mors.g := mors.g
instance : category objs :=
{ id := λ x, ids x,
comp := λ x y z ϕ ψ, comp ϕ ψ,
id_comp' := λ x y ϕ, begin
cases ϕ; refl,
end,
comp_id' := λ x y ϕ, begin
cases ϕ; refl,
end,
assoc' := λ x y z w ϕ ψ ρ, begin
cases ϕ; cases ψ; cases ρ; refl,
end }
Kyle Miller (Feb 11 2022 at 13:24):
I guess creating fintype
instances for this in a somewhat generic way isn't too bad, if you need them:
instance (x y : objs) : fintype (mors x y) :=
begin
let s : finset (mors x y) := ∅,
cases x; cases y;
{ try { let s := insert mors.a1 s, },
try { let s := insert mors.f s, },
try { let s := insert mors.g s, },
try { let s := insert mors.b1 s, },
use s,
intro ϕ,
cases ϕ;
simp [finset.not_mem_empty, false_or, or_false, finset.mem_insert], },
end
Reid Barton (Feb 13 2022 at 01:13):
FWIW while thinking about how to check the other properties of the category I care about, I realized that by adjusting the category slightly I can make them easy to check by hand... so I no longer really need this.
Last updated: Dec 20 2023 at 11:08 UTC