All commands, alphabetic order; letter M

This page contains the description of the following commands macro-expand, macro-expand1, make+, make*, make**, makearray, makefl0, makefl1, makefl2, makegetset, make_get_set, makelist, makering, makestring, makering, makeseq, makeseq_int, make_sequence, make_symmetric, makevector, makunbound, map, mapc, mapcan, mapcar, mapcon, maplist, mapoblist, max, max_degree, maxnegex, maxposex, MB, mcons, member, memq, min, mforma, Mobius_mu, modp, msetq, mul, mull, muln,


(macro-expand L) (Lisp function)

(macro-expand1 L) (Lisp function)

The macro-expand1 function takes one argument L. If this is not a list, whose first element is the name of a macro, then L is returned unchanged. Otherwise the macro is called, with arguments the remainder of the list; if it returns R, then (displace L R) is executed. This (in general) replaces the CAR of L by the CAR of R and the CDR of L by the CDR of R. The function returns L. The macro-expand function takes one argument and calls macro-expand1 as long as the CAR of the list is a macro.

Whenever the Lisp evaluator has to evaluated a list, whose CAR is a macro, it calls macro-expand1, and evaluates the result. In the example that follows, we use macro-expand1 to evaluate the first argument.

[Endymion] (macro-expand1 'foo)
foo
[Endymion] (macro-expand1 '(foo))
(foo)
[Endymion] (macro-expand1 '(ncons))
(ncons)
[Endymion] (macro-expand1 '(incr x))
(setq x (+ x 1))
[Endymion] (macro-expand1 '(incr x y))
(setq x (+ x y))
[Endymion] (dmd yincr (y) `(incr ,y))
yincr
[Endymion] (macro-expand1 '(yincr x))
(incr x)
[Endymion] (macro-expand '(yincr x))
(setq x (+ x 1))
[Endymion] (dmd xincr (a b)
[Endymion]   (macro-expand1 a)
[Endymion]   (if (and (consp a) (eq (car a) 'vref))
[Endymion]      `(vset ,(cadr a) ,(caddr a) (+ ,a ,b))
[Endymion]      `(setq ,a (+ ,a ,b))))
xincr
[Endymion] (dmd var0() '(vref x 0))
var0
[Endymion] (dmd var1() '(vref x 1))
var1
[Endymion] (defun f () (setq x #[1 2]) (xincr (var0) (var1)) x)
f
[Endymion] (f)
#[3 2]
[Endymion] (pretty-print 'f)

(defun f () (setq x #[3 2]) (vset x 0 (+ (vref x 0) (vref x 1))) x)
()

(#:ed:term:make+ list) (Lisp function)

This is the internal function that constructs a sum. The argument is assumed to be a cons (otherwise the result is zero). An initial zero is removed. See examples below.

(#:ed:term:make* list) (Lisp function)

This is the internal function that constructs a product. Behaves like make+, but return zero if the first element is zero. See examples below.

(#:ed:term:make** x y) (Lisp function)

This is the internal function that constructs a power. See examples below.

makearray(name, TE, TI, i1, ..., in) (Symbolic function)

This function creates a symbolic array. See documentation of arrays.

(#:ed:term:makefl0 f list) (Lisp function)

This is the internal function that constructs an expression with an operator and some arguments. The operator should can be a sum nor a product See examples below.

(#:ed:term:makefl1 f x) (Lisp function)

This is the internal function that constructs an expression with an operator and a single argument. The operator should not be a sum nor a product. See examples below.

(#:ed:term:makefl2 f x y) (Lisp function)

This is the internal function that constructs an expression with an operator and two arguments. The operator should not be a sum nor a product. See examples below.

[Endymion] (#:ed:term:make+ (list 'a 'b 'c))
#:fexpression:#[+ (a b c)]
[Endymion] (#:ed:term:make+ (list 0 'a 'b 'c))
#:fexpression:#[+ (a b c)]
[Endymion] (#:ed:term:make+ (list 0 'a))
a
[Endymion] (#:ed:term:make+ 25)
0
[Endymion] (#:ed:term:make+ (list 'a))
a
[Endymion] (#:ed:term:make* (list 'a 'b 'c))
#:fexpression:#[* (a b c)]
[Endymion] (#:ed:term:make* (list 1 'a 'b 'c))
#:fexpression:#[* (a b c)]
[Endymion] (#:ed:term:make* (list 1 'a))
a
[Endymion] (#:ed:term:make* (list 'a))
a
[Endymion] (#:ed:term:make* (list 0 'a 'b 'c))
0
[Endymion] (#:ed:term:make* 25)
1
[Endymion] (#:ed:term:make** 'x 'y)
#:fexpression:#[** (x . y)]
[Endymion] (#:ed:term:make** '1 '10000)
#:fexpression:#[** (1 . 10000)]
[Endymion] (#:ed:term:makefl0 'f (list 'x 'y 'z))
#:fexpression:#[f (x y z)]
[Endymion] (#:ed:term:makefl0 'f (list 'x 'y))
#:fexpression:#[f (x y)]
[Endymion] (#:ed:term:makefl0 'f (list 'x))
#:fexpression:#[f (x)]
[Endymion] (#:ed:term:makefl0 'f (list))
#:fexpression:#[f ()]
[Endymion] (#:ed:term:makefl0 '+ (list 'x 'y 'z))
#:fexpression:#[+ (x y z)]
[Endymion] (#:ed:term:makefl0 '* (list 'x 'y 'z))
#:fexpression:#[* (x y z)]
[Endymion] (#:ed:term:makefl1 'f 'x)
#:fexpression:#[f x]
[Endymion] (#:ed:term:makefl1 '+ 'x)
#:fexpression:#[+ x]
[Endymion] (#:ed:term:makefl1 '- 'x)
#:fexpression:#[- x]
[Endymion] (#:ed:term:makefl2 'f 'a 'b)
#:fexpression:#[f (a . b)]
[Endymion] (#:ed:term:makefl2 '** 'a 'b)
#:fexpression:#[** (a . b)]
[Endymion] (#:ed:term:makefl2 '+ 'a 'b)
#:fexpression:#[+ (a . b)]
[Endymion] (#:ed:term:makefl2 '* 'a 'b)
#:fexpression:#[* (a . b)]

(makeconstant f) (Lisp special form)

The makeconstant special form takes one argument, a symbol. It cannot be a constant like true, nor a variable function like ibase. If the symbol has a value, nothing happens, otherwise, the value of the symbol is set to itself. The return value is the name.

[Endymion]  (makeconstant ibase)
makeconstant : not a variable : ibase
[Endymion]  (makeconstant true)
makeconstant : not a variable : true
[Endymion]  (makeconstant foo (+ 7 8))
makeconstant : wrong number of arguments : 2 this should be 1
[Endymion]  (setq foo (+ 7 8))
15
[Endymion] (makeconstant foo)
foo
[Endymion] foo
15
[Endymion] bar
eval : undefined variable : bar
[Endymion]  (makeconstant bar)
bar
[Endymion] bar
bar

(makegetset f) (Lisp function)

The makegetset function takes one argument. It converts its argument to a get/set function and returns it. In case of failure, nothing happens and the return value is nil. See setq for a real example. The argument has to a be a symbol, associated to a function that takes 0 or 1 arguments. Only user defined functions are allowed.

[Endymion] (makegetset 123)
()
[Endymion] (makegetset 'foo)
()
[Endymion] (makegetset 'ibase)
ibase
[Endymion] (defun f (#:system:nb-args -101) &nobind))
f
[Endymion] (makegetset 'f)
f
[Endymion] (synonym 'foo 'ibase)
foo
[Endymion] (makegetset 'foo)
()

make_get_set( var, val, fct, test) (Symbolic macro with 3 or 4 arguments)

This creates a function fct, that takes zero or more arguments. The function returns the value of the variable var. If an argument is given, its value will be put in var. The initial value of this variable is val. If the macro has more than three arguments, these will be called when the function is called with an argument. As example (6) shows, assignment is done after the test. Thus, the test should be done on the argument of fct, which is named x (as a consequence, the variable var must be different from x). Since everything is in a closure, the global variable var is unchanged (see example (13)), unless declared dynamic, see example(14).

make_get_set(var,val,name,[test])::=
  if nbargs()=3
  then buildq({var:=val,
               name([x]):={ if islist(x) then var:=car(x),var} })
  else buildq({var:=val, 
               name([x]):= { if islist(x) then {splice(test),var:=car(x)},
                         var }});

Example

(2) make_get_set(foo,17,f);

(2)                             <FUNCTION: f>

(3) f();

(3)                                   17

(4) f(25);

(4)                                   25

(5) f();

(5)                                   25

(6) make_get_set(foo,17,g,if not(#isprime(foo))
(6) then #error("g","Prime required", foo) );

(6)                             <FUNCTION: g>

(7) g(25);

(7)                                   25

(8) g(29);
g : Prime required : 25

(9)  make_get_set(foo,17,h,if not(#isprime(car(x)))
(9) then #error("h","Prime required", car(x)) );

(9)                             <FUNCTION: h>

(10) h(26);
h : Prime required : 26
(11) h(29);

(11)                                   29

(12) g();

(12)                                  29

(13) foo;

(13)                                 foo

(14) make_get_set(dynamic(foo),17,k);


(14)                            <FUNCTION: k>

(15) k(7);

(15)                                  7

(16) k() = foo;

(16)                                7 = 7

(makelist n x) (Lisp function)

The makelist function takes two arguments, an integer and an object. It constructs a list containing n times the object. The first argument can be negative, case where the result is empty, but it must be a small integer. The function could be defined as

(defun makelist (x y)
   (if (neq (type-of x) 'fix) (error 'makelist $errnia x))
   (let ((res ()))
        (while (> x 0) (setq x (- x 1) res (cons y res)))
        res))

Example

[Endymion] (makelist 3 'a)
(a a a)
[Endymion] (makelist -3 'a)
()
[Endymion] (makelist 1.5 'a)
makelist : not a fixnum : 1.5

(feval::makering t s) (Symbolic function)

The makering function takes two arguments. The first one is a name, it can be `zp', `pol' or `frac'. The second argument is a set of equalities, the lhs can be one of `order', `linform', `kernels', `dense', `ring', and `modulo'. In the case of `kernels', the value is a list, and if the keyword is repeated, values are merged. Otherwise, keywords must be given once (some keywords can be omitted). If you give the `ring' keyword twice, you will see an error message of the form: ring : wrong number of arguments this should be 1 : 2. The same erropr is signaled if you omit the value.

In the case of `zp', you give the modulo, say 17, and this creates the ring of integers modulo 17. In the other cases, you must give a value for the ring, say K. The result is an entension of K. If the first argument is `frac', this ring must be an integral polynomial ring, and its fraction field is returned. See an example below. Replacing 23 by 22 will signal an error (the ring has dividers of zero); replacing D by E is an error (not a polynomial ring). Finally, if the argument is `pol' a polynomial extension of K wil be constructed. You must give the kernels.

(1)  B:=makering(zp,{modulo=23});

(1)                                 %Z/23Z

(2)  C:=makering(pol,{kernels=[x],ring=B});

(2)                               %Z/23Z[x]

(3)  D:=makering(pol,{kernels=[u,v],ring=C});

(3)                            %Z/23Z[x][u, v]

(4)  E:=makering(frac,{ring=D});

(4)                            %Z/23Z[x](u, v)

(5) F:=makering(pol, {kernels=[Y,Z,T], order=revlex, linform=[1,2,3],
(5) ring=E});

(5)                       %Z/23Z[x](u, v)[Y, Z, T]

(5)  makering(frac,{foo=bar});
makering : not in [order, linform, kernels, dense, ring, modulo] : foo
(6)  makering(zp,{modulo=23,ring='foo'});
makering : Not a key (should be in [modulo]) : ring
(9) makering(frac,{ring=E});
makering : Wrong value of field `ring' : %Z/23Z[x](u, v)
(10) B:=makering(zp,{modulo="x"});
makering : Wrong value of field `modulo' : x

(makestring n c) (Lisp function)

The makestring functions takes two arguments, an integer and a character; it returns a string of size n filled with c. This is a normal string if c is between 0 and 255, a wide-string if c is larger than 256. The function could be defined as follows

(defun makestring (n c)
  (unless (integerp n) (error 'makestring 'errnia n)) 
  (when (< n 0) (error 'makestring 'erroob n)) 
  (unless (integerp c) (error 'makestring 'errnia c))
  (let ((l (makelist n c)))
       (if (>= c 256) (catenate #"" l) (catenate l))))

Example

[Endymion] (makestring 0 #/a)

[Endymion] (makestring 4 #/a)
aaaa
[Endymion] (makestring 1/2 1000)
makestring : not a fixnum : 1/2
[Endymion] (makestring 4 2/3)
makestring : not a fixnum : 2/3
[Endymion] (makestring -4 #/a)
makestring : argument out of bounds : -4
[Endymion] (makestring 4 -3)
makestring : argument out of bounds : -3
[Endymion] (makestring 4 1000)
ϨϨϨϨ

makeseq(x) (Symbolic function)

This function converts its argument into an initialised sequence. The argument should be an uninitialised sequence, or an interval, or an array, or a list, or a vector. If X is an initialised sequence, then endofseq(X) returns true in case the end of the sequence is reached; in such a situation nothing interesting can happen. Otherwise topseq(X) returns the current element of the sequence, discard_seq(X) advances in the list, popseq(X) returns the current element and advances in the list.

For each function that creates an un-initialised sequence, there is an example. Below, there are examples of the other cases. A common operation is: take a sequence, x, initialise it, and as long as the end is not reached, call popseq, and apply some function. This is done trivially by for x in X do f(x). There is also a seq_to_list that converts the whole initialised sequence into a list. This may fail in the case where the sequence is infinite.

As line (5) shows, an initialised list holds a copy of the list, and topseq returns the first element, while discard_seq advances in the list. In the case of a vector, we have the vector plus an index. In the case of an interval a...b step c, the sequence hols the 3 items, and discard_seq replaces a by the sum with c.

(1) L:=[1,2,3]?;

(2) for x in L do print(x);
1
2
3

(2)                                  done

(3) A:=makeseq(L);

(3)                 <InitializedSequence: list, [1, 2, 3]>

(4) popseq(A);

(4)                                   1

(5) A;

(5)                  <InitializedSequence: list, [2, 3]>

(6) seq_to_list(A);

(6)                                [2, 3]


(13) V:=makeseq(#vector(a,b,c,d));

(13)        <InitializedSequence: vector, 0, <vector: a, b, c, d>>

(14) popseq(V);

(14)                                  a

(15) V;

(15)        <InitializedSequence: vector, 1, <vector: a, b, c, d>>

(16) I:=makeseq(1...10 step 3);

(16)              <InitializedSequence: interval, 1, 10, 3>

(17) popseq(I);

(17)                                  1

(18) I;

(18)              <InitializedSequence: interval, 4, 10, 3>

(19) seq_to_list(V);

(19)                              [b, c, d]

(20) seq_to_list(I);

(20)                              [4, 7, 10]

More examples.

(1) A:= N2_seq();

(1)                      <UninitializedSequence: N2>

(2) a:=makeseq(A);

(2)                      <InitializedSequence: N2, 0>

(3) b:=makeseq(1...10 step 3);

(3)               <InitializedSequence: interval, 1, 10, 3>

(4) topseq(A);
topseq : not an initialised sequence : <UninitializedSequence: N2>
(5) topseq(a);

(5)                                 [0, 0]

(6) topseq(b);

(6)                                   1
(7) endofseq(b);

(7)                                 FALSE

(8) popseq(b);

(8)                                   1

(9) discard_seq(b);

(9)                                 FALSE

(10) discard_seq(b);

(10)                                FALSE

(11) endofseq(b);

(11)                                FALSE

(12) topseq(b);

(12)                                  10

(13) discard_seq(b);

(13)                                 TRUE

(14) topseq(b);

(14)                                FALSE

(15) endofseq(b);

(15)                                 TRUE

(16) popseq(b);

(16)                                FALSE

(17) discard_seq(b);

(17)                                 TRUE

(18) popseq(A);
popseq : not an initialised sequence : <UninitializedSequence: N2>
(19) endofseq(A);
endofseq : not an initialised sequence : <UninitializedSequence: N2>
(21) discard_seq(A);
discard_seq : not an initialised sequence : <UninitializedSequence: N2>

makeseq_int(x, y, z) (Symbolic function)

This function creates an initialised sequence formed of all numbers starting with x, with z as increment. In the case where the second argument is Infinity, the sequence is infinite, otherwise only numbers at most y are generated (read "at least y", if the step is negative). There is no difference between makeseq(1...10 step 3), makeseq(1...10 negstep -3) and makeseq_int(1,10,3). When you say for x do y, for x do y, this is the same as for x in 1...Infinity step 1 the same as let(g=makeseq(1...Infinity step 1), loopforever( let(x=popseq(g), y))).

(1)  X:=1...10 step 3;

(1)                            1 ... 10 STEP 3

(2)  Y:=makeseq(X);y:=makeseq_int(0.1, 1, 0.3);

(2)               <InitializedSequence: interval, 1, 10, 3>

(3)              <InitializedSequence: interval, 0.1, 1, 0.3>

(4) {T:=0,for i in 1...4 do T:= T+popseq(Y)-10*popseq(y),T};

(4)                                   0

(5) [Y,y];

(5)  [<InitializedSequence: interval, 13, 10, 3>, <InitializedSequence: 

interval, 1.3, 1, 0.3>]

make_sequence(M, T, E, N) (Symbolic function)

This function creates a sequence. If this sequence is initialised, then M() is evaluated, this gives some quantity D, and the initialised sequence is formed of (D,T,E,N). The current element of the sequence is T(D); the end of the sequence is reached when E(D) is true; and the sequence is updated via D:=N(D). It is an error if arguments are not functions that take zero or one arguments respectively.

(1) mkdata() := makeseq_int(1, 100,10);

(1)                           <FUNCTION: mkdata>

(2) the_top(x):= topseq(x); 

(2)                          <FUNCTION: the_top>

(3) the_end(x):= endofseq(x); 

(3)                          <FUNCTION: the_end>

(4) the_discard(x):= { discard_seq(x),x }; 

(4)                        <FUNCTION: the_discard>


(5) X:=make_sequence(mkdata, the_top, the_end, the_discard); 

(5)  <UninitializedSequence: user, <FUNCTION: mkdata>, <FUNCTION: the_top>, 

<FUNCTION: the_end>, <FUNCTION: the_discard>>

(6) Y:=makeseq(X);

(6)  <InitializedSequence: user, <InitializedSequence: interval, 1, 100, 10>>

(7) popseq(Y);

(7)                                   1

(8) popseq(Y);

(8)                                   11

(9) popseq(Y)?;popseq(Y)?;popseq(Y)?;popseq(Y)?;popseq(Y)?;popseq(Y)?;

(15) popseq(Y)?;popseq(Y);popseq(Y);

(16)                                  91

(17)                                FALSE

(makevector n x) (Lisp/symbolic function)

The makevector function takes two arguments, an integer and an object. It constructs a vector containing n times the object.

[Endymion] (makevector -1 0)
makevector : argument out of bounds : -1
[Endymion] (makevector 0 0)
#[]
[Endymion] (makevector 10 'a)
#[a a a a a a a a a a]
[Endymion] (makevector 1/2 'a)
makevector : not a fixnum : 1/2

(makunbound f) (Lisp function)

The function makunbound takes as argument a variable (a symbol, but not a constant like true). It makes it undefined by evaluating (setq var _undef_). In the case of a variable-function, this may or may not be a valid argument. Some variable functions take as argument a boolean value; In this case _undef_ is not nil, hence the same as true.

[Endymion] (makunbound 'foo)
foo
[Endymion] (makunbound 'ibase)
ibase : not a fixnum : _undef_
[Endymion] (makunbound true)
makunbound : not a variable : true

(mapc f arg1 ... argn) (Lisp function)

(mapcan f arg1 ... argn) (Lisp function)

(mapcar f arg1 ... argn) (Lisp function)

(mapcon f arg1 ... argn) (Lisp function)

(map f arg1 ... argn) (Lisp function)

(maplist f arg1 ... argn) (Lisp function)

The eight functions map, mapc, mapcar, mapcan, mapcon, maplist, every, any take at least two arguments. The first argument is a function. It will be applied to arguments a1k, a2k, ..., ank, for k equals to 1, 2, 3, etc. In the general case, aik is the k-th element of the list argi (the i-th argument of map, with the convention that the function to apply is the 0-th argument). Exception: in the case of maplist, mapcon and map, the argument is aik is the list argi without its k-1 first elements. The return value depends on the function. For details and examples see the mapping functions.

The symbolic functions map and mapcar are the equivalents of mapc and mapcar, for symbolic lists, see example below. There is also a macro Map that maps a function with one argument to a sequence.

(1)  mapcar(lambda(x,x+1),[1,2,3]);

(1)                               [2, 3, 4]

(2)  mapcar(lambda([x,y],x+y),[1,2,3],[a,b,c,d]);

(2)                         [1 + a, 2 + b, 3 + c]

(3) map(lambda([x,y,z], print([z,y,x])),[1,2],[a,b,c,d,ef],[u,v,w]);

[u, a, 1]
[v, b, 2]

(3)                                 false

(4) map(#'print,[1,2],[a,b,c,d,e,f],[u,v,w]);

1au
2bv

(4)                                 false

(5) Map(lambda(x,x*x), 1...3);

(5)                               [1, 4, 9]

(mapoblist f) (Lisp function)

The mapoblist function takes an argument, a function, and appplies it to every symbol in the object list. Note that (mapoblist 'foo) is the same as (mapc 'foo (reverse (oblist))), but is more efficient, since no list is created. See oblist for an example. See oblist for an example.

(max x1 ... xn) (Lisp function)

(min x1 ... xn) (Lisp function)

These two functions try to find the largest and smallest element in the argument list. The result is zero if no argument is given, and nil if one argument is not a real number.

[Endymion] (min 1 2)
1
[Endymion] (min 1 2 'x)
()
[Endymion] (min)
0
[Endymion] (max 1 3/4 2.5)
2.5

max_degree (Variable)

The max_degree variable contains a bound on the degree of polynomials created via the #P construct, or similar. The initial value could be 5000. This variable must be at least one hundred, at most ten millions.

maxnegex (Symbolic Variable)

maxposex (Symbolic Variable)

These variables contain the default values used by expand. The value is an integer, between 0 and one million. The initial value is ten thousand.

(9) [maxposex,maxnegex];

(9)                             [10000, 10000]

(10) let([maxposex,maxnegex]=[5,6], expand((a+b)^ 10));

                                         10
(10)                              (a + b)

(11) maxposex:=foo;
#:feval:maxposex : not a fixnum : foo
(12) maxposex:=1000000;
#:feval:maxposex : argument out of bounds : 1000000

(MB n) (Lisp function)

The MB function takes one argument, an integer n, and return a factor of it; It uses the Morrisson and Brillhart algorithm. Details about the algorithm can be found in in the pdf documentation. Below, there is a Lisp version

;; Toplevel function
(defun MorrBrill (n)
  (tag found (MB0)))

;; Initialises some variables
(defun MB_init ()
  (setq lA 0 lQ n ls 0 lB 1 lP 1 
	iPQ 1 iPQc 1 lr ls
        Rn (isqrt n)
	ls Rn save_q 0save_A 0 save_s 0))

;; Computes one half of the residues (negative ones)
(defun MB_even(n)
  (setq lq (quomod (- (* 2 Rn) ls) lP)
	lr #:ex:mod 
	lA (remainder (+ (* lq  lB) lA) n)
	lQ (+ lQ (* lq (- lr ls))))
  (setq base lA residue (- lQ)))

;; Computes the other residues (positive ones)
(defun MB_odd (n)
  (setq lq (quomod (- (* 2 Rn) lr) lQ)
	ls #:ex:mod 
	lB (remainder (+ (* lq lA) lB) n)
	lP (+ lP (* lq (- ls lr))))
  (setq base lB residue lP))

;; This tests if the period has been reached
(defun MB_check()
  (if (and (= save_q lq) (= save_A lA) (= save_s ls))
      true
    (if (= iPQc iPQ)
	(setq iPQ (* 2 iPQ) iPQc 0 save_q lq save_A lA save_s ls)
      (setq iPQc (+ 1 iPQc)))
    ()))

;; This computes the funny constant X
(defun MBi(n)
  (setq X (length (explode n)))
  (setq X (* 599 X))
  (setq X (quomod X 4))
  (setq X (isqrt X))
  (setq X (- X 11))
  (setq X (** 10 X))
  (setq X (isqrt X))
  (setq X (isqrt X))
  (setq X (isqrt X))
  (setq X (isqrt X))
  (+ X 1))

;; This computes and stores all primes less than X
(defun MB_mk_primes(n X)
  (let (i p temp)
    (setq primes (makevector 2000 ()))
    (setq i 1)
    (vset primes 0 2)
    (vset primes 1 2)
    (setq p 2)
    (while (<= p X)
      (setq p (nextprime p))
      (setq temp (powermod n (/ (- p 1) 2) p))
      (if (= temp 0) (exit found p))
      (when (= temp 1)
	(setq i (+ i 1))
	(setq Psize i)
	(vset primes i p)
	(vset primes 0 (* (vref primes 0) p))))))

;; This Finds the Largest prime factor of r
(defun MB_FL()
  (let ((r residue))
    (if (= r -1)
	-1
      (when (< r 0) (setq r (- r)))
      (tag X
	   (for (i Psize -1 0)
		(if (= 0 (remainder r (vref primes i)))
		    (exit X (vref primes i))))))))

;; This finds a factor, not listed in the primes above
(defun MBset_largest0()
  (setq r residue)
  (print "current residue " r)
  (if (< r 0) (setq r (- r)))
  (setq a (gcd r more_primes))
  (while (<> a 1)
    (setq r (/ r a))
    (if (> r bound_2) 
	(setq r 0 a 1)
      (setq a (gcd r a))))
  (when (> r bound_1) (setq r 0))
  (setq largest r))


;; square-free decomposition
(defun MB_sqfr()
  (let ((G 1) (g some_primes) a)
    (block here
      (while true
	(setq a (gcd g residue))
	(setq g (gcd (/ residue a) a))
	(when (= g 1) (return-from here 0))
	(setq residue (/ residue (* g g)))
	(setq G (* G g))))
    (print "SQFR " residue)
    (MB_divide G)))

;; division of base by G modulo n
(defun MB_divide (G)
  (let ((L (bezout G n)))
    (when (<> (car L) 1) (exit found (car L)))
    (setq base (remainder (* base (cadr L)) n))))

;; This is the real function
(defun MB0()
  (MB_init)
  (setq sq ())
  (setq X (MBi n))
  (let ((a (* X X)) (b (* 20 X)))
    (if (< a b) (setq bound_1 a) (setq bound_1 b)))
  (setq bound_2 (* X bound_1))
  (print "X =" X  " B1= " bound_1 " B2= "bound_2)
  (MB_mk_primes n X)
  (setq some_primes (vref primes 0))
  (setq more_primes (* some_primes 1440))
  (setq OF ())
  (setq Iter 1)
  (while true
    (if (not OF) (MB_even n) (MB_odd n))
    (setq OF (not OF))
    (incr Iter)
    (print "Iteration  " Iter)
    (MBset_largest0)
    (print "largest " largest)
    (if (= largest 0)
	()
      (MB_inner))
    (if (and OF (MB_check)) (exit found 0))))

;; This is the inner loop
(defun MB_inner ()
  (tag Inner
       (while true
	 (MB_sqfr)
	 (when (= residue 1)
	   (if (and (<> base 1) (<> base (- n 1)))
	       (exit found (gcd (- base 1) n)))
	   (exit Inner 0))
	 (when (= largest 1) (setq largest (MB_FL)))
	 (let ((W (assoc largest sq)) b r G)
	   (unless W
	     (setq sq (cons (list largest base residue) sq))
	     (exit Inner 0))
	   (setq b (cadr W) r (caddr W))
	   (setq G largest largest 1)
	   (setq residue (/ (* residue r) (* G G)))
	   (setq base (* base b))
	   (MB_divide G)))))

Example

[Endymion] (setq a 332041393326771929089)
332041393326771929089
[Endymion] (setq b 1328165573307087716353)
1328165573307087716353
[Endymion] (MB (* a b))
1328165573307087716353

(mcons x1 ... xn) (Lisp function)

The mcons function takes an arbitrary number of arguments. It returns nil, in the case no argument is provided, the first argument if only one is given, and a dotted pair otherwise.

[Endymion] (mcons)
()
[Endymion] (mcons 1)
1
[Endymion] (mcons 1 2)
(1 . 2)
[Endymion] (mcons 1 2 3)
(1 2 . 3)
[Endymion] (mcons 1 2 3 4)
(1 2 3 . 4)
[Endymion] (mcons 1 2 3 4 5)
(1 2 3 4 . 5)

(member x l) (Lisp function)

(memq x l) (Lisp function)

The memq function takes two arguments x and l. If x is a member of the list l, it returns the part of the list starting at x. It returns nil, if l is not a list, or does not contain x. The member function is similar; it uses equal is predicate, while memq uses eq. The functiond could be defined as

(defun memq (x l)
  (cond ((atom l) ())
        ((eq (car l) x) l)
        (true (memq x (cdr l)))))
(defun member (x l)
  (cond ((atom l) ())
        ((equal (car l) x) l)
        (true (memq x (cdr l)))))

Example

[Endymion]  (setq x1 "foo" x2 123456789 x3 '(4))
(4)
[Endymion] (setq l '("foo" #.x1 123456789 #.x2 (4) #.x3 a b c a b c))
(foo foo 123456789 123456789 (4) (4) a b c a b c)
[Endymion] (memq 'a l)
(a b c a b c)
[Endymion] (member 'a l)
(a b c a b c)
[Endymion] (member "foo" l)
(foo foo 123456789 123456789 (4) (4) a b c a b c)
[Endymion] (memq "foo" l)
()
[Endymion] (memq x1 l)
(foo 123456789 123456789 (4) (4) a b c a b c)
[Endymion] (member 123456789 l)
(123456789 123456789 (4) (4) a b c a b c)
[Endymion] (memq 123456789 l)
()
[Endymion] (memq x2 l)
(123456789 (4) (4) a b c a b c)
[Endymion] (member '(4) l)
((4) (4) a b c a b c)
[Endymion] (memq '(4) l)
()
[Endymion] (memq x3 l)
((4) a b c a b c)
[Endymion] (member 0 1)
()
[Endymion] (memq 2 3)
()

(mforma x) (Lisp function)

The mforma function converts its argument to a Lisp object; it is used by the symbolic printer.

Example

[Endymion] (list (mforma 1) (mforma 1.2) (mforma 1.2l0) (mforma 1.2b0))
(1 1.2 0.12L1 0.120000000000000000000000000000000000000e1)
[Endymion] (list (mforma -1) (mforma 2/3) (mforma #C(4 -3)))
((- 1) (/ 2 3) (+ 4 (- (* 3 %i))))
[Endymion] (mforma #P5 1 3 0 0 0 -2)
(+ 1 (* 3 z) (- (* 2 (** z 5))))
[Endymion] (list (mforma "foo") (mforma 'foo) (mforma #:foo:#[bar]))
(foo foo (angle vector bar))
[Endymion] (mforma '(format "~S~D~A~A~T~P~P~A" 1 2 "3" 4 5))
(text 2 2 3s 5)

(Mobius_mu n) (Lisp function)

The Mobius_mu function takes one argument, an integer. It returns the Mobius mu function: it is 0 if n can be divided by a square, 1 if n has an even number of prime divisors, and -1 if n has an odd number of prime divisors.

(defun Mobius_mu (n)
  (let ((w (ifactor n)))
       (if (every (lambda (u) (eq (cadr u) 1)) w)
           (let ((m (length w)))
                (if (even? m) 1 -1))
           0)))

Example

[Endymion] (Mobius_mu (* 2 3 5 7))
1
[Endymion] (Mobius_mu (* 2 3 5 ))
-1
[Endymion] (Mobius_mu (* 2 3 5 5))
0
[Endymion] (Mobius_mu 1/2)
Mobius_mu : not a fixnum : 1/2

(modp n p) (Lisp function)

This function assumes that n is an integer or a rational number and p is an integer. If n is an integer, then then remainder of the division of n by p is returned. Otherwise, if n=a/b, the Bezout relation ub+vp=1 is used to find the inverse of b modulo p, and a*u mod p is returned.

[Endymion] (modp 100 17)
15
[Endymion] (modp 1/100 17)
8
[Endymion] (modp 2/3 6)
modp : division by zero : 2/3
[Endymion] (modp 2.3 6)
modp : not a fixnum : 2.3
[Endymion] (modp 2/3 1.3)
modp : not a fixnum : 1.3

(msetq x1 ... xn y) (Lisp macro)

The msetq macro takes at leat two arguments. Its expansion is (setq x1 (setq x2 ... (setq xn y)...)). Said otherwise, it assigns to each xi the value of y.

[Endymion] (setq A '(msetq a1 a2 a3 a4 (+ 2 3)))
(msetq a1 a2 a3 a4 (+ 2 3))
[Endymion] (eval A)
5
[Endymion] (list a1 a2 a3 a4)
(5 5 5 5)
[Endymion] A
(setq a1 (setq a2 (setq a3 (setq a4 (+ 2 3)))))

mul(x1, x2) (Lisp/Symbolic function)

This function returns the product of its arguments. For the general behavior, see the description of *. The example below shows some particular cases: the compiler is told that the function takes arithmetic expressions as arguments, hence signals an error in case an argument is a string or a boolean; on the other hand, the function is optimised so that one times X is X, and zero times X is zero, whatever X. For more examples, see description of the operator.

(1) mul(2=3,3=2);

(1)                                 6 = 6

(2) mul("foo","bar");
Bad type in arithmetic function: string for foo
Bad type in arithmetic function: string for bar
Error : Cannot compute : mul(foo, bar)
(3) mul();
mul : wrong number of arguments : 0 this should be 2
(4) apply(mul,[1,"foo"]);

(4)                                  foo

mull(list) (Symbolic function)

This function takes a list as argument and returns the product of the items in it. In some cases, the compiler calls the * operator, otherwise it's the interpreter; as the example below shows, the distinction can be seen only in case of errors. For more examples, see descriptoin of the operator.

(1) L:=[x,y,z]; { mull([x,y,z]), mull(L) };

(1)                               [x, y, z]


(2)                             {x y z, x y z}

(3) y:="true"?; z:=false?; L:=[x,y,z];

(5)                            [x, true, FALSE]

(6) mull([x,y,z]); mull(L);
* : Cannot compute : *(x, FALSE, true)
mull : Cannot compute : *(x, FALSE, true)

muln(x1, ... ,xn) (Symbolic function)

This function returns the product of its arguments. It is the functional version of the * operator

(1) [muln(), muln(2), muln(2,3,4), muln(2,3,4,5,6,7,8,9,10)];

(1)                          [1, 2, 24, 3628800]

Valid XHTML 1.0 Strict back to home page © INRIA 2005, 2006 Last modified $Date: 2009/01/08 17:43:30 $