On 5/28/07, Nathan Dunfield <[EMAIL PROTECTED]> wrote: > I'm trying to hack up a quick finitely presented group class, and am > trying to write the _gap_init_ method. In simple cases, _gap_init_ > returns a string, but I can't come up with one that works; e.g. the > following fails > > sage: gap.new("F := FreeGroup(2); F/[F.1*F.2*F.1^-1*F.2^-1]") > $sage21:=F := FreeGroup(2); F/[F.1*F.2*F.1^-1*F.2^-1];; > ^ > > executing $sage21:=F := FreeGroup(2); F/[F.1*F.2*F.1^-1*F.2^-1];; > > Now, I could have _gap_init_ return a GAP object created in several > steps, e.g. > > sage: gap.eval("F := FreeGroup(2)") > '<free group on the generators [ f1, f2 ]>' > sage: G = gap.new("F/[F.1*F.2*F.1^-1*F.2^-1]"); > sage: G > <fp group of size infinity on the generators [ f1, f2 ]> > > but this has the disadvantage of littering the GAP interpreter with a > bunch of useless variables
I think the only variable you introduced was F, which you would have introduced anyways. > (or worse, over-writing something from my interactive session). Fortunately, SAGE can use multiple copies of interfaces to GAP. Probably the SAGE group theory package used its own copy of the GAP interpreter, which is different from the interactive session GAP. This is what is done with maxima in the calculus package. E.g., Set x to be 5 in maxima: sage: maxima('x: 5') 5 sage: maxima('x + x + %pi') %pi+10 This simplification is done using maxima (behind the scenes): sage: x + x + pi 2*x + pi Note that x is still x, since the maxima used by the calculus package is different than the one in the interactive interpreter. sage: quit Exiting SAGE (CPU time 0m0.26s, Wall time 6m7.56s). Exiting spawned Maxima process. Exiting spawned Maxima process. [EMAIL PROTECTED]:~$ ---- Likewise, for group theory one should define the group package's copy of GAP in some file: from sage.interfaces.gap import Gap gap = Gap() # the group theory gap Then if you use that gap you won't mess up anything else. You should also define _gap_init_(self) for your FP group to raise a NotImplementedError, so it isn't unintentionally used, and you should define a method def _gap_(self, system=gap): ... which creates your FP group in the given copy of gap (the one that is the system argument). If it's the local group-theory gap, then you're in a controlled copy of the interpreter, and don't have to worry much about variables you define (since you are carefully not to do anything stupid). If another copy of the gap interpreter is passed in, you should be sure to be much more careful about variables names, e.g., call it _sage_F instead of F. Making a new copy of the GAP interpreter is very cheap, since the workspace is cached. You can do it about 5 times a second in Linux: sage: time g=Gap()('2+2') CPU times: user 0.00 s, sys: 0.01 s, total: 0.01 s Wall time: 0.19 <---- this is what matters Note also that it takes not time to just make an instance of Gap without doing a computation (since GAP isn't actually started until a computation is done): sage: time g=Gap() CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s Wall time: 0.00 William --~--~---------~--~----~------------~-------~--~----~ 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://sage.scipy.org/sage/ and http://modular.math.washington.edu/sage/ -~----------~----~----~----~------~----~------~--~---