[BACK]Return to oxcommon.m2 CVS log [TXT][DIR] Up to [local] / OpenXM / src / Macaulay2 / m2

File: [local] / OpenXM / src / Macaulay2 / m2 / oxcommon.m2 (download)

Revision 1.2, Thu Dec 7 00:07:06 2006 UTC (17 years, 5 months ago) by takayama
Branch: MAIN
CVS Tags: R_1_3_1-2, RELEASE_1_3_1_13b, RELEASE_1_2_3_12, HEAD, DEB_REL_1_2_3-9
Changes since 1.1: +12 -6 lines

Update for M2 0.9.95.
A dirty bug fix for readMoreData.

ID = "$OpenXM: OpenXM/src/Macaulay2/m2/oxcommon.m2,v 1.2 2006/12/07 00:07:06 takayama Exp $"
--- class INT32
INT32 = new SelfInitializingType of BasicList
new INT32 from ZZ := (a,n) -> {n}
int32 = method()
int32(INT32) := (n)->(n)
int32(ZZ) := (n)-> (
     if ((abs(n) >> 31) > 0) then error "expected signed 32-bit integer";
     tmp := n;
     if (n < 0) then tmp = 2^32+n; -- 2's complement
     new INT32 from tmp
	 )

--- class ERROR, MATHCAP
ERROR = new SelfInitializingType of BasicList

-- class MATHCAP
MATHCAP = new SelfInitializingType of BasicList

