Mike, Before I reply to your email, let me ask a simple question about sage as installed on sage.math. When I try the axiom interface there I get:
[EMAIL PROTECTED]:~$ sage ---------------------------------------------------------------------- | SAGE Version 3.1, Release Date: 2008-08-16 | | Type notebook() for the GUI, and license() for information. | ---------------------------------------------------------------------- sage: axiom('1+1') sage: axiom('1+1') sage: axiom('1+1') Type: PositiveInteger sage: exit Exiting SAGE (CPU time 0m0.06s, Wall time 0m33.20s). Exiting spawned Axiom process. [EMAIL PROTECTED]:~$ which sage /usr/local/bin/sage -------- This result is typical of the failure due to readline/clisp synchronization problems on some platforms. The only solution I have for this involves calling FriCAS in such a way as to defeat readline in './devel/sage-main/sage/interfaces/axiom.py' as follows: Expect.__init__(self, name = 'axiom', prompt = '\([0-9]+\) -> ', command = "sh -c 'axiom -nox -noclef | cat'", Although it generates more processes than should be required to do the job, perhaps this change should be included in the next release? On Sun, Aug 31, 2008 at 11:11 PM, Mike Hansen wrote: > ... > I don't think the interfaces are as much "magic" as you make them > out to be. Magic is only science that we don't understand, right? :-) I did not mean to give the impression that I thought it was magic - only that I felt some basic documentation in this area was missing. To this end your comments below are very helpful. > If you're interested in converting object from Sage to Axiom/FriCAS, > then there are really only two methods you need to worry about -- > _axiom_ and _axiom_init_. _axiom_init_ method just returns a > string used to construct self in Axiom. For example, say we have > > class Foo(SageObject): > def __init__(self, n): > self.n = int(n) > def _axiom_init_(self): > return str(self.n) > > Then I can do > > sage: a = Foo(2); a > <class '__main__.Foo'> > sage: axiom(a) > 2 > sage: axiom(a).type() > PositiveInteger > Thanks! So the point is that we can obtain the string representation of some Sage object by calling 'str' and often this string can be passed directly to the Axiom interpreter. I think that is a good thing, but of course whether or not this works will depend on the type inferences done by the interpreter. For example: sage: K = FiniteField(2) sage: k=K(1) sage: k.parent() Finite Field of size 2 sage: k+1 0 sage: k_ax = axiom(k) sage: k_ax.type() PositiveInteger sage: k_ax+1 2 Something is wrong here! In Axiom we do have an appropriate type: sage: k_ax2=axiom('1$FiniteField(2,1)') sage: k_ax2.type() FiniteField(2,1) sage: k+1 0 Obviously the default conversion from a string is not correct. How can we make the conversion from Sage to Axiom smarter in this case? Does it mean that we need to override the _axiom_init_ method with something more appropriate in some more specific class in Sage? I see that: sage: k? Type: IntegerMod_int Base Class: <type 'sage.rings.integer_mod.IntegerMod_int'> String Form: 1 Namespace: Interactive Docstring: Elements of Z/nZ for n small enough to be operated on in 32 bits AUTHORS: -- Robert Bradshaw (2006-08-24) So should we add _axiom_init_ to IntegerMod_int class? Something like this? def _axiom_init_(self): return str(self.n)+'::FiniteField(%d,1)'%n where do I get a value for n? But I notice that: sage: k=IntegerModRing(2)(1) sage: k.parent() Ring of integers modulo 2 sage: k? Type: IntegerMod_int Base Class: <type 'sage.rings.integer_mod.IntegerMod_int'> String Form: 1 Namespace: Interactive Docstring: Elements of Z/nZ for n small enough to be operated on in 32 bits AUTHORS: -- Robert Bradshaw (2006-08-24) and also that in Axiom we have 'IntegerMod(2)' as distinct from "FiniteField(2,1)'. Both Sage and Axiom distinguish between the ring and the field, so maybe IntegerMod_int is not the right place for _axiom_init_ since that would make it a field in all cases. Maybe _axiom_init_ has to come from the Sage parent? How do I do that? This is the kind of thing that still seems a little mysterious to me ... > For more complicated things, the _axiom_ method takes in an Axiom > interface object and returns self constructed in Axiom. > > class Foo(SageObject): > def __init__(self, n): > self.n = int(n) > def _axiom_(self, axiom): > return axiom(str(self.n)) > > This behaves the same as above. > This form seems obscure to me. What is an "Axiom interface object"? Why/How does this code behave the same way as the first example? > The Macualay2 interface in sage/interfaces/macaulay2.py has some > good examples of moving objects back and forth between systems. > > Anyway, I did some work on the Axiom interface today such as > doctesting it, removing broken code, adding tab completion, etc. > You can see my changes at > http://trac.sagemath.org/sage_trac/ticket/4028 Great. I have applied these changes to my test version of axiom interface. > Things like the online help didn't work with either the fricas spkg > or just on a local copy, but I'd be more than happy to help adding > that functionality (as well as anything else). > Thanks for your work! I hope it will attract more developers interested in the Axiom interface in Sage. Regards, Bill Page. --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---