Re: [sage-support] Re: Accessing group generators in libgap

2018-10-01 Thread Dima Pasechnik
On Mon, Oct 1, 2018 at 8:58 AM Simon King  wrote:
>
> Hi Dima,
>
> On 2018-09-30, Dima Pasechnik  wrote:
> > it was written before optional parameters era in GAP, as far as I know.
> > Anyhow, you can use GAP's PushOptions() and PopOptions() to achieve more or 
> > less
> > the same effect, with a big uglier syntax.
>
> "Uglier" only internally. I think it shouldn't be too difficult to
> modify libgap's functions so that optional parameters (passed in the
> usual pythonic way) are first pushed and eventually popped from GAP's
> global optional value stack.

Right,  this can all be hidden, and perhaps even implemented with
a decorator (or in some other way?), to avoid manual coding of Push/Pop calls.
Thanks for pointing this out.

>
> When I first saw your work-around, I though it would have ugly side-effects.
> But I just realise that it wouldn't change GAP's behaviour. For instance:
>
>  gap> test := function()
>  >local foo;
>  >foo := ValueOption("foo");
>  >Print(foo);
>  > end;
>  function(  ) ... end
>  gap> f := function()
>  >local foo;
>  >foo := ValueOption("foo");
>  >Print("Original value ",foo);
>  >test();
>  > end;
>  function(  ) ... end
>  gap> f();
>  Original value failfail
>  gap> f(:foo:=5);
>  Original value 55
>
> Note that the option set when calling the outer function is also present
> in the inner function, and that's the same when directly pushing to the
> global option stack:
>
>  gap> PushOptions(rec(foo:=5));
>  gap> f();
>  Original value 55
>  gap> PopOptions();
>  gap> f();
>  Original value failfail
>
> So, that would work as desired.

Indeed, GAP manual says in its Sect 4.11-2 "Function Call With Options"
that the options syntax is exactly equivalent to using Push/Pop explicitly.

Best,
Dima

>
> Best regards,
> Simon
>
> --
> You received this message because you are subscribed to the Google Groups 
> "sage-support" group.
> To unsubscribe from this group and stop receiving emails from it, send an 
> email to sage-support+unsubscr...@googlegroups.com.
> To post to this group, send email to sage-support@googlegroups.com.
> Visit this group at https://groups.google.com/group/sage-support.
> For more options, visit https://groups.google.com/d/optout.

-- 
You received this message because you are subscribed to the Google Groups 
"sage-support" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sage-support+unsubscr...@googlegroups.com.
To post to this group, send email to sage-support@googlegroups.com.
Visit this group at https://groups.google.com/group/sage-support.
For more options, visit https://groups.google.com/d/optout.


[sage-support] Re: Accessing group generators in libgap

2018-10-01 Thread Simon King
Hi Dima,

On 2018-09-30, Dima Pasechnik  wrote:
> it was written before optional parameters era in GAP, as far as I know.
> Anyhow, you can use GAP's PushOptions() and PopOptions() to achieve more or 
> less
> the same effect, with a big uglier syntax.

"Uglier" only internally. I think it shouldn't be too difficult to
modify libgap's functions so that optional parameters (passed in the
usual pythonic way) are first pushed and eventually popped from GAP's
global optional value stack.

When I first saw your work-around, I though it would have ugly side-effects. 
But I just realise that it wouldn't change GAP's behaviour. For instance:

 gap> test := function()
 >local foo;
 >foo := ValueOption("foo");
 >Print(foo);
 > end;
 function(  ) ... end
 gap> f := function()
 >local foo;
 >foo := ValueOption("foo");
 >Print("Original value ",foo);
 >test();
 > end;
 function(  ) ... end
 gap> f();
 Original value failfail
 gap> f(:foo:=5);
 Original value 55

Note that the option set when calling the outer function is also present
in the inner function, and that's the same when directly pushing to the
global option stack:

 gap> PushOptions(rec(foo:=5));
 gap> f();
 Original value 55
 gap> PopOptions();
 gap> f();
 Original value failfail

So, that would work as desired.

Best regards,
Simon

-- 
You received this message because you are subscribed to the Google Groups 
"sage-support" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sage-support+unsubscr...@googlegroups.com.
To post to this group, send email to sage-support@googlegroups.com.
Visit this group at https://groups.google.com/group/sage-support.
For more options, visit https://groups.google.com/d/optout.


