#20515: Proper idiom for defining an axiom as the intersection of two axioms
defined in the same category.
-------------------------------+------------------------
Reporter: nthiery | Owner:
Type: enhancement | Status: new
Priority: minor | Milestone: sage-7.2
Component: categories | Resolution:
Keywords: | Merged in:
Authors: | Reviewers:
Report Upstream: N/A | Work issues:
Branch: | Commit:
Dependencies: | Stopgaps:
-------------------------------+------------------------
Description changed by nthiery:
Old description:
> Let `Cs` be a category, where three axioms are defined, `A`, `A1`,
> `A2`, with `A` being the intersection of `A1` and `A2`. The natural
> implementation would look like:
>
> {{{
> from sage.categories.category_with_axiom import CategoryWithAxiom,
> all_axioms
>
> all_axioms += ("A", "A1", "A2")
>
> class Cs(Category):
> def super_categories(self):
> return [Objects()]
>
> class SubcategoryMethods:
> def A1(self):
> return self._with_axiom("A1")
> def A2(self):
> return self._with_axiom("A2")
> def A(self):
> return self._with_axiom("A")
>
> class A1(CategoryWithAxiom):
> pass
>
> class A2(CategoryWithAxiom):
> def A1_extra_super_categories(self):
> return [Cs().A()]
>
> class A(CategoryWithAxiom):
> def extra_super_categories(self):
> return [Cs().A1(), Cs().A2()]
> }}}
>
> However this triggers an infinite recursion loop:
> {{{
> sage: Cs().A()
> RuntimeError: maximum recursion depth exceeded while calling a Python
> object
> }}}
>
> This is because `Cs().A2().A1_extra_super_categories()` does not
> return a strict super category of the to-be-constructed category,
> which is forbidden by the current specifications:
>
> http://doc.sagemath.org/html/en/reference/categories/sage/categories/category_with_axiom.html#id2
>
> A workaround is to define A (or A1, or A2) in some super category:
> {{{
> class C0(Category):
> def super_categories(self):
> return [Objects()]
> class SubcategoryMethods:
> def A(self):
> return self._with_axiom("A")
> class A(CategoryWithAxiom):
> pass
>
> class C1(Category):
> def super_categories(self):
> return [C0()]
>
> class SubcategoryMethods:
> def A1(self):
> return self._with_axiom("A1")
> def A2(self):
> return self._with_axiom("A2")
>
> class A1(CategoryWithAxiom):
> pass
>
> class A2(CategoryWithAxiom):
> def A1_extra_super_categories(self):
> return [C0.A()]
>
> class A(CategoryWithAxiom):
> def extra_super_categories(self):
> return [C1.A1(), C1.A2()]
> }}}
> Then,
> {{{
> sage: C1().A1().A2() is C1().A()
> True
> sage: C1().A()
> Category of a1 a2 c1
> sage: C1().A().super_categories()
> [Category of a c0, Category of a2 c1, Category of a1 c1]
> sage: C1().A1().A2() is C1().A()
> True
> }}}
>
> A better idiom would be desirable, for cases where none of `A`, `A1`,
> `A2` make sense in a strict super category.
>
> See #18265 for a concrete instance where this workaround is currently
> used.
New description:
Let `Cs` be a category, where three axioms are defined, `A`, `A1`,
`A2`, with `A` being the intersection of `A1` and `A2`. The natural
implementation would look like:
{{{
from sage.categories.category_with_axiom import CategoryWithAxiom,
all_axioms
all_axioms += ("A", "A1", "A2")
class Cs(Category):
def super_categories(self):
return [Objects()]
class SubcategoryMethods:
def A1(self):
return self._with_axiom("A1")
def A2(self):
return self._with_axiom("A2")
def A(self):
return self._with_axiom("A")
class A1(CategoryWithAxiom):
pass
class A2(CategoryWithAxiom):
def A1_extra_super_categories(self):
return [Cs().A()]
class A(CategoryWithAxiom):
def extra_super_categories(self):
return [Cs().A1(), Cs().A2()]
}}}
However this triggers an infinite recursion loop:
{{{
sage: Cs().A()
RuntimeError: maximum recursion depth exceeded while calling a Python
object
}}}
This is because `Cs().A2().A1_extra_super_categories()` does not
return a strict super category of the to-be-constructed category,
which is forbidden by the current specifications:
http://doc.sagemath.org/html/en/reference/categories/sage/categories/category_with_axiom.html#id2
A workaround is to define `A` (or `A1`, or `A2`) in some super category:
{{{
class C0(Category):
def super_categories(self):
return [Objects()]
class SubcategoryMethods:
def A(self):
return self._with_axiom("A")
class A(CategoryWithAxiom):
pass
class C1(Category):
def super_categories(self):
return [C0()]
class SubcategoryMethods:
def A1(self):
return self._with_axiom("A1")
def A2(self):
return self._with_axiom("A2")
class A1(CategoryWithAxiom):
pass
class A2(CategoryWithAxiom):
def A1_extra_super_categories(self):
return [C0.A()]
class A(CategoryWithAxiom):
def extra_super_categories(self):
return [C1.A1(), C1.A2()]
}}}
Then,
{{{
sage: C1().A1().A2() is C1().A()
True
sage: C1().A()
Category of a1 a2 c1
sage: C1().A().super_categories()
[Category of a c0, Category of a2 c1, Category of a1 c1]
sage: C1().A1().A2() is C1().A()
True
}}}
See #18265 for a concrete instance where this workaround is currently
used when none of `A`, `A1`, `A2` make sense in a strict super category.
A better idiom would be desirable if more use cases appear.
--
--
Ticket URL: <http://trac.sagemath.org/ticket/20515#comment:1>
Sage <http://www.sagemath.org>
Sage: Creating a Viable Open Source Alternative to Magma, Maple, Mathematica,
and MATLAB
--
You received this message because you are subscribed to the Google Groups
"sage-trac" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
Visit this group at https://groups.google.com/group/sage-trac.
For more options, visit https://groups.google.com/d/optout.