Changeset 7c4eb8 in git


Ignore:
Timestamp:
Jul 5, 2016, 11:10:45 AM (7 years ago)
Author:
Hans Schoenemann <hannes@…>
Branches:
(u'spielwiese', '8e0ad00ce244dfd0756200662572aef8402f13d5')
Children:
4e6fbc1fa1ac8c8c5a6a951a642c70a5e6d5eb2b
Parents:
446b4ae2669e980ecd9bedab7ad12535004a0e45
Message:
new version of ncfactor.lib
Files:
39 edited

Legend:

Unmodified
Added
Removed
  • Singular/LIB/ncfactor.lib

    r446b4ae r7c4eb8  
    11///////////////////////////////////////////////////////////
    2 version="version ncfactor.lib 4.0.0.0 Jun_2014 "; // $Id$
     2version="version ncfactor.lib 4.0.3.2 Jul_2016 "; // $Id$
    33category="Noncommutative";
    44info="
     
    1818
    1919PROCEDURES:
     20  ncfactor(h);               Factorization in any G-algebra.
    2021  facWeyl(h);                Factorization in the n'th Weyl algebra
    2122  facFirstWeyl(h);           Factorization in the first Weyl algebra
     
    3536LIB "nctools.lib";
    3637LIB "involut.lib";
    37 LIB "freegb.lib"; // for isVar
    3838LIB "crypto.lib"; //for introot
    3939LIB "matrix.lib"; //for submatrix
     
    4444"
    4545A little test if the library works correct.
    46 Runs simply all examples of non-static functions.
     46Runs all tests for static and non-static functions.
    4747"
    4848{
    49   example facWeyl;
    50   example facShift;
    51   example facSubWeyl;
    52   example testNCfac;
    53   example homogfacFirstQWeyl;
    54   example homogfacFirstQWeyl_all;
     49  print("Testing delete_duplicates_noteval.");
     50  if(!test_delete_duplicates_noteval())
     51  {
     52    ERROR("delete_duplicates_noteval is not working properly.");
     53  }
     54  print("Successful.");
     55  print("Testing delete_duplicates_noteval_and_sort");
     56  if(!test_delete_duplicates_noteval_and_sort())
     57  {
     58    ERROR("delete_duplicates_noteval_and_sort is not working properly.");
     59  }
     60  print("Successful.");
     61  print("Testing combinekfinlf");
     62  if(!test_combinekfinlf())
     63  {
     64    ERROR("combinekfinlf is not working properly.");
     65  }
     66  print("Successful.");
     67  print("Testing permpp");
     68  if(!test_permpp())
     69  {
     70    ERROR("permpp is not working properly.");
     71  }
     72  print("Successful.");
     73  print("Testing binarySearch");
     74  if(!test_binarySearch())
     75  {
     76    ERROR("binarySearch is not working properly.");
     77  }
     78  print("Successful.");
     79  print("Testing getAllDivisorsFromFactList");
     80  if(!test_getAllDivisorsFromFactList())
     81  {
     82    ERROR("getAllDivisorsFromFactList is not working properly.");
     83  }
     84  print("Successful.");
     85  print("Testing triangNum");
     86  if (!test_triangNum())
     87  {
     88    ERROR("triangNum is not working properly.");
     89  }
     90  print("Successful.");
     91  print("Testing fromListToIntvec");
     92  if (!test_fromListToIntvec())
     93  {
     94    ERROR("fromListToIntvec is not working properly.");
     95  }
     96  print("Successful.");
     97  print("Testing fromIntvecToList");
     98  if (!test_fromIntvecToList())
     99  {
     100    ERROR("fromIntvecToList is not working properly.");
     101  }
     102  print("Successful.");
     103  print("Testing produceHomogListForProduct");
     104  if (!test_produceHomogListForProduct())
     105  {
     106    ERROR("produceHomogListForProduct is not working properly.");
     107  }
     108  print("Successful.");
     109  print("Testing possibleHomogPartsInBetween");
     110  if (!test_possibleHomogPartsInBetween())
     111  {
     112    ERROR("possibleHomogPartsInBetween is not working properly.");
     113  }
     114  print("Successful.");
     115  print("Testing nextSmallerEntry");
     116  if (!test_nextSmallerEntry())
     117  {
     118    ERROR("nextSmallerEntry is not working properly.");
     119  }
     120  print("Successful.");
     121  print("Testing possibleHomogPartsInBetweenNonRecursive");
     122  if (!test_possibleHomogPartsInBetweenNonRecursive())
     123  {
     124    ERROR("possibleHomogPartsInBetweenNonRecursive is not working properly.");
     125  }
     126  print("Successful.");
     127  print("Testing increment_intvec");
     128  if (!test_increment_intvec())
     129  {
     130    ERROR("increment_intvec is not working properly.");
     131  }
     132  print("Successful.");
     133  print("Testing Min");
     134  if (!test_Min())
     135  {
     136    ERROR("Min is not working properly.");
     137  }
     138  print("Successful.");
     139  print("Testing isListEqual");
     140  if (!test_isListEqual())
     141  {
     142    ERROR("isListEqual is not working properly.");
     143  }
     144  print("Successful.");
     145  print("Testing ncfactor_isWeyl");
     146  if (!test_ncfactor_isWeyl())
     147  {
     148    ERROR("ncfactor_isWeyl is not working properly.");
     149  }
     150  print("Successful.");
     151  print("Testing ncfactor_isQWeyl");
     152  if (!test_ncfactor_isQWeyl())
     153  {
     154    ERROR("ncfactor_isQWeyl is not working properly.");
     155  }
     156  print("Successful.");
     157  print("Testing ncfactor_isShift");
     158  if (!test_ncfactor_isShift())
     159  {
     160    ERROR("ncfactor_isShift is not working properly.");
     161  }
     162  print("Successful.");
     163  print("Testing checkIfProperNthShift");
     164  if (!test_checkIfProperNthShift())
     165  {
     166    ERROR("checkIfProperNthShift is not working properly.");
     167  }
     168  print("Successful.");
     169  print("Testing checkIfProperNthWeyl");
     170  if (!test_checkIfProperNthWeyl())
     171  {
     172    ERROR("checkIfProperNthWeyl is not working properly.");
     173  }
     174  print("Successful.");
     175  print("Testing checkIfProperNthQWeyl");
     176  if (!test_checkIfProperNthQWeyl())
     177  {
     178    ERROR("checkIfProperNthQWeyl is not working properly.");
     179  }
     180  print("Successful.");
     181  print("Testing isInCommutativeSubRing");
     182  if (!test_isInCommutativeSubRing())
     183  {
     184    ERROR("isInCommutativeSubRing is not working properly.");
     185  }
     186  print("Successful.");
     187  print("Testing factor_commutative");
     188  if(!test_factor_commutative())
     189  {
     190    ERROR("factor_commutative is not working properly.");
     191  }
     192  print("Successful.");
     193  print("Testing factorizeInt");
     194  if(!test_factorizeInt())
     195  {
     196    ERROR("factorizeInt is not working properly.");
     197  }
     198  print("Successful.");
     199  print("Testing getAllCoeffTuplesComb");
     200  if(!test_getAllCoeffTuplesComb())
     201  {
     202    ERROR("getAllCoeffTuplesComb is not working properly.");
     203  }
     204  print("Successful.");
     205  print("Testing normalizeFactors");
     206  if(!test_normalizeFactors())
     207  {
     208    ERROR("normalizeFactors is not working properly.");
     209  }
     210  print("Successful.");
     211  print("Testing divides");
     212  if(!test_divides())
     213  {
     214    ERROR("divides is not working properly.");
     215  }
     216  print("Successful.");
     217  print("Testing multiplyFactIntOutput");
     218  if(!test_multiplyFactIntOutput())
     219  {
     220    ERROR("multiplyFactIntOutput is not working properly.");
     221  }
     222  print("Successful.");
     223  print("Testing testNCfac");
     224  if(!test_testNCfac())
     225  {
     226    ERROR("testNCfac is not working properly.");
     227  }
     228  print("Successful.");
     229  print("Testing monsSmallerThan");
     230  if(!test_monsSmallerThan())
     231  {
     232    ERROR("monsSmallerThan is not working properly.");
     233  }
     234  print("Successful.");
     235  print("Testing getMaxDegreeVec");
     236  if(!test_getMaxDegreeVec())
     237  {
     238    ERROR("getMaxDegreeVec is not working properly.");
     239  }
     240  print("Successful.");
     241  print("Testing isFactorizationSmaller");
     242  if(!test_isFactorizationSmaller())
     243  {
     244    ERROR("test_isFactorizationSmaller is not working properly.");
     245  }
     246  print("Successful.");
     247  print("Testing sortedInsert");
     248  if(!test_sortedInsert())
     249  {
     250    ERROR("sortedInsert is not working properly.");
     251  }
     252  print("Successful.");
     253  print("Testing isFactorizationEqual");
     254  if(!test_isFactorizationEqual())
     255  {
     256    ERROR("isFactorizationEqual is not working properly.");
     257  }
     258  print("Successful.");
     259  print("Testing sortFactorizations");
     260  if(!test_sortFactorizations())
     261  {
     262    ERROR("sortFactorizations is not working properly.");
     263  }
     264  print("Successful.");
     265  print("Testing homogfacNthWeyl");
     266  if(!test_homogfacNthWeyl())
     267  {
     268    ERROR("homogfacNthWeyl is not working properly.");
     269  }
     270  print("Successful.");
     271  print("Testing homogfacNthWeyl_all");
     272  if(!test_homogfacNthWeyl_all())
     273  {
     274    ERROR("homogfacNthWeyl_all is not working properly.");
     275  }
     276  print("Successful.");
     277  print("Testing facWeyl");
     278  if(!test_facWeyl())
     279  {
     280    ERROR("facWeyl is not working properly.");
     281  }
     282  print("Successful.");
     283  print("Testing checkForHomogInhomogInterchangabilityNthWeyl");
     284  if(!test_checkForHomogInhomogInterchangabilityNthWeyl())
     285  {
     286    ERROR("checkForHomogInhomogInterchangabilityNthWeyl is not working properly.");
     287  }
     288  print("Successful.");
     289  print("Testing sfacwa2NthWeyl");
     290  if(!test_sfacwa2NthWeyl())
     291  {
     292    ERROR("sfacwaNthWeyl is not working properly.");
     293  }
     294  print("Successful.");
     295  print("Testing sfacwa2NthWeyl");
     296  if(!test_sfacwa2NthWeyl())
     297  {
     298    ERROR("sfacwaNthWeyl is not working properly.");
     299  }
     300  print("Successful.");
     301  print("Testing determineRestOfHomogPartsNthWeyl");
     302  if(!test_determineRestOfHomogPartsNthWeyl())
     303  {
     304    ERROR("determineRestOfHomogPartsNthWeyl is not working properly.");
     305  }
     306  print("Successful.");
     307  print("Testing gammaForThetaNthWeyl");
     308  if(!test_gammaForThetaNthWeyl())
     309  {
     310    ERROR("gammaForThetaNthWeyl is not working properly.");
     311  }
     312  print("Successful.");
     313  print("Testing extractHomogeneousDivisorsNthWeyl");
     314  if(!test_extractHomogeneousDivisorsNthWeyl())
     315  {
     316    ERROR("extractHomogeneousDivisorsNthWeyl is not working properly.");
     317  }
     318  print("Successful.");
     319  print("Testing extractHomogeneousDivisorsLeftNthWeyl");
     320  if(!test_extractHomogeneousDivisorsLeftNthWeyl())
     321  {
     322    ERROR("extractHomogeneousDivisorsLeftNthWeyl is not working properly.");
     323  }
     324  print("Successful.");
     325  print("Testing extractHomogeneousDivisorsRightNthWeyl");
     326  if(!test_extractHomogeneousDivisorsRightNthWeyl())
     327  {
     328    ERROR("extractHomogeneousDivisorsRightNthWeyl is not working properly.");
     329  }
     330  print("Successful.");
     331  print("Testing computeCombinationsMinMaxHomogNthWeyl");
     332  if(!test_computeCombinationsMinMaxHomogNthWeyl())
     333  {
     334    ERROR("computeCombinationsMinMaxHomogNthWeyl is not working properly.");
     335  }
     336  print("Successful.");
     337  print("Testing getAllCombOfHomogFact");
     338  if(!test_getAllCombOfHomogFact())
     339  {
     340    ERROR("getAllCombOfHomogFact is not working properly.");
     341  }
     342  print("Successful.");
     343  print("Testing getPossibilitiesForRightSides");
     344  if(!test_getPossibilitiesForRightSides())
     345  {
     346    ERROR("getPossibilitiesForRightSides is not working properly.");
     347  }
     348  print("Successful.");
     349  print("Testing homogDistributionNthWeyl");
     350  if(!test_homogDistributionNthWeyl())
     351  {
     352    ERROR("homogDistributionNthWeyl is not working properly.");
     353  }
     354  print("Successful.");
     355  print("Testing extractLeadingTermOfNthWeylPoly");
     356  if(!test_extractLeadingTermOfNthWeylPoly())
     357  {
     358    ERROR("extractLeadingTermOfNthWeylPoly is not working properly.");
     359  }
     360  print("Successful.");
     361  print("Testing degreeOfNthWeylPoly");
     362  if(!test_degreeOfNthWeylPoly())
     363  {
     364    ERROR("degreeOfNthWeylPoly is not working properly.");
     365  }
     366  print("Successful.");
     367  print("Testing degreeOfNthWeylPolyInverted");
     368  if(!test_degreeOfNthWeylPolyInverted())
     369  {
     370    ERROR("degreeOfNthWeylPolyInverted is not working properly.");
     371  }
     372  print("Successful.");
     373  print("Testing homogwithorderNthWeyl");
     374  if(!test_homogwithorderNthWeyl())
     375  {
     376    ERROR("homogwithorderNthWeyl is not working properly.");
     377  }
     378  print("Successful.");
     379  print("Testing isInWeylSubAlg");
     380  if(!test_isInWeylSubAlg())
     381  {
     382    ERROR("isInWeylSubAlg is not working properly.");
     383  }
     384  print("Successful.");
     385  print("Testing facSubWeyl");
     386  if(!test_facSubWeyl())
     387  {
     388    ERROR("facSubWeyl is not working properly.");
     389  }
     390  print("Successful.");
     391  print("Testing facShift");
     392  if(!test_facShift())
     393  {
     394    ERROR("facShift is not working properly.");
     395  }
     396  print("Successful.");
     397  print("Testing sFacNthShift");
     398  if(!test_sFacNthShift())
     399  {
     400    ERROR("sfacNthShift is not working properly.");
     401  }
     402  print("Successful.");
     403  print("Testing combineNonnegativeNthShift");
     404  if(!test_combineNonnegativeNthShift())
     405  {
     406    ERROR("combineNonnegativeNthShift is not working properly.");
     407  }
     408  print("Successful.");
     409  print("Testing fromNthWeylToNthShiftPoly");
     410  if(!test_fromNthWeylToNthShiftPoly())
     411  {
     412    ERROR("fromNthWeylToNthShiftPoly is not working properly.");
     413  }
     414  print("Successful.");
     415  print("Testing homogfacNthQWeyl");
     416  if(!test_homogfacNthQWeyl())
     417  {
     418    ERROR("homogfacNthQWeyl is not working properly.");
     419  }
     420  print("Successful.");
     421  print("Testing homogfacNthQWeyl_all");
     422  if(!test_homogfacNthQWeyl_all())
     423  {
     424    ERROR("homogfacNthQWeyl_all is not working properly.");
     425  }
     426  print("Successful.");
     427  print("Testing ncfactor");
     428  if(!test_ncfactor())
     429  {
     430    ERROR("ncfactor is not working properly.");
     431  }
     432  print("Successful.");
     433  print("Testing ncfactor_without_opt");
     434  if(!test_ncfactor_without_opt())
     435  {
     436    ERROR("ncfactor_without_opt is not working properly.");
     437  }
     438  print("Successful.");
     439  print("Testing factorize_nc_s");
     440  if(!test_factorize_nc_s())
     441  {
     442    ERROR("factorize_nc_s is not working properly.");
     443  }
     444  print("Successful.");
     445  print("Testing delete_duplicates_noteval_and_sort");
     446  print("All tests ran successfully.");
    55447}
    56448example
     
    60452}
    61453
    62 /////////////////////////////////////////////////////
    63 //==================================================*
    64 //deletes double-entries in a list of factorization
    65 //without evaluating the product.
    66 static proc delete_dublicates_noteval(list l)
     454//////////////////////////////////////////////////
     455//********COMBINATORIAL HELPER FUNCTIONS**********
     456//////////////////////////////////////////////////
     457
     458static proc delete_duplicates_noteval(list l)
    67459"
    68460INPUT: A list of lists; Output same as e.g. FacFirstWeyl. Containing different factorizations
    69461       of a polynomial
    70 OUTPUT: If there are dublicates in this list, this procedure deletes them and returns the list
     462OUTPUT: If there are duplicates in this list, this procedure deletes them and returns the list
    71463 without double entries
    72464"
    73 {//proc delete_dublicates_noteval
     465{//proc delete_duplicates_noteval
    74466  list result= l;
    75467  int j; int k; int i;
     
    103495  }//Iterate over the different factorizations
    104496  return(result);
    105 }//proc delete_dublicates_noteval
    106 
    107 //==================================================
     497}//proc delete_duplicates_noteval
     498
     499
     500static proc test_delete_duplicates_noteval()
     501{//testing delete_duplicates_noteval
     502  int result = 1;
     503  //Test 1: empty list should return empty list
     504  list expected= list();
     505  list obtained = delete_duplicates_noteval(list());
     506  if (!isListEqual(expected, obtained))
     507  {
     508    print("Test 1 failed for delete_duplicates_noteval.");
     509    print("Expected:\n");
     510    print(expected);
     511    print("obtained:\n");
     512    print(obtained);
     513    result = 0;
     514  }
     515  //Test 2: one element list
     516  expected = list(list(1,15));
     517  obtained = delete_duplicates_noteval(list(list(1,15)));
     518  if (!isListEqual(expected,obtained))
     519  {
     520    print("Test 2 failed for delete_duplicates_noteval.");
     521    print("Expected:\n");
     522    print(expected);
     523    print("obtained:\n");
     524    print(obtained);
     525    result = 0;
     526  }
     527  //Test 3: Two empty lists in input list
     528  expected = list(list());
     529  obtained = delete_duplicates_noteval(list(list(),list()));
     530  if (!isListEqual(expected,obtained))
     531  {
     532    print("Test 3 failed for delete_duplicates_noteval.");
     533    print("Expected:\n");
     534    print(expected);
     535    print("obtained:\n");
     536    print(obtained);
     537    result = 0;
     538  }
     539  ring r = 0,(x,y),dp;
     540  setring r;
     541  //Test 4: Typical output for factorization algorithm, no repeat
     542  expected = list(list(1,x,y),list(1,y,x));
     543  obtained = delete_duplicates_noteval(expected);
     544  if (!isListEqual(obtained,expected))
     545  {
     546    print("Test 4 failed for delete_duplicates_noteval");
     547    result = 0;
     548  }
     549  //Test 5: Typical output for factorization algorithm, repeat
     550  expected =list(list(1,x,y),list(1,y,x));
     551  list input = insert(expected, list(1,x,y));
     552  obtained = delete_duplicates_noteval(input);
     553  if (!isListEqual(expected,obtained))
     554  {
     555    print("Test 5 failed for delete_duplicates_noteval");
     556    result = 0;
     557  }
     558  return(result);
     559}//testing delete_duplicates_noteval
     560
     561
     562static proc delete_duplicates_noteval_and_sort(list l)
     563"
     564INPUT: A list of lists; Output same as e.g. FacFirstWeyl. Containing different factorizations
     565       of a polynomial
     566OUTPUT: If there are duplicates in this list, this procedure deletes them and returns the list
     567        without double entries. Furthermore, it sorts the list
     568"
     569{//proc delete_duplicates_noteval_and_sort
     570  list result= sortFactorizations(l);
     571  int i;
     572  for (i=1; i<size(result);i++)
     573  {
     574    if (isFactorizationEqual(result[i],result[i+1]))
     575    {
     576      result = delete(result, i);
     577      continue;
     578    }
     579  }
     580  return(result);
     581}//proc delete_duplicates_noteval_and_sort
     582
     583
     584static proc test_delete_duplicates_noteval_and_sort()
     585{//testing delete_duplicates_noteval_and_sort
     586  int result = 1;
     587  //Test 1: empty list should return empty list
     588  list expected = list();
     589  list obtained = delete_duplicates_noteval_and_sort(list());
     590  if (!isListEqual(obtained,expected))
     591  {
     592    print("Test 1 failed for delete_duplicates_noteval_and_sort.");
     593    print("Expected:\n");
     594    print(expected);
     595    print("obtained:\n");
     596    print(obtained);
     597    result = 0;
     598  }
     599  //Test 2: one element list
     600  expected = list(list(1,15));
     601  obtained = delete_duplicates_noteval_and_sort(list(list(1,15)));
     602  if (!isListEqual(expected,obtained))
     603  {
     604    print("Test 2 failed for delete_duplicates_noteval_and_sort.");
     605    print("Expected:\n");
     606    print(expected);
     607    print("obtained:\n");
     608    print(obtained);
     609    result = 0;
     610  }
     611  //Test 3: Two empty lists in input list
     612  expected = list(list());
     613  obtained = delete_duplicates_noteval_and_sort(list(list(),list()));
     614  if (!isListEqual(expected,obtained))
     615  {
     616    print("Test 3 failed for delete_duplicates_noteval_and_sort.");
     617    print("Expected:\n");
     618    print(expected);
     619    print("obtained:\n");
     620    print(obtained);
     621    result = 0;
     622  }
     623  ring r = 0,(x,y),dp;
     624  setring r;
     625  //Test 4: Typical output for factorization algorithm, no repeat
     626  list input = list(list(1,x,y),list(1,y,x));
     627  expected = input;
     628  obtained = delete_duplicates_noteval_and_sort(input);
     629  if (!isListEqual(obtained,expected))
     630  {
     631    print("Test 4 failed for delete_duplicates_noteval_and_sort");
     632    print("Expected:\n");
     633    print(expected);
     634    print("obtained:\n");
     635    print(obtained);
     636    result = 0;
     637  }
     638  //Test 5: Typical output for factorization algorithm, repeat
     639  input=insert(input, list(1,x,y));
     640  expected = list(list(1,x,y),list(1,y,x));
     641  obtained = delete_duplicates_noteval_and_sort(input);
     642  if (!isListEqual(expected,obtained))
     643  {
     644    print("Test 5 failed for delete_duplicates_noteval_and_sort");
     645    print("Expected:\n");
     646    print(expected);
     647    print("obtained:\n");
     648    print(obtained);
     649    result = 0;
     650  }
     651  //Test 6: Typical output for factorization algorithm, no repeat, unsorted
     652  input = list(list(1,y,x),list(1,x,y));
     653  expected = list(list(1,x,y),list(1,y,x));
     654  obtained = delete_duplicates_noteval_and_sort(input);
     655  if (!isListEqual(expected,obtained))
     656  {
     657    print("Test 6 failed for delete_duplicates_noteval_and_sort");
     658    print("Expected:\n");
     659    print(expected);
     660    print("obtained:\n");
     661    print(obtained);
     662    result = 0;
     663  }
     664  //Test 7: Typical output for factorization algorithm, repeat,
     665  //unsorted
     666  input=insert(input, list(1,x,y));
     667  expected = list(list(1,x,y),list(1,y,x));
     668  obtained = delete_duplicates_noteval_and_sort(input);
     669  if (!isListEqual(expected,obtained))
     670  {
     671    print("Test 7 failed for delete_duplicates_noteval_and_sort");
     672    result = 0;
     673  }
     674  return(result);
     675}//delete_duplicates_noteval_and_sort
     676
     677
     678static proc combinekfinlf(list g, int nof)
     679"
     680given a list of factors g and a desired size nof, this
     681procedure combines the factors, such that we receive a
     682list of the length nof.
     683INPUT: A list of containing polynomials or any type where the *-operator is existent
     684OUTPUT: All possibilities (without permutation of the given list) to combine the polynomials
     685 into nof polynomials given by the user.
     686"
     687{//Procedure combinekfinlf
     688  list result;
     689  int i; int j; int k; //iteration variables
     690  list fc; //fc stands for "factors combined"
     691  list temp; //a temporary store for factors
     692  def nofgl = size(g); //nofgl stands for "number of factors of the given list"
     693  if (nofgl == 0)
     694  {//g was the empty list
     695    return(result);
     696  }//g was the empty list
     697  if (nof <= 0)
     698  {//The user wants to recieve a negative number or no element as a result
     699    return(result);
     700  }//The user wants to recieve a negative number or no element as a result
     701  if (nofgl == nof)
     702  {//There are no factors to combine
     703    result = result + list(g);
     704    return(result);
     705  }//There are no factors to combine
     706  if (nof == 1)
     707  {//User wants to get just one factor
     708    result = result + list(list(product(g)));
     709    return(result);
     710  }//User wants to get just one factor
     711  if(nof>nofgl)
     712  {//something is so wrong. Just returning the original list
     713    result = result + list(g);
     714    return(result);
     715  }//something is so wrong. Just returning the original list
     716  def leftPart;
     717  list rightPart;
     718  list recResult;
     719  for (i = 1; i<=nofgl-nof+1; i++)
     720  {//combine first i and recursive call results
     721    recResult = list();
     722    rightPart = list();
     723    leftPart = g[1];
     724    for (j=2; j<=i; j++)
     725    {//filling the leftPart
     726      leftPart = leftPart * g[j];
     727    }//filling the leftPart
     728    for (j=i+1; j<=nofgl; j++)
     729    { rightPart[j-i] = g[j]; }
     730    recResult = combinekfinlf(rightPart, nof-1);
     731    for (j=1; j<=size(recResult); j++)
     732    {//pushing the left part in
     733      recResult[j] = insert(recResult[j],leftPart,0);
     734    }//pushing the left part in
     735    result = result + recResult;
     736  }//combine first i and recursive call results
     737  result = delete_duplicates_noteval_and_sort(result);
     738  return(result);
     739}//Procedure combinekfinlf
     740
     741
     742static proc test_combinekfinlf()
     743{//testing combinekfinlf
     744  int result = 1;
     745  //Test1: The usual same old empty list
     746  list expected = list();
     747  list obtained = combinekfinlf(list(),5);
     748  if (!isListEqual(obtained,expected))
     749  {
     750    print("Test 1 for combinekfinlf failed.\n");
     751    print("Expected:\n");
     752    print(expected);
     753    print("obtained:\n");
     754    print(obtained);
     755    result = 0;
     756  }
     757  //Test2: list of length 1, nof=0
     758  expected = list();
     759  obtained = combinekfinlf(list(1),0);
     760  if (!isListEqual(expected,obtained))
     761  {
     762    print("Test 2 for combinekfinlf failed.");
     763    print("Expected:\n");
     764    print(expected);
     765    print("obtained:\n");
     766    print(obtained);
     767    result = 0;
     768  }
     769  //Test3: list of length 1, nof=1
     770  expected= list(list(5));
     771  obtained = combinekfinlf(list(5),1);
     772  if (!isListEqual(expected, obtained))
     773  {
     774    print("Test 3 for combinekfinlf failed.");
     775    print("Expected:\n");
     776    print(expected);
     777    print("obtained:\n");
     778    print(obtained);
     779    result = 0;
     780  }
     781  //Test4: list of length 1, nof > 1
     782  expected = (list(list(5)));
     783  obtained = combinekfinlf(list(5),5);
     784  if (!isListEqual(expected, obtained))
     785  {
     786    print("Test 4 for combinekfinlf failed.");
     787    print("Expected:\n");
     788    print(expected);
     789    print("obtained:\n");
     790    print(obtained);
     791    result = 0;
     792  }
     793  //Test5: list of larger length, nof = 1
     794  expected=list(list(1*2*3*4*5*6));
     795  obtained= combinekfinlf(list(1,2,3,4,5,6),1);
     796  if (!isListEqual(expected, obtained))
     797  {
     798    print("Test 5 for combinekfinlf failed.");
     799    print("Expected:\n");
     800    print(expected);
     801    print("obtained:\n");
     802    print(obtained);
     803    result = 0;
     804  }
     805  //Test6: list of larger length, nof = 2
     806  expected= delete_duplicates_noteval_and_sort(
     807    list(list(1,2*3*4*5*6),list(2,3*4*5*6),
     808     list(1*2*3,4*5*6),list(1*2*3*4,5*6),
     809     list(1*2*3*4*5,6)));
     810  obtained = combinekfinlf(list(1,2,3,4,5,6),2);
     811  if (!isListEqual(expected, obtained))
     812  {
     813    print("Test 6 for combinekfinlf failed.");
     814    print("Expected:\n");
     815    print(expected);
     816    print("obtained:\n");
     817    print(obtained);
     818    result = 0;
     819  }
     820  //Test7: list of larger length, nof = length of list
     821  expected = list(list(1,2,3,4,5,6));
     822  obtained = combinekfinlf(list(1,2,3,4,5,6),6);
     823  if (!isListEqual(expected, obtained))
     824  {
     825    print("Test 7 for combinekfinlf failed.");
     826    print("Expected:\n");
     827    print(expected);
     828    print("obtained:\n");
     829    print(obtained);
     830    result = 0;
     831  }
     832  //Test8 list of larger length, nof = half of the length
     833  expected = delete_duplicates_noteval_and_sort(
     834    list(list(1,2,3*4*5*6),list(1,2*3,4*5*6),
     835     list(1,2*3*4,5*6),list(1,2*3*4*5,6),
     836     list(1*2,3,4*5*6),list(1*2,3*4,5*6),
     837     list(1*2,3*4*5,6),list(1*2*3,4,5*6),
     838     list(1*2*3,4*5,6),list(1*2*3*4,5,6)));
     839  obtained = (combinekfinlf(list(1,2,3,4,5,6),3));
     840  if (!isListEqual(expected, obtained))
     841  {
     842    print("Test 8 for combinekfinlf failed.");
     843    print("Expected:\n");
     844    print(expected);
     845    print("obtained:\n");
     846    print(obtained);
     847    result = 0;
     848  }
     849  return(result);
     850}//testing combinekfinlf
     851
     852
     853static proc permpp(list l)
     854"
     855INPUT: A list with entries of a type, where the ==-operator is defined
     856OUTPUT: A list with all permutations of this given list.
     857"
     858{//proc permpp
     859  int i; int j;
     860  list tempresult;
     861  list l_without_double;
     862  list l_without_double_pos;
     863  int double_entry;
     864  list result;
     865  if (size(l)==0)
     866  {
     867    return(list());
     868  }
     869  if (size(l)==1)
     870  {
     871    return(list(l));
     872  }
     873  for (i = 1; i<=size(l);i++)
     874  {//Filling the list with unique entries
     875    double_entry = 0;
     876    for (j = 1; j<=size(l_without_double);j++)
     877    {
     878      if (l_without_double[j] == l[i])
     879      {
     880        double_entry = 1;
     881        break;
     882      }
     883    }
     884    if (!double_entry)
     885    {
     886      l_without_double = l_without_double + list(l[i]);
     887      l_without_double_pos = l_without_double_pos + list(i);
     888    }
     889  }//Filling the list with unique entries
     890  for (i = 1; i<=size(l_without_double); i++ )
     891  {
     892    tempresult = permpp(delete(l,l_without_double_pos[i]));
     893    for (j = 1; j<=size(tempresult);j++)
     894    {
     895      tempresult[j] = list(l_without_double[i])+tempresult[j];
     896    }
     897    result = result+tempresult;
     898  }
     899  return(result);
     900}//proc permpp
     901
     902
     903static proc test_permpp()
     904{//testing permpp
     905  int result = 1;
     906  //Test 1: empty list
     907  list expected = list();
     908  list obtained = permpp(list());
     909  if (!isListEqual(expected, obtained))
     910  {
     911    print("Test 1 for permpp failed.");
     912    print("Expected:\n");
     913    print(expected);
     914    print("obtained:\n");
     915    print(obtained);
     916    result = 0;
     917  }
     918  //Test 2: 1 element list
     919  expected = list(list(1));
     920  obtained = permpp(list(1));
     921  if (!isListEqual(expected, obtained))
     922  {
     923    print("Test 2 for permpp failed.");
     924    print("Expected:\n");
     925    print(expected);
     926    print("obtained:\n");
     927    print(obtained);
     928    result = 0;
     929  }
     930  //Test 3: multi-element list, but only one unique element.
     931  expected = list(list(2,2,2,2,2,2,2));
     932  obtained = permpp(list(2,2,2,2,2,2,2));
     933  if (!isListEqual(expected, obtained))
     934  {
     935    print("Test 3 for permpp failed.");
     936    print("Expected:\n");
     937    print(expected);
     938    print("obtained:\n");
     939    print(obtained);
     940    result = 0;
     941  }
     942  //Test 4: multi-element list, all elements distinct
     943  expected = sortFactorizations(
     944    list(list(1,2,3,4),list(1,2,4,3),list(1,3,2,4),
     945     list(1,3,4,2),list(1,4,2,3),list(1,4,3,2),
     946     list(2,1,3,4),list(2,1,4,3),list(2,4,1,3),
     947     list(2,4,3,1),list(2,3,1,4),list(2,3,4,1),
     948     list(3,1,2,4),list(3,1,4,2),list(3,2,1,4),
     949     list(3,2,4,1),list(3,4,1,2),list(3,4,2,1),
     950     list(4,1,2,3),list(4,1,3,2),list(4,2,1,3),
     951     list(4,2,3,1),list(4,3,1,2),list(4,3,2,1)));
     952  obtained = sortFactorizations(permpp(list(1,2,3,4)));
     953  if (!isListEqual(expected, obtained))
     954  {
     955    print("Test 4 for permpp failed.");
     956    print("Expected:\n");
     957    print(expected);
     958    print("obtained:\n");
     959    print(obtained);
     960    result = 0;
     961  }
     962  //Test5: multi-element list, same elements available.
     963  expected = sortFactorizations(
     964    list(list(1,2,2,3),list(1,2,3,2),list(1,3,2,2),
     965     list(2,1,2,3),list(2,1,3,2),list(2,2,1,3),
     966     list(2,2,3,1),list(2,3,1,2),list(2,3,2,1),
     967     list(3,2,2,1),list(3,2,1,2),list(3,1,2,2)));
     968  obtained = sortFactorizations(permpp(list(1,2,2,3)));
     969  if (!isListEqual(expected, obtained))
     970  {
     971    print("Test 5 for permpp failed.");
     972    print("Expected:\n");
     973    print(expected);
     974    print("obtained:\n");
     975    print(obtained);
     976    result = 0;
     977  }
     978  return(result);
     979}//testing permpp
     980
     981
     982static proc binarySearch(def inputList, def inputElem)
     983"
     984INPUT: An iterable inputList (ideal/vector/intvec), which has to be
     985       sorted, and an element inputElem, for which it has to be
     986       possible to compare it to the other elements.
     987OUTPUT: If the entry was found, it returns its position, otherwise it returns 0.
     988"
     989{//binarySearch
     990  int first = 1;
     991  int last = size(inputList);
     992  int middle;
     993  while (first <= last)
     994  {
     995    middle = first + ((last - first) div 2);
     996    if (inputList[middle] < inputElem)
     997    {
     998      first = middle + 1;
     999    }
     1000    else
     1001    {
     1002      if (inputList[middle] > inputElem)
     1003      {
     1004        last = middle -1;
     1005      }
     1006      else
     1007      {
     1008        return(middle);
     1009      }
     1010    }
     1011  }
     1012  return(0);
     1013}//binarySearch
     1014
     1015
     1016static proc test_binarySearch()
     1017{//testing binarySearch
     1018  int result = 1;
     1019  //Test 1: Empty list
     1020  int expected = 0;
     1021  int obtained = binarySearch(list(),5);
     1022  if (expected != obtained)
     1023  {
     1024    print("Test 1 for binarySearch failed.");
     1025    print("Expected:\n");
     1026    print(expected);
     1027    print("obtained:\n");
     1028    print(obtained);
     1029    result = 0;
     1030  }
     1031  //Test2: One element list, element not found
     1032  expected = 0;
     1033  obtained = binarySearch(list(1),2);
     1034  if (expected != obtained)
     1035  {
     1036    print("Test 2 for binarySearch failed.");
     1037    print("Expected:\n");
     1038    print(expected);
     1039    print("obtained:\n");
     1040    print(obtained);
     1041    result = 0;
     1042  }
     1043  //Test3: One element list, element found
     1044  expected = 1;
     1045  obtained = binarySearch(list(1),1);
     1046  if (expected != obtained)
     1047  {
     1048    print("Test 3 for binarySearch failed.");
     1049    print("Expected:\n");
     1050    print(expected);
     1051    print("obtained:\n");
     1052    print(obtained);
     1053    result = 0;
     1054  }
     1055  //Test4: Two element list, element not found
     1056  expected = 0;
     1057  obtained = binarySearch(list(1,3),2);
     1058  if (expected != obtained)
     1059  {
     1060    print("Test 4 for binarySearch failed.");
     1061    print("Expected:\n");
     1062    print(expected);
     1063    print("obtained:\n");
     1064    print(obtained);
     1065    result = 0;
     1066  }
     1067  //Test5: Two element list, element found
     1068  expected = 2;
     1069  obtained = binarySearch(list(1,2),2);
     1070  if (expected != obtained)
     1071  {
     1072    print("Test 5 for binarySearch failed.");
     1073    print("Expected:\n");
     1074    print(expected);
     1075    print("obtained:\n");
     1076    print(obtained);
     1077    result = 0;
     1078  }
     1079  //Test6: Multi element list, element not found
     1080  expected =0;
     1081  obtained = binarySearch(list(1,2,6,9,15,22),5);
     1082  if (expected != obtained)
     1083  {
     1084    print("Test 6 for binarySearch failed.");
     1085    print("Expected:\n");
     1086    print(expected);
     1087    print("obtained:\n");
     1088    print(obtained);
     1089    result = 0;
     1090  }
     1091  //Test7: Multi element list, element found
     1092  expected =4;
     1093  obtained = binarySearch(list(1,2,6,9,15,22),9);
     1094  if (expected != obtained)
     1095  {
     1096    print("Test 7 for binarySearch failed.");
     1097    print("Expected:\n");
     1098    print(expected);
     1099    print("obtained:\n");
     1100    print(obtained);
     1101    result = 0;
     1102  }
     1103  return(result);
     1104}//testing binarySearch
     1105
     1106
     1107static proc getAllDivisorsFromFactList(list l)
     1108"USAGE: getAllDivisorsFromFactList(l); l is a list containing two
     1109        lists; first list represents the prime factors, second list
     1110    their powers.
     1111RETURNS: list(int)
     1112PURPOSE: Computes all possible factors of the integer n, whose
     1113          factorization into prime factors is defined by l;
     1114ASSUMPTIONS:
     1115- The list is containing two lists. They can be assumed to be outputs of the function
     1116factorizeInt. They have at least one entry. If it is exactly one entry, the second intvec should
     1117contain a value at least 2.
     1118  "
     1119{//proc getAllDivisorsFromFactList
     1120  list primeFactors=l[1];
     1121  list powersOfThem = l[2];
     1122  int i;int j;
     1123  //Casting the entries to be numbers
     1124  for (i=1; i<=size(primeFactors); i++)
     1125  {
     1126    primeFactors[i] = number(primeFactors[i]);
     1127    powersOfThem[i] = number(powersOfThem[i]);
     1128  }
     1129
     1130  //Alternative Code
     1131  list result;
     1132  number tempPrimeFactor = 1;
     1133  list recursiveCall;
     1134  list recursivePowersOfThem;
     1135  if (size(primeFactors)==1)
     1136  {//base case: we can right away compute the result and return it.
     1137    for (i = 1; i<=powersOfThem[1];i++)
     1138    {
     1139      tempPrimeFactor = tempPrimeFactor*primeFactors[1];
     1140      result = insert(result,tempPrimeFactor);
     1141    }
     1142  }//base case: we can right away compute the result and return it.
     1143  else
     1144  {//non-base-case that involves recursion.
     1145    if (powersOfThem[1] == 1)
     1146    {//we have used up all our powers of that prime
     1147      recursiveCall =
     1148    getAllDivisorsFromFactList(list(delete(primeFactors,1),delete(powersOfThem,1)));
     1149    }//we have used up all our powers of that prime
     1150    else
     1151    {//There is more power to that one prime
     1152      recursivePowersOfThem = powersOfThem;
     1153      recursivePowersOfThem[1] = recursivePowersOfThem[1] -1;
     1154      recursiveCall = getAllDivisorsFromFactList(list(primeFactors, recursivePowersOfThem));
     1155    }//There is more power to that one prime
     1156    result = recursiveCall;
     1157    for (i=1; i<=size(recursiveCall); i++)
     1158    {//inserting the possibilities with the one factor included.
     1159      result = insert(result, recursiveCall[i]*primeFactors[1]);
     1160    }//inserting the possibilities with the one factor included.
     1161  }//non-base-case that involves recursion.
     1162  result = insert(result,number(1));
     1163  result = sort(result)[1];
     1164  result = delete_duplicates_noteval(result);
     1165  return(result);
     1166}//proc getAllDivisorsFromFactList
     1167
     1168
     1169static proc test_getAllDivisorsFromFactList()
     1170{//testing getAllDivisorsFromFactList
     1171  int result = 1;
     1172  ring R = 0,(x),dp;
     1173  //Test 1: factor of 1
     1174  list expected = list(number(1));
     1175  list obtained = getAllDivisorsFromFactList(factorizeInt(1));
     1176  if (!isListEqual(expected, obtained))
     1177  {
     1178    print("Test 1 for getAllDivisorsFromFactList failed.");
     1179    print("Expected:\n");
     1180    print(expected);
     1181    print("obtained:\n");
     1182    print(obtained);
     1183    result = 0;
     1184  }
     1185  //Test2: single prime
     1186  expected = list(number(1),number(5));
     1187  obtained = getAllDivisorsFromFactList(factorizeInt(5));
     1188  if (!isListEqual(expected, obtained))
     1189  {
     1190    print("Test 2 for getAllDivisorsFromFactList failed.");
     1191    print("Expected:\n");
     1192    print(expected);
     1193    print("obtained:\n");
     1194    print(obtained);
     1195    result = 0;
     1196  }
     1197  //Test3: prime power
     1198  expected = list(number(1),number(2),number(4),number(8));
     1199  obtained = getAllDivisorsFromFactList(factorizeInt(8));
     1200  if (!isListEqual(expected, obtained))
     1201  {
     1202    print("Test 3 for getAllDivisorsFromFactList failed.");
     1203    print("Expected:\n");
     1204    print(expected);
     1205    print("obtained:\n");
     1206    print(obtained);
     1207    result = 0;
     1208  }
     1209  //Test4: Arbitrary number
     1210  expected = list(number(1),number(2),number(5),number(10));
     1211  obtained = getAllDivisorsFromFactList(factorizeInt(10));
     1212  if (!isListEqual(expected, obtained))
     1213  {
     1214    print("Test 2 for getAllDivisorsFromFactList failed.");
     1215    print("Expected:\n");
     1216    print(expected);
     1217    print("obtained:\n");
     1218    print(obtained);
     1219    result = 0;
     1220  }
     1221  return(result);
     1222}//testing getAllDivisorsFromFactList
     1223
     1224
     1225static proc triangNum(int n)
     1226"Returns the nth triangular number."
     1227{
     1228  if (n == 0)
     1229  {
     1230    return(0);
     1231  }
     1232  return (n*(n+1) div 2);
     1233}
     1234
     1235
     1236static proc test_triangNum()
     1237{//testing triangNum
     1238  int result = 1;
     1239  //Test 1: 0
     1240  int expected = 0;
     1241  int obtained = triangNum(0);
     1242  if (expected !=obtained)
     1243  {
     1244    print("Test 1 for tringNum failed.");
     1245    print("Expected:\n");
     1246    print(expected);
     1247    print("obtained:\n");
     1248    print(obtained);
     1249    result = 0;
     1250  }
     1251  //Test 2: 1
     1252  expected = 1;
     1253  obtained = triangNum(1);
     1254  if (expected !=obtained)
     1255  {
     1256    print("Test 2 for tringNum failed.");
     1257    print("Expected:\n");
     1258    print(expected);
     1259    print("obtained:\n");
     1260    print(obtained);
     1261    result = 0;
     1262  }
     1263  //Test 3: some non-trivial higher number (gauss)
     1264  expected = 5050;
     1265  obtained = triangNum(100);
     1266  if (expected !=obtained)
     1267  {
     1268    print("Test 3 for tringNum failed.");
     1269    print("Expected:\n");
     1270    print(expected);
     1271    print("obtained:\n");
     1272    print(obtained);
     1273    result = 0;
     1274  }
     1275  return(result);
     1276}//testing triangNum
     1277
     1278
     1279
     1280static proc fromListToIntvec(list l)
     1281"Converter from List to intvec.
     1282Assuming all entries in the given
     1283list are integers, and the list is not empty."
     1284{
     1285  intvec result; int i;
     1286  for (i = 1; i<=size(l); i++)
     1287  {
     1288    result[i] = l[i];
     1289  }
     1290  return(result);
     1291}
     1292
     1293
     1294static proc test_fromListToIntvec()
     1295{//testing fromListToIntvec
     1296  int result = 1;
     1297  //Test 1: List with 1 element
     1298  list input = list(1);
     1299  intvec expected = intvec(1);
     1300  intvec obtained = fromListToIntvec(input);
     1301  if (expected !=obtained)
     1302  {
     1303    print("Test 1 for fromListToIntvec failed.");
     1304    print("Expected:\n");
     1305    print(expected);
     1306    print("obtained:\n");
     1307    print(obtained);
     1308    result = 0;
     1309  }
     1310  //Test 2: List with more than 1 element
     1311  input = list(1,6,3,2);
     1312  expected = intvec(1,6,3,2);
     1313  obtained = fromListToIntvec(input);
     1314  if (expected !=obtained)
     1315  {
     1316    print("Test 2 for fromListToIntvec failed.");
     1317    print("Expected:\n");
     1318    print(expected);
     1319    print("obtained:\n");
     1320    print(obtained);
     1321    result = 0;
     1322  }
     1323  return(result);
     1324}//testing fromListToIntvec
     1325
     1326
     1327static proc fromIntvecToList(intvec l)"
     1328Converter from intvec to list"
     1329{//proc fromIntvecToList
     1330  list result = list();
     1331  int i;
     1332  for (i = size(l); i>=1; i--)
     1333  {
     1334    result = insert(result, l[i]);
     1335  }
     1336  return(result);
     1337}//proc fromIntvecToList
     1338
     1339static proc test_fromIntvecToList()
     1340{//testing fromIntvecToList
     1341  int result = 1;
     1342  //Test1: Intvec(0)
     1343  intvec input;
     1344  list expected = list(0);
     1345  list obtained = fromIntvecToList(input);
     1346  if (!isListEqual(expected,obtained))
     1347  {
     1348    print("Test 1 for fromIntvecToList failed.");
     1349    print("Expected:\n");
     1350    print(expected);
     1351    print("obtained:\n");
     1352    print(obtained);
     1353    result = 0;
     1354  }
     1355  //Test2: Intvec(1)
     1356  input= intvec(1);
     1357  expected = list(1);
     1358  obtained = fromIntvecToList(input);
     1359  if (!isListEqual(expected,obtained))
     1360  {
     1361    print("Test 2 for fromIntvecToList failed.");
     1362    print("Expected:\n");
     1363    print(expected);
     1364    print("obtained:\n");
     1365    print(obtained);
     1366    result = 0;
     1367  }
     1368  //Test 3: Intvec with arbitarily many elements
     1369  input= intvec(6,4,7,1,24);
     1370  expected = list(6,4,7,1,24);
     1371  obtained = fromIntvecToList(input);
     1372  if (!isListEqual(expected,obtained))
     1373  {
     1374    print("Test 3 for fromIntvecToList failed.");
     1375    print("Expected:\n");
     1376    print(expected);
     1377    print("obtained:\n");
     1378    print(obtained);
     1379    result = 0;
     1380  }
     1381  return(result);
     1382}//testing fromIntvecToList
     1383
     1384
     1385static proc produceHomogListForProduct(list homogParts1, list homogParts2)
     1386"
     1387INPUT: Two lists of integer vectors, homogParts1 and homogParts2,
     1388       where the contained integer vectors all have the same size n.
     1389OUTPUT: One list of integer vectors, which have size n respectively.
     1390        The entries form a subset of possible integer vectors which result
     1391        of a sum of an entry y in homogParts1 and an entry x in
     1392    homogParts2.
     1393        The subset is given by the property that for each index i in
     1394    homogparts1, the i'th entry in the resulting list has
     1395    homogparts1[i] as a summand. Furthermore,
     1396    result[length(result)-i] should also have
     1397    homogparts1[length(homogparts)-i] as a summand.
     1398"
     1399{//produceHomogListForProduct
     1400  int i; int j; int k;
     1401  list p = reverse(sort(homogParts1)[1]);
     1402  list q = reverse(sort(homogParts2)[1]);
     1403  list result;
     1404  intvec tempIntVec;
     1405  for (i = 1; i<= size(homogParts1); i++)
     1406  {
     1407    for (j = 1; j<= size(homogParts2); j++)
     1408    {
     1409      tempIntVec = homogParts1[i] + homogParts2[j];
     1410      if (binarySearch(result,tempIntVec)==0)
     1411      {//Element was not yet in result, add it
     1412        result = result + list(tempIntVec);
     1413        result = sort(result)[1];
     1414      }//Element was not yet in result, add it
     1415    }
     1416  }
     1417  if (size(result)==0)
     1418  {
     1419    return(result);
     1420  }
     1421  result = reverse(result);
     1422  //Till here, we have a complete list with entries that are between hmax and hmin
     1423  //Now, we need to filter this list.
     1424
     1425  int isIn;
     1426  for(i = 1; i<=size(p); i++)
     1427  {//Checking, if homogparts[i] has a counterpart in homogparts2
     1428    isIn = 0;
     1429    for (j = 1; j<=size(q); j++)
     1430    {//iterating through the counterparts
     1431      if(p[i] + q[j] == result[i])
     1432      {
     1433        isIn = 1;
     1434        break;
     1435      }
     1436    }//iterating through the counterparts
     1437    if(!isIn)
     1438    {
     1439      result = delete(result,i);
     1440      continue;
     1441    }
     1442  }//Checking, if homogparts[i] has a counterpart in homogparts2
     1443  for (i = 0; i<size(p); i++)
     1444  {//The same from the top
     1445    isIn = 0;
     1446    for (j = 1; j<=size(q); j++)
     1447    {//iterating through the counterparts
     1448      if(p[size(p)-i] + q[j] == result[size(result) - i])
     1449      {
     1450        isIn = 1;
     1451        break;
     1452      }
     1453    }//iterating through the counterparts
     1454    if(!isIn)
     1455    {
     1456      result = delete(result,size(result)-i);
     1457      continue;
     1458    }
     1459  }//The same from the top
     1460  return(result);
     1461}//produceHomogListForProduct
     1462
     1463
     1464static proc test_produceHomogListForProduct()
     1465{//testing produceHomogListForProduct
     1466  int result = 1;
     1467  //Test 1: Both lists are empty
     1468  list expected = list();
     1469  list obtained = produceHomogListForProduct(list(),list());
     1470  if (!isListEqual(expected, obtained))
     1471  {
     1472    print("Test 1 for produceHomogListForProduct failed.");
     1473    print("Expected:\n");
     1474    print(expected);
     1475    print("obtained:\n");
     1476    print(obtained);
     1477    result = 0;
     1478  }
     1479  //Test 2: one list empty, the other one contains elements.
     1480  expected = list();
     1481  list input1 = list();
     1482  list input2 = list(intvec(1,2,3),intvec(4,5,6));
     1483  obtained = produceHomogListForProduct(input1,input2);
     1484  if (!isListEqual(expected, obtained))
     1485  {
     1486    print("Test 2 for produceHomogListForProduct failed.");
     1487    print("Expected:\n");
     1488    print(expected);
     1489    print("obtained:\n");
     1490    print(obtained);
     1491    result = 0;
     1492  }
     1493  //Test 3: one list contains elements, the other list is empty.
     1494  expected = list();
     1495  input2 = list();
     1496  input1 = list(intvec(1,2,3),intvec(4,5,6));
     1497  obtained = produceHomogListForProduct(input1,input2);
     1498  if (!isListEqual(expected, obtained))
     1499  {
     1500    print("Test 3 for produceHomogListForProduct failed.");
     1501    print("Expected:\n");
     1502    print(expected);
     1503    print("obtained:\n");
     1504    print(obtained);
     1505    result = 0;
     1506  }
     1507  //Test 4: each list has one element
     1508  expected = list(intvec(5,7,9));
     1509  input1 = list(intvec(4,5,6));
     1510  input2 = list(intvec(1,2,3));
     1511  obtained = produceHomogListForProduct(input1,input2);
     1512  if (!isListEqual(expected, obtained))
     1513  {
     1514    print("Test 4 for produceHomogListForProduct failed.");
     1515    print("Expected:\n");
     1516    print(expected);
     1517    print("obtained:\n");
     1518    print(obtained);
     1519    result = 0;
     1520  }
     1521  //Test5: Random multiple elements, different size
     1522  expected = list(intvec(19,23,2),intvec(5,7,9),intvec(4,4,4));
     1523  input1 = list(intvec(4,5,6),intvec(3,2,1),intvec(11,15,1));
     1524  input2 = list(intvec(1,2,3),intvec(8,8,1));
     1525  obtained = produceHomogListForProduct(input1,input2);
     1526  if (!isListEqual(expected, obtained))
     1527  {
     1528    print("Test 5 for produceHomogListForProduct failed.");
     1529    print("Expected:\n");
     1530    print(expected);
     1531    print("obtained:\n");
     1532    print(obtained);
     1533    result = 0;
     1534  }
     1535  //Test6: Random multiple elements, same size
     1536  expected = list(intvec(19,23,2),intvec(5,7,9));
     1537  input1 = list(intvec(4,5,6),intvec(11,15,1));
     1538  input2 = list(intvec(1,2,3),intvec(8,8,1));
     1539  obtained = produceHomogListForProduct(input1,input2);
     1540  if (!isListEqual(expected, obtained))
     1541  {
     1542    print("Test 6 for produceHomogListForProduct failed.");
     1543    print("Expected:\n");
     1544    print(expected);
     1545    print("obtained:\n");
     1546    print(obtained);
     1547    result = 0;
     1548  }
     1549  return(result);
     1550}//testing produceHomogListForProduct
     1551
     1552
     1553static proc possibleHomogPartsInBetween(intvec pmax, intvec pmin, intvec maxDegrees)
     1554"
     1555INPUT: Integer vectors pmax, pmin and maxDegrees. All are of the same size,
     1556       except from maxDegrees, which is double of the size of the rest.
     1557OUTPUT: A list of possible points in Z^n that can lie between pmax and
     1558        pmin, sorted with respect to the lexicographic order from
     1559        biggest to smallest (leftmost entry in the intvec is the biggest),
     1560        represented as list of intvecs. Upper bounds are given by maxDegrees.
     1561"
     1562{//possibleHomogPartsInBetween
     1563  if (size(pmax) != size(pmin) || 2*size(pmax)!=size(maxDegrees) || pmax<=pmin)
     1564  {
     1565    ERROR("pmax and pmin shall have the same size, and maxDegrees
     1566    shall be double the size of both. Furhtermore, it must hold that pmax>pmin. The
     1567    Input was: " + string(pmax) + ", " + string(pmin) + ", " + string(maxDegrees));
     1568  }
     1569  list result;
     1570  intvec tempIntVec = pmax;
     1571  while(tempIntVec > pmin)
     1572  {
     1573    result = result + list(tempIntVec);
     1574    tempIntVec = nextSmallerEntry(tempIntVec,pmin,maxDegrees);
     1575  }
     1576  result = result + list(pmin);
     1577  return (sort(result)[1]);
     1578}//possibleHomogPartsInBetween
     1579
     1580
     1581static proc test_possibleHomogPartsInBetween()
     1582{//testing possibleHomogPartsInBetween
     1583  int result = 1;
     1584  //Test 1: Nothing in between
     1585  list expected = list(intvec(1,1),intvec(1,2));
     1586  list obtained =
     1587    possibleHomogPartsInBetween(intvec(1,2),
     1588                intvec(1,1),
     1589                intvec(10,10,10,10));
     1590  if (!isListEqual(expected, obtained))
     1591  {
     1592    print("Test 1 for possibleHomogPartsInBetween failed.");
     1593    print("Expected:\n");
     1594    print(expected);
     1595    print("obtained:\n");
     1596    print(obtained);
     1597    result = 0;
     1598  }
     1599  //Test 2: exactly one intvec in between
     1600  expected = list(intvec(1,1),intvec(1,2),intvec(1,3));
     1601  obtained =
     1602    possibleHomogPartsInBetween(intvec(1,3),
     1603                intvec(1,1),
     1604                intvec(10,10,10,10));
     1605  if (!isListEqual(expected, obtained))
     1606  {
     1607    print("Test 2 for possibleHomogPartsInBetween failed.");
     1608    print("Expected:\n");
     1609    print(expected);
     1610    print("obtained:\n");
     1611    print(obtained);
     1612    result = 0;
     1613  }
     1614  //Test 3: One complete degree of freedom
     1615  expected = list(intvec(1,1,1),
     1616          intvec(1,1,2),
     1617          intvec(1,1,3),
     1618          intvec(1,1,4),
     1619          intvec(1,1,5),
     1620          intvec(1,2,-5),
     1621          intvec(1,2,-4),
     1622          intvec(1,2,-3),
     1623          intvec(1,2,-2),
     1624          intvec(1,2,-1),
     1625          intvec(1,2,0),
     1626          intvec(1,2,1),
     1627          intvec(1,2,2),
     1628          intvec(1,2,3),
     1629          intvec(1,2,4),
     1630          intvec(1,2,5),
     1631          intvec(1,3,-5),
     1632          intvec(1,3,-4),
     1633          intvec(1,3,-3),
     1634          intvec(1,3,-2),
     1635          intvec(1,3,-1),
     1636          intvec(1,3,0),
     1637          intvec(1,3,1),
     1638          intvec(1,3,2),
     1639          intvec(1,3,3),
     1640          intvec(1,3,4),
     1641          intvec(1,3,5));
     1642  obtained =
     1643    possibleHomogPartsInBetween(intvec(1,3,5),
     1644                intvec(1,1,1),
     1645                intvec(5,5,5,5,5,5));
     1646  if (!isListEqual(expected, obtained))
     1647  {
     1648    print("Test 3 for possibleHomogPartsInBetween failed.");
     1649    print("Expected:\n");
     1650    print(expected);
     1651    print("obtained:\n");
     1652    print(obtained);
     1653    result = 0;
     1654  }
     1655  return(result);
     1656}//testing possibleHomogPartsInBetween
     1657
     1658
     1659static proc nextSmallerEntry(intvec pmax, intvec pmin, intvec maxDegrees)
     1660"INPUT: Integer vectors pmax, pmin and maxDegrees. maxDegrees has to have size 2*size(pmax),
     1661        where pmin has to have the same size as pmax.
     1662OUTPUT: Counting down by lexicographical ordering, this function returns the next smaller
     1663entry after pmax, which is still bigger than pmin.
     1664"
     1665{//nextSmallerEntry
     1666  if (pmax == pmin)
     1667  {return (pmin);}
     1668  if (size(pmax) == 1)
     1669  {
     1670    if (pmax <= pmin)
     1671    {return(pmin);}
     1672    else
     1673    {return(pmax -1);}
     1674  }
     1675  int i;
     1676  intvec recPmax = pmax[1..(size(pmax)-1)];
     1677  intvec recPmin = pmin[1..(size(pmin)-1)];
     1678  intvec recMaxDegrees = intvec(maxDegrees[1]);
     1679  for (i = 2; i<=size(maxDegrees); i++)
     1680  {
     1681    if (i!=size(pmax) && i!= size(2*size(pmax)))
     1682    {
     1683      recMaxDegrees = recMaxDegrees,maxDegrees[i];
     1684    }
     1685  }
     1686  if (recPmax == recPmin)
     1687  {//In this case, we can only possibly count down at our current position
     1688    if (pmax[size(pmax)] > pmin[size(pmin)])
     1689    {return (recPmax,(pmax[size(pmax)]-1));}
     1690    else
     1691    {return(pmin);}
     1692  }//In this case, we can only possibly count down at our current position
     1693  else
     1694  {//In this case, we can go down to the bounds given by maxDegrees
     1695    if (pmax[size(pmax)] > -maxDegrees[size(pmax)])
     1696    {
     1697      return (recPmax,(pmax[size(pmax)]-1));
     1698    }
     1699    else
     1700    {
     1701      return(nextSmallerEntry(recPmax,recPmin,recMaxDegrees),maxDegrees[2*size(pmax)]);
     1702    }
     1703  }//In this case, we can go down to the bounds given by maxDegrees
     1704}//nextSmallerEntry
     1705
     1706
     1707static proc test_nextSmallerEntry()
     1708{//testing nextSmallerEntry
     1709  int result = 1;
     1710  //Test 1: one element in intvec
     1711  intvec expected = intvec(2);
     1712  intvec obtained = nextSmallerEntry(intvec(3),
     1713                     intvec(2),
     1714                     intvec(5,5));
     1715  if (expected!=obtained)
     1716  {
     1717    print("Test 1 for nextSmallerEntry failed.");
     1718    print("Expected:\n");
     1719    print(expected);
     1720    print("obtained:\n");
     1721    print(obtained);
     1722    result = 0;
     1723  }
     1724  //Test 2: more than one element in intvec, no overlap
     1725  expected = intvec(1,1);
     1726  obtained = nextSmallerEntry(intvec(1,2), intvec(1,1),
     1727                  intvec(5,5,5,5));
     1728  if (expected!=obtained)
     1729  {
     1730    print("Test 2 for nextSmallerEntry failed.");
     1731    print("Expected:\n");
     1732    print(expected);
     1733    print("obtained:\n");
     1734    print(obtained);
     1735    result = 0;
     1736  }
     1737  //Test 3: More than one element in intvec, overlap
     1738  expected = intvec(1,5);
     1739  obtained = nextSmallerEntry(intvec(2,-5), intvec(1,1),
     1740                  intvec(5,5,5,5));
     1741  if (expected!=obtained)
     1742  {
     1743    print("Test 3 for nextSmallerEntry failed.");
     1744    print("Expected:\n");
     1745    print(expected);
     1746    print("obtained:\n");
     1747    print(obtained);
     1748    result = 0;
     1749  }
     1750  //Test 4: More than one element in intvec, more than one overlap
     1751  expected = intvec(1,5,5);
     1752  obtained = nextSmallerEntry(intvec(2,-5,-5), intvec(1,1,1),
     1753                  intvec(5,5,5,5,5,5));
     1754  if (expected!=obtained)
     1755  {
     1756    print("Test 4 for nextSmallerEntry failed.");
     1757    print("Expected:\n");
     1758    print(expected);
     1759    print("obtained:\n");
     1760    print(obtained);
     1761    result = 0;
     1762  }
     1763  return(result);
     1764}//testing nextSmallerEntry
     1765
     1766
     1767static proc possibleHomogPartsInBetweenNonRecursive(intvec pmax, intvec pmin, intvec maxDegrees)
     1768"
     1769INPUT: Integer vectors pmax and maxDegrees. All but maxDegrees are of the same size,
     1770       except from maxDegrees, which is double of the size of the rest.
     1771OUTPUT: A list of possible points in Z^n that can lie between pmax and
     1772        pmin, sorted with respect to the lexicographic order from
     1773        biggest to smallest (leftmost entry in the intvec is the biggest),
     1774        represented as list of intvecs.
     1775"
     1776{//possibleHomogPartsInBetween
     1777  if (size(pmax) != size(pmin) || 2*size(pmax)!=size(maxDegrees) || pmax<=pmin)
     1778  {
     1779    ERROR("pmax and pmin shall have the same size, and maxDegrees
     1780    shall be double the size of both. Furhtermore, it must hold that pmax>pmin. The
     1781    Input was: " + string(pmax) + ", " + string(pmin) + ", " + string(maxDegrees));
     1782  }
     1783  list result = list(pmax);
     1784  int pos; int i; int j; int k;
     1785  list leftPart;
     1786  int leftPartIsMaxAndMin;
     1787  list possibleMiddles;
     1788  list possibleRightParts = list(list());
     1789  list tempRightParts;
     1790  intvec tempentry;
     1791  for (pos = size(pmax); pos >=1 ; pos--)
     1792  {
     1793    leftPart = list();
     1794    leftPartIsMaxAndMin = 1;
     1795    possibleMiddles = list();
     1796    for (i = 1; i < pos; i++)
     1797    {//filling the left part
     1798      leftPart[i] = pmax[i];
     1799      if(pmax[i]!=pmin[i])
     1800      {leftPartIsMaxAndMin = 0;}
     1801    }//filling the left part
     1802    if (leftPartIsMaxAndMin)
     1803    {
     1804      for (i = pmax[pos]-1; i>pmin[pos]; i--)
     1805      {//possible entries for position pos
     1806        possibleMiddles = possibleMiddles + list(i);
     1807      }//possible entries for position pos
     1808    }
     1809    else
     1810    {
     1811      for (i = pmax[pos]-1; i>=-maxDegrees[pos]; i--)
     1812      {//possible entries for position pos
     1813        possibleMiddles = possibleMiddles + list(i);
     1814      }//possible entries for position pos
     1815    }
     1816    for (i = 1; i<=size(possibleMiddles); i++)
     1817    {//Adding possibilities to result
     1818      for (j = 1; j<=size(possibleRightParts); j++)
     1819      {//going through the right parts
     1820        tempentry = intvec(0);
     1821        for (k = 1; k<=size(leftPart);k++)
     1822        {
     1823          tempentry[k] = leftPart[k];
     1824        }
     1825        if (size(leftPart)==0)
     1826        {tempentry = possibleMiddles[i];}
     1827        else
     1828        {tempentry = tempentry,possibleMiddles[i];}
     1829        for (k = 1; k<=size(possibleRightParts[j]) ; k++)
     1830        {
     1831          tempentry = tempentry, possibleRightParts[j][k];
     1832        }
     1833        result = result + list(tempentry);
     1834      }//going through the right parts
     1835    }//Adding possibilities to result
     1836    tempRightParts = list();
     1837    for (i = 1; i<=size(possibleRightParts);i++)
     1838    {
     1839      for (j = -maxDegrees[pos]; j <= maxDegrees[pos + size(pmax)];
     1840           j++)
     1841      {
     1842        tempRightParts = tempRightParts + list(list(j) + possibleRightParts[i]);
     1843      }
     1844    }
     1845    possibleRightParts = tempRightParts;
     1846  }
     1847  //Now the last possible guys
     1848  result = result + list(pmin);
     1849  leftPart = list();
     1850  int positionWhereDifference = 1;
     1851  for (i = 1; i<= size(pmin); i++)
     1852  {
     1853    if(pmax[i] != pmin[i])
     1854    {
     1855      positionWhereDifference = i;
     1856      break;
     1857    }
     1858  }
     1859  possibleRightParts = list(list());
     1860  for (pos = size(pmin); pos > positionWhereDifference; pos--)
     1861  {//Dealing with the minimal parts that we left out in the loop above
     1862    leftPart = list();
     1863    possibleMiddles = list();
     1864    for (i = 1; i < pos; i++)
     1865    {//filling up the left part
     1866      leftPart[i] = pmin[i];
     1867    }//filling up the left part
     1868    for (i = pmin[pos] +1 ; i<=maxDegrees[pos + size(pmin)] ; i++)
     1869    {
     1870      possibleMiddles = possibleMiddles + list(i);
     1871    }
     1872    for (i = 1; i<=size(possibleMiddles); i++)
     1873    {//Adding possibilities to result
     1874      for (j = 1; j<=size(possibleRightParts); j++)
     1875      {//going through the right parts
     1876        tempentry = intvec(0);
     1877        for (k = 1; k<=size(leftPart);k++)
     1878        {
     1879          tempentry[k] = leftPart[k];
     1880        }
     1881        if (size(leftPart)==0)
     1882        {tempentry = possibleMiddles[i];}
     1883        else
     1884        {tempentry = tempentry,possibleMiddles[i];}
     1885        for (k = 1; k<=size(possibleRightParts[j]) ; k++)
     1886        {
     1887          tempentry = tempentry, possibleRightParts[j][k];
     1888        }
     1889        result = result + list(tempentry);
     1890      }//going through the right parts
     1891    }//Adding possibilities to result
     1892    tempRightParts = list();
     1893    for (i = 1; i<=size(possibleRightParts);i++)
     1894    {
     1895      for (j = -maxDegrees[pos]; j <= maxDegrees[pos + size(pmax)];
     1896           j++)
     1897      {
     1898        tempRightParts = tempRightParts + list(list(j) + possibleRightParts[i]);
     1899      }
     1900    }
     1901    possibleRightParts = tempRightParts;
     1902  }//Dealing with the minimal parts that we left out in the loop above
     1903  result = sort(result)[1];
     1904   if (result[1] != pmin)
     1905  {result = insert(result,pmin);}
     1906  return(result);
     1907}//possibleHomogPartsInBetween
     1908
     1909
     1910static proc test_possibleHomogPartsInBetweenNonRecursive()
     1911{//testing possibleHomogPartsInBetweenNonRecursive
     1912  int result = 1;
     1913  //Test 1: Nothing in between
     1914  list expected = list(intvec(1,1),intvec(1,2));
     1915  list obtained =
     1916    possibleHomogPartsInBetweenNonRecursive(intvec(1,2),
     1917                intvec(1,1),
     1918                intvec(10,10,10,10));
     1919  if (!isListEqual(expected, obtained))
     1920  {
     1921    print("Test 1 for possibleHomogPartsInBetweenNonRecursive failed.");
     1922    print("Expected:\n");
     1923    print(expected);
     1924    print("obtained:\n");
     1925    print(obtained);
     1926    result = 0;
     1927  }
     1928  //Test 2: exactly one intvec in between
     1929  expected = list(intvec(1,1),intvec(1,2),intvec(1,3));
     1930  obtained =
     1931    possibleHomogPartsInBetweenNonRecursive(intvec(1,3),
     1932                intvec(1,1),
     1933                intvec(10,10,10,10));
     1934  if (!isListEqual(expected, obtained))
     1935  {
     1936    print("Test 2 for possibleHomogPartsInBetweenNonRecursive failed.");
     1937    print("Expected:\n");
     1938    print(expected);
     1939    print("obtained:\n");
     1940    print(obtained);
     1941    result = 0;
     1942  }
     1943  //Test 3: One complete degree of freedom
     1944  expected = list(intvec(1,1,1),
     1945          intvec(1,1,2),
     1946          intvec(1,1,3),
     1947          intvec(1,1,4),
     1948          intvec(1,1,5),
     1949          intvec(1,2,-5),
     1950          intvec(1,2,-4),
     1951          intvec(1,2,-3),
     1952          intvec(1,2,-2),
     1953          intvec(1,2,-1),
     1954          intvec(1,2,0),
     1955          intvec(1,2,1),
     1956          intvec(1,2,2),
     1957          intvec(1,2,3),
     1958          intvec(1,2,4),
     1959          intvec(1,2,5),
     1960          intvec(1,3,-5),
     1961          intvec(1,3,-4),
     1962          intvec(1,3,-3),
     1963          intvec(1,3,-2),
     1964          intvec(1,3,-1),
     1965          intvec(1,3,0),
     1966          intvec(1,3,1),
     1967          intvec(1,3,2),
     1968          intvec(1,3,3),
     1969          intvec(1,3,4),
     1970          intvec(1,3,5));
     1971  obtained =
     1972    possibleHomogPartsInBetweenNonRecursive(intvec(1,3,5),
     1973                intvec(1,1,1),
     1974                intvec(5,5,5,5,5,5));
     1975  if (!isListEqual(expected, obtained))
     1976  {
     1977    print("Test 3 for possibleHomogPartsInBetweenNonRecursive failed.");
     1978    print("Expected:\n");
     1979    print(expected);
     1980    print("obtained:\n");
     1981    print(obtained);
     1982    result = 0;
     1983  }
     1984  return(result);
     1985}//testing possibleHomogPartsInBetweenNonRecursive
     1986
     1987
     1988static proc increment_intvec(intvec v, intvec maxDegInCoordinates)
     1989"USAGE: increment_intvec(v,maxDegInCoordinates); v and
     1990maxDegInCoordinates are both intvecs.
     1991RETURN: intvec
     1992PURPOSE: Increments the intvec v, assuming that each coordinate has
     1993maximal entry as given in the respective position in
     1994maxDegInCoordinates.
     1995ASSUMPTIONS:
     1996- v and maxDegInCoordinates have the same size.
     1997"{//increment_intvec
     1998  intvec result = v;
     1999  int i;
     2000  for (i = size(result); i>0; i--)
     2001  {//going through the positions
     2002    if (result[i] >= maxDegInCoordinates[i])
     2003    {//need to go to different position
     2004      if (i == 1)
     2005      {//max position already reached; i.e. max vector
     2006        return(v);
     2007      }//max position already reached; i.e. max vector
     2008      result[i] = 0;
     2009    }//need to go to different position
     2010    else
     2011    {//just change counter at that position and done
     2012      result[i]= result[i]+1;
     2013      break;
     2014    }//just change counter at that position and done
     2015  }//going through the positions
     2016  return(result);
     2017}//increment_intvec
     2018
     2019
     2020static proc test_increment_intvec()
     2021{//testing increment_intvec
     2022  int result = 1;
     2023  //Test 1: one element in intvec
     2024  intvec expected = intvec(4);
     2025  intvec obtained = increment_intvec(intvec(3),
     2026                     intvec(5));
     2027  if (expected!=obtained)
     2028  {
     2029    print("Test 1 for increment_intvec failed.");
     2030    print("Expected:\n");
     2031    print(expected);
     2032    print("obtained:\n");
     2033    print(obtained);
     2034    result = 0;
     2035  }
     2036  //Test 2: more than one element in intvec, no overlap
     2037  expected = intvec(1,3);
     2038  obtained = increment_intvec(intvec(1,2),intvec(5,5));
     2039  if (expected!=obtained)
     2040  {
     2041    print("Test 2 for increment_intvec failed.");
     2042    print("Expected:\n");
     2043    print(expected);
     2044    print("obtained:\n");
     2045    print(obtained);
     2046    result = 0;
     2047  }
     2048  //Test 3: More than one element in intvec, overlap
     2049  expected = intvec(3,0);
     2050  obtained = increment_intvec(intvec(2,5),
     2051                  intvec(5,5));
     2052  if (expected!=obtained)
     2053  {
     2054    print("Test 3 for increment_intvec failed.");
     2055    print("Expected:\n");
     2056    print(expected);
     2057    print("obtained:\n");
     2058    print(obtained);
     2059    result = 0;
     2060  }
     2061  //Test 4: More than one element in intvec, more than one overlap
     2062  expected = intvec(3,0,0);
     2063  obtained = increment_intvec(intvec(2,5,5),
     2064                  intvec(5,5,5));
     2065  if (expected!=obtained)
     2066  {
     2067    print("Test 4 for increment_intvec failed.");
     2068    print("Expected:\n");
     2069    print(expected);
     2070    print("obtained:\n");
     2071    print(obtained);
     2072    result = 0;
     2073  }
     2074  return(result);
     2075}//testing increment_intvec
     2076
     2077
     2078//I know that Singular has this function in the package
     2079//qhmoduli.lib. But I don't see the reason why I should clutter my
     2080//namespace with functions to study Moduli Spaces of
     2081//Semi-Quasihomogeneous Singularities (in case somebody wonders)
     2082static proc Min(def lst)
     2083"USAGE: Min(lst); list is an iterable element (list/ideal/intvec)
     2084        containing ordered elements.
     2085PURPOSE: returns the minimal element in lst
     2086ASSUME: lst contains at least one element
     2087"{//proc Min
     2088  def minElem = lst[1];
     2089  int i;
     2090  for (i = 2; i<=size(lst);i++)
     2091  {
     2092    if (lst[i]<minElem)
     2093    {
     2094      minElem = lst[i];
     2095    }
     2096  }
     2097  return (minElem);
     2098}//proc Min
     2099
     2100
     2101static proc test_Min()
     2102{//Testing Min
     2103  int result = 1;
     2104  //Test 1: One element list
     2105  int expected= 1;
     2106  int obtained = Min(list(1));
     2107  if (expected!=obtained)
     2108  {
     2109    print("Test 1 for Min failed.");
     2110    print("Expected:\n");
     2111    print(expected);
     2112    print("obtained:\n");
     2113    print(obtained);
     2114    result = 0;
     2115  }
     2116  //Test 2: Two element list, first one is Min
     2117  expected = 5;
     2118  obtained = Min(list(5,8));
     2119  if (expected!=obtained)
     2120  {
     2121    print("Test 2 for Min failed.");
     2122    print("Expected:\n");
     2123    print(expected);
     2124    print("obtained:\n");
     2125    print(obtained);
     2126    result = 0;
     2127  }
     2128  //Test 3: Two element list, second one is Min
     2129  expected = 5;
     2130  obtained = Min(list(8,5));
     2131  if (expected!=obtained)
     2132  {
     2133    print("Test 3 for Min failed.");
     2134    print("Expected:\n");
     2135    print(expected);
     2136    print("obtained:\n");
     2137    print(obtained);
     2138    result = 0;
     2139  }
     2140  //Test 4: A lot of elements, Min randomly in between.
     2141  expected = -11;
     2142  obtained = Min(list(5,8,7,2,8,0,-11,0,25));
     2143  if (expected!=obtained)
     2144  {
     2145    print("Test 4 for Min failed.");
     2146    print("Expected:\n");
     2147    print(expected);
     2148    print("obtained:\n");
     2149    print(obtained);
     2150    result = 0;
     2151  }
     2152  return(result);
     2153}//Testing Min
     2154
     2155
     2156static proc isListEqual(list l1, list l2)
     2157"USAGE: isListEq(l1,l2); l1 and l2 are arbitrary lists.
     2158PURPOSE: returns if l1 and l2 contain the same elements
     2159ASSUME: every non-list element in l1 and l2 can be compared with the
     2160== operator
     2161"{
     2162  if (size(l1)!=size(l2))
     2163  {return(0);}
     2164  int i;
     2165  for (i = 1; i<=size(l1);i++)
     2166  {
     2167    if (typeof(l1[i])!=typeof(l2[i]))
     2168    { return (0); }
     2169    if (typeof(l1[i])=="list")
     2170    {
     2171      if (!isListEqual(l1[i],l2[i]))
     2172      {
     2173    return(0);
     2174      }
     2175    }
     2176    else
     2177    {
     2178      if (l1[i]!=l2[i])
     2179      {return(0);}
     2180    }
     2181  }
     2182  return(1);
     2183}
     2184
     2185static proc test_isListEqual()
     2186{
     2187  int result = 1;
     2188  //Test 1: empty list and empty list
     2189  int expected = 1;
     2190  list input1 = list();
     2191  list input2 = list();
     2192  int obtained = isListEqual(input1,input2);
     2193  if (expected !=obtained)
     2194  {
     2195    print("Test 1 for isListEqual failed.");
     2196    print("Expected:\n");
     2197    print(expected);
     2198    print("obtained:\n");
     2199    print(obtained);
     2200    result = 0;
     2201  }
     2202  //Test 2: empty list and non-empty list
     2203  expected = 0;
     2204  input1 = list();
     2205  input2 = list(list(),1,3,4);
     2206  obtained = isListEqual(input1,input2);
     2207  if (expected !=obtained)
     2208  {
     2209    print("Test 2 for isListEqual failed.");
     2210    print("Expected:\n");
     2211    print(expected);
     2212    print("obtained:\n");
     2213    print(obtained);
     2214    result = 0;
     2215  }
     2216  //Test 3: non-empty list and empty list
     2217  expected = 0;
     2218  input2 = list();
     2219  input1 = list(list(),1,3,4);
     2220  obtained = isListEqual(input1,input2);
     2221  if (expected !=obtained)
     2222  {
     2223    print("Test 3 for isListEqual failed.");
     2224    print("Expected:\n");
     2225    print(expected);
     2226    print("obtained:\n");
     2227    print(obtained);
     2228    result = 0;
     2229  }
     2230  //Test 4: lists with entries of the same type, equal
     2231  expected = 1;
     2232  input1 = list(1,2,3,4);
     2233  input2 = list(1,2,3,4);
     2234  obtained = isListEqual(input1,input2);
     2235  if (expected !=obtained)
     2236  {
     2237    print("Test 4 for isListEqual failed.");
     2238    print("Expected:\n");
     2239    print(expected);
     2240    print("obtained:\n");
     2241    print(obtained);
     2242    result = 0;
     2243  }
     2244  //Test 5: lists with entries of the same type, not equal
     2245  expected = 0;
     2246  input1 = list(4,3,2,1);
     2247  input2 = list(1,2,3,4);
     2248  obtained = isListEqual(input1,input2);
     2249  if (expected !=obtained)
     2250  {
     2251    print("Test 5 for isListEqual failed.");
     2252    print("Expected:\n");
     2253    print(expected);
     2254    print("obtained:\n");
     2255    print(obtained);
     2256    result = 0;
     2257  }
     2258  //Test 6: lists with entries of the different types, equal
     2259  expected = 1;
     2260  input1 = list(4,intvec(3,2),list(list()),1);
     2261  input2 = list(4,intvec(3,2),list(list()),1);
     2262  obtained = isListEqual(input1,input2);
     2263  if (expected !=obtained)
     2264  {
     2265    print("Test 6 for isListEqual failed.");
     2266    print("Expected:\n");
     2267    print(expected);
     2268    print("obtained:\n");
     2269    print(obtained);
     2270    result = 0;
     2271  }
     2272  //Test 7: lists with entries of the different types, not equal
     2273  expected = 0;
     2274  input1 = list(4,intvec(3,2),list(),1);
     2275  input2 = list(4,intvec(3,2),list(list()),1);
     2276  obtained = isListEqual(input1,input2);
     2277  if (expected !=obtained)
     2278  {
     2279    print("Test 7 for isListEqual failed.");
     2280    print("Expected:\n");
     2281    print(expected);
     2282    print("obtained:\n");
     2283    print(obtained);
     2284    result = 0;
     2285  }
     2286  return(result);
     2287}
     2288
     2289//////////////////////////////////////////////////
     2290//*********RING HANDLING HELPER FUNCTIONS*********
     2291//////////////////////////////////////////////////
     2292
    1082293static proc ncfactor_isWeyl()
    1092294"
     
    1852370}//ncfactor_isWeyl
    1862371
    187 //==================================================
     2372
     2373static proc test_ncfactor_isWeyl()
     2374{//testing ncfactor_isWeyl
     2375  int result = 1;
     2376  int i; int j; int k;
     2377  //Test 1: first Weyl algebra, x before d
     2378  ring R = 0,(x,d),dp;
     2379  def r = nc_algebra(1,1);
     2380  setring(r);
     2381  int expected = 1;
     2382  int obtained = ncfactor_isWeyl();
     2383  if (expected !=obtained)
     2384  {
     2385    print("Test 1 for ncfactor_isWeyl failed.");
     2386    print("Expected:\n");
     2387    print(expected);
     2388    print("obtained:\n");
     2389    print(obtained);
     2390    result = 0;
     2391  }
     2392  //Test 2: first Weyl algebra, d before x
     2393  ring R2 = 0,(x,d),dp;
     2394  def r2 = nc_algebra(1,-1);
     2395  setring(r);
     2396  expected = 1;
     2397  obtained = ncfactor_isWeyl();
     2398  if (expected !=obtained)
     2399  {
     2400    print("Test 2 for ncfactor_isWeyl failed.");
     2401    print("Expected:\n");
     2402    print(expected);
     2403    print("obtained:\n");
     2404    print(obtained);
     2405    result = 0;
     2406  }
     2407  //Test 3: All possibilities for third Weyl algebra
     2408  list perms =list(list(list(1,0,0,0,0,0),
     2409            list(0,1,0,0,0,0),
     2410            list(0,0,1,0,0,0)),
     2411           list(list(1,0,0,0,0,0),
     2412            list(0,0,1,0,0,0),
     2413            list(0,1,0,0,0,0)),
     2414           list(list(0,1,0,0,0,0),
     2415            list(1,0,0,0,0,0),
     2416            list(0,0,1,0,0,0)),
     2417           list(list(0,1,0,0,0,0),
     2418            list(0,0,1,0,0,0),
     2419            list(1,0,0,0,0,0)),
     2420           list(list(0,0,1,0,0,0),
     2421            list(0,1,0,0,0,0),
     2422            list(1,0,0,0,0,0)),
     2423           list(list(0,0,1,0,0,0),
     2424            list(1,0,0,0,0,0),
     2425            list(0,1,0,0,0,0)));
     2426  for(i=1;i<=size(perms);i++)
     2427  {
     2428    ring R3 = 0,(x,y,z,w,v,u),dp;
     2429    matrix C[6][6] = 1,1,1,1,1,1,
     2430      1,1,1,1,1,1,
     2431      1,1,1,1,1,1,
     2432      1,1,1,1,1,1,
     2433      1,1,1,1,1,1,
     2434      1,1,1,1,1,1;
     2435    matrix D[6][6];
     2436    for (j=1;j<=size(perms[i]);j++)
     2437    {
     2438      for (k=1;k<=size(perms[i][j]);k++)
     2439      {
     2440    D[k,3+j]=perms[i][j][k];
     2441      }
     2442    }
     2443    def r3 = nc_algebra(C,D);
     2444    setring(r3);
     2445    expected = 1;
     2446    obtained = ncfactor_isWeyl();
     2447    if (expected !=obtained)
     2448    {
     2449      print("Test 3 for ncfactor_isWeyl failed.");
     2450      print("Expected:\n");
     2451      print(expected);
     2452      print("obtained:\n");
     2453      print(obtained);
     2454      result = 0;
     2455    }
     2456    kill r3;
     2457    kill R3;
     2458  }
     2459  //Test 4: All possibilities for third Weyl algebra reversed
     2460  kill perms;
     2461  list perms =list(list(list(-1,0,0,0,0,0),
     2462            list(0,-1,0,0,0,0),
     2463            list(0,0,-1,0,0,0)),
     2464           list(list(-1,0,0,0,0,0),
     2465            list(0,0,-1,0,0,0),
     2466            list(0,-1,0,0,0,0)),
     2467           list(list(0,-1,0,0,0,0),
     2468            list(-1,0,0,0,0,0),
     2469            list(0,0,-1,0,0,0)),
     2470           list(list(0,-1,0,0,0,0),
     2471            list(0,0,-1,0,0,0),
     2472            list(-1,0,0,0,0,0)),
     2473           list(list(0,0,-1,0,0,0),
     2474            list(0,-1,0,0,0,0),
     2475            list(-1,0,0,0,0,0)),
     2476           list(list(0,0,-1,0,0,0),
     2477            list(-1,0,0,0,0,0),
     2478            list(0,-1,0,0,0,0)));
     2479  for(i=1;i<=size(perms);i++)
     2480  {
     2481    ring R3 = 0,(x,y,z,w,v,u),dp;
     2482    matrix C[6][6] = 1,1,1,1,1,1,
     2483      1,1,1,1,1,1,
     2484      1,1,1,1,1,1,
     2485      1,1,1,1,1,1,
     2486      1,1,1,1,1,1,
     2487      1,1,1,1,1,1;
     2488    matrix D[6][6];
     2489    for (j=1;j<=size(perms[i]);j++)
     2490    {
     2491      for (k=1;k<=size(perms[i][j]);k++)
     2492      {
     2493    D[k,3+j]=perms[i][j][k];
     2494      }
     2495    }
     2496    def r3 = nc_algebra(C,D);
     2497    setring(r3);
     2498    expected = 1;
     2499    obtained = ncfactor_isWeyl();
     2500    if (expected !=obtained)
     2501    {
     2502      print("Test 4 for ncfactor_isWeyl failed.");
     2503      print("Expected:\n");
     2504      print(expected);
     2505      print("obtained:\n");
     2506      print(obtained);
     2507      result = 0;
     2508    }
     2509    kill r3;
     2510    kill R3;
     2511  }
     2512  //Test 5: SubWeyl but not Weyl
     2513  ring R4 = 0,(x,y,z),dp;
     2514  matrix D[3][3] = 0,0,1,0,0,0,0,0,0;
     2515  matrix C[3][3] = 1,1,1,1,1,1,1,1,1;
     2516  def r4 = nc_algebra(C,D);
     2517  expected = 0;
     2518  obtained = ncfactor_isWeyl();
     2519  if (expected !=obtained)
     2520  {
     2521    print("Test 5 for ncfactor_isWeyl failed.");
     2522    print("Expected:\n");
     2523    print(expected);
     2524    print("obtained:\n");
     2525    print(obtained);
     2526    result = 0;
     2527  }
     2528  //Test 6: Commutative ring
     2529  ring R5 = 0,(x,d),dp;
     2530  expected = 0;
     2531  obtained = ncfactor_isWeyl();
     2532  if (expected !=obtained)
     2533  {
     2534    print("Test 6 for ncfactor_isWeyl failed.");
     2535    print("Expected:\n");
     2536    print(expected);
     2537    print("obtained:\n");
     2538    print(obtained);
     2539    result = 0;
     2540  }
     2541  //Test 7: q-Weyl algebra
     2542  ring R6 = (0,q),(x,d),dp;
     2543  def r6 = nc_algebra(q,1);
     2544  setring r6;
     2545  expected = 0;
     2546  obtained = ncfactor_isWeyl();
     2547  if (expected !=obtained)
     2548  {
     2549    print("Test 7 for ncfactor_isWeyl failed.");
     2550    print("Expected:\n");
     2551    print(expected);
     2552    print("obtained:\n");
     2553    print(obtained);
     2554    result = 0;
     2555  }
     2556  //Test 8: Weyl, but with parameter
     2557  ring R7 = (0,q),(x,d),dp;
     2558  def r7 = nc_algebra(1,1);
     2559  setring r7;
     2560  expected = 1;
     2561  obtained = ncfactor_isWeyl();
     2562  if (expected !=obtained)
     2563  {
     2564    print("Test 8 for ncfactor_isWeyl failed.");
     2565    print("Expected:\n");
     2566    print(expected);
     2567    print("obtained:\n");
     2568    print(obtained);
     2569    result = 0;
     2570  }
     2571  return(result);
     2572}//testing ncfactor_isWeyl
     2573
     2574
    1882575static proc ncfactor_isQWeyl()
    1892576"
    1902577INPUT: None
    191 OUTPUT: Returns 1 if the basering is a Weyl algebra,
     2578OUTPUT: Returns 1 if the basering is a q-Weyl algebra,
    1922579        0 otherwise.
     2580ASSUMPTIONS:
     2581- A q-Weyl algebra in this setup is an algebra that has
     2582  half as many parameters than variables, and the non-commutative
     2583  relations are strictly given by
     2584  x_id_i = q(i)*d_ix_i+1
    1932585"
    1942586{//ncfactor_isqWeyl
     
    2182610      {
    2192611        validentry = 0;
    220         for (k = 1; k<=npars(r); k++)
     2612        for (k = 1; k<=npars(basering); k++)
    2212613        {
    222           if (C[i,j]==par(k))
     2614          if (C[i,j]==par(k) || C[i,j]==1/par(k))
    2232615          {
    2242616            validentry = 1;
     
    2672659    for (i = 2; i<=size(the_vars); i++)
    2682660    {//Compare the commutation relations of the jth variable to the first one
    269       for (j = 1; j<=npars(basering);j++)
     2661      for (k = 1; k<= npars(basering); k++)
    2702662      {
    271         for (k = 1; k<= npars(basering); k++)
    272         {
    273           if (the_vars[1]*the_vars[i] - par(k)*the_vars[i]*the_vars[1] == 1 or
    274               par(k)*the_vars[1]*the_vars[i] - the_vars[i]*the_vars[1] == -1)
    275           {//Found a counter matching one
    276             noPairForFirstOne = 0;
    277             break;
    278           }//Found a counter matching one
    279         }
    280         if (noPairForFirstOne == 0)
    281         {
    282           break;
    283         }
     2663    if (the_vars[1]*the_vars[i] - 1/par(k)*the_vars[i]*the_vars[1] ==1 or
     2664        1/par(k)*the_vars[1]*the_vars[i] - the_vars[i]*the_vars[1]==1 or
     2665        the_vars[1]*the_vars[i] - par(k)*the_vars[i]*the_vars[1] ==-1 or
     2666        par(k)*the_vars[1]*the_vars[i] - the_vars[i]*the_vars[1]==-1)
     2667      {//Found a counter matching one
     2668      noPairForFirstOne = 0;
     2669      break;
     2670    }//Found a counter matching one
    2842671      }
    2852672      if(noPairForFirstOne==0)
     
    2962683}//ncfactor_isqWeyl
    2972684
    298 ////////////////////////////////////////////////////
    299 //==================================================
    300 ////////////////////////////////////////////////////
     2685
     2686static proc test_ncfactor_isQWeyl()
     2687{//testing ncfactor_isQWeyl
     2688  int result = 1;
     2689  int i; int j; int k;
     2690  //Test 1: first Weyl algebra, x before d
     2691  ring R = (0,q),(x,d),dp;
     2692  def r = nc_algebra(q,1);
     2693  setring(r);
     2694  int expected = 1;
     2695  int obtained = ncfactor_isQWeyl();
     2696  if (expected !=obtained)
     2697  {
     2698    print("Test 1 for ncfactor_isQWeyl failed.");
     2699    print("Expected:\n");
     2700    print(expected);
     2701    print("obtained:\n");
     2702    print(obtained);
     2703    result = 0;
     2704  }
     2705  //Test 2: first Weyl algebra, d before x
     2706  ring R2 = (0,q),(x,d),dp;
     2707  def r2 = nc_algebra(1/q,-1);
     2708  setring(r2);
     2709  expected = 1;
     2710  obtained = ncfactor_isQWeyl();
     2711  if (expected !=obtained)
     2712  {
     2713    print("Test 2 for ncfactor_isQWeyl failed.");
     2714    print("Expected:\n");
     2715    print(expected);
     2716    print("obtained:\n");
     2717    print(obtained);
     2718    result = 0;
     2719  }
     2720  //Test 3: All possibilities for third Weyl algebra
     2721  list perms =list(list(list(1,0,0,0,0,0),
     2722              list(0,1,0,0,0,0),
     2723              list(0,0,1,0,0,0)),
     2724             list(list(1,0,0,0,0,0),
     2725              list(0,0,1,0,0,0),
     2726              list(0,1,0,0,0,0)),
     2727             list(list(0,1,0,0,0,0),
     2728              list(1,0,0,0,0,0),
     2729              list(0,0,1,0,0,0)),
     2730             list(list(0,1,0,0,0,0),
     2731              list(0,0,1,0,0,0),
     2732              list(1,0,0,0,0,0)),
     2733             list(list(0,0,1,0,0,0),
     2734              list(0,1,0,0,0,0),
     2735              list(1,0,0,0,0,0)),
     2736             list(list(0,0,1,0,0,0),
     2737              list(1,0,0,0,0,0),
     2738              list(0,1,0,0,0,0)));
     2739  for(i=1;i<=size(perms);i++)
     2740  {
     2741    ring R3 = (0,q(1..3)),(x,y,z,w,v,u),dp;
     2742    matrix D[6][6];
     2743    for (j=1;j<=size(perms[i]);j++)
     2744    {
     2745      for (k=1;k<=size(perms[i][j]);k++)
     2746      {
     2747      D[k,3+j]=perms[i][j][k];
     2748      }
     2749    }
     2750    matrix C[6][6] = 1,1,1,1,1,1,
     2751      1,1,1,1,1,1,
     2752      1,1,1,1,1,1,
     2753      1,1,1,1,1,1,
     2754      1,1,1,1,1,1,
     2755      1,1,1,1,1,1;
     2756    for (j=1;j<=size(perms[i]);j++)
     2757    {
     2758      for (k=1;k<=size(perms[i][j]);k++)
     2759      {
     2760      if(perms[i][j][k]==1)
     2761      {
     2762        C[k,3+j]=q(j);
     2763      }
     2764      }
     2765    }
     2766    def r3 = nc_algebra(C,D);
     2767    setring(r3);
     2768    expected = 1;
     2769    obtained = ncfactor_isQWeyl();
     2770    if (expected !=obtained)
     2771    {
     2772      print("Test 3 for ncfactor_isQWeyl failed. Basering:");
     2773      basering;
     2774      print("Expected:\n");
     2775      print(expected);
     2776      print("obtained:\n");
     2777      print(obtained);
     2778      result = 0;
     2779    }
     2780    kill r3;
     2781    kill R3;
     2782  }
     2783  //Test 4: All possibilities for third Weyl algebra reversed
     2784  kill perms;
     2785  list perms =list(list(list(-1,0,0,0,0,0),
     2786              list(0,-1,0,0,0,0),
     2787              list(0,0,-1,0,0,0)),
     2788             list(list(-1,0,0,0,0,0),
     2789              list(0,0,-1,0,0,0),
     2790              list(0,-1,0,0,0,0)),
     2791             list(list(0,-1,0,0,0,0),
     2792              list(-1,0,0,0,0,0),
     2793              list(0,0,-1,0,0,0)),
     2794             list(list(0,-1,0,0,0,0),
     2795              list(0,0,-1,0,0,0),
     2796              list(-1,0,0,0,0,0)),
     2797             list(list(0,0,-1,0,0,0),
     2798              list(0,-1,0,0,0,0),
     2799              list(-1,0,0,0,0,0)),
     2800             list(list(0,0,-1,0,0,0),
     2801              list(-1,0,0,0,0,0),
     2802              list(0,-1,0,0,0,0)));
     2803  for(i=1;i<=size(perms);i++)
     2804  {
     2805    ring R3 = (0,q(1..3)),(x,y,z,w,v,u),dp;
     2806    matrix D[6][6];
     2807    matrix C[6][6] = 1,1,1,1,1,1,
     2808      1,1,1,1,1,1,
     2809      1,1,1,1,1,1,
     2810      1,1,1,1,1,1,
     2811      1,1,1,1,1,1,
     2812      1,1,1,1,1,1;
     2813    for (j=1;j<=size(perms[i]);j++)
     2814    {
     2815      for (k=1;k<=size(perms[i][j]);k++)
     2816      {
     2817      if(perms[i][j][k]==-1)
     2818      {
     2819        C[k,3+j]=1/q(j);
     2820      }
     2821      }
     2822    }
     2823    for (j=1;j<=size(perms[i]);j++)
     2824    {
     2825      for (k=1;k<=size(perms[i][j]);k++)
     2826      {
     2827      D[k,3+j]=perms[i][j][k];
     2828      }
     2829    }
     2830    def r3 = nc_algebra(C,D);
     2831    setring(r3);
     2832    expected = 1;
     2833    obtained = ncfactor_isQWeyl();
     2834    if (expected !=obtained)
     2835    {
     2836      print("Test 4 for ncfactor_isQWeyl failed. Basering:");
     2837      basering;
     2838      print("Expected:\n");
     2839      print(expected);
     2840      print("obtained:\n");
     2841      print(obtained);
     2842      result = 0;
     2843    }
     2844    kill r3;
     2845    kill R3;
     2846  }
     2847  //Test 5: SubQWeyl but not Weyl
     2848  ring R4 = (0,q),(x,y,z),dp;
     2849  matrix D[3][3] = 0,0,1,0,0,0,0,0,0;
     2850  matrix C[3][3] = 1,1,q,1,1,1,1,1,1;
     2851  def r4 = nc_algebra(C,D);
     2852  expected = 0;
     2853  obtained = ncfactor_isQWeyl();
     2854  if (expected !=obtained)
     2855  {
     2856    print("Test 5 for ncfactor_isQWeyl failed.");
     2857    print("Expected:\n");
     2858    print(expected);
     2859    print("obtained:\n");
     2860    print(obtained);
     2861    result = 0;
     2862  }
     2863  //Test 6: Commutative ring
     2864  ring R5 = 0,(x,d),dp;
     2865  expected = 0;
     2866  obtained = ncfactor_isQWeyl();
     2867  if (expected !=obtained)
     2868  {
     2869    print("Test 6 for ncfactor_isQWeyl failed.");
     2870    print("Expected:\n");
     2871    print(expected);
     2872    print("obtained:\n");
     2873    print(obtained);
     2874    result = 0;
     2875  }
     2876  //Test 7: Weyl algebra
     2877  ring R6 = 0,(x,d),dp;
     2878  def r6 = nc_algebra(1,1);
     2879  setring r6;
     2880  expected = 0;
     2881  obtained = ncfactor_isQWeyl();
     2882  if (expected !=obtained)
     2883  {
     2884    print("Test 7 for ncfactor_isQWeyl failed.");
     2885    print("Expected:\n");
     2886    print(expected);
     2887    print("obtained:\n");
     2888    print(obtained);
     2889    result = 0;
     2890  }
     2891  //Test 8: q-Weyl, but with extra parameter
     2892  ring R7 = (0,q,q2),(x,d),dp;
     2893  def r7 = nc_algebra(q,1);
     2894  setring r7;
     2895  expected = 1;
     2896  obtained = ncfactor_isQWeyl();
     2897  if (expected !=obtained)
     2898  {
     2899    print("Test 8 for ncfactor_isQWeyl failed.");
     2900    print("Expected:\n");
     2901    print(expected);
     2902    print("obtained:\n");
     2903    print(obtained);
     2904    result = 0;
     2905  }
     2906  return(result);
     2907}//testing ncfactor_isQWeyl
     2908
    3012909
    3022910static proc ncfactor_isShift()
     
    3292937    }//Iterating the off-diagonal
    3302938  }//Iterating the diagonal
    331 
    3322939  //Checking if D is okay
    3332940  int countOperators;
     
    4183025}//ncfactor_isShift
    4193026
    420 //==================================================
     3027
     3028static proc test_ncfactor_isShift()
     3029{//testing ncfactor_isShift
     3030  int result = 1;
     3031  int i; int j; int k;
     3032  //Test 1: Shift with no surprises
     3033  ring R = 0,(n,s),dp;
     3034  def r = nc_algebra(1,s);
     3035  setring r;
     3036  int expected = 1;
     3037  int obtained = ncfactor_isShift();
     3038  if (expected !=obtained)
     3039  {
     3040    print("Test 1 for ncfactor_isShift failed.");
     3041    print("Expected:\n");
     3042    print(expected);
     3043    print("obtained:\n");
     3044    print(obtained);
     3045    result = 0;
     3046  }
     3047  kill R;
     3048  kill r;
     3049  //Test 2: Shift with reversed parameters
     3050  ring R = 0,(n,s),dp;
     3051  def r = nc_algebra(1,-n);
     3052  setring r;
     3053  expected = 1;
     3054  obtained = ncfactor_isShift();
     3055  if (expected !=obtained)
     3056  {
     3057    print("Test 2 for ncfactor_isShift failed.");
     3058    print("Expected:\n");
     3059    print(expected);
     3060    print("obtained:\n");
     3061    print(obtained);
     3062    result = 0;
     3063  }
     3064  kill R; kill r;
     3065  //Test 3: All possibilities of the third shift algebra.
     3066  for(i=1;i<=6;i++)
     3067  {
     3068    ring R3 = 0,(x,y,z,s1,s2,s3),dp;
     3069    matrix D[6][6];
     3070    list perms = list(list(list(s1,0,0,0,0,0),
     3071              list(0,s2,0,0,0,0),
     3072              list(0,0,s3,0,0,0)),
     3073             list(list(s1,0,0,0,0,0),
     3074              list(0,0,s2,0,0,0),
     3075              list(0,s3,0,0,0,0)),
     3076             list(list(0,s1,0,0,0,0),
     3077              list(s2,0,0,0,0,0),
     3078              list(0,0,s3,0,0,0)),
     3079             list(list(0,s1,0,0,0,0),
     3080              list(0,0,s2,0,0,0),
     3081              list(s3,0,0,0,0,0)),
     3082             list(list(0,0,s1,0,0,0),
     3083              list(0,s2,0,0,0,0),
     3084              list(s3,0,0,0,0,0)),
     3085             list(list(0,0,s1,0,0,0),
     3086              list(s2,0,0,0,0,0),
     3087              list(0,s3,0,0,0,0)));
     3088    for (j=1;j<=size(perms[i]);j++)
     3089    {
     3090      for (k=1;k<=size(perms[i][j]);k++)
     3091      {
     3092      D[k,3+j]=perms[i][j][k];
     3093      }
     3094    }
     3095    matrix C[6][6] = 1,1,1,1,1,1,
     3096      1,1,1,1,1,1,
     3097      1,1,1,1,1,1,
     3098      1,1,1,1,1,1,
     3099      1,1,1,1,1,1,
     3100      1,1,1,1,1,1;
     3101    def r3 = nc_algebra(C,D);
     3102    setring(r3);
     3103    expected = 1;
     3104    obtained = ncfactor_isShift();
     3105    if (expected !=obtained)
     3106    {
     3107      print("Test 3 for ncfactor_isShift failed. Basering:");
     3108      basering;
     3109      print("Expected:\n");
     3110      print(expected);
     3111      print("obtained:\n");
     3112      print(obtained);
     3113      result = 0;
     3114    }
     3115    kill r3;
     3116    kill R3;
     3117  }
     3118  //test 4: All possibilities for third shift algebra with reversed parameters.
     3119  for(i=1;i<=6;i++)
     3120  {
     3121    ring R3 = 0,(x,y,z,s1,s2,s3),dp;
     3122    matrix D[6][6];
     3123    list perms = list(list(list(-x,0,0,0,0,0),
     3124              list(0,-y,0,0,0,0),
     3125              list(0,0,-z,0,0,0)),
     3126             list(list(-x,0,0,0,0,0),
     3127              list(0,0,-z,0,0,0),
     3128              list(0,-y,0,0,0,0)),
     3129             list(list(0,-y,0,0,0,0),
     3130              list(-x,0,0,0,0,0),
     3131              list(0,0,-z,0,0,0)),
     3132             list(list(0,-y,0,0,0,0),
     3133              list(0,0,-z,0,0,0),
     3134              list(-x,0,0,0,0,0)),
     3135             list(list(0,0,-z,0,0,0),
     3136              list(0,-y,0,0,0,0),
     3137              list(-x,0,0,0,0,0)),
     3138             list(list(0,0,-z,0,0,0),
     3139              list(-x,0,0,0,0,0),
     3140              list(0,-y,0,0,0,0)));
     3141    for (j=1;j<=size(perms[i]);j++)
     3142    {
     3143      for (k=1;k<=size(perms[i][j]);k++)
     3144      {
     3145      D[k,3+j]=perms[i][j][k];
     3146      }
     3147    }
     3148    matrix C[6][6] = 1,1,1,1,1,1,
     3149      1,1,1,1,1,1,
     3150      1,1,1,1,1,1,
     3151      1,1,1,1,1,1,
     3152      1,1,1,1,1,1,
     3153      1,1,1,1,1,1;
     3154    def r3 = nc_algebra(C,D);
     3155    setring(r3);
     3156    expected = 1;
     3157    obtained = ncfactor_isShift();
     3158    if (expected !=obtained)
     3159    {
     3160      print("Test 4 for ncfactor_isShift failed. Basering:");
     3161      basering;
     3162      print("Expected:\n");
     3163      print(expected);
     3164      print("obtained:\n");
     3165      print(obtained);
     3166      result = 0;
     3167    }
     3168    kill r3;
     3169    kill R3;
     3170  }
     3171  //Test 5: subshift, but not shift
     3172  ring R = 0,(x,y,z),dp;
     3173  matrix C[3][3] = 1,1,1,1,1,1,1,1,1;
     3174  matrix D[3][3] = 0,0,0,
     3175    0,0,z,
     3176    0,0,0;
     3177  def r = nc_algebra(C,D);
     3178  setring(r);
     3179  expected = 0;
     3180  obtained = ncfactor_isShift();
     3181  if (expected !=obtained)
     3182  {
     3183    print("Test 5 for ncfactor_isShift failed. Basering:");
     3184    basering;
     3185    print("Expected:\n");
     3186    print(expected);
     3187    print("obtained:\n");
     3188    print(obtained);
     3189    result = 0;
     3190  }
     3191  kill R; kill r;
     3192  //Test 6: Commutative ring
     3193  ring R = 0,(n,sn),dp;
     3194  expected = 0;
     3195  obtained = ncfactor_isShift();
     3196  if (expected !=obtained)
     3197  {
     3198    print("Test 6 for ncfactor_isShift failed. Basering:");
     3199    basering;
     3200    print("Expected:\n");
     3201    print(expected);
     3202    print("obtained:\n");
     3203    print(obtained);
     3204    result = 0;
     3205  }
     3206  kill R;
     3207  return(result);
     3208}//testing ncfactor_isShift
     3209
     3210
     3211static proc checkIfProperNthShift()
     3212"
     3213INPUT: None
     3214OUTPUT: Checks whether the given basering is a proper shift algebra.
     3215        Proper means in the sense of our algorithms, i.e. fulfilling
     3216        the assumption that our basering is the Nth shift algebra and
     3217        that the xs are the first n variables, the shift
     3218        operators are the last n. Returns 1 if proper, 0 otherwise.
     3219"
     3220{//checkIfProperNthShift
     3221  if (!ncfactor_isShift())
     3222  {return(0);}
     3223  int i;
     3224  for (i = 1; i<=nvars(basering) div 2; i++)
     3225  {
     3226    if (var(i + nvars(basering) div 2)*var(i)
     3227        - var(i)*var(i+nvars(basering) div 2)!=var(i+nvars(basering) div 2))
     3228    {
     3229      return(0);
     3230    }
     3231  }
     3232  return(1);
     3233}//checkIfProperNthShift
     3234
     3235
     3236static proc test_checkIfProperNthShift()
     3237{//testing checkIfProperNthShift
     3238  int result = 1;
     3239  int i; int j; int k;
     3240  //Test 1: Shift with no surprises
     3241  ring R = 0,(n,s),dp;
     3242  def r = nc_algebra(1,s);
     3243  setring r;
     3244  int expected = 1;
     3245  int obtained = checkIfProperNthShift();
     3246  if (expected !=obtained)
     3247  {
     3248    print("Test 1 for checkIfProperNthShift failed.");
     3249    print("Expected:\n");
     3250    print(expected);
     3251    print("obtained:\n");
     3252    print(obtained);
     3253    result = 0;
     3254  }
     3255  kill R;
     3256  kill r;
     3257  //Test 2: Shift with reversed parameters
     3258  ring R = 0,(n,s),dp;
     3259  def r = nc_algebra(1,-n);
     3260  setring r;
     3261  expected = 0;
     3262  obtained = checkIfProperNthShift();
     3263  if (expected !=obtained)
     3264  {
     3265    print("Test 2 for checkIfProperNthShift failed.");
     3266    print("Expected:\n");
     3267    print(expected);
     3268    print("obtained:\n");
     3269    print(obtained);
     3270    result = 0;
     3271  }
     3272  kill R; kill r;
     3273  //Test 3: All possibilities of the third shift algebra, that are not
     3274  //valid.
     3275  for(i=1;i<=5;i++)
     3276  {
     3277    ring R3 = 0,(x,y,z,s1,s2,s3),dp;
     3278    matrix D[6][6];
     3279    list perms = list(list(list(s1,0,0,0,0,0),
     3280              list(0,0,s2,0,0,0),
     3281              list(0,s3,0,0,0,0)),
     3282             list(list(0,s1,0,0,0,0),
     3283              list(s2,0,0,0,0,0),
     3284              list(0,0,s3,0,0,0)),
     3285             list(list(0,s1,0,0,0,0),
     3286              list(0,0,s2,0,0,0),
     3287              list(s3,0,0,0,0,0)),
     3288             list(list(0,0,s1,0,0,0),
     3289              list(0,s2,0,0,0,0),
     3290              list(s3,0,0,0,0,0)),
     3291             list(list(0,0,s1,0,0,0),
     3292              list(s2,0,0,0,0,0),
     3293              list(0,s3,0,0,0,0)));
     3294    for (j=1;j<=size(perms[i]);j++)
     3295    {
     3296      for (k=1;k<=size(perms[i][j]);k++)
     3297      {
     3298      D[k,3+j]=perms[i][j][k];
     3299      }
     3300    }
     3301    matrix C[6][6] = 1,1,1,1,1,1,
     3302      1,1,1,1,1,1,
     3303      1,1,1,1,1,1,
     3304      1,1,1,1,1,1,
     3305      1,1,1,1,1,1,
     3306      1,1,1,1,1,1;
     3307    def r3 = nc_algebra(C,D);
     3308    setring(r3);
     3309    expected = 0;
     3310    obtained = checkIfProperNthShift();
     3311    if (expected !=obtained)
     3312    {
     3313      print("Test 3 for checkIfProperNthShift failed. Basering:");
     3314      basering;
     3315      print("Expected:\n");
     3316      print(expected);
     3317      print("obtained:\n");
     3318      print(obtained);
     3319      result = 0;
     3320    }
     3321    kill r3;
     3322    kill R3;
     3323  }
     3324  //test 4: All possibilities for third shift algebra with reversed parameters.
     3325  for(i=1;i<=6;i++)
     3326  {
     3327    ring R3 = 0,(x,y,z,s1,s2,s3),dp;
     3328    matrix D[6][6];
     3329    list perms = list(list(list(-x,0,0,0,0,0),
     3330              list(0,-y,0,0,0,0),
     3331              list(0,0,-z,0,0,0)),
     3332             list(list(-x,0,0,0,0,0),
     3333              list(0,0,-z,0,0,0),
     3334              list(0,-y,0,0,0,0)),
     3335             list(list(0,-y,0,0,0,0),
     3336              list(-x,0,0,0,0,0),
     3337              list(0,0,-z,0,0,0)),
     3338             list(list(0,-y,0,0,0,0),
     3339              list(0,0,-z,0,0,0),
     3340              list(-x,0,0,0,0,0)),
     3341             list(list(0,0,-z,0,0,0),
     3342              list(0,-y,0,0,0,0),
     3343              list(-x,0,0,0,0,0)),
     3344             list(list(0,0,-z,0,0,0),
     3345              list(-x,0,0,0,0,0),
     3346              list(0,-y,0,0,0,0)));
     3347    for (j=1;j<=size(perms[i]);j++)
     3348    {
     3349      for (k=1;k<=size(perms[i][j]);k++)
     3350      {
     3351      D[k,3+j]=perms[i][j][k];
     3352      }
     3353    }
     3354    matrix C[6][6] = 1,1,1,1,1,1,
     3355      1,1,1,1,1,1,
     3356      1,1,1,1,1,1,
     3357      1,1,1,1,1,1,
     3358      1,1,1,1,1,1,
     3359      1,1,1,1,1,1;
     3360    def r3 = nc_algebra(C,D);
     3361    setring(r3);
     3362    expected = 0;
     3363    obtained = checkIfProperNthShift();
     3364    if (expected !=obtained)
     3365    {
     3366      print("Test 4 for checkIfProperNthShift failed. Basering:");
     3367      basering;
     3368      print("Expected:\n");
     3369      print(expected);
     3370      print("obtained:\n");
     3371      print(obtained);
     3372      result = 0;
     3373    }
     3374    kill r3;
     3375    kill R3;
     3376  }
     3377  //Test 5: commutative ring
     3378  ring R = 0,(n,s),lp;
     3379  expected = 0;
     3380  obtained = checkIfProperNthShift();
     3381  if (expected !=obtained)
     3382  {
     3383    print("Test 5 for checkIfProperNthShift failed. Basering:");
     3384    basering;
     3385    print("Expected:\n");
     3386    print(expected);
     3387    print("obtained:\n");
     3388    print(obtained);
     3389    result = 0;
     3390  }
     3391  kill R;
     3392  //Test 6: Proper 3rd shift algebra
     3393  ring R = 0,(n1,n2,n3,s1,s2,s3),lp;
     3394  matrix C[6][6] = 1,1,1,1,1,1,
     3395    1,1,1,1,1,1,
     3396    1,1,1,1,1,1,
     3397    1,1,1,1,1,1,
     3398    1,1,1,1,1,1,
     3399    1,1,1,1,1,1;
     3400  matrix D[6][6] = 0,0,0,s1,0,0,
     3401    0,0,0,0,s2,0,
     3402    0,0,0,0,0,s3;
     3403  def r = nc_algebra(C,D);
     3404  setring r;
     3405  expected = 1;
     3406  obtained = checkIfProperNthShift();
     3407  if (expected !=obtained)
     3408  {
     3409    print("Test 6 for checkIfProperNthShift failed. Basering:");
     3410    basering;
     3411    print("Expected:\n");
     3412    print(expected);
     3413    print("obtained:\n");
     3414    print(obtained);
     3415    result = 0;
     3416  }
     3417  kill R; kill r;
     3418  return(result);
     3419}//testing checkIfProperNthShift
     3420
     3421
     3422static proc checkIfProperNthWeyl()
     3423"
     3424INPUT: None
     3425OUTPUT: Checks whether the given basering is a proper Weyl algebra.
     3426        Proper means in the sense of our algorithms, i.e. fulfilling
     3427        the assumption that o ur basering is the Nth Weyl algebra and
     3428        that the xs are the first n variables, the differential
     3429        operators are the last n. Returns 1 if proper, 0 otherwise.
     3430"
     3431{//checkIfProperNthWeyl
     3432  if (!ncfactor_isWeyl())
     3433  {return(0);}
     3434  int i;
     3435  for (i = 1; i<=nvars(basering) div 2; i++)
     3436  {
     3437    if (var(i + nvars(basering) div 2)*var(i)
     3438        - var(i)*var(i+nvars(basering) div 2)!=1)
     3439    {
     3440      return(0);
     3441    }
     3442  }
     3443  return(1);
     3444}//checkIfProperNthWeyl
     3445
     3446
     3447static proc test_checkIfProperNthWeyl()
     3448{//testing checkIfProperNthWeyl
     3449  int result = 1; int i; int j; int k;
     3450  //Test 1: proper 1st Weyl
     3451  ring R = 0,(x,y),dp;
     3452  def r= nc_algebra(1,1);
     3453  setring r;
     3454  int expected = 1;
     3455  int obtained = checkIfProperNthWeyl();
     3456  if (expected !=obtained)
     3457  {
     3458    print("Test 1 for checkIfProperNthWeyl failed. Basering:");
     3459    basering;
     3460    print("Expected:\n");
     3461    print(expected);
     3462    print("obtained:\n");
     3463    print(obtained);
     3464    result = 0;
     3465  }
     3466  kill R; kill r;
     3467  //Test 2: non proper 1st Weyl
     3468  ring R = 0,(x,y),dp;
     3469  def r= nc_algebra(1,-1);
     3470  setring r;
     3471  expected = 0;
     3472  obtained = checkIfProperNthWeyl();
     3473  if (expected !=obtained)
     3474  {
     3475    print("Test 2 for checkIfProperNthWeyl failed. Basering:");
     3476    basering;
     3477    print("Expected:\n");
     3478    print(expected);
     3479    print("obtained:\n");
     3480    print(obtained);
     3481    result = 0;
     3482  }
     3483  kill R; kill r;
     3484  //Test 3: All possible non-proper third Weyls
     3485  list perms =list(list(list(1,0,0,0,0,0),
     3486            list(0,0,1,0,0,0),
     3487            list(0,1,0,0,0,0)),
     3488           list(list(0,1,0,0,0,0),
     3489            list(1,0,0,0,0,0),
     3490            list(0,0,1,0,0,0)),
     3491           list(list(0,1,0,0,0,0),
     3492            list(0,0,1,0,0,0),
     3493            list(1,0,0,0,0,0)),
     3494           list(list(0,0,1,0,0,0),
     3495            list(0,1,0,0,0,0),
     3496            list(1,0,0,0,0,0)),
     3497           list(list(0,0,1,0,0,0),
     3498            list(1,0,0,0,0,0),
     3499            list(0,1,0,0,0,0)));
     3500  for(i=1;i<=size(perms);i++)
     3501  {
     3502    ring R3 = 0,(x,y,z,w,v,u),dp;
     3503    matrix C[6][6] = 1,1,1,1,1,1,
     3504      1,1,1,1,1,1,
     3505      1,1,1,1,1,1,
     3506      1,1,1,1,1,1,
     3507      1,1,1,1,1,1,
     3508      1,1,1,1,1,1;
     3509    matrix D[6][6];
     3510    for (j=1;j<=size(perms[i]);j++)
     3511    {
     3512      for (k=1;k<=size(perms[i][j]);k++)
     3513      {
     3514    D[k,3+j]=perms[i][j][k];
     3515      }
     3516    }
     3517    def r3 = nc_algebra(C,D);
     3518    setring(r3);
     3519    expected = 0;
     3520    obtained = checkIfProperNthWeyl();
     3521    if (expected !=obtained)
     3522    {
     3523      print("Test 3 for checkIfProperNthWeyl failed.");
     3524      print("Expected:\n");
     3525      print(expected);
     3526      print("obtained:\n");
     3527      print(obtained);
     3528      result = 0;
     3529    }
     3530    kill r3;
     3531    kill R3;
     3532  }
     3533  //Test 4: All reversed possibilities for the 3rd weyl algebra
     3534  kill perms;
     3535  list perms =list(list(list(-1,0,0,0,0,0),
     3536            list(0,-1,0,0,0,0),
     3537            list(0,0,-1,0,0,0)),
     3538           list(list(-1,0,0,0,0,0),
     3539            list(0,0,-1,0,0,0),
     3540            list(0,-1,0,0,0,0)),
     3541           list(list(0,-1,0,0,0,0),
     3542            list(-1,0,0,0,0,0),
     3543            list(0,0,-1,0,0,0)),
     3544           list(list(0,-1,0,0,0,0),
     3545            list(0,0,-1,0,0,0),
     3546            list(-1,0,0,0,0,0)),
     3547           list(list(0,0,-1,0,0,0),
     3548            list(0,-1,0,0,0,0),
     3549            list(-1,0,0,0,0,0)),
     3550           list(list(0,0,-1,0,0,0),
     3551            list(-1,0,0,0,0,0),
     3552            list(0,-1,0,0,0,0)));
     3553  for(i=1;i<=size(perms);i++)
     3554  {
     3555    ring R3 = 0,(x,y,z,w,v,u),dp;
     3556    matrix C[6][6] = 1,1,1,1,1,1,
     3557      1,1,1,1,1,1,
     3558      1,1,1,1,1,1,
     3559      1,1,1,1,1,1,
     3560      1,1,1,1,1,1,
     3561      1,1,1,1,1,1;
     3562    matrix D[6][6];
     3563    for (j=1;j<=size(perms[i]);j++)
     3564    {
     3565      for (k=1;k<=size(perms[i][j]);k++)
     3566      {
     3567    D[k,3+j]=perms[i][j][k];
     3568      }
     3569    }
     3570    def r3 = nc_algebra(C,D);
     3571    setring(r3);
     3572    expected = 0;
     3573    obtained = checkIfProperNthWeyl();
     3574    if (expected !=obtained)
     3575    {
     3576      print("Test 4 for checkIfProperNthWeyl failed.");
     3577      print("Expected:\n");
     3578      print(expected);
     3579      print("obtained:\n");
     3580      print(obtained);
     3581      result = 0;
     3582    }
     3583    kill r3;
     3584    kill R3;
     3585  }
     3586  //Test 5: Proper third Weyl algebra
     3587  ring R = 0,(x1,x2,x3,d1,d2,d3),dp;
     3588  matrix C[6][6] = 1,1,1,1,1,1,
     3589    1,1,1,1,1,1,
     3590    1,1,1,1,1,1,
     3591    1,1,1,1,1,1,
     3592    1,1,1,1,1,1,
     3593    1,1,1,1,1,1;
     3594  matrix D[6][6] = 0,0,0,1,0,0,
     3595    0,0,0,0,1,0,
     3596    0,0,0,0,0,1;
     3597  def r= nc_algebra(C,D);
     3598  setring r;
     3599  expected = 1;
     3600  obtained = checkIfProperNthWeyl();
     3601  if (expected !=obtained)
     3602  {
     3603    print("Test 5 for checkIfProperNthWeyl failed. Basering:");
     3604    basering;
     3605    print("Expected:\n");
     3606    print(expected);
     3607    print("obtained:\n");
     3608    print(obtained);
     3609    result = 0;
     3610  }
     3611  kill R; kill r;
     3612  //Test 6: Commutative ring
     3613  ring R = 0,(x1,x2,x3,d1,d2,d3),dp;
     3614  expected = 0;
     3615  obtained = checkIfProperNthWeyl();
     3616  if (expected !=obtained)
     3617  {
     3618    print("Test 6 for checkIfProperNthWeyl failed. Basering:");
     3619    basering;
     3620    print("Expected:\n");
     3621    print(expected);
     3622    print("obtained:\n");
     3623    print(obtained);
     3624    result = 0;
     3625  }
     3626  return(result);
     3627}//testing checkIfProperNthWeyl
     3628
     3629
     3630static proc checkIfProperNthQWeyl()
     3631"
     3632INPUT: None
     3633OUTPUT: Checks whether the given basering is a proper q-Weyl algebra.
     3634        Proper means in the sense of our algorithms, i.e. fulfilling
     3635        the assumption that o ur basering is the Nth Weyl algebra and
     3636        that the xs are the first n variables, the differential
     3637        operators are the last n. Returns 1 if proper, 0 otherwise.
     3638"
     3639{//checkIfProperNthQWeyl
     3640  if (!ncfactor_isQWeyl())
     3641  {return(0);}
     3642  int i;
     3643  for (i = 1; i<=nvars(basering) div 2; i++)
     3644  {
     3645    if (var(i + nvars(basering) div 2)*var(i)
     3646        - par(i)*var(i)*var(i+nvars(basering) div 2)!=1)
     3647    {
     3648      return(0);
     3649    }
     3650  }
     3651  return(1);
     3652}//checkIfProperNthQWeyl
     3653
     3654
     3655static proc test_checkIfProperNthQWeyl()
     3656{//testing checkIfProperNthQWeyl
     3657  int result = 1;
     3658  int i; int j; int k;
     3659  //Test 1: first Weyl algebra, x before d
     3660  ring R = (0,q),(x,d),dp;
     3661  def r = nc_algebra(q,1);
     3662  setring(r);
     3663  int expected = 1;
     3664  int obtained = checkIfProperNthQWeyl();
     3665  if (expected !=obtained)
     3666  {
     3667    print("Test 1 for checkIfProperNthQWeyl failed.");
     3668    print("Expected:\n");
     3669    print(expected);
     3670    print("obtained:\n");
     3671    print(obtained);
     3672    result = 0;
     3673  }
     3674  //Test 2: first Weyl algebra, d before x
     3675  ring R2 = (0,q),(x,d),dp;
     3676  def r2 = nc_algebra(q,-1);
     3677  setring(r2);
     3678  expected = 0;
     3679  obtained = checkIfProperNthQWeyl();
     3680  if (expected !=obtained)
     3681  {
     3682    print("Test 2 for checkIfProperNthQWeyl failed.");
     3683    print("Expected:\n");
     3684    print(expected);
     3685    print("obtained:\n");
     3686    print(obtained);
     3687    result = 0;
     3688  }
     3689  //Test 3: All possibilities for third Weyl algebra
     3690  list perms =list(list(list(1,0,0,0,0,0),
     3691              list(0,0,1,0,0,0),
     3692              list(0,1,0,0,0,0)),
     3693             list(list(0,1,0,0,0,0),
     3694              list(1,0,0,0,0,0),
     3695              list(0,0,1,0,0,0)),
     3696             list(list(0,1,0,0,0,0),
     3697              list(0,0,1,0,0,0),
     3698              list(1,0,0,0,0,0)),
     3699             list(list(0,0,1,0,0,0),
     3700              list(0,1,0,0,0,0),
     3701              list(1,0,0,0,0,0)),
     3702             list(list(0,0,1,0,0,0),
     3703              list(1,0,0,0,0,0),
     3704              list(0,1,0,0,0,0)));
     3705  for(i=1;i<=size(perms);i++)
     3706  {
     3707    ring R3 = (0,q(1..3)),(x,y,z,w,v,u),dp;
     3708    matrix D[6][6];
     3709    for (j=1;j<=size(perms[i]);j++)
     3710    {
     3711      for (k=1;k<=size(perms[i][j]);k++)
     3712      {
     3713      D[k,3+j]=perms[i][j][k];
     3714      }
     3715    }
     3716    matrix C[6][6] = 1,1,1,1,1,1,
     3717      1,1,1,1,1,1,
     3718      1,1,1,1,1,1,
     3719      1,1,1,1,1,1,
     3720      1,1,1,1,1,1,
     3721      1,1,1,1,1,1;
     3722    for (j=1;j<=size(perms[i]);j++)
     3723    {
     3724      for (k=1;k<=size(perms[i][j]);k++)
     3725      {
     3726      if(perms[i][j][k]==1)
     3727      {
     3728        C[k,3+j]=q(j);
     3729      }
     3730      }
     3731    }
     3732    def r3 = nc_algebra(C,D);
     3733    setring(r3);
     3734    expected = 0;
     3735    obtained = checkIfProperNthQWeyl();
     3736    if (expected !=obtained)
     3737    {
     3738      print("Test 3 for checkIfProperNthQWeyl failed. Basering:");
     3739      basering;
     3740      print("Expected:\n");
     3741      print(expected);
     3742      print("obtained:\n");
     3743      print(obtained);
     3744      result = 0;
     3745    }
     3746    kill r3;
     3747    kill R3;
     3748  }
     3749  //Test 4: All possibilities for third Weyl algebra reversed
     3750  kill perms;
     3751  list perms =list(list(list(-1,0,0,0,0,0),
     3752              list(0,-1,0,0,0,0),
     3753              list(0,0,-1,0,0,0)),
     3754             list(list(-1,0,0,0,0,0),
     3755              list(0,0,-1,0,0,0),
     3756              list(0,-1,0,0,0,0)),
     3757             list(list(0,-1,0,0,0,0),
     3758              list(-1,0,0,0,0,0),
     3759              list(0,0,-1,0,0,0)),
     3760             list(list(0,-1,0,0,0,0),
     3761              list(0,0,-1,0,0,0),
     3762              list(-1,0,0,0,0,0)),
     3763             list(list(0,0,-1,0,0,0),
     3764              list(0,-1,0,0,0,0),
     3765              list(-1,0,0,0,0,0)),
     3766             list(list(0,0,-1,0,0,0),
     3767              list(-1,0,0,0,0,0),
     3768              list(0,-1,0,0,0,0)));
     3769  for(i=1;i<=size(perms);i++)
     3770  {
     3771    ring R3 = (0,q(1..3)),(x,y,z,w,v,u),dp;
     3772    matrix D[6][6];
     3773    matrix C[6][6] = 1,1,1,1,1,1,
     3774      1,1,1,1,1,1,
     3775      1,1,1,1,1,1,
     3776      1,1,1,1,1,1,
     3777      1,1,1,1,1,1,
     3778      1,1,1,1,1,1;
     3779    for (j=1;j<=size(perms[i]);j++)
     3780    {
     3781      for (k=1;k<=size(perms[i][j]);k++)
     3782      {
     3783      if(perms[i][j][k]==-1)
     3784      {
     3785        C[k,3+j]=1/q(j);
     3786      }
     3787      }
     3788    }
     3789    for (j=1;j<=size(perms[i]);j++)
     3790    {
     3791      for (k=1;k<=size(perms[i][j]);k++)
     3792      {
     3793      D[k,3+j]=perms[i][j][k];
     3794      }
     3795    }
     3796    def r3 = nc_algebra(C,D);
     3797    setring(r3);
     3798    expected = 0;
     3799    obtained = checkIfProperNthQWeyl();
     3800    if (expected !=obtained)
     3801    {
     3802      print("Test 4 for checkIfProperNthQWeyl failed. Basering:");
     3803      basering;
     3804      print("Expected:\n");
     3805      print(expected);
     3806      print("obtained:\n");
     3807      print(obtained);
     3808      result = 0;
     3809    }
     3810    kill r3;
     3811    kill R3;
     3812  }
     3813  //Test 5: SubQWeyl but not Weyl
     3814  ring R4 = (0,q),(x,y,z),dp;
     3815  matrix D[3][3] = 0,0,1,0,0,0,0,0,0;
     3816  matrix C[3][3] = 1,1,q,1,1,1,1,1,1;
     3817  def r4 = nc_algebra(C,D);
     3818  expected = 0;
     3819  obtained = checkIfProperNthQWeyl();
     3820  if (expected !=obtained)
     3821  {
     3822    print("Test 5 for checkIfProperNthQWeyl failed.");
     3823    print("Expected:\n");
     3824    print(expected);
     3825    print("obtained:\n");
     3826    print(obtained);
     3827    result = 0;
     3828  }
     3829  //Test 6: Commutative ring
     3830  ring R5 = 0,(x,d),dp;
     3831  expected = 0;
     3832  obtained = checkIfProperNthQWeyl();
     3833  if (expected !=obtained)
     3834  {
     3835    print("Test 6 for checkIfProperNthQWeyl failed.");
     3836    print("Expected:\n");
     3837    print(expected);
     3838    print("obtained:\n");
     3839    print(obtained);
     3840    result = 0;
     3841  }
     3842  //Test 7: Weyl algebra
     3843  ring R6 = 0,(x,d),dp;
     3844  def r6 = nc_algebra(1,1);
     3845  setring r6;
     3846  expected = 0;
     3847  obtained = checkIfProperNthQWeyl();
     3848  if (expected !=obtained)
     3849  {
     3850    print("Test 7 for checkIfProperNthQWeyl failed.");
     3851    print("Expected:\n");
     3852    print(expected);
     3853    print("obtained:\n");
     3854    print(obtained);
     3855    result = 0;
     3856  }
     3857  //Test 8: q-Weyl, but with extra parameter
     3858  ring R7 = (0,q,q2),(x,d),dp;
     3859  def r7 = nc_algebra(q,1);
     3860  setring r7;
     3861  expected = 1;
     3862  obtained = checkIfProperNthQWeyl();
     3863  if (expected !=obtained)
     3864  {
     3865    print("Test 8 for checkIfProperNthQWeyl failed.");
     3866    print("Expected:\n");
     3867    print(expected);
     3868    print("obtained:\n");
     3869    print(obtained);
     3870    result = 0;
     3871  }
     3872  return(result);
     3873}//testing checkIfProperNthQWeyl
     3874
     3875
     3876//////////////////////////////////////////////////
     3877//*****COMMUTATIVE FACTORIZATION HELPERS**********
     3878//////////////////////////////////////////////////
     3879
    4213880static proc isInCommutativeSubRing(poly h)
    4223881"
     
    4573916}//isInCommutativeSubRing
    4583917
    459 //==================================================
    460 //deletes the double-entries in a list with
    461 //evaluating the products
    462 static proc delete_dublicates_eval(list l)
    463 "
    464 DEPRECATED
    465 "
    466 {//proc delete_dublicates_eval
    467   list result=l;
    468   int j; int k; int i;
    469   int deleted = 0;
    470   int is_equal;
    471   for (i = 1; i<= size(result); i++)
    472   {//Iterating over all elements in result
    473     for (j = i+1; j<= size(result); j++)
    474     {//comparing with the other elements
    475       if (product(result[i]) == product(result[j]))
    476       {//There are two equal results; throw away that one with the smaller size
    477         if (size(result[i])>=size(result[j]))
    478         {//result[i] has more entries
    479           result = delete(result,j);
    480           continue;
    481         }//result[i] has more entries
    482         else
    483         {//result[j] has more entries
    484           result = delete(result,i);
    485           i--;
    486           break;
    487         }//result[j] has more entries
    488       }//There are two equal results; throw away that one with the smaller size
    489     }//comparing with the other elements
    490   }//Iterating over all elements in result
     3918
     3919static proc test_isInCommutativeSubRing()
     3920{//testing isInCommutativeSubRing
     3921  int result = 1;
     3922  //Test 1: Commutative ring anyways
     3923  ring R = 0,(x1,x2,d1,d2),dp;
     3924  int expected = 1;
     3925  int obtained = isInCommutativeSubRing(x1+x2+d1+d2);
     3926  if (expected !=obtained)
     3927  {
     3928    print("Test 1 for isInCommutativeSubRing failed.");
     3929    print("Expected:\n");
     3930    print(expected);
     3931    print("obtained:\n");
     3932    print(obtained);
     3933    result = 0;
     3934  }
     3935  kill R;
     3936  //Test 2: Non-commutative ring, constant
     3937  ring R = 0,(x,d),dp;
     3938  def r = nc_algebra(1,1);
     3939  setring(r);
     3940  expected = 1;
     3941  obtained = isInCommutativeSubRing(3445);
     3942  if (expected !=obtained)
     3943  {
     3944    print("Test 2 for isInCommutativeSubRing failed.");
     3945    print("Expected:\n");
     3946    print(expected);
     3947    print("obtained:\n");
     3948    print(obtained);
     3949    result = 0;
     3950  }
     3951  kill r; kill R;
     3952  //Test 3: Non-commutative ring, definitely commutative subring
     3953  ring R = 0,(x1,x2,d1,d2),dp;
     3954  def r = Weyl();
     3955  setring r;
     3956  expected = 1;
     3957  obtained = isInCommutativeSubRing(x1*d2+ x1 + d2 + 1);
     3958  if (expected !=obtained)
     3959  {
     3960    print("Test 3 for isInCommutativeSubRing failed.");
     3961    print("Expected:\n");
     3962    print(expected);
     3963    print("obtained:\n");
     3964    print(obtained);
     3965    result = 0;
     3966  }
     3967  //Test 4: Non-commutative ring, definitely non-commutative subring
     3968  expected = 0;
     3969  obtained = isInCommutativeSubRing(x1*d2*d1+ x1 + d2 + d1+5);
     3970  if (expected !=obtained)
     3971  {
     3972    print("Test 4 for isInCommutativeSubRing failed.");
     3973    print("Expected:\n");
     3974    print(expected);
     3975    print("obtained:\n");
     3976    print(obtained);
     3977    result = 0;
     3978  }
    4913979  return(result);
    492 }//proc delete_dublicates_eval
    493 
    494 
    495 //==================================================*
    496 
    497 static proc combinekfinlf(list g, int nof) //nof stands for "number of factors"
    498 "
    499 given a list of factors g and a desired size nof, this
    500 procedure combines the factors, such that we recieve a
    501 list of the length nof.
    502 INPUT: A list of containing polynomials or any type where the *-operator is existent
    503 OUTPUT: All possibilities (without permutation of the given list) to combine the polynomials
    504  into nof polynomials given by the user.
    505 "
    506 {//Procedure combinekfinlf
    507   list result;
    508   int i; int j; int k; //iteration variables
    509   list fc; //fc stands for "factors combined"
    510   list temp; //a temporary store for factors
    511   def nofgl = size(g); //nofgl stands for "number of factors of the given list"
    512   if (nofgl == 0)
    513   {//g was the empty list
    514     return(result);
    515   }//g was the empty list
    516   if (nof <= 0)
    517   {//The user wants to recieve a negative number or no element as a result
    518     return(result);
    519   }//The user wants to recieve a negative number or no element as a result
    520   if (nofgl == nof)
    521   {//There are no factors to combine
    522     result = result + list(g);
    523     return(result);
    524   }//There are no factors to combine
    525   if (nof == 1)
    526   {//User wants to get just one factor
    527     result = result + list(list(product(g)));
    528     return(result);
    529   }//User wants to get just one factor
    530   for (i = nof; i > 1; i--)
    531   {//computing the possibilities that have at least one original factor from g
    532     for (j = i; j>=1; j--)
    533     {//shifting the window of combinable factors to the left
    534       //fc below stands for "factors combined"
    535       fc = combinekfinlf(list(g[(j)..(j+nofgl - i)]),nof - i + 1);
    536       for (k = 1; k<=size(fc); k++)
    537       {//iterating over the different solutions of the smaller problem
    538         if (j>1)
    539         {//There are g_i before the combination
    540           if (j+nofgl -i < nofgl)
    541           {//There are g_i after the combination
    542             temp = list(g[1..(j-1)]) + fc[k] + list(g[(j+nofgl-i+1)..nofgl]);
    543           }//There are g_i after the combination
    544           else
    545           {//There are no g_i after the combination
    546             temp = list(g[1..(j-1)]) + fc[k];
    547           }//There are no g_i after the combination
    548         }//There are g_i before the combination
    549         if (j==1)
    550         {//There are no g_i before the combination
    551           if (j+ nofgl -i <nofgl)
    552           {//There are g_i after the combination
    553             temp = fc[k]+ list(g[(j + nofgl - i +1)..nofgl]);
    554           }//There are g_i after the combination
    555         }//There are no g_i before the combination
    556         result = result + list(temp);
    557       }//iterating over the different solutions of the smaller problem
    558     }//shifting the window of combinable factors to the left
    559   }//computing the possibilities that have at least one original factor from g
    560   for (i = 2; i<=nofgl div nof;i++)
    561   {//getting the other possible results
    562     result = result + combinekfinlf(list(product(list(g[1..i])))+list(g[(i+1)..nofgl]),nof);
    563   }//getting the other possible results
    564   result = delete_dublicates_noteval(result);
    565   return(result);
    566 }//Procedure combinekfinlf
    567 
    568 
    569 //==================================================*
    570 //merges two sets of factors ignoring common
    571 //factors
    572 static proc merge_icf(list l1, list l2, intvec limits)
    573 "
    574 DEPRECATED
    575 "
    576 {//proc merge_icf
    577   list g;
    578   list f;
    579   int i; int j;
    580   if (size(l1)==0)
    581   {
    582     return(list());
    583   }
    584   if (size(l2)==0)
    585   {
    586     return(list());
    587   }
    588   if (size(l2)<=size(l1))
    589   {//l1 will be our g, l2 our f
    590     g = l1;
    591     f = l2;
    592   }//l1 will be our g, l2 our f
    593   else
    594   {//l1 will be our f, l2 our g
    595     g = l2;
    596     f = l1;
    597   }//l1 will be our f, l2 our g
    598   def result = combinekfinlf(g,size(f),limits);
    599   for (i = 1 ; i<= size(result); i++)
    600   {//Adding the factors of f to every possibility listed in temp
    601     for (j = 1; j<= size(f); j++)
    602     {
    603       result[i][j] = result[i][j]+f[j];
    604     }
    605     if(!limitcheck(result[i],limits))
    606     {
    607       result = delete(result,i);
    608       continue;
    609     }
    610     for (j = 1; j<=size(f);j++)
    611     {//Delete entry if there is a zero or an integer as a factor
    612       if (deg(result[i][j]) <= 0)
    613       {//found one
    614         result = delete(result,i);
    615         i--;
    616         break;
    617       }//found one
    618     }//Delete entry if there is a zero as factor
    619   }//Adding the factors of f to every possibility listed in temp
    620   return(result);
    621 }//proc merge_icf
    622 
    623 //==================================================*
    624 //merges two sets of factors with respect to the occurrence
    625 //of common factors
    626 static proc merge_cf(list l1, list l2, intvec limits)
    627 "
    628 DEPRECATED
    629 "
    630 {//proc merge_cf
    631   list g;
    632   list f;
    633   int i; int j;
    634   list pre;
    635   list post;
    636   list candidate;
    637   list temp;
    638   int temppos;
    639   if (size(l1)==0)
    640   {//the first list is empty
    641     return(list());
    642   }//the first list is empty
    643   if(size(l2)==0)
    644   {//the second list is empty
    645     return(list());
    646   }//the second list is empty
    647   if (size(l2)<=size(l1))
    648   {//l1 will be our g, l2 our f
    649     g = l1;
    650     f = l2;
    651   }//l1 will be our g, l2 our f
    652   else
    653   {//l1 will be our f, l2 our g
    654     g = l2;
    655     f = l1;
    656   }//l1 will be our f, l2 our g
    657   list M;
    658   for (i = 2; i<size(f); i++)
    659   {//finding common factors of f and g...
    660     for (j=2; j<size(g);j++)
    661     {//... with g
    662       if (f[i] == g[j])
    663       {//we have an equal pair
    664         M = M + list(list(i,j));
    665       }//we have an equal pair
    666     }//... with g
    667   }//finding common factors of f and g...
    668   if (g[1]==f[1])
    669   {//Checking for the first elements to be equal
    670     M = M + list(list(1,1));
    671   }//Checking for the first elements to be equal
    672   if (g[size(g)]==f[size(f)])
    673   {//Checking for the last elements to be equal
    674     M = M + list(list(size(f),size(g)));
    675   }//Checking for the last elements to be equal
    676   list result;//= list(list());
    677   while(size(M)>0)
    678   {//set of equal pairs is not empty
    679     temp = M[1];
    680     temppos = 1;
    681     for (i = 2; i<=size(M); i++)
    682     {//finding the minimal element of M
    683       if (M[i][1]<=temp[1])
    684       {//a possible candidate that is smaller than temp could have been found
    685         if (M[i][1]==temp[1])
    686         {//In this case we must look at the second number
    687           if (M[i][2]< temp[2])
    688           {//the candidate is smaller
    689             temp = M[i];
    690             temppos = i;
    691           }//the candidate is smaller
    692         }//In this case we must look at the second number
    693         else
    694         {//The candidate is definately smaller
    695           temp = M[i];
    696           temppos = i;
    697         }//The candidate is definately smaller
    698       }//a possible candidate that is smaller than temp could have been found
    699     }//finding the minimal element of M
    700     M = delete(M, temppos);
    701     if(temp[1]>1)
    702     {//There are factors to combine before the equal factor
    703       if (temp[1]<size(f))
    704       {//The most common case
    705         //first the combinations ignoring common factors
    706         pre = merge_icf(list(f[1..(temp[1]-1)]),list(g[1..(temp[2]-1)]),limits);
    707         post = merge_icf(list(f[(temp[1]+1)..size(f)]),list(g[(temp[2]+1..size(g))]),limits);
    708         for (i = 1; i <= size(pre); i++)
    709         {//all possible pre's...
    710           for (j = 1; j<= size(post); j++)
    711           {//...combined with all possible post's
    712             candidate = pre[i]+list(f[temp[1]])+post[j];
    713             if (limitcheck(candidate,limits))
    714             {
    715               result = result + list(candidate);
    716             }
    717           }//...combined with all possible post's
    718         }//all possible pre's...
    719         //Now the combinations with respect to common factors
    720         post = merge_cf(list(f[(temp[1]+1)..size(f)]),list(g[(temp[2]+1..size(g))]),limits);
    721         if (size(post)>0)
    722         {//There are factors to combine
    723           for (i = 1; i <= size(pre); i++)
    724           {//all possible pre's...
    725             for (j = 1; j<= size(post); j++)
    726             {//...combined with all possible post's
    727               candidate= pre[i]+list(f[temp[1]])+post[j];
    728               if (limitcheck(candidate,limits))
    729               {
    730                 result = result + list(candidate);
    731               }
    732             }//...combined with all possible post's
    733           }//all possible pre's...
    734         }//There are factors to combine
    735       }//The most common case
    736       else
    737       {//the last factor is the common one
    738         pre = merge_icf(list(f[1..(temp[1]-1)]),list(g[1..(temp[2]-1)]),limits);
    739         for (i = 1; i<= size(pre); i++)
    740         {//iterating over the possible pre-factors
    741           candidate = pre[i]+list(f[temp[1]]);
    742           if (limitcheck(candidate,limits))
    743           {
    744             result = result + list(candidate);
    745           }
    746         }//iterating over the possible pre-factors
    747       }//the last factor is the common one
    748     }//There are factors to combine before the equal factor
    749     else
    750     {//There are no factors to combine before the equal factor
    751       if (temp[1]<size(f))
    752       {//Just a check for security
    753         //first without common factors
    754         post=merge_icf(list(f[(temp[1]+1)..size(f)]),list(g[(temp[2]+1..size(g))]),limits);
    755         for (i = 1; i<=size(post); i++)
    756         {
    757           candidate = list(f[temp[1]])+post[i];
    758           if (limitcheck(candidate,limits))
    759           {
    760             result = result + list(candidate);
    761           }
    762         }
    763         //Now with common factors
    764         post = merge_cf(list(f[(temp[1]+1)..size(f)]),list(g[(temp[2]+1..size(g))]),limits);
    765         if(size(post)>0)
    766         {//we could find other combinations
    767           for (i = 1; i<=size(post); i++)
    768           {
    769             candidate = list(f[temp[1]])+post[i];
    770             if (limitcheck(candidate,limits))
    771             {
    772               result = result + list(candidate);
    773             }
    774           }
    775         }//we could find other combinations
    776       }//Just a check for security
    777     }//There are no factors to combine before the equal factor
    778   }//set of equal pairs is not empty
    779   for (i = 1; i <= size(result); i++)
    780   {//delete those combinations, who have an entry with degree less or equal 0
    781     for (j = 1; j<=size(result[i]);j++)
    782     {//Delete entry if there is a zero or an integer as a factor
    783       if (deg(result[i][j]) <= 0)
    784       {//found one
    785         result = delete(result,i);
    786         i--;
    787         break;
    788       }//found one
    789     }//Delete entry if there is a zero as factor
    790   }//delete those combinations, who have an entry with degree less or equal 0
    791   return(result);
    792 }//proc merge_cf
    793 
    794 
    795 //==================================================*
    796 //merges two sets of factors
    797 
    798 static proc mergence(list l1, list l2, intvec limits)
    799 "
    800 DEPRECATED
    801 "
    802 {//Procedure mergence
    803   list g;
    804   list f;
    805   int k; int i; int j;
    806   list F = list();
    807   list G = list();
    808   list tempEntry;
    809   list comb;
    810   if (size(l2)<=size(l1))
    811   {//l1 will be our g, l2 our f
    812     g = l1;
    813     f = l2;
    814   }//l1 will be our g, l2 our f
    815   else
    816   {//l1 will be our f, l2 our g
    817     g = l2;
    818     f = l1;
    819   }//l1 will be our f, l2 our g
    820   if (size(f)==1 or size(g)==1)
    821   {//One of them just has one entry
    822     if (size(f)== 1) {f = list(1) + f;}
    823     if (size(g) == 1) {g = list(1) + g;}
    824   }//One of them just has one entry
    825   //first, we need to add some latent -1's to the list f and to the list g in order
    826   //to get really all possibilities of combinations later
    827   for (i=1;i<=size(f)-1;i++)
    828   {//first iterator
    829     for (j=i+1;j<=size(f);j++)
    830     {//second iterator
    831       tempEntry = f;
    832       tempEntry[i] = (-1)*tempEntry[i];
    833       tempEntry[j] = (-1)*tempEntry[j];
    834       F = F + list(tempEntry);
    835     }//secont iterator
    836   }//first iterator
    837   F = F + list(f);
    838   //And now same game with g
    839   for (i=1;i<=size(g)-1;i++)
    840   {//first iterator
    841     for (j=i+1;j<=size(g);j++)
    842     {//second iterator
    843       tempEntry = g;
    844       tempEntry[i] = (-1)*tempEntry[i];
    845       tempEntry[j] = (-1)*tempEntry[j];
    846       G = G + list(tempEntry);
    847     }//secont iterator
    848   }//first iterator
    849   G = G + list(g);
    850   //Done with that
    851 
    852   list result;
    853   for (i = 1; i<=size(F); i++)
    854   {//Iterate over all entries in F
    855     for (j = 1;j<=size(G);j++)
    856     {//Same with G
    857       comb = combinekfinlf(F[i],2,limits);
    858       for (k = 1; k<= size(comb);k++)
    859       {//for all possibilities of combinations of the factors of f
    860         result = result + merge_cf(comb[k],G[j],limits);
    861         result = result + merge_icf(comb[k],G[j],limits);
    862         result = delete_dublicates_noteval(result);
    863       }//for all possibilities of combinations of the factors of f
    864     }//Same with G
    865   }//Iterate over all entries in F
    866   return(result);
    867 }//Procedure mergence
    868 
    869 
    870 //==================================================
    871 //Checks, whether a list of factors doesn't exceed the given limits
    872 static proc limitcheck(list g, intvec limits)
    873 "
    874 DEPRECATED
    875 "
    876 {//proc limitcheck
    877   int i;
    878   if (size(limits)!=3)
    879   {//check the input
    880     return(0);
    881   }//check the input
    882   if(size(g)==0)
    883   {
    884     return(0);
    885   }
    886   def prod = product(g);
    887   intvec iv11 = intvec(1,1);
    888   intvec iv10 = intvec(1,0);
    889   intvec iv01 = intvec(0,1);
    890   def limg = intvec(deg(prod,iv11) ,deg(prod,iv10),deg(prod,iv01));
    891   for (i = 1; i<=size(limg);i++)
    892   {//the final check
    893     if(limg[i]>limits[i])
    894     {
    895       return(0);
    896     }
    897   }//the final check
    898   return(1);
    899 }//proc limitcheck
    900 
    901 
    902 //==================================================*
    903 //one factorization of a homogeneous polynomial
    904 //in the first Weyl Algebra
    905 static proc homogfacFirstWeyl(poly h)
    906 "USAGE: homogfacFirstWeyl(h); h is a homogeneous polynomial in the
    907  first Weyl algebra with respect to the weight vector [-1,1]
    908 RETURN: list
    909 PURPOSE: Computes a factorization of a homogeneous polynomial h with
    910   respect to the weight vector [-1,1] in the first Weyl algebra
    911 THEORY: @code{homogfacFirstWeyl} returns a list with a factorization of the given,
    912  [-1,1]-homogeneous polynomial. If the degree of the polynomial is k with
    913  k positive, the last k entries in the output list are the second
    914  variable. If k is positive, the last k entries will be x. The other
    915  entries will be irreducible polynomials of degree zero or 1 resp. -1.
    916 SEE ALSO: homogfacFirstWeyl_all
    917 "{//proc homogfacFirstWeyl
    918   int p = printlevel-voice+2;//for dbprint
    919   def r = basering;
    920   poly hath;
     3980}//testing isInCommutativeSubRing
     3981
     3982
     3983static proc factor_commutative(poly h)
     3984"USAGE: factor_commutative(h); h is a polynomial in a
     3985        non-commutative ring, for which all the variables that appear in a
     3986        positive powers in the monomials of h are pairwise commutative.
     3987RETURN: list(list)
     3988PURPOSE: Sometimes, we end up having polynomials in a non-commutative
     3989         ring, which lie in a commutative subring, and we can factor
     3990         them in a commutative fashion.
     3991ASSUME:
     3992- k is a ring, such that factorize can factor any univariate and
     3993  multivariate commutative polynomial over k.
     3994- h is in a commutative subring (NOT CHECKED)
     3995SEE ALSO: ncfactor
     3996"{//proc factor_commutative
     3997  int p = printlevel-voice+2;
    9213998  int i; int j;
    9223999  string dbprintWhitespace = "";
    9234000  for (i = 1; i<=voice;i++)
    9244001  {dbprintWhitespace = dbprintWhitespace + " ";}
    925   intvec ivm11 = intvec(-1,1);
    926   if (!homogwithorder(h,ivm11))
    927   {//The given polynomial is not homogeneous
    928     ERROR("Given polynomial was not [-1,1]-homogeneous");
     4002  if (deg(h)<=0)
     4003  {
     4004    dbprint(p,dbprintWhitespace + "h is a constant. Returning
     4005 immediately");
     4006    return(list(list(h)));
     4007  }
     4008  def r = basering;
     4009  list factorizeOutput;
     4010  if (size(ringlist(basering))<=4)
     4011  {//commutative ring case
     4012    dbprint(p,dbprintWhitespace + "We are in a commutative
     4013 ring. Factoring h using factorize.");
     4014    factorizeOutput = factorize(h);
     4015  }//commutative ring case
     4016  else
     4017  {//commutative subring case;
     4018    dbprint(p,dbprintWhitespace + "We are in a commutative
     4019 subring. Generating commutative ring..");
     4020    def rList = ringlist(basering);
     4021    rList = delete(rList,5);
     4022    rList = delete(rList,5);
     4023    def tempRing = ring(rList);
     4024    setring(tempRing);
     4025    poly h = imap(r,h);
     4026    dbprint(p, dbprintWhitespace+"Factoring h in commutative ring.");
     4027    list tempResult = factorize(h);
     4028    setring(r);
     4029    factorizeOutput = imap(tempRing,tempResult);
     4030  }//commutative subring case;
     4031  dbprint(p,dbprintWhitespace + "Done commutatively factorizing.
     4032 The result is:");
     4033  dbprint(p,factorizeOutput);
     4034  dbprint(p,dbprintWhitespace+"Computing all permutations of this factorization.");
     4035  list result = list(list());
     4036  for (i = 1; i<=size(factorizeOutput[1]); i++)
     4037  {
     4038    for (j = 1; j<=factorizeOutput[2][i]; j++)
     4039    {
     4040      result[1] = result[1] + list(factorizeOutput[1][i]);
     4041    }
     4042  }
     4043  poly constantFactor = result[1][1];
     4044  result[1] = delete(result[1],1);//Deleting the constant factor
     4045  result=permpp(result[1]);
     4046  for (i = 1; i<=size(result);i++)
     4047  {//Insert constant factor
     4048    result[i] = insert(result[i],constantFactor);
     4049  }//Insert constant factor
     4050  dbprint(p,dbprintWhitespace+"Done.");
     4051  result = delete_duplicates_noteval_and_sort(result);
     4052  return(result);
     4053}//proc factor_commutative
     4054
     4055
     4056static proc test_factor_commutative()
     4057{//testing factor_commutative
     4058  int result = 1;
     4059  //Test 1: Commutative ring anyways
     4060  ring R = 0,(x1,x2,d1,d2),dp;
     4061  list expected = list(list(poly(1),x1+x2+d1+d2));
     4062  list obtained = factor_commutative(x1+x2+d1+d2);
     4063  if (!isListEqual(expected,obtained))
     4064  {
     4065    print("Test 1 for factor_commutative failed.");
     4066    print("Expected:\n");
     4067    print(expected);
     4068    print("obtained:\n");
     4069    print(obtained);
     4070    result = 0;
     4071  }
     4072  kill R;
     4073  //Test 2: Non-commutative ring, constant
     4074  ring R = 0,(x,d),dp;
     4075  def r = nc_algebra(1,1);
     4076  setring(r);
     4077  list expected = list(list(poly(3445)));
     4078  list obtained = factor_commutative(3445);
     4079  if (!isListEqual(expected,obtained))
     4080  {
     4081    print("Test 2 for factor_commutative failed.");
     4082    print("Expected:\n");
     4083    print(expected);
     4084    print("obtained:\n");
     4085    print(obtained);
     4086    result = 0;
     4087  }
     4088  kill r; kill R;
     4089  //Test 3: Non-commutative ring, definitely commutative subring, irreducible
     4090  ring R = 0,(x1,x2,d1,d2),dp;
     4091  def r = Weyl();
     4092  setring r;
     4093  list expected = list(list(poly(1), x1*d2+ x1 + d2 + 2));
     4094  list obtained = factor_commutative(x1*d2+ x1 + d2 + 2);
     4095  if (!isListEqual(expected,obtained))
     4096  {
     4097    print("Test 3 for factor_commutative failed.");
     4098    print("Expected:\n");
     4099    print(expected);
     4100    print("obtained:\n");
     4101    print(obtained);
     4102    result = 0;
     4103  }
     4104  kill r; kill R;
     4105  //Test 4: Non-commutative ring, definitely commutative subring,
     4106  //reducible
     4107  ring R = 0,(x1,x2,d1,d2),dp;
     4108  def r = Weyl();
     4109  setring r;
     4110  list expected = list(list(poly(1), x1*d2+ x1 + d2 + 2, x1*d2- x1 -
     4111                d2 - 2),
     4112               (list(poly(1), x1*d2- x1 - d2 - 2,  x1*d2+ x1 +
     4113                 d2 + 2)));
     4114  list obtained = factor_commutative((x1*d2+ x1 + d2 + 2)*(x1*d2- x1 -
     4115                               d2 - 2));
     4116  if (!isListEqual(expected,obtained))
     4117  {
     4118    print("Test 4 for factor_commutative failed.");
     4119    print("Expected:\n");
     4120    print(expected);
     4121    print("obtained:\n");
     4122    print(obtained);
     4123    result = 0;
     4124  }
     4125  kill r; kill R;
     4126  return(result);
     4127}//testing factor_commutative
     4128
     4129
     4130static proc factorizeInt(number n)
     4131"Given an integer n, factorizeInt computes its factorization. The output is a list
     4132containing two lists. The first contains the prime factors, the second its powers.
     4133ASSUMPTIONS:
     4134- n is given as integer number
     4135"{//factorizeInt
     4136  if (n==0)
     4137  {return(list(list(0),list(1)));}
     4138  int i;
     4139  list temp = primefactors(n);
     4140  if (n<0)
     4141  {list result = list(list(-1),list(1));}
     4142  else
     4143  {list result = list(list(1),list(1));}
     4144  result[1] = result[1] + temp[1];
     4145  result[2] = result[2] + temp[2];
     4146  return(result);
     4147}//factorizeInt
     4148
     4149
     4150static proc test_factorizeInt()
     4151{//Testing factorizeInt
     4152  int result =1;
     4153  //Test 1: factorizing 0
     4154  ring R = 0,(x),dp;
     4155  list expected = list(list(0),list(1));
     4156  list obtained = factorizeInt(number(0));
     4157  if (!isListEqual(expected,obtained))
     4158  {
     4159    print("Test 1 for factorizeInt failed.");
     4160    print("Expected:\n");
     4161    print(expected);
     4162    print("obtained:\n");
     4163    print(obtained);
     4164    result = 0;
     4165  }
     4166  //Test 2: factorizing 1
     4167  expected = list(list(1),list(1));
     4168  obtained = factorizeInt(number(1));
     4169  if (!isListEqual(expected,obtained))
     4170  {
     4171    print("Test 2 for factorizeInt failed.");
     4172    print("Expected:\n");
     4173    print(expected);
     4174    print("obtained:\n");
     4175    print(obtained);
     4176    result = 0;
     4177  }
     4178  //Test 3: factorizing a positive composite
     4179  expected = list(list(1,2,5),list(1,2,1));
     4180  obtained = factorizeInt(20);
     4181  if (!isListEqual(expected,obtained))
     4182  {
     4183    print("Test 3 for factorizeInt failed.");
     4184    print("Expected:\n");
     4185    print(expected);
     4186    print("obtained:\n");
     4187    print(obtained);
     4188    result = 0;
     4189  }
     4190  //Test 4: factorizing a negative composite
     4191  expected = list(list(-1,2,5),list(1,2,1));
     4192  obtained = factorizeInt(-20);
     4193  if (!isListEqual(expected,obtained))
     4194  {
     4195    print("Test 4 for factorizeInt failed.");
     4196    print("Expected:\n");
     4197    print(expected);
     4198    print("obtained:\n");
     4199    print(obtained);
     4200    result = 0;
     4201  }
     4202  //Test 5: factoring a prime
     4203  expected = list(list(1,23),list(1,1));
     4204  obtained = factorizeInt(23);
     4205  if (!isListEqual(expected,obtained))
     4206  {
     4207    print("Test 5 for factorizeInt failed.");
     4208    print("Expected:\n");
     4209    print(expected);
     4210    print("obtained:\n");
     4211    print(obtained);
     4212    result = 0;
     4213  }
     4214  return(result);
     4215}//Testing factorizeInt
     4216
     4217
     4218static proc getAllCoeffTuplesComb(list l)"
     4219Given the output of factorizeInt ((a_1,...,a_n),(i_1,...,i_n)) , it returns all possible tuples
     4220of the set {(a,b) | There exists a real N!=emptyset subset of {1,...,n}, such that
     4221a = prod_{i \in N}a_i, b=prod_{i \not\in N} a_i}
     4222Assumption: The list is sorted from smallest integer to highest.
     4223- it is not the factorization of 0.
     4224"
     4225{//proc getAllCoeffTuplesComb
     4226  list result;
     4227  if (l[1][1] == 0)
     4228  {
     4229    ERROR("getAllCoeffTuplesComb: Zero Coefficients as leading and Tail Coeffs?
     4230That is not possible. Something went wrong.");
     4231  }
     4232  if (size(l[1]) == 1)
     4233  {//Trivial Factorization, just 1
     4234    if (l[1][1] == 1)
     4235    {
     4236      return(list(list(number(1),number(1)),list(-number(1),-number(1))));
     4237    }
     4238    else
     4239    {
     4240      return(list(list(-number(1),number(1)),list(number(1),-number(1))));
     4241    }
     4242  }//Trivial Factorization, just 1
     4243  if (size(l[1]) == 2 and l[2][2]==1)
     4244  {//Just a prime number
     4245    if (l[1][1] == 1)
     4246    {
     4247      result = list(number(l[1][2]),number(1)),list(number(1),number(l[1][2]));
     4248      result = result + list(list(number(-l[1][2]),number(-1)),list(number(-1),number(-l[1][2])));
     4249      return(result);
     4250    }
     4251    else
     4252    {
     4253      result = list(list(number(l[1][2]),number(-1)),list(number(1),number(-l[1][2])));
     4254      result = result + list(list(number(-l[1][2]),number(1)),list(number(-1),number(l[1][2])));
     4255      return(result);
     4256    }
     4257  }//Just a prime number
     4258  //Now comes the interesting case: a product of primes
     4259  list tempPrimeFactors;
     4260  list tempPowersOfThem;
     4261  int i;
     4262  for (i = 2; i<=size(l[1]);i++)
     4263  {//Removing the starting 1 or -1 to get the N's
     4264    tempPrimeFactors[i-1] = l[1][i];
     4265    tempPowersOfThem[i-1] = l[2][i];
     4266  }//Removing the starting 1 or -1 to get the N's
     4267  list Ns = getAllDivisorsFromFactList(list(tempPrimeFactors,tempPowersOfThem));
     4268  list tempTuples;
     4269  number productOfl = multiplyFactIntOutput(l);
     4270  if (productOfl<0){productOfl = -productOfl;}
     4271  tempTuples = tempTuples + list(list(number(1),productOfl),list(productOfl,number(1)));
     4272  for (i = 1; i<=size(Ns); i++)
     4273  {
     4274    if (productOfl/Ns[i]>Ns[i])
     4275    {
     4276      tempTuples = tempTuples + list(list(Ns[i],productOfl/Ns[i]),list(productOfl/Ns[i],Ns[i]));
     4277    }
     4278    if (productOfl/Ns[i]==Ns[i])
     4279    {
     4280      tempTuples = tempTuples + list(list(Ns[i],Ns[i]));
     4281    }
     4282  }
     4283  //And now, it just remains to get the -1s and 1-s correctly to the tuples
     4284  list tempEntry;
     4285  if (l[1][1] == 1)
     4286  {
     4287    for (i = 1; i<=size(tempTuples);i++)
     4288    {//Adding everything to result
     4289      tempEntry = tempTuples[i];
     4290      result = result + list(tempEntry);
     4291      result = result + list(list(-tempEntry[1], -tempEntry[2]));
     4292    }//Adding everyThing to Result
     4293  }
     4294  else
     4295  {
     4296    for (i = 1; i<=size(tempTuples);i++)
     4297    {//Adding everything to result
     4298      tempEntry = tempTuples[i];
     4299      result = result + list(list(tempEntry[1],-tempEntry[2]));
     4300      result = result + list(list(-tempEntry[1], tempEntry[2]));
     4301    }//Adding everyThing to Result
     4302  }
     4303  return(delete_duplicates_noteval_and_sort(result));
     4304}//proc getAllCoeffTuplesComb
     4305
     4306
     4307static proc test_getAllCoeffTuplesComb()
     4308{//testing getAllCoeffTuplesComb
     4309  int result = 1;
     4310  ring R = 0,(x),dp;
     4311  //Test 1: 1
     4312  list input = factorizeInt(1);
     4313  list expected = list(list(number(1),number(1)),list(-number(1),-number(1)));
     4314  list obtained = getAllCoeffTuplesComb(input);
     4315  if (!isListEqual(expected,obtained))
     4316  {
     4317    print("Test 1 for getAllCoeffTuplesComb failed.");
     4318    print("Expected:\n");
     4319    print(expected);
     4320    print("obtained:\n");
     4321    print(obtained);
     4322    result = 0;
     4323  }
     4324  //Test 2: prime
     4325  input = factorizeInt(13);
     4326  expected = sortFactorizations(
     4327    list(
     4328      list(number(1),number(13)),list(number(13),number(1)),
     4329      list(-number(1),-number(13)),list(-number(13),-number(1))));
     4330  obtained = sortFactorizations(getAllCoeffTuplesComb(input));
     4331  if (!isListEqual(expected,obtained))
     4332  {
     4333    print("Test 2 for getAllCoeffTuplesComb failed.");
     4334    print("Expected:\n");
     4335    print(expected);
     4336    print("obtained:\n");
     4337    print(obtained);
     4338    result = 0;
     4339  }
     4340  //Test 3: composite
     4341  input = factorizeInt(13*5);
     4342  expected = sortFactorizations(
     4343    list(
     4344      list(number(1),number(13)*number(5)),list(number(13)*number(5),number(1)),
     4345      list(number(13),number(5)),list(number(5),number(13)),
     4346      list(-number(1),-number(13)*number(5)),list(-number(13)*number(5),-number(1)),
     4347      list(-number(13),-number(5)),list(-number(5),-number(13))
     4348      ));
     4349  obtained = sortFactorizations(getAllCoeffTuplesComb(input));
     4350  if (!isListEqual(expected,obtained))
     4351  {
     4352    print("Test 3 for getAllCoeffTuplesComb failed.");
     4353    print("Expected:\n");
     4354    print(expected);
     4355    print("obtained:\n");
     4356    print(obtained);
     4357    result = 0;
     4358  }
     4359  return(result);
     4360}//testing getAllCoeffTuplesComb
     4361
     4362
     4363//////////////////////////////////////////////////
     4364//*FACTORIZATION RELATED GENERAL HELPER FUNCTIONS*
     4365//////////////////////////////////////////////////
     4366
     4367
     4368static proc normalizeFactors(list factList)
     4369"INPUT: A list of factorizations, as outputted e.g. by facWeyl
     4370OUTPUT: If any entry  in a factorization is not primitive, this function
     4371        divides the common divisor out and multiplies the first entry with it.
     4372"
     4373{//normalizeFactors
     4374  int i; int j;
     4375  list result = factList;
     4376  for (i = 1; i<=size(result); i++)
     4377  {//iterating through every different factorization
     4378    for (j=2; j<=size(result[i]); j++)
     4379    {//Iterating through all respective factors
     4380      if (content(result[i][j])!=number(1))
     4381      {//Got one where the content is not equal to 1
     4382        result[i][1] = result[i][1] * content(result[i][j]);
     4383        result[i][j] = result[i][j] / content(result[i][j]);
     4384      }//Got one where the content is not equal to 1
     4385    }//Iterating through all respective factors
     4386  }//iterating through every different factorization
     4387  return(result);
     4388}//normalizeFactors
     4389
     4390
     4391static proc test_normalizeFactors()
     4392{//testing normalizeFactors
     4393  int result = 1;
     4394  //Test 1: Empty list
     4395  list expected = list();
     4396  list obtained = normalizeFactors(list());
     4397  if (!isListEqual(expected,obtained))
     4398  {
     4399    print("Test 1 for normalizeFactors failed.");
     4400    print("Expected:\n");
     4401    print(expected);
     4402    print("obtained:\n");
     4403    print(obtained);
     4404    result = 0;
     4405  }
     4406  //Test 2: list with only constant factor
     4407  expected = list(list(2));
     4408  obtained = normalizeFactors(list(list(2)));
     4409  if (!isListEqual(expected,obtained))
     4410  {
     4411    print("Test 2 for normalizeFactors failed.");
     4412    print("Expected:\n");
     4413    print(expected);
     4414    print("obtained:\n");
     4415    print(obtained);
     4416    result = 0;
     4417  }
     4418  // Test 3: list with one factor, content 1
     4419  ring R = 0,(x,y),dp;
     4420  expected = list(list(2,x^2+y^2));
     4421  obtained = normalizeFactors(list(list(2,x^2+y^2)));
     4422  if (!isListEqual(expected,obtained))
     4423  {
     4424    print("Test 3 for normalizeFactors failed.");
     4425    print("Expected:\n");
     4426    print(expected);
     4427    print("obtained:\n");
     4428    print(obtained);
     4429    result = 0;
     4430  }
     4431  kill R;
     4432  // Test 4: list with one factor, content not 1
     4433  ring R = 0,(x,y),dp;
     4434  list expected = list(list(number(6),x^2+y^2));
     4435  list obtained = normalizeFactors(list(list(2,3*x^2+3*y^2)));
     4436  if (!isListEqual(expected,obtained))
     4437  {
     4438    print("Test 4 for normalizeFactors failed.");
     4439    print("Expected:\n");
     4440    print(expected);
     4441    print("obtained:\n");
     4442    print(obtained);
     4443    result = 0;
     4444  }
     4445  kill R;
     4446  // Test 5: list with more than one factor, content 1
     4447  ring R = 0,(x,y),dp;
     4448  list expected = list(list(2,x^2+y^2,x,y));
     4449  list obtained = normalizeFactors(list(list(2,x^2+y^2,x,y)));
     4450  if (!isListEqual(expected,obtained))
     4451  {
     4452    print("Test 5 for normalizeFactors failed.");
     4453    print("Expected:\n");
     4454    print(expected);
     4455    print("obtained:\n");
     4456    print(obtained);
     4457    result = 0;
     4458  }
     4459  kill R;
     4460  //Test 6: list with more than one factor, content not 1
     4461  ring R = 0,(x,y),dp;
     4462  list expected = list(list(number(12),x^2+y^2,x,y));
     4463  list obtained = normalizeFactors(list(list(2,x^2+y^2,2*x,3*y)));
     4464  if (!isListEqual(expected,obtained))
     4465  {
     4466    print("Test 6 for normalizeFactors failed.");
     4467    print("Expected:\n");
     4468    print(expected);
     4469    print("obtained:\n");
     4470    print(obtained);
     4471    result = 0;
     4472  }
     4473  return(result);
     4474}//testing normalizeFactors
     4475
     4476
     4477static proc divides(poly p1, poly p2,map invo, list #)
     4478  "Tests, whether p1 divides p2 either from left or from right. The involution invo is needed
     4479for checking both sides. The optional argument is needed in order to also return the other factor.
     4480RETURN: If no optional argument is given, it will just return 1 or 0.
     4481 Otherwise a list with at least one element
     4482 Case 1: p1 does not divide p2 from any side. Then the output will be the empty list.
     4483 Case 2: p2 does divide p2 from one side at least.
     4484  Then it returns a list with tuples p,q, such that p or q equals p1 and
     4485  pq = p2.
     4486ASSUMPTIONS: - The map invo is an involution on the basering."
     4487{//proc divides
     4488  list result = list();
     4489  poly tempfactor;
     4490  if (involution(reduce(involution(p2,invo),std(involution(ideal(p1),invo))),invo)==0)
     4491  {//p1 is a left divisor
     4492    if(size(#)==0){return(1);}
     4493    tempfactor = involution(lift(involution(p1,invo),involution(p2,invo))[1,1],invo);
     4494    result = result + list(list(content(p1)*content(p2),
     4495                p1/content(p1),tempfactor/content(tempfactor)));
     4496  }//p1 is a left divisor
     4497
     4498  if (reduce(p2,std(ideal(p1))) == 0)
     4499  {//p1 is  a right divisor
     4500    if(size(#)==0){return(1);}
     4501    tempfactor = lift(p1, p2)[1,1];
     4502    result = result + list(list(content(p1)*content(p2),
     4503                tempfactor/content(tempfactor),p1/content(p1)));
     4504  }//p1 is already a right divisor
     4505  if (size(#)==0){return(0);}
     4506  return(result);
     4507}//proc divides
     4508
     4509
     4510static proc test_divides()
     4511{//testing divides
     4512  int result = 1;
     4513  //Test 1: both polys are constant
     4514  ring R = 0,(x,y),dp;
     4515  def r = nc_algebra(1,1);
     4516  setring r;
     4517  map invo = r, -x , y;
     4518  int expected = 1;
     4519  int obtained = divides(1,2,invo);
     4520  if (expected!=obtained)
     4521  {
     4522    print("Test 1 for divides failed.");
     4523    print("Expected:\n");
     4524    print(expected);
     4525    print("obtained:\n");
     4526    print(obtained);
     4527    result = 0;
     4528  }
     4529  //Test 2: poly 1 does not divide poly 2
     4530  expected = 0;
     4531  obtained = divides(x+y, x-y, invo);
     4532  if (expected!=obtained)
     4533  {
     4534    print("Test 2 for divides failed.");
     4535    print("Expected:\n");
     4536    print(expected);
     4537    print("obtained:\n");
     4538    print(obtained);
     4539    result = 0;
     4540  }
     4541  //Test 3: poly 1 does divide poly 2 from the left
     4542  expected = 1;
     4543  obtained = divides(x+y, (x+y)*(x-y), invo);
     4544  list  poly_expected = list(list(number(1),x+y,x-y));
     4545  list  poly_obtained = divides(x+y, (x+y)*(x-y), invo,1);
     4546  if (expected!=obtained||!isListEqual(poly_expected,poly_obtained))
     4547  {
     4548    print("Test 3 for divides failed.");
     4549    print("Expected 1:\n");
     4550    print(expected);
     4551    print("Obtained 1:\n");
     4552    print(obtained);
     4553    print("Expected 2:\n");
     4554    print(poly_expected);
     4555    print("Obtained 2:\n");
     4556    print(poly_obtained);
     4557    result = 0;
     4558  }
     4559  //Test 4: poly 1 does divide poly 2 from the right
     4560  expected = 1;
     4561  obtained = divides(x+y, (x-y)*(x+y), invo);
     4562  poly_expected = list(list(1,x-y,x+y));
     4563  poly_obtained = divides(x+y, (x-y)*(x+y), invo,1);
     4564  if (expected!=obtained)
     4565  {
     4566    print("Test 4 for divides failed.");
     4567    print("Expected:\n");
     4568    print(expected);
     4569    print("obtained:\n");
     4570    print(obtained);
     4571    print("Expected 2:\n");
     4572    print(poly_expected);
     4573    print("Obtained 2:\n");
     4574    print(poly_obtained);
     4575    result = 0;
     4576  }
     4577  kill R; kill r;
     4578  //Test 5: different algebra, no division
     4579  ring R = 0,(x1,x2,n1,n2),dp;
     4580  matrix C[4][4] = 1,1,1,1,
     4581    1,1,1,1,
     4582    1,1,1,1,
     4583    1,1,1,1;
     4584  matrix D[4][4] = 0,0,n1,0,
     4585    0,0,0,n2,
     4586    0,0,0,0,
     4587    0,0,0,0;
     4588  def r = nc_algebra(C,D);
     4589  setring r;
     4590  map invo = r, -x1,-x2,n1,n2;
     4591  expected = 0;
     4592  obtained = divides(x1+n1, (x1-n1), invo);
     4593  if (expected!=obtained)
     4594  {
     4595    print("Test 5 for divides failed.");
     4596    print("Expected:\n");
     4597    print(expected);
     4598    print("obtained:\n");
     4599    print(obtained);
     4600    result = 0;
     4601  }
     4602  //Test 6: different algebra, division from both sides
     4603  expected = 1;
     4604  obtained = divides(x1+n1, (x1+n1)*(x1-n1)*(x1+n1), invo);
     4605  list poly_expected = list(list(number(1), (x1+n1),(x1-n1)*(x1+n1)),
     4606                list(number(1), (x1+n1)*(x1-n1),(x1+n1)));
     4607  list poly_obtained = divides(x1+n1, (x1+n1)*(x1-n1)*(x1+n1), invo,1);
     4608  if (expected!=obtained||!isListEqual(poly_expected,poly_obtained))
     4609  {
     4610    print("Test 6 for divides failed.");
     4611    print("Expected:\n");
     4612    print(expected);
     4613    print("obtained:\n");
     4614    print(obtained);
     4615    print("Expected 2:\n");
     4616    print(poly_expected);
     4617    print("Obtained 2:\n");
     4618    print(poly_obtained);
     4619    result = 0;
     4620  }
     4621  //Test 7: Content is not 1
     4622  expected = 1;
     4623  obtained = divides(x1+n1, 5*(x1+n1)*(x1-n1)*(x1+n1), invo);
     4624  poly_expected = list(list(number(5), (x1+n1),(x1-n1)*(x1+n1)),
     4625               list(number(5), (x1+n1)*(x1-n1),(x1+n1)));
     4626  poly_obtained = divides(x1+n1, 5*(x1+n1)*(x1-n1)*(x1+n1), invo,1);
     4627  if (expected!=obtained||!isListEqual(poly_expected,poly_obtained))
     4628  {
     4629    print("Test 7 for divides failed.");
     4630    print("Expected:\n");
     4631    print(expected);
     4632    print("obtained:\n");
     4633    print(obtained);
     4634    print("Expected 2:\n");
     4635    print(poly_expected);
     4636    print("Obtained 2:\n");
     4637    print(poly_obtained);
     4638    result = 0;
     4639  }
     4640  return(result);
     4641}//testing divides
     4642
     4643
     4644static proc multiplyFactIntOutput(list l)
     4645"Given the output of factorizeInt, this method computes the product of it."
     4646{//proc multiplyFactIntOutput
     4647  int i;
     4648  number result = 1;
     4649  for (i = 1; i<=size(l[1]); i++)
     4650  {
     4651    result = result*(l[1][i])^(l[2][i]);
     4652  }
     4653  return(result);
     4654}//proc multiplyFactIntOutput
     4655
     4656
     4657static proc test_multiplyFactIntOutput()
     4658{//testing multiplyFactIntOutput
     4659  int result = 1;
     4660  //Test 1: empty list
     4661  ring R = 0,(x),dp;
     4662  number expected = 1;
     4663  number obtained = multiplyFactIntOutput(list(list(),list()));
     4664  if (expected!=obtained)
     4665  {
     4666    print("Test 1 for multiplyFactIntOutput failed.");
     4667    print("Expected:\n");
     4668    print(expected);
     4669    print("obtained:\n");
     4670    print(obtained);
     4671    result = 0;
     4672  }
     4673  //Test 2: 1
     4674  expected = 1;
     4675  obtained = multiplyFactIntOutput(factorizeInt(1));
     4676  if (expected!=obtained)
     4677  {
     4678    print("Test 2 for multiplyFactIntOutput failed.");
     4679    print("Expected:\n");
     4680    print(expected);
     4681    print("obtained:\n");
     4682    print(obtained);
     4683    result = 0;
     4684  }
     4685  //Test 3: prime
     4686  expected = 5;
     4687  obtained = multiplyFactIntOutput(factorizeInt(5));
     4688  if (expected!=obtained)
     4689  {
     4690    print("Test 3 for multiplyFactIntOutput failed.");
     4691    print("Expected:\n");
     4692    print(expected);
     4693    print("obtained:\n");
     4694    print(obtained);
     4695    result = 0;
     4696  }
     4697  //Test 4: Arbitrary composite
     4698  expected = 5*10*66;
     4699  obtained = multiplyFactIntOutput(factorizeInt(5*10*66));
     4700  if (expected!=obtained)
     4701  {
     4702    print("Test 4 for multiplyFactIntOutput failed.");
     4703    print("Expected:\n");
     4704    print(expected);
     4705    print("obtained:\n");
     4706    print(obtained);
     4707    result = 0;
     4708  }
     4709  //Test 5: 0
     4710  expected = 0;
     4711  obtained = multiplyFactIntOutput(factorizeInt(0));
     4712  if (expected!=obtained)
     4713  {
     4714    print("Test 5 for multiplyFactIntOutput failed.");
     4715    print("Expected:\n");
     4716    print(expected);
     4717    print("obtained:\n");
     4718    print(obtained);
     4719    result = 0;
     4720  }
     4721  return(result);
     4722}//testing multiplyFactIntOutput
     4723
     4724
     4725//Testfac: Given a list with different factorizations of
     4726// one polynomial, the following procedure checks
     4727// whether they all refer to the same polynomial.
     4728// If they do, the output will be a list, that contains
     4729// the product of each factorization. If not, the empty
     4730// list will be returned.
     4731// If the optional argument # is given (i.e. the polynomial
     4732// which is factorized by the elements of the given list),
     4733// then we look, if the entries are factorizations of p
     4734// and if not, a list with the products subtracted by p
     4735// will be returned
     4736proc testNCfac(list l, list #)
     4737"USAGE: testNCfac(l[,p,b]); l is a list, p is an optional poly, b is 1 or 0
     4738RETURN: Case 1: No optional argument. In this case the output is 1, if the
     4739  entries in the given list represent the same polynomial or 0
     4740  otherwise.
     4741 Case 2: One optional argument p is given. In this case it returns 1,
     4742  if all the entries in l are factorizations of p, otherwise 0.
     4743 Case 3: Second optional b is given. In this case a list is returned
     4744  containing the difference between the product of each entry in
     4745  l and p.
     4746ASSUME: basering is the first Weyl algebra, the entries of l are polynomials
     4747PURPOSE: Checks whether a list of factorizations contains factorizations of
     4748  the same element in the first Weyl algebra
     4749THEORY: @code{testNCfac} multiplies out each factorization and checks whether
     4750 each factorization was a factorization of the same element.
     4751@* - if there is only a list given, the output will be 0, if it
     4752     does not contain factorizations of the same element. Otherwise the output
     4753     will be 1.
     4754@* - if there is a polynomial in the second argument, then the procedure checks
     4755     whether the given list contains factorizations of this polynomial. If it
     4756     does, then the output depends on the third argument. If it is not given,
     4757     the procedure will check whether the factorizations in the list
     4758     l are associated to this polynomial and return either 1 or 0, respectively.
     4759     If the third argument is given, the output will be a list with
     4760     the length of the given one and in each entry is the product of one
     4761     entry in l subtracted by the polynomial.
     4762EXAMPLE: example testNCfac; shows examples
     4763SEE ALSO: facFirstWeyl, facSubWeyl, facFirstShift
     4764"{//proc testfac
     4765  int p = printlevel - voice + 2;
     4766  int i;
     4767  string dbprintWhitespace = "";
     4768  for (i = 1; i<=voice;i++)
     4769  {dbprintWhitespace = dbprintWhitespace + " ";}
     4770  dbprint(p,dbprintWhitespace + " Checking the input");
     4771  if (size(l)==0)
     4772  {//The empty list is given
     4773    dbprint(p,dbprintWhitespace + " Given list was empty");
    9294774    return(list());
    930   }//The given polynomial is not homogeneous
    931   if (h==0)
    932   {
    933     return(list(0));
    934   }
     4775  }//The empty list is given
     4776  if (size(#)>2)
     4777  {//We want max. two optional arguments
     4778    dbprint(p,dbprintWhitespace + " More than two optional arguments");
     4779    return(list());
     4780  }//We want max. two optional arguments
     4781  dbprint(p,dbprintWhitespace + " Done");
    9354782  list result;
    936   int m = deg(h,ivm11);
    937   dbprint(p,dbprintWhitespace +" Splitting the polynomial in A_0 and A_k-Part");
    938   if (m!=0)
    939   {//The degree is not zero
    940     if (m <0)
    941     {//There are more x than y
    942       hath = lift(var(1)^(-m),h)[1,1];
    943       for (i = 1; i<=-m; i++)
     4783  int j;
     4784  if (size(#)==0)
     4785  {//No optional argument is given
     4786    dbprint(p,dbprintWhitespace + " No optional arguments");
     4787    int valid = 1;
     4788    for (i = size(l);i>=1;i--)
     4789    {//iterate over the elements of the given list
     4790      if (size(result)>0)
    9444791      {
    945         result = result + list(var(1));
     4792        if (product(l[i])!=result[size(l)-i])
     4793        {
     4794          valid = 0;
     4795          break;
     4796        }
    9464797      }
    947     }//There are more x than y
     4798      result = insert(result, product(l[i]));
     4799    }//iterate over the elements of the given list
     4800    return(valid);
     4801  }//No optional argument is given
     4802  else
     4803  {
     4804    dbprint(p,dbprintWhitespace + " Optional arguments are given.");
     4805    int valid = 1;
     4806    for (i = size(l);i>=1;i--)
     4807    {//iterate over the elements of the given list
     4808      if (product(l[i])!=#[1])
     4809      {
     4810        valid = 0;
     4811      }
     4812      result = insert(result, product(l[i])-#[1]);
     4813    }//iterate over the elements of the given list
     4814    if(size(#)==2)
     4815    {
     4816      dbprint(p,dbprintWhitespace + " A third argument is given. Output is a list now.");
     4817      return(result);
     4818    }
     4819    return(valid);
     4820  }
     4821}//proc testfac
     4822example
     4823{
     4824  "EXAMPLE:";echo=2;
     4825  ring r = 0,(x,y),dp;
     4826  def R = nc_algebra(1,1);
     4827  setring R;
     4828  poly h = (x^2*y^2+1)*(x^2);
     4829  def t1 = facFirstWeyl(h);
     4830  //fist a correct list
     4831  testNCfac(t1);
     4832  //now a correct list with the factorized polynomial
     4833  testNCfac(t1,h);
     4834  //now we put in an incorrect list without a polynomial
     4835  t1[3][3] = y;
     4836  testNCfac(t1);
     4837  // take h as additional input
     4838  testNCfac(t1,h);
     4839  // take h as additional input and output list of differences
     4840  testNCfac(t1,h,1);
     4841}
     4842
     4843
     4844static proc test_testNCfac()
     4845{//testing testNCfac
     4846  int result = 1;
     4847  //Test 1: 1, no second or third parameter
     4848  int expected = 1;
     4849  int obtained = testNCfac(list(list(1)));
     4850  if (expected!=obtained)
     4851  {
     4852    print("Test 1 for testNCfac failed.");
     4853    print("Expected:\n");
     4854    print(expected);
     4855    print("obtained:\n");
     4856    print(obtained);
     4857    result = 0;
     4858  }
     4859  //Test 2: 1, second parameter, no third parameter
     4860  expected = 1;
     4861  obtained = testNCfac(list(list(1)),1);
     4862  if (expected!=obtained)
     4863  {
     4864    print("Test 2 for testNCfac failed.");
     4865    print("Expected:\n");
     4866    print(expected);
     4867    print("obtained:\n");
     4868    print(obtained);
     4869    result = 0;
     4870  }
     4871  //Test 3: 1, all possible parameters set
     4872  list expected_third = list(0);
     4873  list obtained_third = testNCfac(list(list(1)),1,1);
     4874  if (!isListEqual(expected_third,obtained_third))
     4875  {
     4876    print("Test 3 for testNCfac failed.");
     4877    print("Expected:\n");
     4878    print(expected_third);
     4879    print("obtained:\n");
     4880    print(obtained_third);
     4881    result = 0;
     4882  }
     4883  //Test 4: correct factorization, more than one element, no second or
     4884  //third parameter
     4885  ring R = 0,(x,d),dp;
     4886  def r = nc_algebra(1,1);
     4887  setring r;
     4888  expected = 1;
     4889  obtained =
     4890    testNCfac(list(list(1,x4d-x3d-3x3+3x2d+6x2-3xd-3x+12,x2d+xd-3x-1),
     4891           list(1,x4d+x3d-4x3+3x2d-3x2+3xd-6x-3,x2d-xd-2x+4)));
     4892  if (expected!=obtained)
     4893  {
     4894    print("Test 4 for testNCfac failed.");
     4895    print("Expected:\n");
     4896    print(expected);
     4897    print("obtained:\n");
     4898    print(obtained);
     4899    result = 0;
     4900  }
     4901  //Test 5: correct factorization, more than one element, correct second
     4902  //but not third parameter
     4903  expected = 1;
     4904  obtained =
     4905    testNCfac(list(list(1,x4d-x3d-3x3+3x2d+6x2-3xd-3x+12,x2d+xd-3x-1),
     4906           list(1,x4d+x3d-4x3+3x2d-3x2+3xd-6x-3,x2d-xd-2x+4)),
     4907      (x^6+2*x^4-3*x^2)*d^2-(4*x^5-4*x^4-12*x^2-12*x)*d +
     4908      (6*x^4-12*x^3-6*x^2-24*x-12));
     4909  if (expected!=obtained)
     4910  {
     4911    print("Test 5 for testNCfac failed.");
     4912    print("Expected:\n");
     4913    print(expected);
     4914    print("obtained:\n");
     4915    print(obtained);
     4916    result = 0;
     4917  }
     4918  //Test 6: incorrect factorization, more than one element, incorrect second
     4919  //but not third parameter
     4920  expected = 0;
     4921  obtained =
     4922    testNCfac(list(list(1,x4d-x3d-3x3+3x2d+6x2-3xd-3x+12,x2d+xd-3x-1),
     4923           list(1,x4d+x3d-4x3+3x2d-3x2+3xd-6x-3,x2d-xd-2x+4)),
     4924      (x^6+2*x^4-3*x^2)*d^2-(4*x^5-4*x^4-12*x^2-12*x)*d +
     4925      (6*x^4-12*x^3-6*x^2-24*x+12));
     4926  if (expected!=obtained)
     4927  {
     4928    print("Test 6 for testNCfac failed.");
     4929    print("Expected:\n");
     4930    print(expected);
     4931    print("obtained:\n");
     4932    print(obtained);
     4933    result = 0;
     4934  }
     4935  //Test 7: incorrect factorization, more than one element, no second
     4936  //or third parameter
     4937  expected = 0;
     4938  obtained =
     4939    testNCfac(list(list(1,x4d-x3d-3x3+3x2d+6x2-3xd-3x+12,x2d+xd-3x-1),
     4940           list(1,x4d+x3d-4x3+3x2d-3x2+3xd-6x-3,x2d-xd-2x-4)));
     4941  if (expected!=obtained)
     4942  {
     4943    print("Test 7 for testNCfac failed.");
     4944    print("Expected:\n");
     4945    print(expected);
     4946    print("obtained:\n");
     4947    print(obtained);
     4948    result = 0;
     4949  }
     4950  //Test 8: correct factorization, more than one element, correct second
     4951  //and third parameter
     4952  expected_third = list(poly(0),poly(0));
     4953  obtained_third =
     4954    testNCfac(list(list(1,x4d-x3d-3x3+3x2d+6x2-3xd-3x+12,x2d+xd-3x-1),
     4955           list(1,x4d+x3d-4x3+3x2d-3x2+3xd-6x-3,x2d-xd-2x+4)),
     4956          (x^6+2*x^4-3*x^2)*d^2-(4*x^5-4*x^4-12*x^2-12*x)*d +
     4957          (6*x^4-12*x^3-6*x^2-24*x-12),1);
     4958  if (!isListEqual(expected_third,obtained_third))
     4959  {
     4960    print("Test 8 for testNCfac failed.");
     4961    print("Expected:\n");
     4962    print(expected_third);
     4963    print("obtained:\n");
     4964    print(obtained_third);
     4965    result = 0;
     4966  }
     4967  //Test 9: incorrect factorization, more than one element, correct second
     4968  //and third parameter
     4969  expected_third = list(poly(2x4d-2x3d-6x3+6x2d+12x2-6xd-6x+24),poly(0));
     4970  obtained_third =
     4971    testNCfac(list(list(1,x4d-x3d-3x3+3x2d+6x2-3xd-3x+12,x2d+xd-3x+1),
     4972           list(1,x4d+x3d-4x3+3x2d-3x2+3xd-6x-3,x2d-xd-2x+4)),
     4973          (x^6+2*x^4-3*x^2)*d^2-(4*x^5-4*x^4-12*x^2-12*x)*d +
     4974          (6*x^4-12*x^3-6*x^2-24*x-12),1);
     4975  if (!isListEqual(expected_third,obtained_third))
     4976  {
     4977    print("Test 9 for testNCfac failed.");
     4978    print("Expected:\n");
     4979    print(expected_third);
     4980    print("obtained:\n");
     4981    print(obtained_third);
     4982    result = 0;
     4983  }
     4984  //Test 9: correct factorization, more than one element, incorrect second
     4985  //and third parameter
     4986  expected_third = list(poly(-24),poly(-24));
     4987  obtained_third =
     4988    testNCfac(list(list(1,x4d-x3d-3x3+3x2d+6x2-3xd-3x+12,x2d+xd-3x-1),
     4989           list(1,x4d+x3d-4x3+3x2d-3x2+3xd-6x-3,x2d-xd-2x+4)),
     4990          (x^6+2*x^4-3*x^2)*d^2-(4*x^5-4*x^4-12*x^2-12*x)*d +
     4991          (6*x^4-12*x^3-6*x^2-24*x+12),1);
     4992  if (!isListEqual(expected_third,obtained_third))
     4993  {
     4994    print("Test 9 for testNCfac failed.");
     4995    print("Expected:\n");
     4996    print(expected_third);
     4997    print("obtained:\n");
     4998    print(obtained_third);
     4999    result = 0;
     5000  }
     5001  return(result);
     5002}//testing testNCfac
     5003
     5004
     5005static proc monsSmallerThan(poly e, intvec maxDegInCoordinates)
     5006"USAGE: monsSmallerThan(e, maxDegInCoordinates); e is a
     5007polynomial, but we are only interested in its leading monomial.
     5008maxDegInCoordinates encodes the maximal degree we want to encounter
     5009in each variable.
     5010RETURN: list
     5011PURPOSE: Computes all monomials in the basering which are degree-wise
     5012smaller than the leading monomial of e.
     5013"{//monsSmallerThan
     5014  int p=printlevel-voice+2;//for dbprint
     5015  int i;
     5016  string dbprintWhitespace = "";
     5017  for (i = 1; i<=voice;i++)
     5018  {dbprintWhitespace = dbprintWhitespace + " ";}
     5019  list result;
     5020  intvec tempIntVec = leadexp(1);
     5021  while(increment_intvec(tempIntVec,maxDegInCoordinates) != tempIntVec)
     5022  {//counting through all possible monomials
     5023    tempIntVec = increment_intvec(tempIntVec,maxDegInCoordinates);
     5024    if (monomial(tempIntVec)<leadmonom(e))
     5025    {
     5026      result = insert(result, monomial(tempIntVec));
     5027    }
     5028  }//counting through all possible monomials
     5029  return(result);
     5030}//monsSmallerThan
     5031
     5032
     5033static proc test_monsSmallerThan()
     5034{//testing monsSmallerThan
     5035  int result = 1;
     5036  ring R = 0,(x,y,z,d,w),lp;
     5037  //Test 1: 0
     5038  poly input1 = 0;
     5039  intvec input2 = intvec(2,2,2,2,2);
     5040  list expected = list();
     5041  list obtained = monsSmallerThan(input1, input2);
     5042  if (!isListEqual(expected,obtained))
     5043  {
     5044    print("Test 1 for monsSmallerThan failed.");
     5045    print("Expected:\n");
     5046    print(expected);
     5047    print("obtained:\n");
     5048    print(obtained);
     5049    result = 0;
     5050  }
     5051  //Test 2: 1
     5052  input1 = 1;
     5053  input2 = intvec(2,2,2,2,2);
     5054  expected = list();
     5055  obtained = monsSmallerThan(input1, input2);
     5056  if (!isListEqual(expected,obtained))
     5057  {
     5058    print("Test 2 for monsSmallerThan failed.");
     5059    print("Expected:\n");
     5060    print(expected);
     5061    print("obtained:\n");
     5062    print(obtained);
     5063    result = 0;
     5064  }
     5065  //Test 3: lowest monomial
     5066  input1 = w;
     5067  input2 = intvec(2,2,2,2,2);
     5068  expected = list();
     5069  obtained = monsSmallerThan(input1, input2);
     5070  if (!isListEqual(expected,obtained))
     5071  {
     5072    print("Test 3 for monsSmallerThan failed.");
     5073    print("Expected:\n");
     5074    print(expected);
     5075    print("obtained:\n");
     5076    print(obtained);
     5077    result = 0;
     5078  }
     5079  //Test 4: second lowest monomial
     5080  input1 = d;
     5081  input2 = intvec(2,2,2,2,2);
     5082  expected = list(w^2,w);
     5083  obtained = monsSmallerThan(input1, input2);
     5084  if (!isListEqual(expected,obtained))
     5085  {
     5086    print("Test 4 for monsSmallerThan failed.");
     5087    print("Expected:\n");
     5088    print(expected);
     5089    print("obtained:\n");
     5090    print(obtained);
     5091    result = 0;
     5092  }
     5093  //Test 5: third lowest monomial, no second lowest
     5094  input1 = z;
     5095  input2 = intvec(2,2,2,0,2);
     5096  expected = list(w^2,w);
     5097  obtained = monsSmallerThan(input1, input2);
     5098  if (!isListEqual(expected,obtained))
     5099  {
     5100    print("Test 5 for monsSmallerThan failed.");
     5101    print("Expected:\n");
     5102    print(expected);
     5103    print("obtained:\n");
     5104    print(obtained);
     5105    result = 0;
     5106  }
     5107  //Test 6: highest monomial, random max degrees for the others
     5108  input1 = x;
     5109  input2 = intvec(3,1,1,0,1);
     5110  expected = list(yzw,yz,yw,y,zw,z,w);
     5111  obtained = monsSmallerThan(input1, input2);
     5112  if (!isListEqual(expected,obtained))
     5113  {
     5114    print("Test 6 for monsSmallerThan failed.");
     5115    print("Expected:\n");
     5116    print(expected);
     5117    print("obtained:\n");
     5118    print(obtained);
     5119    result = 0;
     5120  }
     5121  return (result);
     5122}//testing monsSmallerThan
     5123
     5124
     5125static proc getMaxDegreeVec(poly h)
     5126"USAGE: getMaxDegreeVec(h); h is a polynomial in the
     5127current ring.
     5128RETURN: intvec
     5129PURPOSE: Returns for each variable in the ring the maximal
     5130         degree in which it appears in h.
     5131"
     5132{
     5133  if (h == 0)
     5134  {return(0:nvars(basering));}
     5135  intvec tempIntVec1 = 0:nvars(basering);
     5136  intvec maxDegrees = 0:nvars(basering);
     5137  int i;
     5138  for (i = 1; i <= nvars(basering); i++)
     5139  {//filling maxDegrees
     5140    tempIntVec1 = 0:nvars(basering);
     5141    tempIntVec1[i] = 1;
     5142    maxDegrees[i] = deg(h,tempIntVec1);
     5143  }//filling maxDegrees
     5144  return(maxDegrees);
     5145}
     5146
     5147
     5148static proc test_getMaxDegreeVec()
     5149{//testing getMaxDegreeVec
     5150  int result = 1;
     5151  //Test1: 0
     5152  ring R = 0,(u,v,w,x,y,z),dp;
     5153  intvec expected = 0:6;
     5154  intvec obtained = getMaxDegreeVec(0);
     5155  if (expected!=obtained)
     5156  {
     5157    print("Test 1 for getMaxDegreeVec failed.");
     5158    print("Expected:\n");
     5159    print(expected);
     5160    print("obtained:\n");
     5161    print(obtained);
     5162    result = 0;
     5163  }
     5164  //Test2: Constant neq 0
     5165  expected = 0:6;
     5166  obtained = getMaxDegreeVec(5);
     5167  if (expected!=obtained)
     5168  {
     5169    print("Test 2 for getMaxDegreeVec failed.");
     5170    print("Expected:\n");
     5171    print(expected);
     5172    print("obtained:\n");
     5173    print(obtained);
     5174    result = 0;
     5175  }
     5176  //Test 3: univariate, first variable
     5177  expected = 2,0,0,0,0,0;
     5178  obtained = getMaxDegreeVec(5*u^2 + u + 1);
     5179  if (expected!=obtained)
     5180  {
     5181    print("Test 3 for getMaxDegreeVec failed.");
     5182    print("Expected:\n");
     5183    print(expected);
     5184    print("obtained:\n");
     5185    print(obtained);
     5186    result = 0;
     5187  }
     5188  //Test 4: univariate, another variable
     5189  expected = 0,0,0,3,0,0;
     5190  obtained = getMaxDegreeVec(5*x^3 + x^2 + 1);
     5191  if (expected!=obtained)
     5192  {
     5193    print("Test 4 for getMaxDegreeVec failed.");
     5194    print("Expected:\n");
     5195    print(expected);
     5196    print("obtained:\n");
     5197    print(obtained);
     5198    result = 0;
     5199  }
     5200  //Test 5: random polynomial
     5201  expected = 3,1,2,4,3,2;
     5202  obtained = getMaxDegreeVec(u^3*x^2*v*w^2*z + x^4 + y^3*z^2 + 1);
     5203  if (expected!=obtained)
     5204  {
     5205    print("Test 5 for getMaxDegreeVec failed.");
     5206    print("Expected:\n");
     5207    print(expected);
     5208    print("obtained:\n");
     5209    print(obtained);
     5210    result = 0;
     5211  }
     5212  return(result);
     5213}//testing getMaxDegreeVec
     5214
     5215
     5216static proc isFactorizationSmaller(list f1, list f2)
     5217"USAGE: isFactorizationSmallerEq(f1,f2); f1 and f2 are lists
     5218        containing polynomials
     5219RETURN: bool
     5220PURPOSE: Checks entry-wise of all factorizations in f1 are smaller
     5221         than the ones in f2 (lexicographic order, starting from
     5222     the first position).
     5223"{//proc isFactorizationSmaller
     5224  return (string(f1)<string(f2));
     5225}//proc isFactorizationSmaller
     5226
     5227
     5228static proc test_isFactorizationSmaller()
     5229{//isFactorizationSmaller
     5230  int result = 1;
     5231  ring R = 0,(x,d),dp;
     5232  def r = nc_algebra(1,1);
     5233  setring r;
     5234  //Test 1: Two equal lists, empty
     5235  list input1 = list();
     5236  list input2 = list();
     5237  int expected = 0;
     5238  int obtained = isFactorizationSmaller(input1,input2);
     5239  if (expected!=obtained)
     5240  {
     5241    print("Test 1 for isFactorizationSmaller failed.");
     5242    print("Expected:\n");
     5243    print(expected);
     5244    print("obtained:\n");
     5245    print(obtained);
     5246    result = 0;
     5247  }
     5248  //Test 2: Two not equal lists, first one is empty
     5249  input1 = list(1,2,3);
     5250  input2 = list();
     5251  expected = 0;
     5252  obtained = isFactorizationSmaller(input1,input2);
     5253  if (expected!=obtained)
     5254  {
     5255    print("Test 2 for isFactorizationSmaller failed.");
     5256    print("Expected:\n");
     5257    print(expected);
     5258    print("obtained:\n");
     5259    print(obtained);
     5260    result = 0;
     5261  }
     5262  //Test 3: Two not equal lists, second one is empty
     5263  input1 = list();
     5264  input2 = list(1,2,3);
     5265  expected = 1;
     5266  obtained = isFactorizationSmaller(input1,input2);
     5267  if (expected!=obtained)
     5268  {
     5269    print("Test 3 for isFactorizationSmaller failed.");
     5270    print("Expected:\n");
     5271    print(expected);
     5272    print("obtained:\n");
     5273    print(obtained);
     5274    result = 0;
     5275  }
     5276  //Test 4: Two different factorizations, real ones
     5277  input1 = list(1,x4d-x3d-3x3+3x2d+6x2-3xd-3x+12,x2d+xd-3x-1);
     5278  input2 = list(1,x4d+x3d-4x3+3x2d-3x2+3xd-6x-3,x2d-xd-2x+4);
     5279  expected = 0;
     5280  obtained = isFactorizationSmaller(input1,input2);
     5281  if (expected!=obtained)
     5282  {
     5283    print("Test 4 for isFactorizationSmaller failed.");
     5284    print("Expected:\n");
     5285    print(expected);
     5286    print("obtained:\n");
     5287    print(obtained);
     5288    result = 0;
     5289  }
     5290  //Test 5: Same as test 4, but reversed
     5291  input1 = list(1,x4d+x3d-4x3+3x2d-3x2+3xd-6x-3,x2d-xd-2x+4);
     5292  input2 = list(1,x4d-x3d-3x3+3x2d+6x2-3xd-3x+12,x2d+xd-3x-1);
     5293  expected = 1;
     5294  obtained = isFactorizationSmaller(input1,input2);
     5295  if (expected!=obtained)
     5296  {
     5297    print("Test 5 for isFactorizationSmaller failed.");
     5298    print("Expected:\n");
     5299    print(expected);
     5300    print("obtained:\n");
     5301    print(obtained);
     5302    result = 0;
     5303  }
     5304  return(result);
     5305}//testing isFactorizationSmaller
     5306
     5307
     5308static proc sortedInsert(list newFact, list factList)
     5309"USAGE: sortedInsert(newFact, factList); newFact is a list that
     5310represents a factorization of a certain polynomial, and factList is a
     5311list containing several different factorizations of the same
     5312polynomial.
     5313RETURN: list(list)
     5314PURPOSE: Inserts newFact into factList, if not yet contained in
     5315         factList.
     5316"{//proc sortedInsert
     5317  int first = 1;
     5318  int last = size(factList);
     5319  int middle;
     5320  while (first <= last)
     5321  {
     5322    middle = first + ((last - first) div 2);
     5323    if (isFactorizationSmaller(factList[middle], newFact))
     5324    {
     5325      first = middle + 1;
     5326    }
    9485327    else
    949     {//There are more y than x
    950       hath = lift(var(2)^m,h)[1,1];
    951       for (i = 1; i<=m;i++)
     5328    {
     5329      if (isFactorizationSmaller(newFact, factList[middle]))
    9525330      {
    953         result = result + list(var(2));
     5331        last = middle -1;
    9545332      }
    955     }//There are more y than x
    956   }//The degree is not zero
    957   else
    958   {//The degree is zero
    959     hath = h;
    960   }//The degree is zero
    961   dbprint(p,dbprintWhitespace+" Done");
    962   //beginning to transform x^i*y^i in theta(theta-1)...(theta-i+1)
    963   list mons;
    964   dbprint(p,dbprintWhitespace+" Putting the monomials in the A_0-part in a list.");
    965   for(i = 1; i<=size(hath);i++)
    966   {//Putting the monomials in a list
    967     mons = mons+list(hath[i]);
    968   }//Putting the monomials in a list
    969   dbprint(p,dbprintWhitespace+" Done");
    970   dbprint(p,dbprintWhitespace+" Mapping this monomials to K[theta]");
    971   ring tempRing = 0,(x,y,theta),dp;
    972   setring tempRing;
    973   map thetamap = r,x,y;
    974   list mons = thetamap(mons);
    975   poly entry;
    976   for (i = 1; i<=size(mons);i++)
    977   {//transforming the monomials as monomials in theta
    978     entry = leadcoef(mons[i]);
    979     for (j = 0; j<leadexp(mons[i])[2];j++)
     5333      else
     5334      {
     5335        return(factList);
     5336      }
     5337    }
     5338  }
     5339  return(insert(factList,newFact,first-1));
     5340}//proc sortedInsert
     5341
     5342
     5343static proc test_sortedInsert()
     5344{//testing sortedInsert
     5345  int result = 1;
     5346  //Test 1: empty list to insert into emtpy list
     5347  ring R = 0,(x,d),dp;
     5348  def r = nc_algebra(1,1);
     5349  setring r;
     5350  list input1 = list();
     5351  list input2 = list();
     5352  list expected = list(list());
     5353  list obtained = sortedInsert(input1,input2);
     5354  if (!isListEqual(expected,obtained))
     5355  {
     5356    print("Test 1 for sortedInsert failed.");
     5357    print("Expected:\n");
     5358    print(expected);
     5359    print("obtained:\n");
     5360    print(obtained);
     5361    result = 0;
     5362  }
     5363  //Test 2: One element list, insert
     5364  input1 = list(1,x4d+x3d-4x3+3x2d-3x2+3xd-6x-3,x2d-xd-2x+4);
     5365  input2 = list(list(1,x4d-x3d-3x3+3x2d+6x2-3xd-3x+12,x2d+xd-3x-1));
     5366  expected = list(list(1,x4d+x3d-4x3+3x2d-3x2+3xd-6x-3,x2d-xd-2x+4),
     5367    list(1,x4d-x3d-3x3+3x2d+6x2-3xd-3x+12,x2d+xd-3x-1));
     5368  obtained = sortedInsert(input1,input2);
     5369  if (!isListEqual(expected,obtained))
     5370  {
     5371    print("Test 2 for sortedInsert failed.");
     5372    print("Expected:\n");
     5373    print(expected);
     5374    print("obtained:\n");
     5375    print(obtained);
     5376    result = 0;
     5377  }
     5378  //Test 3: Multi-element list, insert in middle
     5379  input1 = list(1,x4d-x3d-2x3+3x2d-3x2+3xd-6x-3,x2d-xd-2x+4);
     5380  input2 = list(list(1,x4d+x3d-4x3+3x2d-3x2+3xd-6x-3,x2d-xd-2x+4),
     5381        list(1,x4d-x3d-3x3+3x2d+6x2-3xd-3x+12,x2d+xd-3x-1));
     5382  expected = list(list(1,x4d+x3d-4x3+3x2d-3x2+3xd-6x-3,x2d-xd-2x+4),
     5383          list(1,x4d-x3d-2x3+3x2d-3x2+3xd-6x-3,x2d-xd-2x+4),
     5384          list(1,x4d-x3d-3x3+3x2d+6x2-3xd-3x+12,x2d+xd-3x-1));
     5385  obtained = sortedInsert(input1,input2);
     5386  if (!isListEqual(expected,obtained))
     5387  {
     5388    print("Test 3 for sortedInsert failed.");
     5389    print("Expected:\n");
     5390    print(expected);
     5391    print("obtained:\n");
     5392    print(obtained);
     5393    result = 0;
     5394  }
     5395  return(result);
     5396}//testing sortedInsert
     5397
     5398
     5399static proc isFactorizationEqual(list l1, list l2)
     5400"USAGE: isFactorizationEqual(l1,l2); l1 and l2 are factorizations of
     5401        the same polynomial.
     5402RETURN: bool
     5403PURPOSE: checks if two lists are equal in every entry.
     5404"{//isFactorizationEqual
     5405  if (size(l1)!=size(l2))
     5406  { return(0); }
     5407  int i;
     5408  for (i=1;i<=size(l1);i++)
     5409  {
     5410    if (l1[i]!=l2[i])
     5411    {return(0);}
     5412  }
     5413  return(1);
     5414}//isFactorizationEqual
     5415
     5416
     5417static proc test_isFactorizationEqual()
     5418{//testing isFactorizationEqual
     5419  int result = 1;
     5420  ring R = 0,(x,d),dp;
     5421  def r = nc_algebra(1,1);
     5422  setring r;
     5423  //Test 1: Two empty lists
     5424  int expected = 1;
     5425  list input1 = list();
     5426  list input2 = list();
     5427  int obtained = isFactorizationEqual(input1,input2);
     5428  if (expected!=obtained)
     5429  {
     5430    print("Test 1 for isFactorizationEqual failed.");
     5431    print("Expected:\n");
     5432    print(expected);
     5433    print("obtained:\n");
     5434    print(obtained);
     5435    result = 0;
     5436  }
     5437  //Test 2: empty list, non-empty list
     5438  expected = 0;
     5439  input1 = list();
     5440  input2 = list(1,x,d);
     5441  obtained = isFactorizationEqual(input1,input2);
     5442  if (expected!=obtained)
     5443  {
     5444    print("Test 2 for isFactorizationEqual failed.");
     5445    print("Expected:\n");
     5446    print(expected);
     5447    print("obtained:\n");
     5448    print(obtained);
     5449    result = 0;
     5450  }
     5451  //Test 3: non-empty list, empty list
     5452  expected = 0;
     5453  input1 = list(1,x,d);
     5454  input2 = list();
     5455  obtained = isFactorizationEqual(input1,input2);
     5456  if (expected!=obtained)
     5457  {
     5458    print("Test 3 for isFactorizationEqual failed.");
     5459    print("Expected:\n");
     5460    print(expected);
     5461    print("obtained:\n");
     5462    print(obtained);
     5463    result = 0;
     5464  }
     5465  //Test 4: Two different factorizations of the same polynomial
     5466  expected = 0;
     5467  input1 = list(1,x4d+x3d-4x3+3x2d-3x2+3xd-6x-3,x2d-xd-2x+4);
     5468  input2 = list(1,x4d-x3d-3x3+3x2d+6x2-3xd-3x+12,x2d+xd-3x-1);
     5469  obtained = isFactorizationEqual(input1,input2);
     5470  if (expected!=obtained)
     5471  {
     5472    print("Test 4 for isFactorizationEqual failed.");
     5473    print("Expected:\n");
     5474    print(expected);
     5475    print("obtained:\n");
     5476    print(obtained);
     5477    result = 0;
     5478  }
     5479  //Test 5: Two same factorizations
     5480  expected = 1;
     5481  input1 = list(1,x4d+x3d-4x3+3x2d-3x2+3xd-6x-3,x2d-xd-2x+4);
     5482  input2 = list(1,x4d+x3d-4x3+3x2d-3x2+3xd-6x-3,x2d-xd-2x+4);
     5483  obtained = isFactorizationEqual(input1,input2);
     5484  if (expected!=obtained)
     5485  {
     5486    print("Test 5 for isFactorizationEqual failed.");
     5487    print("Expected:\n");
     5488    print(expected);
     5489    print("obtained:\n");
     5490    print(obtained);
     5491    result = 0;
     5492  }
     5493  return(result);
     5494}//testing isFactorizationEqual
     5495
     5496
     5497static proc sortFactorizations(list factList)
     5498"USAGE: sortFactorizations(factList); factList is a list of different
     5499        factorizations of the same polynomial h.
     5500RETURN: list(list)
     5501PURPOSE: sorts the list of factorizations in O(nlog(n))
     5502"{//sortFactorizations
     5503  if (size(factList)<=1)
     5504  {//empty lists and 1 element lists are already sorted.
     5505    return(factList);
     5506  }//empty lists and 1 element lists are already sorted.
     5507  int middle = size(factList) div 2;
     5508  list left;
     5509  list right;
     5510  int i;
     5511  for (i = 0; i<middle;i++)
     5512  {//filling in left
     5513    left = insert(left, factList[i+1], i);
     5514  }//filling in left
     5515  for (i = middle; i<size(factList);i++)
     5516  {//filling in right
     5517    right = insert(right, factList[i+1], i-middle);
     5518  }//filling in right
     5519  left = sortFactorizations(left);
     5520  right = sortFactorizations(right);
     5521  list result;
     5522  int posl=1;
     5523  int posr=1;
     5524  for (i = 1; i<=size(left)+size(right); i++)
     5525  {//merging the lists
     5526    if (posl > size(left))
     5527    {//we can only insert elements from the right list
     5528      result= insert(result, right[posr], i-1);
     5529      posr++;
     5530    }//we can only insert elements from the right list
     5531    else
     5532    {//in this case we have still elements in the left list
     5533      if (posr>size(right))
     5534      {//only elements from the left list can be filled
     5535    result= insert(result, left[posl], i-1);
     5536    posl++;
     5537      }//only elements from the left list can be filled
     5538      else
     5539      {//We have still both lists available
     5540    if (isFactorizationSmaller(left[posl],right[posr]))
    9805541    {
    981       entry = entry * (theta-j);
     5542      result= insert(result, left[posl], i-1);
     5543      posl++;
    9825544    }
    983     mons[i] = entry;
    984   }//transforming the monomials as monomials in theta
    985   dbprint(p,dbprintWhitespace+" Done");
    986   dbprint(p,dbprintWhitespace+" Factorize the A_0-Part in K[theta]");
    987   list azeroresult = factorize(sum(mons));
    988   dbprint(p,dbprintWhitespace+" Successful");
    989   list azeroresult_return_form;
    990   for (i = 1; i<=size(azeroresult[1]);i++)
    991   {//rewrite the result of the commutative factorization
    992     for (j = 1; j <= azeroresult[2][i];j++)
     5545    else
    9935546    {
    994       azeroresult_return_form = azeroresult_return_form + list(azeroresult[1][i]);
     5547      result= insert(result, right[posr], i-1);
     5548      posr++;
    9955549    }
    996   }//rewrite the result of the commutative factorization
    997   dbprint(p,dbprintWhitespace+" Mapping back to A_0.");
     5550      }//We have still both lists available
     5551    }//in this case we have still elements in the left list
     5552  }//merging the lists
     5553  return(result);
     5554}//sortFactorizations
     5555
     5556
     5557static proc test_sortFactorizations()
     5558{//testing sortFactorizations
     5559  int result = 1;
     5560  //Test 1: empty list
     5561  list input = list();
     5562  list expected = list();
     5563  list obtained = sortFactorizations(input);
     5564  if (!isListEqual(expected,obtained))
     5565  {
     5566    print("Test 1 for sortFactorizations failed.");
     5567    print("Expected:\n");
     5568    print(expected);
     5569    print("obtained:\n");
     5570    print(obtained);
     5571    result = 0;
     5572  }
     5573  //Test 2: sorted list, two elements
     5574  ring R = 0,(x,d),dp;
     5575  def r = nc_algebra(1,1);
    9985576  setring(r);
    999   map finalmap = tempRing,var(1),var(2),var(1)*var(2);
    1000   list tempresult = finalmap(azeroresult_return_form);
    1001   dbprint(p,dbprintWhitespace+"Successful.");
    1002   for (i = 1; i<=size(tempresult);i++)
    1003   {//factorizations of theta resp. theta +1
    1004     if(tempresult[i]==var(1)*var(2))
    1005     {
    1006       tempresult = insert(tempresult,var(1),i-1);
    1007       i++;
    1008       tempresult[i]=var(2);
    1009     }
    1010     if(tempresult[i]==var(2)*var(1))
    1011     {
    1012       tempresult = insert(tempresult,var(2),i-1);
    1013       i++;
    1014       tempresult[i]=var(1);
    1015     }
    1016   }//factorizations of theta resp. theta +1
    1017   result = tempresult+result;
     5577  input = list(list(1,x4d+x3d-4x3+3x2d-3x2+3xd-6x-3,x2d-xd-2x+4),
     5578           list(1,x4d-x3d-3x3+3x2d+6x2-3xd-3x+12,x2d+xd-3x-1));
     5579  expected = input;
     5580  obtained = sortFactorizations(input);
     5581  if (!isListEqual(expected,obtained))
     5582  {
     5583    print("Test 2 for sortFactorizations failed.");
     5584    print("Expected:\n");
     5585    print(expected);
     5586    print("obtained:\n");
     5587    print(obtained);
     5588    result = 0;
     5589  }
     5590  //Test 3: unsorted list, two elements
     5591  input = list(list(1,x4d-x3d-3x3+3x2d+6x2-3xd-3x+12,x2d+xd-3x-1),
     5592           list(1,x4d+x3d-4x3+3x2d-3x2+3xd-6x-3,x2d-xd-2x+4));
     5593  expected = list(list(1,x4d+x3d-4x3+3x2d-3x2+3xd-6x-3,x2d-xd-2x+4),
     5594          list(1,x4d-x3d-3x3+3x2d+6x2-3xd-3x+12,x2d+xd-3x-1));
     5595  obtained = sortFactorizations(input);
     5596  if (!isListEqual(expected,obtained))
     5597  {
     5598    print("Test 3 for sortFactorizations failed.");
     5599    print("Expected:\n");
     5600    print(expected);
     5601    print("obtained:\n");
     5602    print(obtained);
     5603    result = 0;
     5604  }
     5605  //Test 4: sorted list, many elements
     5606  input = list(list(1,d,xd-2,x+1,x-1,x2+1),
     5607           list(1,d,xd-2,x+1,x2+1,x-1),
     5608           list(1,d,xd-2,x-1,x+1,x2+1),
     5609           list(1,d,xd-2,x-1,x2+1,x+1),
     5610           list(1,d,xd-2,x2+1,x+1,x-1),
     5611           list(1,d,xd-2,x2+1,x-1,x+1),
     5612           list(1,x3d+3x2+xd-1,d,x+1,x-1),
     5613           list(1,x3d+3x2+xd-1,d,x-1,x+1),
     5614           list(1,xd-1,d,x+1,x-1,x2+1),
     5615           list(1,xd-1,d,x+1,x2+1,x-1),
     5616           list(1,xd-1,d,x-1,x+1,x2+1),
     5617           list(1,xd-1,d,x-1,x2+1,x+1),
     5618           list(1,xd-1,d,x2+1,x+1,x-1),
     5619           list(1, xd-1,d,x2+1,x-1,x+1));
     5620  expected = input;
     5621  obtained = sortFactorizations(input);
     5622  if (!isListEqual(expected,obtained))
     5623  {
     5624    print("Test 4 for sortFactorizations failed.");
     5625    print("Expected:\n");
     5626    print(expected);
     5627    print("obtained:\n");
     5628    print(obtained);
     5629    result = 0;
     5630  }
     5631  //Test 5: unsorted list, many elements
     5632  input = list(list(1,d,xd-2,x-1,x+1,x2+1),
     5633           list(1,d,xd-2,x+1,x-1,x2+1),
     5634           list(1,d,xd-2,x-1,x2+1,x+1),
     5635           list(1,d,xd-2,x2+1,x+1,x-1),
     5636           list(1,d,xd-2,x2+1,x-1,x+1),
     5637           list(1,x3d+3x2+xd-1,d,x-1,x+1),
     5638           list(1,x3d+3x2+xd-1,d,x+1,x-1),
     5639           list(1,xd-1,d,x+1,x-1,x2+1),
     5640           list(1,xd-1,d,x+1,x2+1,x-1),
     5641           list(1,xd-1,d,x-1,x+1,x2+1),
     5642           list(1, xd-1,d,x2+1,x-1,x+1),
     5643           list(1,d,xd-2,x+1,x2+1,x-1),
     5644           list(1,xd-1,d,x-1,x2+1,x+1),
     5645           list(1,xd-1,d,x2+1,x+1,x-1));
     5646  expected = list(list(1,d,xd-2,x+1,x-1,x2+1),
     5647           list(1,d,xd-2,x+1,x2+1,x-1),
     5648           list(1,d,xd-2,x-1,x+1,x2+1),
     5649           list(1,d,xd-2,x-1,x2+1,x+1),
     5650           list(1,d,xd-2,x2+1,x+1,x-1),
     5651           list(1,d,xd-2,x2+1,x-1,x+1),
     5652           list(1,x3d+3x2+xd-1,d,x+1,x-1),
     5653           list(1,x3d+3x2+xd-1,d,x-1,x+1),
     5654           list(1,xd-1,d,x+1,x-1,x2+1),
     5655           list(1,xd-1,d,x+1,x2+1,x-1),
     5656           list(1,xd-1,d,x-1,x+1,x2+1),
     5657           list(1,xd-1,d,x-1,x2+1,x+1),
     5658           list(1,xd-1,d,x2+1,x+1,x-1),
     5659           list(1, xd-1,d,x2+1,x-1,x+1));
     5660  obtained = sortFactorizations(input);
     5661  if (!isListEqual(expected,obtained))
     5662  {
     5663    print("Test 5 for sortFactorizations failed.");
     5664    print("Expected:\n");
     5665    print(expected);
     5666    print("obtained:\n");
     5667    print(obtained);
     5668    result = 0;
     5669  }
    10185670  return(result);
    1019 }//proc homogfacFirstWeyl
    1020 /* example */
    1021 /* { */
    1022 /*      "EXAMPLE:";echo=2; */
    1023 /*      ring R = 0,(x,y),Ws(-1,1); */
    1024 /*      def r = nc_algebra(1,1); */
    1025 /*      setring(r); */
    1026 /*      poly h = (x^2*y^2+1)*(x^4); */
    1027 /*      homogfacFirstWeyl(h); */
    1028 /* } */
    1029 
     5671}//testing sortFactorizations
     5672
     5673
     5674//////////////////////////////////////////////////
     5675//*******N'TH WEYL ALGEBRA SECTION***************
     5676//////////////////////////////////////////////////
    10305677
    10315678static proc homogfacNthWeyl(poly h)
     
    11775824
    11785825
    1179 
    1180 //==================================================
    1181 //Computes all possible homogeneous factorizations
    1182 static proc homogfacFirstWeyl_all(poly h)
    1183 "USAGE: homogfacFirstWeyl_all(h); h is a homogeneous polynomial in the first Weyl algebra
    1184  with respect to the weight vector [-1,1]
    1185 RETURN: list
    1186 PURPOSE: Computes all factorizations of a homogeneous polynomial h with respect
    1187   to the weight vector [-1,1] in the first Weyl algebra
    1188 THEORY: @code{homogfacFirstWeyl} returns a list with all factorization of the given,
    1189  homogeneous polynomial. It uses the output of homogfacFirstWeyl and permutes
    1190  its entries with respect to the commutation rule. Furthermore, if a
    1191  factor of degree zero is irreducible in K[  heta], but reducible in
    1192  the first Weyl algebra, the permutations of this element with the other
    1193  entries will also be computed.
    1194 SEE ALSO: homogfacFirstWeyl
    1195 "{//proc HomogfacFirstWeylAll
    1196   int p=printlevel-voice+2;//for dbprint
    1197   intvec iv11= intvec(1,1);
    1198   if (deg(h,iv11) <= 0 )
    1199   {//h is a constant
    1200     dbprint(p,"Given polynomial was not homogeneous");
    1201     return(list(list(h)));
    1202   }//h is a constant
    1203   def r = basering;
    1204   list one_hom_fac; //stands for one homogeneous factorization
    1205   int i; int j; int k;
    1206   string dbprintWhitespace = "";
    1207   for (i = 1; i<=voice;i++)
    1208   {dbprintWhitespace = dbprintWhitespace + " ";}
    1209   intvec ivm11 = intvec(-1,1);
    1210   dbprint(p,dbprintWhitespace +" Calculate one homogeneous factorization using homogfacFirstWeyl");
    1211   //Compute again a homogeneous factorization
    1212   one_hom_fac = homogfacFirstWeyl(h);
    1213   dbprint(p,dbprintWhitespace +"Successful");
    1214   if (size(one_hom_fac) == 0)
    1215   {//there is no homogeneous factorization or the polynomial was not homogeneous
    1216     return(list());
    1217   }//there is no homogeneous factorization or the polynomial was not homogeneous
    1218   //divide list in A0-Part and a list of x's resp. y's
    1219   list list_not_azero = list();
    1220   list list_azero;
    1221   list k_factor;
    1222   int is_list_not_azero_empty = 1;
    1223   int is_list_azero_empty = 1;
    1224   k_factor = list(one_hom_fac[1]);
    1225   if (absValue(deg(h,ivm11))<size(one_hom_fac)-1)
    1226   {//There is a nontrivial A_0-part
    1227     list_azero = one_hom_fac[2..(size(one_hom_fac)-absValue(deg(h,ivm11)))];
    1228     is_list_azero_empty = 0;
    1229   }//There is a nontrivial A_0 part
    1230   dbprint(p,dbprintWhitespace +" Combine x,y to xy in the factorization again.");
    1231   for (i = 1; i<=size(list_azero)-1;i++)
    1232   {//in homogfacFirstWeyl, we factorized theta, and this will be made undone
    1233     if (list_azero[i] == var(1))
    1234     {
    1235       if (list_azero[i+1]==var(2))
    1236       {
    1237         list_azero[i] = var(1)*var(2);
    1238         list_azero = delete(list_azero,i+1);
    1239       }
    1240     }
    1241     if (list_azero[i] == var(2))
    1242     {
    1243       if (list_azero[i+1]==var(1))
    1244       {
    1245         list_azero[i] = var(2)*var(1);
    1246         list_azero = delete(list_azero,i+1);
    1247       }
    1248     }
    1249   }//in homogfacFirstWeyl, we factorized theta, and this will be made undone
    1250   dbprint(p,dbprintWhitespace +" Done");
    1251   if(deg(h,ivm11)!=0)
    1252   {//list_not_azero is not empty
    1253     list_not_azero =
    1254       one_hom_fac[(size(one_hom_fac)-absValue(deg(h,ivm11))+1)..size(one_hom_fac)];
    1255     is_list_not_azero_empty = 0;
    1256   }//list_not_azero is not empty
    1257   //Map list_azero in K[theta]
    1258   dbprint(p,dbprintWhitespace +" Map list_azero to K[theta]");
    1259   ring tempRing = 0,(x,y,theta), dp;
    1260   setring(tempRing);
    1261   poly entry;
    1262   map thetamap = r,x,y;
    1263   if(!is_list_not_azero_empty)
    1264   {//Mapping in Singular is only possible, if the list before
    1265     //contained at least one element of the other ring
    1266     list list_not_azero = thetamap(list_not_azero);
    1267   }//Mapping in Singular is only possible, if the list before
    1268   //contained at least one element of the other ring
    1269   if(!is_list_azero_empty)
    1270   {//Mapping in Singular is only possible, if the list before
    1271     //contained at least one element of the other ring
    1272     list list_azero= thetamap(list_azero);
    1273   }//Mapping in Singular is only possible, if the list before
    1274   //contained at least one element of the other ring
    1275   list k_factor = thetamap(k_factor);
    1276   list tempmons;
    1277   dbprint(p,dbprintWhitespace +" Done");
    1278   for(i = 1; i<=size(list_azero);i++)
    1279   {//rewrite the polynomials in A1 as polynomials in K[theta]
    1280     tempmons = list();
    1281     for (j = 1; j<=size(list_azero[i]);j++)
    1282     {
    1283       tempmons = tempmons + list(list_azero[i][j]);
    1284     }
    1285     for (j = 1 ; j<=size(tempmons);j++)
    1286     {
    1287       entry = leadcoef(tempmons[j]);
    1288       for (k = 0; k < leadexp(tempmons[j])[2];k++)
    1289       {
    1290         entry = entry*(theta-k);
    1291       }
    1292       tempmons[j] = entry;
    1293     }
    1294     list_azero[i] = sum(tempmons);
    1295   }//rewrite the polynomials in A1 as polynomials in K[theta]
    1296   //Compute all permutations of the A0-part
    1297   dbprint(p,dbprintWhitespace +" Compute all permutations of the A_0-part with the first resp.
    1298 the snd. variable");
    1299   list result;
    1300   int shift_sign;
    1301   int shift;
    1302   poly shiftvar;
    1303   if (size(list_not_azero)!=0)
    1304   {//Compute all possibilities to permute the x's resp. the y's in the list
    1305     if (list_not_azero[1] == x)
    1306     {//h had a negative weighted degree
    1307       shift_sign = 1;
    1308       shiftvar = x;
    1309     }//h had a negative weighted degree
    1310     else
    1311     {//h had a positive weighted degree
    1312       shift_sign = -1;
    1313       shiftvar = y;
    1314     }//h had a positive weighted degree
    1315     result = permpp(list_azero + list_not_azero);
    1316     for (i = 1; i<= size(result); i++)
    1317     {//adjust the a_0-parts
    1318       shift = 0;
    1319       for (j=1; j<=size(result[i]);j++)
    1320       {
    1321         if (result[i][j]==shiftvar)
    1322         {
    1323           shift = shift + shift_sign;
    1324         }
    1325         else
    1326         {
    1327           result[i][j] = subst(result[i][j],theta,theta + shift);
    1328         }
    1329       }
    1330     }//adjust the a_0-parts
    1331   }//Compute all possibilities to permute the x's resp. the y's in the list
    1332   else
    1333   {//The result is just all the permutations of the a_0-part
    1334     result = permpp(list_azero);
    1335   }//The result is just all the permutations of the a_0 part
    1336   if (size(result)==0)
    1337   {
    1338     return(result);
    1339   }
    1340   dbprint(p,dbprintWhitespace +" Done");
    1341   dbprint(p,dbprintWhitespace +" Searching for theta resp. theta+1 in the list and fact. them");
    1342   //Now we are going deeper and search for theta resp. theta + 1, substitute
    1343   //them by xy resp. yx and go on permuting
    1344   int found_theta;
    1345   int thetapos;
    1346   list leftpart;
    1347   list rightpart;
    1348   list lparts;
    1349   list rparts;
    1350   list tempadd;
    1351   for (i = 1; i<=size(result) ; i++)
    1352   {//checking every entry of result for theta or theta +1
    1353     found_theta = 0;
    1354     for(j=1;j<=size(result[i]);j++)
    1355     {
    1356       if (result[i][j]==theta)
    1357       {//the jth entry is theta and can be written as x*y
    1358         thetapos = j;
    1359         result[i]= insert(result[i],x,j-1);
    1360         j++;
    1361         result[i][j] = y;
    1362         found_theta = 1;
    1363         break;
    1364       }//the jth entry is theta and can be written as x*y
    1365       if(result[i][j] == theta +1)
    1366       {
    1367         thetapos = j;
    1368         result[i] = insert(result[i],y,j-1);
    1369         j++;
    1370         result[i][j] = x;
    1371         found_theta = 1;
    1372         break;
    1373       }
    1374     }
    1375     if (found_theta)
    1376     {//One entry was theta resp. theta +1
    1377       leftpart = result[i];
    1378       leftpart = leftpart[1..thetapos];
    1379       rightpart = result[i];
    1380       rightpart = rightpart[(thetapos+1)..size(rightpart)];
    1381       lparts = list(leftpart);
    1382       rparts = list(rightpart);
    1383       //first deal with the left part
    1384       if (leftpart[thetapos] == x)
    1385       {
    1386         shift_sign = 1;
    1387         shiftvar = x;
    1388       }
    1389       else
    1390       {
    1391         shift_sign = -1;
    1392         shiftvar = y;
    1393       }
    1394       for (j = size(leftpart); j>1;j--)
    1395       {//drip x resp. y
    1396         if (leftpart[j-1]==shiftvar)
    1397         {//commutative
    1398           j--;
    1399           continue;
    1400         }//commutative
    1401         if (deg(leftpart[j-1],intvec(-1,1,0))!=0)
    1402         {//stop here
    1403           break;
    1404         }//stop here
    1405         //Here, we can only have a a0- part
    1406         leftpart[j] = subst(leftpart[j-1],theta, theta + shift_sign);
    1407         leftpart[j-1] = shiftvar;
    1408         lparts = lparts + list(leftpart);
    1409       }//drip x resp. y
    1410       //and now deal with the right part
    1411       if (rightpart[1] == x)
    1412       {
    1413         shift_sign = 1;
    1414         shiftvar = x;
    1415       }
    1416       else
    1417       {
    1418         shift_sign = -1;
    1419         shiftvar = y;
    1420       }
    1421       for (j = 1 ; j < size(rightpart); j++)
    1422       {
    1423         if (rightpart[j+1] == shiftvar)
    1424         {
    1425           j++;
    1426           continue;
    1427         }
    1428         if (deg(rightpart[j+1],intvec(-1,1,0))!=0)
    1429         {
    1430           break;
    1431         }
    1432         rightpart[j] = subst(rightpart[j+1], theta, theta - shift_sign);
    1433         rightpart[j+1] = shiftvar;
    1434         rparts = rparts + list(rightpart);
    1435       }
    1436       //And now, we put all possibilities together
    1437       tempadd = list();
    1438       for (j = 1; j<=size(lparts); j++)
    1439       {
    1440         for (k = 1; k<=size(rparts);k++)
    1441         {
    1442           tempadd = tempadd + list(lparts[j]+rparts[k]);
    1443         }
    1444       }
    1445       tempadd = delete(tempadd,1); // The first entry is already in the list
    1446       result = result + tempadd;
    1447       continue; //We can may be not be done already with the ith entry
    1448     }//One entry was theta resp. theta +1
    1449   }//checking every entry of result for theta or theta +1
    1450   dbprint(p,dbprintWhitespace +" Done");
    1451   //map back to the basering
    1452   dbprint(p,dbprintWhitespace +" Mapping back everything to the basering");
     5826static proc test_homogfacNthWeyl()
     5827{//testing homogfacNthWeyl
     5828  int result=1;
     5829  ring R = 0,(x,d),dp;
     5830  def r = nc_algebra(1,1);
    14535831  setring(r);
    1454   map finalmap = tempRing, var(1), var(2),var(1)*var(2);
    1455   list result = finalmap(result);
    1456   for (i=1; i<=size(result);i++)
    1457   {//adding the K factor
    1458     result[i] = k_factor + result[i];
    1459   }//adding the k-factor
    1460   dbprint(p,dbprintWhitespace +" Done");
    1461   dbprint(p,dbprintWhitespace +" Delete double entries in the list.");
    1462   result = delete_dublicates_noteval(result);
    1463   dbprint(p,dbprintWhitespace +" Done");
     5832  //Test 1: 0
     5833  poly input = 0;
     5834  list expected = list(0);
     5835  list obtained = homogfacNthWeyl(input);
     5836  if (!isListEqual(expected,obtained))
     5837  {
     5838    print("Test 1 for homogfacNthWeyl failed.");
     5839    print("Expected:\n");
     5840    print(expected);
     5841    print("obtained:\n");
     5842    print(obtained);
     5843    result = 0;
     5844  }
     5845  //Test 2: Any other constant
     5846  input = 1/3;
     5847  expected = list(poly(1/3));
     5848  obtained = homogfacNthWeyl(input);
     5849  if (!isListEqual(expected,obtained))
     5850  {
     5851    print("Test 2 for homogfacNthWeyl failed.");
     5852    print("Expected:\n");
     5853    print(expected);
     5854    print("obtained:\n");
     5855    print(obtained);
     5856    result = 0;
     5857  }
     5858  //Test 3: one variable first Weyl
     5859  input = 2*x;
     5860  expected = list(poly(2),x);
     5861  obtained = homogfacNthWeyl(input);
     5862  if (!isListEqual(expected,obtained))
     5863  {
     5864    print("Test 3 for homogfacNthWeyl failed.");
     5865    print("Expected:\n");
     5866    print(expected);
     5867    print("obtained:\n");
     5868    print(obtained);
     5869    result = 0;
     5870  }
     5871  //Test 4: reducible polynomial first Weyl
     5872  input = (x*d-1)*(x*d + 4);
     5873  expected = list(poly(1),x*d-1,x*d+4);
     5874  list expected_alt = list(poly(1),x*d+4,x*d-1);
     5875  obtained = homogfacNthWeyl(input);
     5876  if ((!isListEqual(expected,obtained)) and
     5877      (!isListEqual(expected_alt,obtained)))
     5878  {
     5879    print("Test 4 for homogfacNthWeyl failed.");
     5880    print("Expected:\n");
     5881    print(expected);
     5882    print("or");
     5883    print(expected_alt);
     5884    print("obtained:\n");
     5885    print(obtained);
     5886    result = 0;
     5887  }
     5888  //Test 5: irreducible polynomial first Weyl
     5889  input = (x*d-1);
     5890  expected = list(poly(1),x*d-1);
     5891  obtained = homogfacNthWeyl(input);
     5892  if ((!isListEqual(expected,obtained)))
     5893  {
     5894    print("Test 5 for homogfacNthWeyl failed.");
     5895    print("Expected:\n");
     5896    print(expected);
     5897    print("obtained:\n");
     5898    print(obtained);
     5899    result = 0;
     5900  }
     5901  //Test 6: edge case x*d
     5902  input = (x*d);
     5903  expected = list(poly(1),x,d);
     5904  obtained = homogfacNthWeyl(input);
     5905  if ((!isListEqual(expected,obtained)))
     5906  {
     5907    print("Test 6 for homogfacNthWeyl failed.");
     5908    print("Expected:\n");
     5909    print(expected);
     5910    print("obtained:\n");
     5911    print(obtained);
     5912    result = 0;
     5913  }
     5914  //Test 7: edge case x*d+1
     5915  input = (x*d+1);
     5916  expected = list(poly(1),d,x);
     5917  obtained = homogfacNthWeyl(input);
     5918  if ((!isListEqual(expected,obtained)))
     5919  {
     5920    print("Test 7 for homogfacNthWeyl failed.");
     5921    print("Expected:\n");
     5922    print(expected);
     5923    print("obtained:\n");
     5924    print(obtained);
     5925    result = 0;
     5926  }
     5927  kill R;
     5928  kill r;
     5929  //Test 8: Multivariate irreducible
     5930  ring R = 0,(x(1..4),d(1..4)),lp;
     5931  def r = Weyl();
     5932  setring r;
     5933  poly input = x(1)^2*x(3)^2*d(1)^2*d(3)^2-1;
     5934  list expected = list(poly(1), x(1)^2*x(3)^2*d(1)^2*d(3)^2-1);
     5935  list obtained = homogfacNthWeyl(input);
     5936  if ((!isListEqual(expected,obtained)))
     5937  {
     5938    print("Test 8 for homogfacNthWeyl failed.");
     5939    print("Expected:\n");
     5940    print(expected);
     5941    print("obtained:\n");
     5942    print(obtained);
     5943    result = 0;
     5944  }
     5945  //Test 9: Multivariate reducible
     5946  input = (x(1)*d(1)+1)*d(4);
     5947  expected = list(poly(1), d(1),x(1),d(4));
     5948  list expected_alt = list(poly(1), d(1),d(4),x(1));
     5949  list expected_alt2 = list(poly(1), d(4),d(1),x(1));
     5950  obtained = homogfacNthWeyl(input);
     5951  if ((!isListEqual(expected,obtained)) and
     5952      (!isListEqual(expected_alt,obtained)) and
     5953      (!isListEqual(expected,obtained)))
     5954  {
     5955    print("Test 9 for homogfacNthWeyl failed.");
     5956    print("Expected:\n");
     5957    print(expected);
     5958    print("or");
     5959    print(expected_alt);
     5960    print("or");
     5961    print(expected_alt2);
     5962    print("obtained:\n");
     5963    print(obtained);
     5964    result = 0;
     5965  }
    14645966  return(result);
    1465 }//proc HomogfacFirstWeylAll
    1466 /* example */
    1467 /* { */
    1468 /*      "EXAMPLE:";echo=2; */
    1469 /*      ring R = 0,(x,y),Ws(-1,1); */
    1470 /*      def r = nc_algebra(1,1); */
    1471 /*      setring(r); */
    1472 /*      poly h = (x^2*y^2+1)*(x^4); */
    1473 /*      homogfacFirstWeyl_all(h); */
    1474 /* } */
     5967}//testing homogfacNthWeyl
    14755968
    14765969
     
    18156308  dbprint(p,dbprintWhitespace +" Done");
    18166309  dbprint(p,dbprintWhitespace +" Delete double entries in the list.");
    1817   result = delete_dublicates_noteval(result);
     6310  result = delete_duplicates_noteval_and_sort(result);
    18186311  dbprint(p,dbprintWhitespace +" Done");
    18196312  return(result);
     
    18396332h = (x1*x2^2*x3 + d1^2*d2*d3^3*x1^3*x2^3*x3^4)*(x1*d1 + x2*d2 + x3*d3);
    18406333h = x1^2*d1+x1*x2*d2;
    1841 
    1842  */
    1843 
    1844 //==================================================*
    1845 //Computes all permutations of a given list
    1846 static proc perm(list l)
    1847 "
    1848 DEPRECATED
    1849 "
    1850 {//proc perm
    1851   int i; int j;
    1852   list tempresult;
    1853   list result;
    1854   if (size(l)==0)
    1855   {
    1856     return(list());
    1857   }
    1858   if (size(l)==1)
    1859   {
    1860     return(list(l));
    1861   }
    1862   for (i = 1; i<=size(l); i++ )
    1863   {
    1864     tempresult = perm(delete(l,i));
    1865     for (j = 1; j<=size(tempresult);j++)
    1866     {
    1867       tempresult[j] = list(l[i])+tempresult[j];
    1868     }
    1869     result = result+tempresult;
     6334*/
     6335
     6336
     6337static proc test_homogfacNthWeyl_all()
     6338{//testing homogfacNthWeyl_all
     6339  int result=1;
     6340  ring R = 0,(x,d),dp;
     6341  def r = nc_algebra(1,1);
     6342  setring(r);
     6343  //Test 1: 0
     6344  poly input = 0;
     6345  list expected = list(list(poly(0)));
     6346  list obtained = homogfacNthWeyl_all(input);
     6347  if (!isListEqual(expected,obtained))
     6348  {
     6349    print("Test 1 for homogfacNthWeyl_all failed.");
     6350    print("Expected:\n");
     6351    print(expected);
     6352    print("obtained:\n");
     6353    print(obtained);
     6354    result = 0;
     6355  }
     6356  //Test 2: Any other constant
     6357  input = 1/3;
     6358  expected = list(list(poly(1/3)));
     6359  obtained = homogfacNthWeyl_all(input);
     6360  if (!isListEqual(expected,obtained))
     6361  {
     6362    print("Test 2 for homogfacNthWeyl_all failed.");
     6363    print("Expected:\n");
     6364    print(expected);
     6365    print("obtained:\n");
     6366    print(obtained);
     6367    result = 0;
     6368  }
     6369  //Test 3: one variable first Weyl
     6370  input = 2*x;
     6371  expected = list(list(number(2),x));
     6372  obtained = homogfacNthWeyl_all(input);
     6373  if (!isListEqual(expected,obtained))
     6374  {
     6375    print("Test 3 for homogfacNthWeyl_all failed.");
     6376    print("Expected:\n");
     6377    print(expected);
     6378    print("obtained:\n");
     6379    print(obtained);
     6380    result = 0;
     6381  }
     6382  //Test 4: reducible polynomial first Weyl
     6383  input = (x*d-1)*(x*d + 4);
     6384  expected =
     6385    sortFactorizations(list(list(number(1),x*d-1,x*d+4),
     6386                list(number(1),x*d+4,x*d-1)));
     6387  obtained = homogfacNthWeyl_all(input);
     6388  if ((!isListEqual(expected,obtained)))
     6389  {
     6390    print("Test 4 for homogfacNthWeyl_all failed.");
     6391    print("Expected:\n");
     6392    print(expected);
     6393    print("obtained:\n");
     6394    print(obtained);
     6395    result = 0;
     6396  }
     6397  //Test 5: irreducible polynomial first Weyl
     6398  input = (x*d-1);
     6399  expected = list(list(number(1),x*d-1));
     6400  obtained = homogfacNthWeyl_all(input);
     6401  if ((!isListEqual(expected,obtained)))
     6402  {
     6403    print("Test 5 for homogfacNthWeyl_all failed.");
     6404    print("Expected:\n");
     6405    print(expected);
     6406    print("or");
     6407    print(expected_alt);
     6408    print("obtained:\n");
     6409    print(obtained);
     6410    result = 0;
     6411  }
     6412  //Test 6: edge case x*d
     6413  input = (x*d);
     6414  expected = list(list(number(1),x,d));
     6415  obtained = homogfacNthWeyl_all(input);
     6416  if ((!isListEqual(expected,obtained)))
     6417  {
     6418    print("Test 6 for homogfacNthWeyl_all failed.");
     6419    print("Expected:\n");
     6420    print(expected);
     6421    print("obtained:\n");
     6422    print(obtained);
     6423    result = 0;
     6424  }
     6425  //Test 7: edge case x*d+1
     6426  input = (x*d+1);
     6427  expected = list(list(number(1),d,x));
     6428  obtained = homogfacNthWeyl_all(input);
     6429  if ((!isListEqual(expected,obtained)))
     6430  {
     6431    print("Test 7 for homogfacNthWeyl_all failed.");
     6432    print("Expected:\n");
     6433    print(expected);
     6434    print("obtained:\n");
     6435    print(obtained);
     6436    result = 0;
     6437  }
     6438  kill R;
     6439  kill r;
     6440  //Test 8: Multivariate irreducible
     6441  ring R = 0,(x(1..4),d(1..4)),lp;
     6442  def r = Weyl();
     6443  setring r;
     6444  poly input = x(1)^2*x(3)^2*d(1)^2*d(3)^2-1;
     6445  list expected = list(list(number(1), x(1)^2*x(3)^2*d(1)^2*d(3)^2-1));
     6446  list obtained = homogfacNthWeyl_all(input);
     6447  if ((!isListEqual(expected,obtained)))
     6448  {
     6449    print("Test 8 for homogfacNthWeyl_all failed.");
     6450    print("Expected:\n");
     6451    print(expected);
     6452    print("or");
     6453    print(expected_alt);
     6454    print("obtained:\n");
     6455    print(obtained);
     6456    result = 0;
     6457  }
     6458  //Test 9: Multivariate reducible
     6459  input = (x(1)*d(1)+1)*d(4);
     6460  expected = sortFactorizations(list(list(number(1), d(1),x(1),d(4)),
     6461                     list(number(1), d(1),d(4),x(1)),
     6462                     list(number(1), d(4),d(1),x(1))));
     6463  obtained = homogfacNthWeyl_all(input);
     6464  if ((!isListEqual(expected,obtained)))
     6465  {
     6466    print("Test 9 for homogfacNthWeyl_all failed.");
     6467    print("Expected:\n");
     6468    print(expected);
     6469    print("obtained:\n");
     6470    print(obtained);
     6471    result = 0;
    18706472  }
    18716473  return(result);
    1872 }//proc perm
    1873 
    1874 //==================================================
    1875 //computes all permutations of a given list by
    1876 //ignoring equal entries (faster than perm)
    1877 static proc permpp(list l)
    1878 "
    1879 INPUT: A list with entries of a type, where the ==-operator is defined
    1880 OUTPUT: A list with all permutations of this given list.
    1881 "
    1882 {//proc permpp
    1883   int i; int j;
    1884   list tempresult;
    1885   list l_without_double;
    1886   list l_without_double_pos;
    1887   int double_entry;
    1888   list result;
    1889   if (size(l)==0)
    1890   {
    1891     return(list());
    1892   }
    1893   if (size(l)==1)
    1894   {
    1895     return(list(l));
    1896   }
    1897   for (i = 1; i<=size(l);i++)
    1898   {//Filling the list with unique entries
    1899     double_entry = 0;
    1900     for (j = 1; j<=size(l_without_double);j++)
    1901     {
    1902       if (l_without_double[j] == l[i])
    1903       {
    1904         double_entry = 1;
    1905         break;
    1906       }
    1907     }
    1908     if (!double_entry)
    1909     {
    1910       l_without_double = l_without_double + list(l[i]);
    1911       l_without_double_pos = l_without_double_pos + list(i);
    1912     }
    1913   }//Filling the list with unique entries
    1914   for (i = 1; i<=size(l_without_double); i++ )
    1915   {
    1916     tempresult = permpp(delete(l,l_without_double_pos[i]));
    1917     for (j = 1; j<=size(tempresult);j++)
    1918     {
    1919       tempresult[j] = list(l_without_double[i])+tempresult[j];
    1920     }
    1921     result = result+tempresult;
    1922   }
    1923   return(result);
    1924 }//proc permpp
    1925 
    1926 //==================================================
    1927 static proc checkIfProperNthWeyl()
    1928 "
    1929 INPUT: None
    1930 OUTPUT: Checks whether the given basering is a proper Weyl algebra.
    1931         Proper means in the sense of our algorithms, i.e. fulfilling
    1932         the assumption that o ur basering is the Nth Weyl algebra and
    1933         that the xs are the first n variables, the differential
    1934         operators are the last n. Returns 1 if proper, 0 otherwise.
    1935 "
    1936 {//checkIfProperNthWeyl
    1937   if (!ncfactor_isWeyl())
    1938   {return(0);}
    1939   int i;
    1940   for (i = 1; i<=nvars(basering) div 2; i++)
    1941   {
    1942     if (var(i + nvars(basering) div 2)*var(i)
    1943         - var(i)*var(i+nvars(basering) div 2)!=1)
    1944     {
    1945       return(0);
    1946     }
    1947   }
    1948   return(1);
    1949 }//checkIfProperNthWeyl
    1950 //==================================================
    1951 static proc checkIfProperNthQWeyl()
    1952 "
    1953 INPUT: None
    1954 OUTPUT: Checks whether the given basering is a proper q-Weyl algebra.
    1955         Proper means in the sense of our algorithms, i.e. fulfilling
    1956         the assumption that o ur basering is the Nth Weyl algebra and
    1957         that the xs are the first n variables, the differential
    1958         operators are the last n. Returns 1 if proper, 0 otherwise.
    1959 "
    1960 {//checkIfProperNthQWeyl
    1961   if (!ncfactor_isQWeyl())
    1962   {return(0);}
    1963   int i;
    1964   for (i = 1; i<=nvars(basering) div 2; i++)
    1965   {
    1966     if (var(i + nvars(basering) div 2)*var(i)
    1967         - par(i)*var(i)*var(i+nvars(basering) div 2)!=1)
    1968     {
    1969       return(0);
    1970     }
    1971   }
    1972   return(1);
    1973 }//checkIfProperNthQWeyl
    1974 //==================================================
    1975 static proc checkIfProperNthShift()
    1976 "
    1977 INPUT: None
    1978 OUTPUT: Checks whether the given basering is a proper shift algebra.
    1979         Proper means in the sense of our algorithms, i.e. fulfilling
    1980         the assumption that our basering is the Nth shift algebra and
    1981         that the xs are the first n variables, the shift
    1982         operators are the last n. Returns 1 if proper, 0 otherwise.
    1983 "
    1984 {//checkIfProperNthShift
    1985   if (!ncfactor_isShift())
    1986   {return(0);}
    1987   int i;
    1988   for (i = 1; i<=nvars(basering) div 2; i++)
    1989   {
    1990     if (var(i + nvars(basering) div 2)*var(i)
    1991         - var(i)*var(i+nvars(basering) div 2)!=var(i+nvars(basering) div 2))
    1992     {
    1993       return(0);
    1994     }
    1995   }
    1996   return(1);
    1997 }//checkIfProperNthShift
    1998 
    1999 //==================================================
     6474}//testing homogfacNthWeyl_all
     6475
     6476
    20006477proc facWeyl(poly h)
    20016478"USAGE: facWeyl(h); h a polynomial in the nth Weyl algebra
     
    20286505  if (isInCommutativeSubRing(h))
    20296506  {//h is in a commutative subring
    2030     list hdepvars;
    2031     intvec tempIntVec;
    2032     for (i = 1; i<=nvars(basering) ; i++)
    2033     {
    2034       tempIntVec = 0:nvars(basering);
    2035       tempIntVec[i] = 1;
    2036       if (deg(h,tempIntVec)>0)
    2037       {
    2038         hdepvars = hdepvars + list(var(i));
    2039       }
    2040     }
    2041     if (size(hdepvars) ==0)
    2042     {//We just have a constant
    2043       return(list(list(h)));
    2044     }//We just have a constant
    2045     dbprint(p,dbprintWhitespace+"Polynomial was given commutative subring.
    2046 Performing commutative factorization.");
    2047     def r = basering;
    2048     def rList = ringlist(basering);
    2049     rList = delete(rList,5);
    2050     rList = delete(rList,5);
    2051     def tempRing = ring(rList);
    2052     setring(tempRing);
    2053     poly h = imap(r,h);
    2054     list tempResult = factorize(h);
    2055     list result = list(list());
    2056     int j;
    2057     for (i = 1; i<=size(tempResult[1]); i++)
    2058     {
    2059       for (j = 1; j<=tempResult[2][i]; j++)
    2060       {
    2061         result[1] = result[1] + list(tempResult[1][i]);
    2062       }
    2063     }
    2064     //mapping back
    2065     setring(r);
    2066     def result = imap(tempRing,result);
    2067     dbprint(p,dbprintWhitespace+"result:");
    2068     dbprint(p,result);
    2069     dbprint(p,dbprintWhitespace+"Computing all permutations of this factorization");
    2070     poly constantFactor = result[1][1];
    2071     result[1] = delete(result[1],1);//Deleting the constant factor
    2072     result=permpp(result[1]);
    2073     for (i = 1; i<=size(result);i++)
    2074     {//Insert constant factor
    2075       result[i] = insert(result[i],constantFactor);
    2076     }//Insert constant factor
    2077     dbprint(p,dbprintWhitespace+"Done.");
    2078     return(result);
     6507    return(factor_commutative(h));
    20796508  }//h is in a commutative subring
    20806509  dbprint(p,dbprintWhitespace +" Successful");
     
    20926521    for (i = 1; i<=nvars(r); i++)
    20936522    {the_vars[i] = var(i);}
    2094     int maybeDInWrongPos;
    20956523    poly tempVariable;
    20966524    for (i = 1; i<=size(the_vars) div 2; i++)
    20976525    {//Swapping the variables as needed
    2098       maybeDInWrongPos = 1;
    20996526      if (the_vars[i + size(the_vars) div 2]*the_vars[i]
    21006527          -the_vars[i]*the_vars[i + size(the_vars) div 2] == 1)
     
    21116538          the_vars[i + size(the_vars) div 2] = the_vars[j];
    21126539          the_vars[j] = tempVariable;
    2113           maybeDInWrongPos = 0;
    21146540