Re: [sage-support] Re: Accessing group generators in libgap

2018-09-30 Thread Dima Pasechnik
Hi Simon,
On Sun, Sep 30, 2018 at 11:01 AM Simon King  wrote:

> On 2018-09-30, Dima Pasechnik  wrote:
> > if you have a nontrivial GAP computation to be done in libgap, why not just
> > use libgap's function_factory?
> > Then you don't need to jump various hoops across sage/libgap boundary.
>
> If I understand correctly, the function_factory allows to create a
> libgap function from the string of a GAP function. But that doesn't
> explain how to set or not set optional values of such function, as in
> the GAP syntax
>regularPermutationAction(G: forceDefiningGenerators)

it was written before optional parameters era in GAP, as far as I know.
Anyhow, you can use GAP's PushOptions() and PopOptions() to achieve more or less
the same effect, with a big uglier syntax.

Sage's (lib)GAP is lagging behind the GAP development quite a bit, as
you might know.
See https://trac.sagemath.org/ticket/22626
So it's more urgent to catch up.

Dima


>
> In my concrete example, the function regularPermutationAction is defined
> in some file that can be read into libgap, and I could easily create
> just TWO versions of that function, once with
> forceDefiningGenerators=true, and once with
> forceDefiningGenerators=false. However, I am asking for the general
> picture.
>
> Best regards,
> Simon
>
> --
> You received this message because you are subscribed to the Google Groups 
> "sage-support" group.
> To unsubscribe from this group and stop receiving emails from it, send an 
> email to sage-support+unsubscr...@googlegroups.com.
> To post to this group, send email to sage-support@googlegroups.com.
> Visit this group at https://groups.google.com/group/sage-support.
> For more options, visit https://groups.google.com/d/optout.

-- 
You received this message because you are subscribed to the Google Groups 
"sage-support" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sage-support+unsubscr...@googlegroups.com.
To post to this group, send email to sage-support@googlegroups.com.
Visit this group at https://groups.google.com/group/sage-support.
For more options, visit https://groups.google.com/d/optout.


[sage-support] Re: Accessing group generators in libgap

2018-09-30 Thread Simon King
Hi Dima,

On 2018-09-30, Dima Pasechnik  wrote:
> if you have a nontrivial GAP computation to be done in libgap, why not just
> use libgap's function_factory?
> Then you don't need to jump various hoops across sage/libgap boundary.

If I understand correctly, the function_factory allows to create a
libgap function from the string of a GAP function. But that doesn't
explain how to set or not set optional values of such function, as in
the GAP syntax
   regularPermutationAction(G: forceDefiningGenerators)

In my concrete example, the function regularPermutationAction is defined
in some file that can be read into libgap, and I could easily create
just TWO versions of that function, once with
forceDefiningGenerators=true, and once with
forceDefiningGenerators=false. However, I am asking for the general
picture.

Best regards,
Simon

-- 
You received this message because you are subscribed to the Google Groups 
"sage-support" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sage-support+unsubscr...@googlegroups.com.
To post to this group, send email to sage-support@googlegroups.com.
Visit this group at https://groups.google.com/group/sage-support.
For more options, visit https://groups.google.com/d/optout.


Re: [sage-support] Re: Accessing group generators in libgap

2018-09-30 Thread Dima Pasechnik
On Sun, 30 Sep 2018, 10:10 Simon King,  wrote:

> Hi Vincent,
>
> On 2018-09-30, Vincent Delecroix <20100.delecr...@gmail.com> wrote:
> > The main problem is that G is a gap group and not a libgap
> > group. By gap group I mean that the interface going through
> > the pexpect interface. The two systems gap and libgap do not
> > seem to share the namespaces (which make sense).
>
> Oops. You are right. After correcting it, my example works just fine.
>
> Sorry for that.
>
> Nonetheless, I have a wishlist concerning libgap:
>
> A) Generator access with dot syntax
>
> I'd like to have that G.1 returns the first generator of the
> group (which it does in GAP language, but neither in the gap pexpect
> interface nor in libgap).
>
> ---
> B) Optional values for libGAP functions
>
> In Gap, it is possible to create functions with
> optional arguments. I have a function in Gap whose definition starts
> like that:
>   regularPermutationAction := function(G)
> local gens, N, S, L, gg, forceDefiningGenerators;
> forceDefiningGenerators := ValueOption("forceDefiningGenerators");
>

