Hi Nathann, On 2013-12-25, Nathann Cohen <nathann.co...@gmail.com> wrote: > sage: F23 = IntegerModRing(23) > sage: F23.category().is_subcategory(Fields()) > True
You mean "False". > sage: F23 in Fields() > True > sage: F23.category().is_subcategory(Fields()) > True Only now it is "True". > For this reason, I do not understand the code of > FiniteEnumeratedSets().__contains__ : > > try: > c = x.category() > except AttributeError: > return False > return c.is_subcategory(self) > > To me, this is wrong, To me as well. FiniteEnumeratedSets should not inherit from the class "Category", but from the class "CategorySingleton". And then, the category containment test would look like @lazy_class_attribute def __contains__(cls): return Category_contains_method_by_parent_class(cls()) which would be a *lot* faster! But this is fixed in the famous trac ticket #10963. > as a set whose category does *not* specify anything > on the cardinality will be detected as non-Finite, without any actual > attempt at determining its cardinality. Hmm. In a way, I think you could be right, as the situation can be compared with Fields(). There are rings that may or may not be fields, depending on the input parameters; but detecting "fieldness" would be rather expensive. In some (but not all!) applications, it is not needed to know whether it is a field or not. Solution: We don't test "fieldness" during initialisation, and only test if it is explicitly asked for. And in this case, we may refine the category that was specified during initialisation. And in your setting, we have things that may or may not be finite, depending on parameters. And testing finiteness would be expensive. Hence, we could (again) decide to postpone the finiteness test until it is really needed. Nicolas, couldn't this be solved using your approach (axioms...) from #10963? In the sense of "applying an axiom A to a category C may override C.__contains__ by a new containment test that takes into account both C.__contains__ and some specific tests for A"? In the end, the containment test for Sets().Enumerated().Finite() could be made to look similar to what we do now for fields, namely: def __contains__(self, x): try: # This is a very fast test that is correct if the category # of x is fully initialised. Also it is correct, if it # returns "True" c = self._contains_helper(x) except StandardError: return False if c: return True # (*) see below if x not in self._base_category: return False try: if x.is_finite(): # (**) x._refine_category(self) return True return False except StandardError: return False The problem with this test: If x is provably infinite, it would be better if we had a fast shortcut. E.g., we could insert the following line into the above __contains__ method of finite enumerated sets, in the line marked (*) or perhaps in a better place: if self._base_category.Infinite()._contains_helper(x): return False Remark: 1. The above is totally generic, hence, it could easily be put into the axiom "Finite()", isn't it, Nicolas? 2. Moreover, the above could easily be generalised to other axioms, as there is only the line marked (**) (and perhaps also the insertion in (*)) that refers to the specific axiom "Finite()". 3. The above should *only* be done if we have an application where determining finiteness during initialisation is a waste of time that seriously affects efficiency. Best regards, Simon -- You received this message because you are subscribed to the Google Groups "sage-combinat-devel" group. To unsubscribe from this group and stop receiving emails from it, send an email to sage-combinat-devel+unsubscr...@googlegroups.com. To post to this group, send email to sage-combinat-devel@googlegroups.com. Visit this group at http://groups.google.com/group/sage-combinat-devel. For more options, visit https://groups.google.com/groups/opt_out.