On Mar 5, 12:07 pm, "William Stein" <[EMAIL PROTECTED]> wrote:
> On Wed, Mar 5, 2008 at 11:45 AM, Carl Witty <[EMAIL PROTECTED]> wrote:

> >  2) Modify sage_eval so that it can process a sequence of statements
> >  followed by an expression; then _sage_init_ could return
> >  """
> >  R1 = GF(17)
> >  R2 = R1['x,y']
> >  x, y = R2.gens()
> >  3*x^2*y^3
> >  """

> +1
> I really like option 2 as well, but only with a lot more discussion and
> thought.   The "single expression" requirement
> is particularly hard to do on nontrivial things.  Even with other interfaces,
> e.g., _magma_init_, we're going to have to change this soon I think.
> (BTW, I've been funded to greatly enhance the Sage/Magma interface,
> and have been thinking some about this problem as a result.)
>
> I'm not sure that 2 as suggested is the best idea.  It might be better
> to have *two* methods _sage_init_setup_ and _sage_init_ where setup
> returns a block of code that sets of the environment
> where the sage_init works.    Or maybe _sage_init_ should return a 2-tuple.
> This is just brainstorming.
>
> William

Here's a nicely overengineered rough proposal.  The idea is to make it
easy to write _sage_init_ methods, and get very nice output; without
worrying much about how hard it is to write the framework.  (I would
probably write the framework, since I enjoy that sort of thing...)

Here is a sample _sage_init_ method, for IntegerMod_abstract:

  def _sage_init_(pp, coerced):
      if coerced:
          return pp(self.lift())
      elif is_FiniteField(self.parent()):
          return pp(self.parent)(self.lift())
      else:
          return pp.lit('mod')(pp(self.lift()), pp(self.modulus()))

A _sage_init_ method takes two arguments, pp (for "pretty printer")
and coerced.  "coerced" means that when the final expression is
evaluated, the value will be automatically coerced into the
appropriate type; this will be True for polynomial coefficients and
for
matrix elements, among others.  The call pp(foo, True) will eventually
call foo._sage_init_(pp, True).

The _sage_init_ method returns a ppvalue.  There are various methods
on the pp object to create ppvalues, like pp.lit('mod') and
pp.numlit('3.14159').  Also, almost all operators on ppvalues are
overloaded to create new ppvalues; so a _sage_init_ method on complex
numbers might include:
   return pp(self.real()) + pp(self.imag()) * pp.lit('I')

This method of creating ppvalues means that the framework can
automatically insert parentheses, since it knows all about the
operators used to create the expressions.

Values which are likely to be used multiple times in an expression
(parents and generators) should use the pp.cache() method in their
 _sage_init_:

     v = ...
     pp.cache(self, v, 'R')
     return v

This puts the self -> v mapping in a hash table; all calls to pp(foo)
check foo in the hash table.

If a cached value actually is used multiple times, then the output
will include an assignment to hold this value, and the users will use
the variable.  The third (optional) argument to pp.cache() is a
suggested variable name; in the above example, the framework will try
to use the variable name R, but if that's already used, it will use R1
or R2 or ...

Carl

--~--~---------~--~----~------------~-------~--~----~
To post to this group, send email to sage-devel@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at http://groups.google.com/group/sage-devel
URLs: http://www.sagemath.org
-~----------~----~----~----~------~----~------~--~---

Reply via email to