if you have a nontrivial GAP computation to be done in libgap, why not just
use libgap's function_factory?
Then you don't need to jump various hoops across sage/libgap boundary.

...
>
> In GAP syntax, having a group G, I would call the function as follows:
>P := regularPermutationAction(G: forceDefiningGenerators);;
>
> How would I call it when G is defined in libgap?
>G.regularPermutationAction(forceDefiningGenerators=True)
> doesn't work.
>
> 
> C) Make it possible to refer to an libgap object in a command string
>
> In gap (the pexpect interface), in the example from B), I'd do
>P = gap('regularPermutationAction({}:
> forceDefiningGenerators)'.format(G.name()))
> and in the example from A), I'd do
>gap('{}.1'.format(G.name()))
> but libgap objects apparently have no name by which they are known in
> the libgap interpreter.
>
> ---
> D) libgap's and gap's methods should have roughly similar semantics
>
> It is really unfortunate that it hasn't been attempted
> to keep libgap as close to the pexpect interface as possible. For
> example:
> 1.  sage: libgap('SymmetricGroup(8)')
> "SymmetricGroup(8)"
> sage: type(_)
> 
> sage: gap.eval('SymmetricGroup(8)')
> 'Sym( [ 1 .. 8 ] )'
> sage: type(_)
> 
>   In other words, libgap() behaves roughly like gap.eval()
> 2.  sage: libgap.eval('SymmetricGroup(8)')
> Sym( [ 1 .. 8 ] )
> sage: gap('SymmetricGroup(8)')
> SymmetricGroup( [ 1 .. 8 ] )
>   In other words, libgap.eval() behaves roughly like gap()
>
> Best regards,
> Simon
>
> --
> You received this message because you are subscribed to the Google Groups
> "sage-support" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to sage-support+unsubscr...@googlegroups.com.
> To post to this group, send email to sage-support@googlegroups.com.
> Visit this group at https://groups.google.com/group/sage-support.
> For more options, visit https://groups.google.com/d/optout.
>

-- 
You received this message because you are subscribed to the Google Groups 
"sage-support" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sage-support+unsubscr...@googlegroups.com.
To post to this group, send email to sage-support@googlegroups.com.
Visit this group at https://groups.google.com/group/sage-support.
For more options, visit https://groups.google.com/d/optout.


[sage-support] Re: Accessing group generators in libgap

2018-09-30 Thread Simon King
On 2018-09-30, Simon King  wrote:
> D) libgap's and gap's methods should have roughly similar semantics

That said: Of course I see the point of designing the libgap interface
in the way it was done: libgap(X), where X is something in Sage, should
return something in libgap that corresponds to X (hence, if X is a
string, it should return a libgap-string), whereas evaluation of
commands should only happen when explicitly requested (i.e., when doing
libgap.eval(X)).

So, point D) of my wish list actually isn't really a wish. The
differences however make porting my code from gap to libgap go beyond
search-and-replace...

-- 
You received this message because you are subscribed to the Google Groups 
"sage-support" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sage-support+unsubscr...@googlegroups.com.
To post to this group, send email to sage-support@googlegroups.com.
Visit this group at https://groups.google.com/group/sage-support.
For more options, visit https://groups.google.com/d/optout.


[sage-support] Re: Accessing group generators in libgap

2018-09-30 Thread Simon King
Hi Vincent,

On 2018-09-30, Vincent Delecroix <20100.delecr...@gmail.com> wrote:
> The main problem is that G is a gap group and not a libgap
> group. By gap group I mean that the interface going through
> the pexpect interface. The two systems gap and libgap do not
> seem to share the namespaces (which make sense).

Oops. You are right. After correcting it, my example works just fine.

Sorry for that.

Nonetheless, I have a wishlist concerning libgap:

A) Generator access with dot syntax

I'd like to have that G.1 returns the first generator of the
group (which it does in GAP language, but neither in the gap pexpect
interface nor in libgap).

---
B) Optional values for libGAP functions

In Gap, it is possible to create functions with
optional arguments. I have a function in Gap whose definition starts
like that:
  regularPermutationAction := function(G)
local gens, N, S, L, gg, forceDefiningGenerators;
forceDefiningGenerators := ValueOption("forceDefiningGenerators");
...

In GAP syntax, having a group G, I would call the function as follows:
   P := regularPermutationAction(G: forceDefiningGenerators);;