MATHCAP'OF'M2 = MATHCAP
  {{INT32{1001003}, "M2 client " | ID}, 
       {},
       {{INT32{OX'DATA}, 
         {INT32{CMO'NULL}, INT32{CMO'INT32}, INT32{CMO'STRING}, 
          INT32{CMO'LIST}, INT32{CMO'ERROR2}, INT32{CMO'MATHCAP}, 
	  INT32{CMO'ZZ}}
     }}
}

MATHCAP'OF'M2'SERVER = MATHCAP
  {{INT32{1001003}, "M2 client " | ID}, 
       {INT32{SM'popCMO},
	INT32{SM'popString},
	INT32{SM'pops},
	INT32{SM'nop},
	INT32{SM'setName},
	INT32{SM'evalName},
	INT32{SM'executeStringByLocalParser},
	INT32{SM'executeFunction},
	INT32{SM'dupErrors},
	INT32{SM'setMathCap},
	INT32{SM'mathcap}
	},
       {{INT32{OX'DATA}, 
         {INT32{CMO'NULL}, INT32{CMO'INT32}, INT32{CMO'STRING}, 
          INT32{CMO'LIST}, INT32{CMO'ERROR2}, INT32{CMO'MATHCAP}, 
	  INT32{CMO'ZZ}}
     }}
}


--- class OXSESSION
OXSESSION = new Type of MutableHashTable;

toNetwork = (n) -> (
     n3 := n % 256;
     n = n >> 8;
     n2 := n % 256;
     n = n >> 8;
     n1 := n % 256;
     n0 := n >> 8;
     (ascii n0) | (ascii n1) | (ascii n2) | (ascii n3))

fromNetwork = (s) -> (
     s = ascii substring(s,0,4);
     n := s#0;
     n = (n << 8) + s#1;
     n = (n << 8) + s#2;
     n = (n << 8) + s#3;
     n)


OXCOMMAND = toNetwork 513
OXDATA = toNetwork 514

OX'COMMAND = 513
OX'DATA = 514

CMO'NULL = 1
CMO'INT32 = 2
CMO'STRING = 4
CMO'LIST = 17
CMO'ZZ = 20
CMO'QQ = 21
CMO'ERROR2 = 2130706432 + 2
CMO'MATHCAP = 5
CMO'RECURSIVE'POLYNOMIAL = 27
CMO'POLYNOMIAL'IN'ONE'VARIABLE = 33
CMO'INDETERMINATE = 60

CMONULL = toNetwork CMO'NULL
CMOINT32 = toNetwork CMO'INT32
CMOSTRING = toNetwork CMO'STRING
CMOLIST = toNetwork CMO'LIST
CMOZZ = toNetwork CMO'ZZ
CMOQQ = toNetwork CMO'QQ
CMOERROR2 = toNetwork CMO'ERROR2
CMOMATHCAP = toNetwork CMO'MATHCAP
CMORECURSIVEPOLYNOMIAL = toNetwork CMO'RECURSIVE'POLYNOMIAL
CMOPOLYNOMIALINONEVARIABLE = toNetwork CMO'POLYNOMIAL'IN'ONE'VARIABLE
CMOINDETERMINATE = toNetwork CMO'INDETERMINATE

-- Defines taken from the OpenXM documentation
-------------------
-- Stack machine --
-------------------
SM'popSerializedLocalObject = 258
SM'popCMO = 262
SM'popString = 263 

SM'mathcap = 264
SM'pops = 265
SM'setName = 266
SM'evalName = 267 
SM'executeStringByLocalParser = 268 
SM'executeFunction = 269
SM'beginBlock  = 270
SM'endBlock    = 271
SM'shutdown    = 272
SM'setMathCap  = 273
SM'executeStringByLocalParserInBatchMode = 274
SM'getsp   = 275
SM'dupErrors = 276
SM'pushCMOtag = 277

SM'control'kill = 1024
SM'control'reset'connection  = 1030
SM'control'to'debug'mode = 1025
SM'control'exit'debug'mode = 1026

--------------------------------
-- binary string --> CMObject --
--------------------------------

OXINPUT = new Type of MutableHashTable
makeOXINPUT = (F) -> (
     result := new OXINPUT;
     result.F = F;
     result.buffer = "";
     result.loc = 0;
     result)

readMoreData = (OX) -> (
     -- OX is an OXINPUT
     --stderr <<"before read: "<<OX.loc << ascii OX.buffer <<endl << flush;
     --OX.buffer = copy(OX.buffer); --copy it because "read" distroy it.
     OX.buffer = ascii(ascii(OX.buffer)); --copy by a dirty trick. BUG
     newstring := read (OX.F);
     stderr << "Read " << #newstring << " bytes: " << ascii newstring 
            << endl << flush;
     left := #OX.buffer - OX.loc;
     --stderr <<"before: "<<OX.loc << ascii OX.buffer <<endl << flush;	
     if left > 0 then
        OX.buffer = substring(OX.buffer, OX.loc, left)
                    | newstring
     else
        OX.buffer = newstring;
     --stderr <<"after: "<<ascii OX.buffer <<endl << flush;	
     OX.loc = 0;
     )

get32bits = (OX) -> (
     -- OX is an OXINPUT
     while  #OX.buffer < OX.loc + 4 do (
       readMoreData OX; );
     result := fromNetwork(substring(OX.buffer, OX.loc, 4));
     OX.loc = OX.loc + 4;  
     --debug: stderr << "get32bits" << ascii OX.buffer <<endl <<flush; 
     result
     )

getBytes = (OX,n) -> (
     -- OX is an OXINPUT
     while #OX.buffer < OX.loc + n  do (
       readMoreData OX; );
     result := substring(OX.buffer, OX.loc, n);
     OX.loc = OX.loc + n;
     result)
     
CMOfromBinary = (OX) -> (
     -- OX is an OXINPUT
     local result;
     cmoTag := get32bits OX;
     if cmoTag === CMO'NULL then 
         null
     else if cmoTag === CMO'INT32 then (
	  -- next 4 bytes are an integer
	  result = get32bits OX;
	  if (result > 2^31 - 1) then result = result - 2^32;	  
	  INT32 result)
     else if cmoTag === CMO'STRING then (
     	  len = get32bits OX;
	  getBytes(OX,len))
     else if cmoTag === CMO'LIST then (
     	  len = get32bits OX;
     	  apply(len, i -> CMOfromBinary OX))
     else if cmoTag === CMO'ERROR2 then (
	  CMOfromBinary OX)
     else if cmoTag === CMO'ZZ then (
	  len = get32bits OX;
	  if (len > 2^31-1) then len = len - 2^32;
	  result = 0;
	  i = 0;
	  while (i < abs(len)) do (
	       result = result + ( (get32bits OX) << (32*i) );
	       i = i+1;
	       );
	  if (len < 0) then result = -result;
	  result
	  )
     else if cmoTag === CMO'QQ then (
	  -- make the numerator
	  len = get32bits OX;
	  if (len > 2^31-1) then len = len - 2^32;
	  num := 0;
	  i := 0;
	  while (i < abs(len)) do (
	       num = num + ( (get32bits OX) << (32*i) );
	       i = i+1;
	       );
	  if (len < 0) then num = -num;
	  -- make the denominator
	  len = get32bits OX;
	  if (len > 2^31-1) then len = len - 2^32;
	  den := 0;
	  i = 0;
	  while (i < abs(len)) do (
	       den = den + ( (get32bits OX) << (32*i) );
	       i = i+1;
	       );
	  if (len < 0) then den = -den;
	  num/den
	  )
     else if cmoTag === CMO'MATHCAP then (
	  MATHCAP(CMOfromBinary OX)
	  )
     else if cmoTag === CMO'RECURSIVE'POLYNOMIAL then (
	  -- recursive'varlist is a global variable for now
	  -- otherwise, we need way to pass it as a parameter in recursion
     	  recursive'varlist = apply(CMOfromBinary OX, i -> value i);
     	  CMOfromBinary OX
	  )
     else if cmoTag === CMO'POLYNOMIAL'IN'ONE'VARIABLE then (
	  m := get32bits(OX);
	  v := get32bits(OX);
	  i = 0;
	  result = 0;
	  while (i < m) do (
	       exponent := get32bits(OX);
	       result=result+(recursive'varlist_v)^exponent*CMOfromBinary(OX);
	       i = i+1;
	       );
	  result
	  )
     else if cmoTag === CMO'INDETERMINATE then (
	  CMOfromBinary OX
	  )
     else error "unknown CMO tag"
     )

---------------------------
-- CMObject --> binary ----
---------------------------
CMOSerialize = method()

CMOSerialize(File,List) := (F,x) -> (
     F << CMOLIST << toNetwork(#x);
     scan(x, a -> CMOSerialize(F,a)))

CMOSerialize(File,ZZ) := (F,x) -> (
     -- BUG: write this
     temp := abs(x);
     stringform := "";
     i := 0;
     while (temp != 0) do (
	  stringform = stringform | toNetwork(temp % (2^32));
	  temp = temp >> 32;
	  i = i+1;
	  );
     if (i > 2^31-1) then error "integer too large to push";
     if (x < 0) then stringform = toNetwork(2^32-i) | stringform
     else stringform = toNetwork(i) | stringform;
     F << CMOZZ << stringform;
     )

CMOSerialize(File,QQ) := (F,x) -> (
     -- BUG: write this
     temp := abs(numerator x);
     numstring := "";
     i := 0;
     while (temp != 0) do (
	  numstring = numstring | toNetwork(temp % (2^32));
	  temp = temp >> 32;
	  i = i+1;
	  );
     if (i > 2^31-1) then error "number too large to push";
     if (numerator x < 0) then numstring = toNetwork(2^32-i) | numstring
     else numstring = toNetwork(i) | numstring;
     temp = abs(denominator x);
     denstring := "";
     i = 0;
     while (temp != 0) do (
	  denstring = denstring | toNetwork(temp % (2^32));
	  temp = temp >> 32;
	  i = i+1;
	  );
     if (i > 2^31-1) then error "number too large to push";
     denstring = toNetwork(i) | denstring;
     F << CMOQQ << numstring << denstring;
     )

CMOSerialize(File,INT32) := (F,x) -> (
     -- Recall that INT32 handles 2-complemented numbers already.
     F << CMOINT32 << toNetwork(x#0);
     )

CMOSerialize(File,String) := (F,x) -> (
     F << CMOSTRING << toNetwork(#x) << x;
     )

CMOSerialize(File,Nothing) := (F,x) -> (
     F << CMONULL;
     )

CMOSerialize(File,ERROR) := (F,x) -> (
     F << CMOERROR2;
     CMOSerialize(F,toList x);
     )

CMOSerialize(File,MATHCAP) := (F,x) -> (
     F << CMOMATHCAP;
     CMOSerialize(x#0);
     )

CMOSerialize(File, RingElement) := (F, x) -> (
     -- make list of indeterminates
     L := apply(generators ring x, i -> toString i);
     L = apply(L, i -> (CMOINDETERMINATE | CMOSTRING | toNetwork(#i) | i));
     L = CMOLIST | toNetwork(#L) | demark("", L);
     F << CMORECURSIVEPOLYNOMIAL << L;
     -- bug: if 1_R is pushed, then 1_ZZ is popped
     if (sum mingle exponents x == 0) then (F << CMOPOLYNOMIALINONEVARIABLE 
     	  << toNetwork(1) << toNetwork(0) << toNetwork(0));
     CMOSerializePolyInOneVar(F, x);
     )

CMOSerializePolyInOneVar = (F, f) -> (
     local tmp;
     local allVars;
     -- number of variables appearing in f
     allVars = positions(sum exponents f, i -> i > 0);
     if (allVars === {}) then (
	  CMOSerialize(F, substitute(f, coefficientRing ring f));
	  )
     else (
	  -- given a polynomial with only one variable x appearing, 
	  -- make list of sorted pairs where the first element is 
	  -- a monomial in x and the second is the coefficient
	  tmp = coefficients({allVars#0}, f);
	  tmp = sort pack(2, mingle {(entries tmp#0)#0, (entries tmp#1)#0});
	  j := 0;
	  F << CMOPOLYNOMIALINONEVARIABLE << toNetwork(#tmp) << 
	  toNetwork(allVars#0);
	  if (#allVars == 1) then (
	       -- if f is a polynomial of a single variable
	       while (j < #tmp) do (
		    F << toNetwork(sum mingle exponents tmp#j#0);
		    CMOSerialize(F, substitute(tmp#j#1, coefficientRing ring tmp#j#1));
		    j = j+1;
		    );
	       )
	  else (
	       -- otherwise need to do recursion
	       while(j < #tmp) do (
		    F << toNetwork(sum mingle exponents (tmp#j#0));
		    CMOSerializePolyInOneVar(F, tmp#j#1);
		    j = j+1;
		    );
	       );
	  );
     )