2

Part 1

If we have this

[> restart; a[5]:=23: a[7]:=41:

then

[> about(a); whattype(a);
a:
  nothing known about this object
                        symbol

but

[> print(a);
                 table([5 = 23, 7 = 41])

and

[> convert(a,list);
                        [23, 41]

So Maple does have enough information about variable a and its indexes somewhere. How can we check that information without printing?

For small indexes it's not a problem, but if b[123457891234578912345789]:=789; then how do we check if there is some index i for which b[i] has a defined value and what that index i is (without printing, i. e. not manually)?

Part 2

I'd like to be able to work with such variables inside a function and return such variable. For example, let's say I want to increase all indexes by 1. If I know which indexes exist then I can do that

[> a[5]:=23: a[7]:=41:
   f:=proc(x) local y;
      y[6]:=x[5]; y[8]:=x[7]; y;
      end proc:
   b:=f(a); b[6]; b[8];
           b:=y
            23
            41

but often I don't know what indexes variable a has.

Robai
  • 197
  • 9

1 Answers1

2

There are several programmatic queries you can make,

restart;
a[5]:=23: a[7]:=41:

# test whether a is assigned
assigned('a');
                  true

# test whether a is assigned a table
type(a, table);
                  true

# test whether table a has any indexed values
evalb( nops([indices(a, 'nolist')]) > 0 );

                  true

assigned('a'[7]);
                  true

If you wish you can make such queries prior to attempting to access and utilize the indexed reference (ie. to check that it has an assigned value). For example,

if type(a,table) and assigned('a'[7]) then
  a[7];
end if;
             41

if type(a, table) then
  [indices(a, 'nolist')];
end if;
            [5, 7]
acer
  • 6,671
  • 15
  • 15
  • 1
    Thank you very much! The two commands `type(a, table);` and `[indices(a, 'nolist')];` will solve the problem! – Robai Aug 12 '21 at 00:51
  • 1
    But it's still weird that a variable can have two different types at once since `type(a, symbol);` and `type(a, table);` both return `true`. Isn't that a bug? – Robai Aug 12 '21 at 01:07
  • 2
    The reason that `type(a,symbol)` returns `true` (even when `a` has been assigned a `table`) is so-called last-name-evaluation. The old `table` datastructure got "lne" to allow certain functionality, eg. in-place behaviour as mutable structure when passed as a proc argument. Some description of lne at: https://www.maplesoft.com/support/help/maple/view.aspx?path=last_name_eval – acer Aug 12 '21 at 12:26
  • 1
    Thanks, that link also explained the usage of **eval** for this. So I could use `whattype(eval(a))` for checking the final type and use `op(eval(a))` for extracting indices too (especially useful when need key=value format). – Robai Aug 13 '21 at 05:31
  • @acer what about when the indexing is done by double underscore, i.e. `a__7`? Is there a way to see what such indices of `a` have been assigned? In this case `a` is not a table anymore. – AmirHosein Sadeghimanesh Jun 05 '22 at 07:09
  • The double underscore suffix is NOT indexing. It happens to pretty-print in the GUI in a subscripted manner similar to that of indexed names. But it is not any kind of indexing. And assignment of such names will have no effect on whether `a` is a table. Those names are not directly related to the name `a`. Note however that you can check whether a prefix is suffixed, as a `type` check. Thus you can extract from an expression suffixed names. Eg. `indets(f,'suffixed(a__)')` for some expression `f` that might contain, say, `a__7`, `a__13`, etc. – acer Jun 06 '22 at 12:11