In order to sanitize the behavior of objects, parents and elements in sage,
I'm about to add some tests to the framework. I think they are all reasonable
but I may be asking to much. Please comment about the following:
1 - Any SageObject must have an equality methods such that
self == self and self != None
2 - Element construction should be idempotent. More precisely, for any
element e within parent P, the equality P(e) == e must hold.
This is for example needed by the constructor of many Parent with a base
ring, such as matrices.
3 - .zero() and .one() must never be mutable. I'd like to enforce this by
computing .__hash__(). Here I see two possibilities:
* decide that for any monoid M, if M.one() implement __hash__ it must
returns an int (not an Integer) and not raise an exception like in
sage: m = matrix([1]).__hash__()
...
TypeError: mutable matrices are unhashable
* decide that any element of a monoid must be hashable.
Do you think this is asking too much ?
By the way, if you have ideas of other basic sanity checks which must be added
please tell me.
Cheers,
Florent, back from Sage days 20.
PS: Sage days 20 were extremely fun and enjoyable ! Though we worked quite
hard (I typically went to bed at 3 and woke up at 8), we haven't been
producing that much code but I think we recruited a *lot* of new users among
which there may be many developers. A progress report is being written and
should be posted very soon. I need some rest now :-)
Sorry for replying to myself.
> In order to sanitize the behavior of objects, parents and elements in sage,
> I'm about to add some tests to the framework. I think they are all reasonable
> but I may be asking to much. Please comment about the following:
>
> 1 - Any SageObject must have an equality methods such that
> self == self and self != None
>
> 2 - Element construction should be idempotent. More precisely, for any
> element e within parent P, the equality P(e) == e must hold.
> This is for example needed by the constructor of many Parent with a base
> ring, such as matrices.
>
> 3 - .zero() and .one() must never be mutable. I'd like to enforce this by
> computing .__hash__(). Here I see two possibilities:
> * decide that for any monoid M, if M.one() implement __hash__ it must
> returns an int (not an Integer) and not raise an exception like in
> sage: m = matrix([1]).__hash__()
> ...
> TypeError: mutable matrices are unhashable
The following sentence is ambiguous:
> * decide that any element of a monoid must be hashable.
Please replace it by:
* decide that element of any monoid must have a __hash__ method,
which may raise an error for mutable element but never on .one()
(and .zero() in a commutative monoid).
Hi there,
In order to sanitize the behavior of objects, parents and elements in sage,
I'm about to add some tests to the framework. I think they are all reasonable
but I may be asking to much. Please comment about the following:
1 - Any SageObject must have an equality methods such that
self == self and self != None
2 - Element construction should be idempotent. More precisely, for any
element e within parent P, the equality P(e) == e must hold.
This is for example needed by the constructor of many Parent with a base
ring, such as matrices.
3 - .zero() and .one() must never be mutable. I'd like to enforce this by
computing .__hash__(). Here I see two possibilities:
* decide that for any monoid M, if M.one() implement __hash__ it must
returns an int (not an Integer) and not raise an exception like in
sage: m = matrix([1]).__hash__()
...
TypeError: mutable matrices are unhashable
* decide that element of any monoid must have a __hash__ method,
which may raise an error for mutable element but never on .one()
(and .zero() in a commutative monoid).
John
> --
> To post to this group, send an email to sage-...@googlegroups.com
> To unsubscribe from this group, send an email to
> sage-devel+...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/sage-devel
> URL: http://www.sagemath.org
>
> Hi there,
>
> In order to sanitize the behavior of objects, parents and elements
> in sage,
> I'm about to add some tests to the framework. I think they are all
> reasonable
> but I may be asking to much.
I think your suggestions are reasonable, and am a strong +1 to these
automated testing frameworks.
Nick
> > In order to sanitize the behavior of objects, parents and elements in sage,
> > I'm about to add some tests to the framework. I think they are all
> > reasonable
> > but I may be asking to much. Please comment about the following:
> >
> > 1 - Any SageObject must have an equality methods such that
> > self == self and self != None
> >
>
> I don't think this should be true for an arbitrary SageObject. There are
> some (eg subclasses of sage.factory.UniqueFactory) that are mainly used
> either internally or as object constructors. I don't think we need to
> support GF == GF for example.
>
> Requiring it for Parents and Elements seems completely reasonable on the
> other hand. Perhaps CategoryObjects as well.
Ok This is easy to change...
[...]
> > 3 - .zero() and .one() must never be mutable. I'd like to enforce this by
> > computing .__hash__(). Here I see two possibilities:
> > * decide that for any monoid M, if M.one() implement __hash__ it
> > must
> > returns an int (not an Integer) and not raise an exception like in
> > sage: m = matrix([1]).__hash__()
> > ...
> > TypeError: mutable matrices are unhashable
> >
>
> I have no problem with requiring an int return value, though I'm not sure
> how compliant the current sage library is with this condition.
The best way to know is to check (in progress). I'm expecting to catch some
bugs with it. I'll see how hard it is to fix the lib accordingly. The
framework allows to make case by case exception. Anyway, it's certainly good to
know.
> I don't like the requirement that __hash__ never raise an error: we want to
> allow mutable matrices.
Of course I'm not forgetting mutable matrices. Let me restate. Please choose
between (or suggest something else):
Strong requirement:
For any Monoid. __hash__ *must* be implemented and it don't raise an error for
.one() (Idem for CommutativeMonoids and zero())
Weak requirement:
For any monoid M, if M.one() implement __hash__ it must returns an int.
> This seems like the better option. Though some have raised objections to
> the idea of zero() and one() returning immutable elements, it did seem to be
> the consensus in that thread.
So I understand that you'll go for strong requirement.
I'm sorry for not making myself clear it the first mail. I'm not accustomed in
writing computer-law statement like SEP (Sage Enhancement Proposal :-)
Cheers,
Florent
I had the impression that this has been already decided see eg [1]:
def one_element(self):
r"""
Backward compatibility alias for :meth:`self.one()`.
TESTS::
sage: S = Monoids().example()
sage: S.one_element()
''
"""
return self.one()
Though I can't find the thread. Also, In the category roadmap [2]:
A.one() A.zero() a.is_one() a.is_zero() A(1) A(0) when it makes sense
A.one_element() A.zero_element() deprecated in the doc; fully deprecated
later.
Cheers,
Florent
[1] sage/categories/monoids.py
[2] http://trac.sagemath.org/sage_trac/wiki/CategoriesRoadMap
> Hi there,
>
> In order to sanitize the behavior of objects, parents and elements
> in sage,
> I'm about to add some tests to the framework. I think they are all
> reasonable
> but I may be asking to much. Please comment about the following:
>
> 1 - Any SageObject must have an equality methods such that
> self == self and self != None
>
> 2 - Element construction should be idempotent. More precisely, for any
> element e within parent P, the equality P(e) == e must hold.
> This is for example needed by the constructor of many Parent
> with a base
> ring, such as matrices.
Elements of real interval fields don't satisfy the above two
constraints (the notion of equality for intervals being that every
element of the first interval is equal to every element in the second).
- Robert
You get the point. As far as I understand a RIF only return True if the
interval are reduced to a single point. Is it right ? It would be better to
return a special value like Unknown than False. But that's another question...
Anyway, I'm strongly info favor of giving 1- and 2- a general rule with an
explicit exception for RIF. As I said, the test framework allows such
exceptions. Is there an agreement on
* Making 1- and 2- below a general rule
>> 1 - Any SageObject must have an equality methods such that
>> self == self and self != None
>>
>> 2 - Element construction should be idempotent. More precisely, for any
>> element e within parent P, the equality P(e) == e must hold.
* Making explicit exception for particular cases such as RIF.
Cheers,
Florent
I certainly agree that 1-2 should be the general rule, I was just
pointing out an exception. I like the idea of returning an Unknown
object on RIF comparisons as well.
- Robert
This is now #8402 (work in progress).
Florent
>> You get the point. As far as I understand a RIF only return True if the
>> interval are reduced to a single point. Is it right ? It would be better
>> to
>> return a special value like Unknown than False. But that's another
>> question...
>>
>> [...]
>
> I certainly agree that 1-2 should be the general rule, I was just pointing
> out an exception. I like the idea of returning an Unknown object on RIF
> comparisons as well.
Not my idea. This was the way it worked in MuPAD. There was a three state
boolean value, which was quite useful. Looking into python docs to see if we
can have "and" and "or" work with a 3-state booleans, I found:
" A rich comparison method may return the singleton NotImplemented if it does
not implement the operation for a given pair of arguments. By convention,
False and True are returned for a successful comparison. However, these
methods can return any value, so if the comparison operator is used in a
Boolean context (e.g., in the condition of an if statement), Python will call
bool() on the value to determine if the result is true or false. "
Wouldn't it be mor meaningful to return NotImplemented ?
Cheers,
Florent
We do this to get symbolic equations.
> Wouldn't it be mor meaningful to return NotImplemented ?
No. If a.__richcmp__(b) returns NotImplemented then b.__richcmp__(a)
is attempted (basically). Also, the value is truly unkownable, so
Unknowns is the right thing to return here.
- Robert
One of the main problem here is that PEP 335 "Overloadable Boolean Operators"
is not yet accepted. So right now there is no way to implement a three state
logic, is there one ? If not, Is there a way we can push on python dev to have
this PEP accepted ?
Cheers,
Florent
It's unclear how this would work with the current short-circuit
semantics of and and or. However, if Unknown was returned such that
bool(Unknown) was False, then the information would be preserved at
least a little bit longer.
- Robert
>> One of the main problem here is that PEP 335 "Overloadable Boolean
>> Operators"
>> is not yet accepted. So right now there is no way to implement a three
>> state
>> logic, is there one ? If not, Is there a way we can push on python dev to
>> have
>> this PEP accepted ?
>
> It's unclear how this would work with the current short-circuit semantics
> of and and or.
Here are the truth table in MuPAD, all computed in short-circuit semantics.
>> bool3 := [FALSE, UNKNOWN, TRUE];
>> print ([(a and b) $ b in bool3]) $ a in bool3
[FALSE, FALSE, FALSE]
[FALSE, UNKNOWN, UNKNOWN]
[FALSE, UNKNOWN, TRUE]
>> print ([(a or b) $ b in bool3]) $ a in bool3
[FALSE, UNKNOWN, TRUE]
[UNKNOWN, UNKNOWN, TRUE]
[TRUE, TRUE, TRUE]
To have a precise short-circuit semantic. Consider that
False < Unknown < True
and define "and" = "min" and "or" = "max". The natural short-circuit
evaluation for min and max works as expected.
in preudocode:
if a is False: return False
else if a <= b: return a
else: return b
in preudocode:
if a is True : return True
else if a >= b: return a
else: return b
> However, if Unknown was returned such that bool(Unknown) was False, then the
> information would be preserved at least a little bit longer.
This could indeed be a fallback.
Cheers,
Florent
Please review my proposal on #8413.
Cheers,
Florent
Yup. This had been decided after a poll with the developers at Sage
days 15 in Seattle.
Cheers,
Nicolas
--
Nicolas M. Thi�ry "Isil" <nth...@users.sf.net>
http://Nicolas.Thiery.name/