Why not R.is_field(unknown_returns=XXX) so you can specify the desired
value for "I don't know", either False or True? Otherwise, +1 -- this
has been a problem in other places for me.
Nick
Would this be a good place for the proof=True/False parameter? If
proof=True, then an exception is thrown if we don't know the result. If
proof=False, then False means that we don't know for sure it is True.
A similar issue to this came up when testing equality of symbolic
expressions. There, the decision was that True was returned if we knew
two expressions were equal, and otherwise False was returned. The logic
between the equality testing and this question seems like it should be
consistent.
Thanks,
Jason
A similar issue to this came up when testing equality of symbolic
expressions. There, the decision was that True was returned if we knew
two expressions were equal, and otherwise False was returned. The logic
between the equality testing and this question seems like it should be
consistent.
Hi William,
On Aug 22, 8:30 pm, William Stein <wst...@gmail.com> wrote:
[...]
> > The logicIs it deprecated? I get
> > between the equality testing and this question seems like it should be
> > consistent.
>
> That's a good point -- the question is perhaps impossible to answer in
> general in both cases. That said, I know for a fact a lot of people will
> complain if R.is_field() returns False by default when one can't decide,
> even when R is a field, since I think that used to be the case and people
> *very* frequently completely. This was when is_Field(...) was in the
> top-level namespace (it has since been deprecated).
sage: is_field(RR)
True
without a deprecation warning and without importing anything in Sage
4.1
I agree that consistent behaviour is good, but I don't see the point
of the "proof=True" option: Catching an error is not more difficult
than putting an extra argument "proof=False".
What do you think about returning "None" if the answer can't be
determined?
Namely, the typical use case in existing programs should be
if R.is_field():
run some special algorithm
else:
do the generic blurp
If R.is_field() returns None, then the generic case would apply (which
is natural if one doesn't know for sure whether R is a field).
If one really wants to know whether R is provably not a field, then
one asks R.is_field()==False.
Since it is generally undecidable whether a ring is a field, I think
there should be a generic method for rings that allows the user to
assert that R is a field. Say:
sage: R = some weird definition, the user knows it is a field
sage: R.is_field()
=> NotImplementedError
sage: R.assert_field(True)
sage: R.is_field()
True
Thank you for working on it!
Best regards,
Simon
> If one really wants to know whether R is provably not a field, then
> one asks R.is_field()==False.
A short aside unrelated to the general discussion, but good to know:
it's usually much faster to do "some_value is False", since that is a
pointer comparison. Also, 0==False is true, where I don't think that's
what you want in the above test.
sage: %timeit None==False
1000000 loops, best of 3: 264 ns per loop
sage: %timeit None is False
10000000 loops, best of 3: 171 ns per loop
sage: a=3
sage: %timeit a==False
100000 loops, best of 3: 2.82 盜 per loop
sage: %timeit a is False
10000000 loops, best of 3: 211 ns per loop
sage: 0==False
True
sage: 0 is False
False
Jason
Hi!
On Aug 23, 8:42 pm, William Stein <wst...@gmail.com> wrote:
[...]
> Don't make it upper case. Make the attribute _is_field. Otherwise theOr one could have a single attribute "_properties", which is a
> above sounds great to me.
dictionary, and then one can define
self._properties['integrally_closed'] = True
self._properties['field'] = False
...
I guess this would provide some flexibility, but I don't know if it
would be a "clean" thing to do.
Since I am not an experienced programmer:
Are there reasons to not use
a dictionary for those kind of things?
Hi Minh,
On 24 Aug., 02:10, Minh Nguyen <nguyenmi...@gmail.com> wrote:
[...]
> > Since I am not an experienced programmer: Are there reasons to not useBut you couldn't use the attribute "._properties" in doc tests anyway,
> > a dictionary for those kind of things?
>
> A good point: searching through a dictionary is essentially constant time.
>
> A bad point: can't assume that each key/value pair in a dictionary
> would always be ordered in exactly the same way. This assumption was
> uncovered during the development of Sage 4.1.1 when a doctest failed.
> The cause of the failure: the doctest assumed that printing the
> key/value pairs of a dictionary would always result in exactly the
> same arrangement of key/value pairs. Bad assumption there.
because AFAIK rings are cdef classes, so, you can't access the
attributes on a python level.
> On Sun, Aug 23, 2009 at 12:27 PM, Sebastian Pancratz
> <sa...@pancratz.org> wrote:
>
> I think as a first step I'll only implement the additional argument
> for the two methods "is_field" and "is_integral_domain".
+1 to this idea.
> For the other suggestion, namely to allow the user to assert that a
> ring is in fact a field, would the following be the "right" way to
> implement this? 1. Add a new attribute to the ring class, say
> IS_FIELD, initialised to None, 2. Implement "assert_field(check)" to
> set IS_FIELD = check, 3. Change "is_field" such that (ignoring the
> issue about raising an exception or returning False) if IS_FIELD is
> None it should behave as now and otherwise it should return the value
> of IS_FIELD.
>
> Don't make it upper case. Make the attribute _is_field. Otherwise
> the above sounds great to me.
I'm not sure about this--it means everyone implementing an is_field
method will have to know about this "trick" and the number of
properties to know about grows as the number of is_* methods. What
I'd rather see is something like
sage: R = Zmod(6)
sage: K = categories.Fields(R, check=False) # any ring R
sage: K
Ring of integers modulo 6 as a field.
sage: K.is_field()
True
where all other methods are inherited via dynamically.
- Robert
You have a really good point.
> What I'd rather see is something like
>
> sage: R = Zmod(6)
> sage: K = categories.Fields(R, check=False) # any ring R
> sage: K
> Ring of integers modulo 6 as a field.
> sage: K.is_field()
> True
>
> where all other methods are inherited via dynamically.
That would be pretty cool. I'm not sure if I like
sage: K = categories.Fields(R, check=False)
since it could be hard for me to remember. That said, it does fit
the "Sage/Magma" design philosophy pretty nicely, and is a natural way
to use coercions and categories.
Cool idea.
William
Getting back on my late sage e-mails ...
Variant:
sage: R = Zmod(6)
sage: R.set_category(Fields()) # or maybe better R.add_category(Fields())
sage: R in Fields()
True
sage: assert R in Fields()
This avoids cluttering each sage object with an is_bla method which
might refer to a completely unrelated category bla. Also, this handles
automatically the inheritance of category (so that stating that R is
in Fields imposes that it also is a division ring, ...).
Now, to what `x in Y` should return. That's a general problem, that we
also often encounter in our enumerated sets. For example, in generic
code, it's often natural to write:
sage: assert x in Y
But what if containment test is expensive/indecidable/not implemented?
In the use case above, we would like the assertion to just be ignored.
In MuPAD, we had taken advantage of the available three-valued logic
(TRUE / FALSE / UNKNOWN), to write:
sage: assert x in Y = TRUE
which is pretty similar to the suggestion of using None for UNKNOWN
(without the peculiarities of `None` and its disadvantages that
William pointed out).
In fact, most of this kind of type checking was done by specifying the
types of the arguments of a procedure:
MuPAD: proc(R: Rings()) ...
which resulted down the road to an assertion check as above.
The downside is that there is no way to specify how hard one wants to
do a containment test.
Altogether, I would vote for something along the lines:
sage: x in Y
returns True or False if provable; raises an exception in all other cases
sage: Y.__contains__(x, proof = False)
returns a best guess, or raises an exception
sage: x.hopefully_in(Y) # find a better name!
Try in turn Y.__contains__(x, proof = False) and Y.__contains__(x)
Return False if the first returned False, or if the first raised and the second returned False
Return True in all other situations (exception, ...).
Allowing altogether for:
sage: assert x.hopefully_in(Y)
Programmatically speaking, it might be easier to use something like
Y._contains_probabilist(x) rather then Y.__contains__(x, proof =
False); this plays better with inheritance.
More thoughts on demand!
Cheers,
Nicolas
--
Nicolas M. Thiéry "Isil" <nth...@users.sf.net>
http://Nicolas.Thiery.name/
One issue with that is that, forever after in your sage session, Zmod
(6) will be a field (unless you change it manually back, if you know
that the library function you called changed it...) That's why I
liked the new object method. Alternatively, this might be a good use
for contexts.
- Robert
Good point. I am not very keen on adding new categories on the fly
either. Then, I would vote for R = Zmod(6, category = Fields()), since
many parents readily support this features.