MuPAD - Demo

# ... Domains - User Defined Types

MuPAD has a flexible and object oriented type concept called domains. Users can define their own data structures/types and may overload standard operators like *, +, etc for them. The library package domains contains some predefined algebraic structures and also domain constructors.

## Contents

1. The field Z/Z7
2. The abstract domain NUMERIC
3. The library package domains
4. Index of algebraic examples

### The field Z/Z7

The following example demonstrates how new user-defined data types can be created. We create the field Z/Z7, but nevertheless any kind of data types can be defined. At first we tell MuPAD that Z7 is a so-called domain and we declare the name "Z7" for it.

- `>> Z7:=domain(); Z7::name:="Z7";`
  `domain( )
  "Z7"`

  We define how to create new elements of this field and how to print them.

- `

      >> Z7::new:= proc(x)
         begin  new(Z7, x mod 7);
         end_proc:

         Z7::print:= proc(x)
         begin  subs( hold(q mod 7), hold(q)=extop(x,1) )
         end_proc:

  `

  After that we are able to create elements of Z/Z7.

- `>> a:= Z7::new(9); b:= Z7(9);`
  `2 mod 7
  2 mod 7`

  What we also need are functions to add and multiply elements of Z/Z7.

- `

      >> Z7::_plus:= proc()
         local  x, i;
         begin
            x:= extop(args(1), 1);
            for i from 2 to args(0) do x:= (x + extop(args(i), 1)) mod 7;
            end_for;
            Z7::new(x);
         end_proc:

         Z7::_mult:= proc()
         local   x, i;
         begin
            x:= extop(args(1), 1);
            for i from 2 to args(0) do x:= (x * extop(args(i), 1)) mod 7;
            end_for;
            Z7::new(x);
         end_proc:

  `

  Now we are able to operate on elements of Z/Z7 in the usual way.

- `>> b:=Z7(1); c:=Z7(11); a+a+Z7(3)*b; a*b*b;`
  `1 mod 7
  4 mod 7
  0 mod 7
  2 mod 7`

  To complete the definition of Z/Z7 we also declare the zero and the one element of the field and define some further operations.

- `

      >> Z7::zero:= Z7::new(0):  Z7::one:= Z7::new(1):
         Z7::divide:= proc(x,y)
         begin  Z7::new((extop(x,1) / extop(x,2)) mod 7);
         end_proc:

         Z7::negate:= proc(x)
         begin  Z7::new( - extop(x,1) mod 7);
         end_proc:

         Z7::invert:= proc(x)
         begin  Z7::new((1/extop(x,1)) mod 7);
         end_proc:

         Z7::_power:= proc(x,y)
         local  help, i;
         begin
            if y=0 then return( Z7::one );
            end_if;
            if y>0 then help:= x;
                   else help:= Z7::invert(x);	 x:= help;
            end_if;
            for i from 2 to abs(y) do help:= Z7::_mult(help, x);
            end_for;
         end_proc:

  `

  And now we are able to perform all arithmetical operations for the elements of Z7 in the same way as we do for predefined types like integers or rationals.

- `>> a^5-b/c; 1/Z7(100);`
  `2 mod 7
  4 mod 7`

  Using the library package domains a field like Z/Z7 can be created easier by using the constructor IntegerMod. Refer to section "The library domains".

### The abstract domain NUMERIC

Also abstract domains like NUMERIC can be defined.

- `>> NUMERIC:=domain(); NUMERIC::name:="NUMERIC";`
  `domain()
  "NUMERIC"`

- `

      >> NUMERIC::testtype:= proc(x, y)
         begin
            if contains({DOM_INT,DOM_FLOAT,DOM_COMPLEX,DOM_RAT}, domtype(x))
            then TRUE;
            else FAIL;
            end_if;
         end_proc:

  `

  And now it can be used to test if an expresion is numerical.

- `

      >> testtype(123, NUMERIC),
         testtype(4.5, NUMERIC),
         testtype(1/2, NUMERIC),
         testtype(2*a, NUMERIC);

  `
  `TRUE, TRUE, TRUE, FALSE`

### The library package domains

At first we load the library package domains and define the field Z/Z7 by using the constructor IntegerMod.

- `

      >> loadlib("domains"): export(domains):
         Z7:= IntegerMod(7);

  `
  `IntegerMod(7)`

  After creating some elements of Z/Z7 we can perform usual arithmetical operations in the usual way.

- `>> a:= Z7(-100); b:= Z7(57); c:= Z7(2);`
  `5 mod 7
  1 mod 7
  2 mod 7`

- `>> a-b^2; a*b/c+a^3;`
  `4 mod 7
  5 mod 7`

  We can also test if Z/Z7 is a field or not.

- `>> Z7::hasProp(Field);`
  `TRUE`

  We know Z/Z8 is not a field but only a ring.

- `>> Z8:= IntegerMod(8);`
  `IntegerMod(8)`

- `>> d:= Z8(22); b+d;`
  `6 mod 8
  FAIL`

- `>> Z8::hasProp(Field); Z8::hasProp(Ring);`
  `FALSE
  TRUE`