How would I call it when G is defined in libgap?
   G.regularPermutationAction(forceDefiningGenerators=True)
doesn't work.


C) Make it possible to refer to an libgap object in a command string

In gap (the pexpect interface), in the example from B), I'd do
   P = gap('regularPermutationAction({}: 
forceDefiningGenerators)'.format(G.name()))
and in the example from A), I'd do
   gap('{}.1'.format(G.name()))
but libgap objects apparently have no name by which they are known in
the libgap interpreter.

---
D) libgap's and gap's methods should have roughly similar semantics

It is really unfortunate that it hasn't been attempted
to keep libgap as close to the pexpect interface as possible. For
example:
1.  sage: libgap('SymmetricGroup(8)')
"SymmetricGroup(8)"
sage: type(_)

sage: gap.eval('SymmetricGroup(8)')
'Sym( [ 1 .. 8 ] )'
sage: type(_)

  In other words, libgap() behaves roughly like gap.eval()
2.  sage: libgap.eval('SymmetricGroup(8)')
Sym( [ 1 .. 8 ] )
sage: gap('SymmetricGroup(8)')
SymmetricGroup( [ 1 .. 8 ] )
  In other words, libgap.eval() behaves roughly like gap()

Best regards,
Simon

-- 
You received this message because you are subscribed to the Google Groups 
"sage-support" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sage-support+unsubscr...@googlegroups.com.
To post to this group, send email to sage-support@googlegroups.com.
Visit this group at https://groups.google.com/group/sage-support.
For more options, visit https://groups.google.com/d/optout.


Re: [sage-support] Re: Accessing group generators in libgap

2018-09-30 Thread Vincent Delecroix

Dear Simon,

The main problem is that G is a gap group and not a libgap
group. By gap group I mean that the interface going through
the pexpect interface. The two systems gap and libgap do not
seem to share the namespaces (which make sense).

For example, this does work

  sage: gap(g1)
  f1


but this does not

  sage: libgap(g1)
  Traceback (most recent call last):
  ...
  ValueError: libGAP: Error, Variable: 'f1' must have a value

Best
Vincent

Le 30/09/2018 à 02:32, Simon King a écrit :

Here is another question on libgap: Let some libgap elements be given;
how to form the list of these elements in libgap? The purpose would, for
example, be to create a group from that list.

For instance:
 sage: G = gap.SmallGroup(48,36)
 sage: g1,g2,g3,g4,g5 = G.GeneratorsOfGroup()

Since G is a polycyclic group, its generators look not very informative,
but in any case they are valid elements in libgap:

 sage: g1*g2,g1*g2*g3,g4
 (f1*f2, f1*f2*f3, f4)

Nonetheless, the following doesn't work:

 sage: libgap.List(g1*g2,g1*g2*g3,g4)
 Traceback (most recent call last):
 ...
 ValueError: libGAP: Error, Variable: 'f1' must have a value

What to do instead?

Best regards,
Simon



--
You received this message because you are subscribed to the Google Groups 
"sage-support" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sage-support+unsubscr...@googlegroups.com.
To post to this group, send email to sage-support@googlegroups.com.
Visit this group at https://groups.google.com/group/sage-support.
For more options, visit https://groups.google.com/d/optout.


[sage-support] Re: Accessing group generators in libgap

2018-09-29 Thread Simon King
Here is another question on libgap: Let some libgap elements be given;
how to form the list of these elements in libgap? The purpose would, for
example, be to create a group from that list.

For instance:
sage: G = gap.SmallGroup(48,36)
sage: g1,g2,g3,g4,g5 = G.GeneratorsOfGroup()

Since G is a polycyclic group, its generators look not very informative,
but in any case they are valid elements in libgap:

sage: g1*g2,g1*g2*g3,g4
(f1*f2, f1*f2*f3, f4)

Nonetheless, the following doesn't work:

sage: libgap.List(g1*g2,g1*g2*g3,g4)
Traceback (most recent call last):
...
ValueError: libGAP: Error, Variable: 'f1' must have a value

What to do instead?

Best regards,
Simon

-- 
You received this message because you are subscribed to the Google Groups 
"sage-support" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sage-support+unsubscr...@googlegroups.com.
To post to this group, send email to sage-support@googlegroups.com.
Visit this group at https://groups.google.com/group/sage-support.
For more options, visit https://groups.google.com/d/optout.