[BACK]Return to dp.c CVS log [TXT][DIR] Up to [local] / OpenXM_contrib2 / asir2000 / builtin

Annotation of OpenXM_contrib2/asir2000/builtin/dp.c, Revision 1.97

1.5       noro        1: /*
                      2:  * Copyright (c) 1994-2000 FUJITSU LABORATORIES LIMITED
                      3:  * All rights reserved.
                      4:  *
                      5:  * FUJITSU LABORATORIES LIMITED ("FLL") hereby grants you a limited,
                      6:  * non-exclusive and royalty-free license to use, copy, modify and
                      7:  * redistribute, solely for non-commercial and non-profit purposes, the
                      8:  * computer program, "Risa/Asir" ("SOFTWARE"), subject to the terms and
1.68      noro        9:  * conditions of this Agreement. For the avoidance of doubt, you acquire * only a limited right to use the SOFTWARE hereunder, and FLL or any
1.5       noro       10:  * third party developer retains all rights, including but not limited to
                     11:  * copyrights, in and to the SOFTWARE.
                     12:  *
                     13:  * (1) FLL does not grant you a license in any way for commercial
                     14:  * purposes. You may use the SOFTWARE only for non-commercial and
                     15:  * non-profit purposes only, such as academic, research and internal
                     16:  * business use.
                     17:  * (2) The SOFTWARE is protected by the Copyright Law of Japan and
                     18:  * international copyright treaties. If you make copies of the SOFTWARE,
                     19:  * with or without modification, as permitted hereunder, you shall affix
                     20:  * to all such copies of the SOFTWARE the above copyright notice.
                     21:  * (3) An explicit reference to this SOFTWARE and its copyright owner
                     22:  * shall be made on your publication or presentation in any form of the
                     23:  * results obtained by use of the SOFTWARE.
                     24:  * (4) In the event that you modify the SOFTWARE, you shall notify FLL by
1.6       noro       25:  * e-mail at risa-admin@sec.flab.fujitsu.co.jp of the detailed specification
1.5       noro       26:  * for such modification or the source code of the modified part of the
                     27:  * SOFTWARE.
                     28:  *
                     29:  * THE SOFTWARE IS PROVIDED AS IS WITHOUT ANY WARRANTY OF ANY KIND. FLL
                     30:  * MAKES ABSOLUTELY NO WARRANTIES, EXPRESSED, IMPLIED OR STATUTORY, AND
                     31:  * EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS
                     32:  * FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT OF THIRD PARTIES'
                     33:  * RIGHTS. NO FLL DEALER, AGENT, EMPLOYEES IS AUTHORIZED TO MAKE ANY
                     34:  * MODIFICATIONS, EXTENSIONS, OR ADDITIONS TO THIS WARRANTY.
                     35:  * UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, TORT, CONTRACT,
                     36:  * OR OTHERWISE, SHALL FLL BE LIABLE TO YOU OR ANY OTHER PERSON FOR ANY
                     37:  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, PUNITIVE OR CONSEQUENTIAL
                     38:  * DAMAGES OF ANY CHARACTER, INCLUDING, WITHOUT LIMITATION, DAMAGES
                     39:  * ARISING OUT OF OR RELATING TO THE SOFTWARE OR THIS AGREEMENT, DAMAGES
                     40:  * FOR LOSS OF GOODWILL, WORK STOPPAGE, OR LOSS OF DATA, OR FOR ANY
                     41:  * DAMAGES, EVEN IF FLL SHALL HAVE BEEN INFORMED OF THE POSSIBILITY OF
                     42:  * SUCH DAMAGES, OR FOR ANY CLAIM BY ANY OTHER PARTY. EVEN IF A PART
                     43:  * OF THE SOFTWARE HAS BEEN DEVELOPED BY A THIRD PARTY, THE THIRD PARTY
                     44:  * DEVELOPER SHALL HAVE NO LIABILITY IN CONNECTION WITH THE USE,
                     45:  * PERFORMANCE OR NON-PERFORMANCE OF THE SOFTWARE.
                     46:  *
1.97    ! noro       47:  * $OpenXM: OpenXM_contrib2/asir2000/builtin/dp.c,v 1.96 2015/09/24 04:43:12 noro Exp $
1.5       noro       48: */
1.1       noro       49: #include "ca.h"
                     50: #include "base.h"
                     51: #include "parse.h"
                     52:
1.61      noro       53: extern int dp_fcoeffs;
1.8       noro       54: extern int dp_nelim;
                     55: extern int dp_order_pair_length;
                     56: extern struct order_pair *dp_order_pair;
1.46      noro       57: extern struct order_spec *dp_current_spec;
1.52      noro       58: extern struct modorder_spec *dp_current_modspec;
1.94      noro       59: extern int nd_rref2;
1.8       noro       60:
1.11      noro       61: int do_weyl;
1.1       noro       62:
1.44      noro       63: void Pdp_sort();
1.32      noro       64: void Pdp_mul_trunc(),Pdp_quo();
1.64      noro       65: void Pdp_ord(), Pdp_ptod(), Pdp_dtop(), Phomogenize();
1.1       noro       66: void Pdp_ptozp(), Pdp_ptozp2(), Pdp_red(), Pdp_red2(), Pdp_lcm(), Pdp_redble();
                     67: void Pdp_sp(), Pdp_hm(), Pdp_ht(), Pdp_hc(), Pdp_rest(), Pdp_td(), Pdp_sugar();
1.30      ohara      68: void Pdp_set_sugar();
1.1       noro       69: void Pdp_cri1(),Pdp_cri2(),Pdp_subd(),Pdp_mod(),Pdp_red_mod(),Pdp_tdiv();
                     70: void Pdp_prim(),Pdp_red_coef(),Pdp_mag(),Pdp_set_kara(),Pdp_rat();
1.70      noro       71: void Pdp_nf(),Pdp_true_nf(),Pdp_true_nf_marked(),Pdp_true_nf_marked_mod();
1.97    ! noro       72: void Pdp_true_nf_and_quotient();
1.79      noro       73: void Pdp_true_nf_and_quotient_marked(),Pdp_true_nf_and_quotient_marked_mod();
1.1       noro       74: void Pdp_nf_mod(),Pdp_true_nf_mod();
                     75: void Pdp_criB(),Pdp_nelim();
1.9       noro       76: void Pdp_minp(),Pdp_sp_mod();
1.1       noro       77: void Pdp_homo(),Pdp_dehomo();
1.16      noro       78: void Pdp_gr_mod_main(),Pdp_gr_f_main();
1.1       noro       79: void Pdp_gr_main(),Pdp_gr_hm_main(),Pdp_gr_d_main(),Pdp_gr_flags();
1.63      noro       80: void Pdp_interreduce();
1.16      noro       81: void Pdp_f4_main(),Pdp_f4_mod_main(),Pdp_f4_f_main();
1.1       noro       82: void Pdp_gr_print();
1.28      noro       83: void Pdp_mbase(),Pdp_lnf_mod(),Pdp_nf_tab_mod(),Pdp_mdtod(), Pdp_nf_tab_f();
1.8       noro       84: void Pdp_vtoe(), Pdp_etov(), Pdp_dtov(), Pdp_idiv(), Pdp_sep();
                     85: void Pdp_cont();
1.22      noro       86: void Pdp_gr_checklist();
1.52      noro       87: void Pdp_ltod(),Pdpv_ord(),Pdpv_ht(),Pdpv_hm(),Pdpv_hc();
1.1       noro       88:
1.13      noro       89: void Pdp_weyl_red();
                     90: void Pdp_weyl_sp();
                     91: void Pdp_weyl_nf(),Pdp_weyl_nf_mod();
1.16      noro       92: void Pdp_weyl_gr_main(),Pdp_weyl_gr_mod_main(),Pdp_weyl_gr_f_main();
                     93: void Pdp_weyl_f4_main(),Pdp_weyl_f4_mod_main(),Pdp_weyl_f4_f_main();
1.96      noro       94: void Pdp_weyl_mul(),Pdp_weyl_mul_mod(),Pdp_weyl_act();
1.15      noro       95: void Pdp_weyl_set_weight();
1.77      noro       96: void Pdp_set_weight(),Pdp_set_top_weight(),Pdp_set_module_weight();
1.16      noro       97: void Pdp_nf_f(),Pdp_weyl_nf_f();
                     98: void Pdp_lnf_f();
1.62      noro       99: void Pnd_gr(),Pnd_gr_trace(),Pnd_f4(),Pnd_f4_trace();
1.75      noro      100: void Pnd_gr_postproc(), Pnd_weyl_gr_postproc();
1.89      noro      101: void Pnd_gr_recompute_trace(), Pnd_btog();
1.38      noro      102: void Pnd_weyl_gr(),Pnd_weyl_gr_trace();
1.83      noro      103: void Pnd_nf(),Pnd_weyl_nf();
1.49      noro      104: void Pdp_initial_term();
                    105: void Pdp_order();
1.66      noro      106: void Pdp_inv_or_split();
1.74      noro      107: void Pdp_compute_last_t();
1.68      noro      108: void Pdp_compute_last_w();
1.70      noro      109: void Pdp_compute_essential_df();
1.72      noro      110: void Pdp_get_denomlist();
1.80      noro      111: void Pdp_symb_add();
1.82      noro      112: void Pdp_mono_raddec();
1.84      noro      113: void Pdp_mono_reduce();
1.95      noro      114: void Pdp_rref2(),Psumi_updatepairs(),Psumi_symbolic();
1.49      noro      115:
                    116: LIST dp_initial_term();
                    117: LIST dp_order();
                    118: void parse_gr_option(LIST f,NODE opt,LIST *v,Num *homo,
                    119:        int *modular,struct order_spec **ord);
1.88      ohara     120: NODE dp_inv_or_split(NODE gb,DP f,struct order_spec *spec, DP *inv);
1.11      noro      121:
1.25      noro      122: LIST remove_zero_from_list(LIST);
                    123:
1.1       noro      124: struct ftab dp_tab[] = {
1.8       noro      125:        /* content reduction */
1.1       noro      126:        {"dp_ptozp",Pdp_ptozp,1},
                    127:        {"dp_ptozp2",Pdp_ptozp2,2},
                    128:        {"dp_prim",Pdp_prim,1},
1.8       noro      129:        {"dp_red_coef",Pdp_red_coef,2},
                    130:        {"dp_cont",Pdp_cont,1},
                    131:
1.11      noro      132: /* polynomial ring */
1.32      noro      133:        /* special operations */
                    134:        {"dp_mul_trunc",Pdp_mul_trunc,3},
                    135:        {"dp_quo",Pdp_quo,2},
                    136:
1.8       noro      137:        /* s-poly */
                    138:        {"dp_sp",Pdp_sp,2},
                    139:        {"dp_sp_mod",Pdp_sp_mod,3},
                    140:
                    141:        /* m-reduction */
1.1       noro      142:        {"dp_red",Pdp_red,3},
                    143:        {"dp_red_mod",Pdp_red_mod,4},
1.8       noro      144:
                    145:        /* normal form */
1.1       noro      146:        {"dp_nf",Pdp_nf,4},
1.16      noro      147:        {"dp_nf_f",Pdp_nf_f,4},
1.1       noro      148:        {"dp_true_nf",Pdp_true_nf,4},
1.97    ! noro      149:        {"dp_true_nf_and_quotient",Pdp_true_nf_and_quotient,4},
1.67      noro      150:        {"dp_true_nf_marked",Pdp_true_nf_marked,4},
1.73      noro      151:        {"dp_true_nf_and_quotient_marked",Pdp_true_nf_and_quotient_marked,4},
1.79      noro      152:        {"dp_true_nf_and_quotient_marked_mod",Pdp_true_nf_and_quotient_marked_mod,5},
1.70      noro      153:        {"dp_true_nf_marked_mod",Pdp_true_nf_marked_mod,5},
1.1       noro      154:        {"dp_nf_mod",Pdp_nf_mod,5},
                    155:        {"dp_true_nf_mod",Pdp_true_nf_mod,5},
1.8       noro      156:        {"dp_lnf_mod",Pdp_lnf_mod,3},
1.28      noro      157:        {"dp_nf_tab_f",Pdp_nf_tab_f,2},
1.8       noro      158:        {"dp_nf_tab_mod",Pdp_nf_tab_mod,3},
1.16      noro      159:        {"dp_lnf_f",Pdp_lnf_f,2},
1.8       noro      160:
                    161:        /* Buchberger algorithm */
1.46      noro      162:        {"dp_gr_main",Pdp_gr_main,-5},
1.63      noro      163:        {"dp_interreduce",Pdp_interreduce,3},
1.1       noro      164:        {"dp_gr_mod_main",Pdp_gr_mod_main,5},
1.27      noro      165:        {"dp_gr_f_main",Pdp_gr_f_main,4},
1.23      noro      166:        {"dp_gr_checklist",Pdp_gr_checklist,2},
1.40      noro      167:        {"nd_f4",Pnd_f4,4},
1.33      noro      168:        {"nd_gr",Pnd_gr,4},
1.36      noro      169:        {"nd_gr_trace",Pnd_gr_trace,5},
1.62      noro      170:        {"nd_f4_trace",Pnd_f4_trace,5},
1.58      noro      171:        {"nd_gr_postproc",Pnd_gr_postproc,5},
1.86      noro      172:        {"nd_gr_recompute_trace",Pnd_gr_recompute_trace,5},
1.90      noro      173:        {"nd_btog",Pnd_btog,-6},
1.75      noro      174:        {"nd_weyl_gr_postproc",Pnd_weyl_gr_postproc,5},
1.38      noro      175:        {"nd_weyl_gr",Pnd_weyl_gr,4},
                    176:        {"nd_weyl_gr_trace",Pnd_weyl_gr_trace,5},
1.39      noro      177:        {"nd_nf",Pnd_nf,5},
1.83      noro      178:        {"nd_weyl_nf",Pnd_weyl_nf,5},
1.8       noro      179:
                    180:        /* F4 algorithm */
1.1       noro      181:        {"dp_f4_main",Pdp_f4_main,3},
                    182:        {"dp_f4_mod_main",Pdp_f4_mod_main,4},
1.8       noro      183:
1.11      noro      184: /* weyl algebra */
1.12      noro      185:        /* multiplication */
                    186:        {"dp_weyl_mul",Pdp_weyl_mul,2},
1.13      noro      187:        {"dp_weyl_mul_mod",Pdp_weyl_mul_mod,3},
1.96      noro      188:        {"dp_weyl_act",Pdp_weyl_act,2},
1.12      noro      189:
1.11      noro      190:        /* s-poly */
                    191:        {"dp_weyl_sp",Pdp_weyl_sp,2},
                    192:
                    193:        /* m-reduction */
                    194:        {"dp_weyl_red",Pdp_weyl_red,3},
                    195:
                    196:        /* normal form */
                    197:        {"dp_weyl_nf",Pdp_weyl_nf,4},
1.13      noro      198:        {"dp_weyl_nf_mod",Pdp_weyl_nf_mod,5},
1.16      noro      199:        {"dp_weyl_nf_f",Pdp_weyl_nf_f,4},
1.11      noro      200:
                    201:        /* Buchberger algorithm */
1.50      noro      202:        {"dp_weyl_gr_main",Pdp_weyl_gr_main,-5},
1.11      noro      203:        {"dp_weyl_gr_mod_main",Pdp_weyl_gr_mod_main,5},
1.16      noro      204:        {"dp_weyl_gr_f_main",Pdp_weyl_gr_f_main,4},
1.11      noro      205:
                    206:        /* F4 algorithm */
                    207:        {"dp_weyl_f4_main",Pdp_weyl_f4_main,3},
1.19      noro      208:        {"dp_weyl_f4_mod_main",Pdp_weyl_f4_mod_main,4},
1.11      noro      209:
1.15      noro      210:        /* misc */
1.66      noro      211:        {"dp_inv_or_split",Pdp_inv_or_split,3},
1.24      noro      212:        {"dp_set_weight",Pdp_set_weight,-1},
1.77      noro      213:        {"dp_set_module_weight",Pdp_set_module_weight,-1},
1.71      noro      214:        {"dp_set_top_weight",Pdp_set_top_weight,-1},
1.15      noro      215:        {"dp_weyl_set_weight",Pdp_weyl_set_weight,-1},
1.72      noro      216:
                    217:        {"dp_get_denomlist",Pdp_get_denomlist,0},
1.8       noro      218:        {0,0,0},
                    219: };
                    220:
                    221: struct ftab dp_supp_tab[] = {
                    222:        /* setting flags */
1.44      noro      223:        {"dp_sort",Pdp_sort,1},
1.8       noro      224:        {"dp_ord",Pdp_ord,-1},
1.52      noro      225:        {"dpv_ord",Pdpv_ord,-2},
1.8       noro      226:        {"dp_set_kara",Pdp_set_kara,-1},
                    227:        {"dp_nelim",Pdp_nelim,-1},
1.1       noro      228:        {"dp_gr_flags",Pdp_gr_flags,-1},
                    229:        {"dp_gr_print",Pdp_gr_print,-1},
1.8       noro      230:
                    231:        /* converters */
1.64      noro      232:        {"homogenize",Phomogenize,3},
1.53      noro      233:        {"dp_ptod",Pdp_ptod,-2},
1.8       noro      234:        {"dp_dtop",Pdp_dtop,2},
                    235:        {"dp_homo",Pdp_homo,1},
                    236:        {"dp_dehomo",Pdp_dehomo,1},
                    237:        {"dp_etov",Pdp_etov,1},
                    238:        {"dp_vtoe",Pdp_vtoe,1},
                    239:        {"dp_dtov",Pdp_dtov,1},
                    240:        {"dp_mdtod",Pdp_mdtod,1},
                    241:        {"dp_mod",Pdp_mod,3},
                    242:        {"dp_rat",Pdp_rat,1},
1.53      noro      243:        {"dp_ltod",Pdp_ltod,-2},
1.8       noro      244:
                    245:        /* criteria */
                    246:        {"dp_cri1",Pdp_cri1,2},
                    247:        {"dp_cri2",Pdp_cri2,2},
                    248:        {"dp_criB",Pdp_criB,3},
                    249:
                    250:        /* simple operation */
                    251:        {"dp_subd",Pdp_subd,2},
                    252:        {"dp_lcm",Pdp_lcm,2},
                    253:        {"dp_hm",Pdp_hm,1},
                    254:        {"dp_ht",Pdp_ht,1},
                    255:        {"dp_hc",Pdp_hc,1},
1.52      noro      256:        {"dpv_hm",Pdpv_hm,1},
                    257:        {"dpv_ht",Pdpv_ht,1},
                    258:        {"dpv_hc",Pdpv_hc,1},
1.8       noro      259:        {"dp_rest",Pdp_rest,1},
1.49      noro      260:        {"dp_initial_term",Pdp_initial_term,1},
                    261:        {"dp_order",Pdp_order,1},
1.80      noro      262:        {"dp_symb_add",Pdp_symb_add,2},
1.8       noro      263:
                    264:        /* degree and size */
                    265:        {"dp_td",Pdp_td,1},
                    266:        {"dp_mag",Pdp_mag,1},
                    267:        {"dp_sugar",Pdp_sugar,1},
1.30      ohara     268:        {"dp_set_sugar",Pdp_set_sugar,2},
1.8       noro      269:
                    270:        /* misc */
                    271:        {"dp_mbase",Pdp_mbase,1},
                    272:        {"dp_redble",Pdp_redble,2},
                    273:        {"dp_sep",Pdp_sep,2},
                    274:        {"dp_idiv",Pdp_idiv,2},
                    275:        {"dp_tdiv",Pdp_tdiv,2},
                    276:        {"dp_minp",Pdp_minp,2},
1.68      noro      277:        {"dp_compute_last_w",Pdp_compute_last_w,5},
1.74      noro      278:        {"dp_compute_last_t",Pdp_compute_last_t,5},
1.70      noro      279:        {"dp_compute_essential_df",Pdp_compute_essential_df,2},
1.82      noro      280:        {"dp_mono_raddec",Pdp_mono_raddec,2},
1.84      noro      281:        {"dp_mono_reduce",Pdp_mono_reduce,2},
1.8       noro      282:
1.94      noro      283:        {"dp_rref2",Pdp_rref2,2},
1.95      noro      284:        {"sumi_updatepairs",Psumi_updatepairs,3},
                    285:        {"sumi_symbolic",Psumi_symbolic,5},
1.94      noro      286:
1.8       noro      287:        {0,0,0}
1.1       noro      288: };
1.44      noro      289:
1.68      noro      290: NODE compute_last_w(NODE g,NODE gh,int n,int **v,int row1,int **m1,int row2,int **m2);
1.74      noro      291: Q compute_last_t(NODE g,NODE gh,Q t,VECT w1,VECT w2,NODE *homo,VECT *wp);
                    292:
                    293: void Pdp_compute_last_t(NODE arg,LIST *rp)
                    294: {
                    295:        NODE g,gh,homo,n;
                    296:        LIST hlist;
                    297:        VECT v1,v2,w;
                    298:        Q t;
                    299:
                    300:        g = (NODE)BDY((LIST)ARG0(arg));
                    301:        gh = (NODE)BDY((LIST)ARG1(arg));
                    302:        t = (Q)ARG2(arg);
                    303:        v1 = (VECT)ARG3(arg);
                    304:        v2 = (VECT)ARG4(arg);
                    305:        t = compute_last_t(g,gh,t,v1,v2,&homo,&w);
                    306:        MKLIST(hlist,homo);
                    307:        n = mknode(3,t,w,hlist);
                    308:        MKLIST(*rp,n);
                    309: }
1.68      noro      310:
                    311: void Pdp_compute_last_w(NODE arg,LIST *rp)
                    312: {
                    313:        NODE g,gh,r;
                    314:        VECT w,rv;
                    315:        LIST l;
                    316:        MAT w1,w2;
                    317:        int row1,row2,i,j,n;
                    318:        int *v;
                    319:        int **m1,**m2;
                    320:        Q q;
                    321:
                    322:        g = (NODE)BDY((LIST)ARG0(arg));
                    323:        gh = (NODE)BDY((LIST)ARG1(arg));
                    324:        w = (VECT)ARG2(arg);
                    325:        w1 = (MAT)ARG3(arg);
                    326:        w2 = (MAT)ARG4(arg);
                    327:        n = w1->col;
                    328:        row1 = w1->row;
                    329:        row2 = w2->row;
                    330:        if ( w ) {
                    331:                v = W_ALLOC(n);
                    332:                for ( i = 0; i < n; i++ ) v[i] = QTOS((Q)w->body[i]);
                    333:        } else v = 0;
                    334:        m1 = almat(row1,n);
                    335:        for ( i = 0; i < row1; i++ )
                    336:                for ( j = 0; j < n; j++ ) m1[i][j] = QTOS((Q)w1->body[i][j]);
                    337:        m2 = almat(row2,n);
                    338:        for ( i = 0; i < row2; i++ )
                    339:                for ( j = 0; j < n; j++ ) m2[i][j] = QTOS((Q)w2->body[i][j]);
                    340:        r = compute_last_w(g,gh,n,&v,row1,m1,row2,m2);
                    341:        if ( !r ) *rp = 0;
                    342:        else {
                    343:                MKVECT(rv,n);
                    344:                for ( i = 0; i < n; i++ ) {
                    345:                        STOQ(v[i],q); rv->body[i] = (pointer)q;
                    346:                }
                    347:                MKLIST(l,r);
                    348:                r = mknode(2,rv,l);
                    349:                MKLIST(*rp,r);
                    350:        }
                    351: }
                    352:
1.70      noro      353: NODE compute_essential_df(DP *g,DP *gh,int n);
                    354:
                    355: void Pdp_compute_essential_df(NODE arg,LIST *rp)
                    356: {
                    357:        VECT g,gh;
                    358:        NODE r;
                    359:
                    360:        g = (VECT)ARG0(arg);
                    361:        gh = (VECT)ARG1(arg);
                    362:        r = (NODE)compute_essential_df((DP *)BDY(g),(DP *)BDY(gh),g->len);
                    363:        MKLIST(*rp,r);
                    364: }
                    365:
1.97    ! noro      366: void Pdp_inv_or_split(NODE arg,Obj *rp)
1.66      noro      367: {
                    368:        NODE gb,newgb;
                    369:        DP f,inv;
                    370:        struct order_spec *spec;
                    371:        LIST list;
                    372:
                    373:        do_weyl = 0; dp_fcoeffs = 0;
                    374:        asir_assert(ARG0(arg),O_LIST,"dp_inv_or_split");
                    375:        asir_assert(ARG1(arg),O_DP,"dp_inv_or_split");
                    376:        if ( !create_order_spec(0,(Obj)ARG2(arg),&spec) )
                    377:                error("dp_inv_or_split : invalid order specification");
                    378:        gb = BDY((LIST)ARG0(arg));
                    379:        f = (DP)ARG1(arg);
                    380:        newgb = (NODE)dp_inv_or_split(gb,f,spec,&inv);
                    381:        if ( !newgb ) {
                    382:                /* invertible */
                    383:                *rp = (Obj)inv;
                    384:        } else {
                    385:                MKLIST(list,newgb);
                    386:                *rp = (Obj)list;
                    387:        }
                    388: }
                    389:
1.97    ! noro      390: void Pdp_sort(NODE arg,DP *rp)
1.44      noro      391: {
                    392:        dp_sort((DP)ARG0(arg),rp);
                    393: }
1.1       noro      394:
1.97    ! noro      395: void Pdp_mdtod(NODE arg,DP *rp)
1.8       noro      396: {
                    397:        MP m,mr,mr0;
                    398:        DP p;
                    399:        P t;
                    400:
                    401:        p = (DP)ARG0(arg);
                    402:        if ( !p )
                    403:                *rp = 0;
                    404:        else {
                    405:                for ( mr0 = 0, m = BDY(p); m; m = NEXT(m) ) {
                    406:                        mptop(m->c,&t); NEXTMP(mr0,mr); mr->c = t; mr->dl = m->dl;
                    407:                }
                    408:                NEXT(mr) = 0; MKDP(p->nv,mr0,*rp); (*rp)->sugar = p->sugar;
                    409:        }
                    410: }
                    411:
1.97    ! noro      412: void Pdp_sep(NODE arg,VECT *rp)
1.8       noro      413: {
                    414:        DP p,r;
                    415:        MP m,t;
                    416:        MP *w0,*w;
                    417:        int i,n,d,nv,sugar;
                    418:        VECT v;
                    419:        pointer *pv;
                    420:
                    421:        p = (DP)ARG0(arg); m = BDY(p);
                    422:        d = QTOS((Q)ARG1(arg));
                    423:        for ( t = m, n = 0; t; t = NEXT(t), n++ );
                    424:        if ( d > n )
                    425:                d = n;
                    426:        MKVECT(v,d); *rp = v;
                    427:        pv = BDY(v); nv = p->nv; sugar = p->sugar;
                    428:        w0 = (MP *)MALLOC(d*sizeof(MP)); bzero(w0,d*sizeof(MP));
                    429:        w = (MP *)MALLOC(d*sizeof(MP)); bzero(w,d*sizeof(MP));
                    430:        for ( t = BDY(p), i = 0; t; t = NEXT(t), i++, i %= d  ) {
                    431:                NEXTMP(w0[i],w[i]); w[i]->c = t->c; w[i]->dl = t->dl;
                    432:        }
                    433:        for ( i = 0; i < d; i++ ) {
                    434:                NEXT(w[i]) = 0; MKDP(nv,w0[i],r); r->sugar = sugar;
                    435:                pv[i] = (pointer)r;
                    436:        }
                    437: }
                    438:
1.97    ! noro      439: void Pdp_idiv(NODE arg,DP *rp)
1.8       noro      440: {
                    441:        dp_idiv((DP)ARG0(arg),(Q)ARG1(arg),rp);
                    442: }
                    443:
1.97    ! noro      444: void Pdp_cont(NODE arg,Q *rp)
1.8       noro      445: {
                    446:        dp_cont((DP)ARG0(arg),rp);
                    447: }
                    448:
1.97    ! noro      449: void Pdp_dtov(NODE arg,VECT *rp)
1.8       noro      450: {
                    451:        dp_dtov((DP)ARG0(arg),rp);
                    452: }
                    453:
1.97    ! noro      454: void Pdp_mbase(NODE arg,LIST *rp)
1.8       noro      455: {
                    456:        NODE mb;
                    457:
                    458:        asir_assert(ARG0(arg),O_LIST,"dp_mbase");
                    459:        dp_mbase(BDY((LIST)ARG0(arg)),&mb);
                    460:        MKLIST(*rp,mb);
                    461: }
                    462:
1.97    ! noro      463: void Pdp_etov(NODE arg,VECT *rp)
1.8       noro      464: {
                    465:        DP dp;
                    466:        int n,i;
                    467:        int *d;
                    468:        VECT v;
                    469:        Q t;
                    470:
                    471:        dp = (DP)ARG0(arg);
                    472:        asir_assert(dp,O_DP,"dp_etov");
                    473:        n = dp->nv; d = BDY(dp)->dl->d;
                    474:        MKVECT(v,n);
                    475:        for ( i = 0; i < n; i++ ) {
                    476:                STOQ(d[i],t); v->body[i] = (pointer)t;
                    477:        }
                    478:        *rp = v;
                    479: }
                    480:
1.97    ! noro      481: void Pdp_vtoe(NODE arg,DP *rp)
1.8       noro      482: {
                    483:        DP dp;
                    484:        DL dl;
                    485:        MP m;
                    486:        int n,i,td;
                    487:        int *d;
                    488:        VECT v;
                    489:
                    490:        v = (VECT)ARG0(arg);
                    491:        asir_assert(v,O_VECT,"dp_vtoe");
                    492:        n = v->len;
                    493:        NEWDL(dl,n); d = dl->d;
                    494:        for ( i = 0, td = 0; i < n; i++ ) {
1.24      noro      495:                d[i] = QTOS((Q)(v->body[i])); td += MUL_WEIGHT(d[i],i);
1.8       noro      496:        }
                    497:        dl->td = td;
                    498:        NEWMP(m); m->dl = dl; m->c = (P)ONE; NEXT(m) = 0;
                    499:        MKDP(n,m,dp); dp->sugar = td;
                    500:        *rp = dp;
                    501: }
                    502:
1.97    ! noro      503: void Pdp_lnf_mod(NODE arg,LIST *rp)
1.8       noro      504: {
                    505:        DP r1,r2;
                    506:        NODE b,g,n;
                    507:        int mod;
                    508:
                    509:        asir_assert(ARG0(arg),O_LIST,"dp_lnf_mod");
                    510:        asir_assert(ARG1(arg),O_LIST,"dp_lnf_mod");
                    511:        asir_assert(ARG2(arg),O_N,"dp_lnf_mod");
                    512:        b = BDY((LIST)ARG0(arg)); g = BDY((LIST)ARG1(arg));
                    513:        mod = QTOS((Q)ARG2(arg));
                    514:        dp_lnf_mod((DP)BDY(b),(DP)BDY(NEXT(b)),g,mod,&r1,&r2);
                    515:        NEWNODE(n); BDY(n) = (pointer)r1;
                    516:        NEWNODE(NEXT(n)); BDY(NEXT(n)) = (pointer)r2;
                    517:        NEXT(NEXT(n)) = 0; MKLIST(*rp,n);
                    518: }
                    519:
1.97    ! noro      520: void Pdp_lnf_f(NODE arg,LIST *rp)
1.16      noro      521: {
                    522:        DP r1,r2;
                    523:        NODE b,g,n;
                    524:
                    525:        asir_assert(ARG0(arg),O_LIST,"dp_lnf_f");
                    526:        asir_assert(ARG1(arg),O_LIST,"dp_lnf_f");
                    527:        b = BDY((LIST)ARG0(arg)); g = BDY((LIST)ARG1(arg));
                    528:        dp_lnf_f((DP)BDY(b),(DP)BDY(NEXT(b)),g,&r1,&r2);
                    529:        NEWNODE(n); BDY(n) = (pointer)r1;
                    530:        NEWNODE(NEXT(n)); BDY(NEXT(n)) = (pointer)r2;
                    531:        NEXT(NEXT(n)) = 0; MKLIST(*rp,n);
                    532: }
                    533:
1.97    ! noro      534: void Pdp_nf_tab_mod(NODE arg,DP *rp)
1.8       noro      535: {
                    536:        asir_assert(ARG0(arg),O_DP,"dp_nf_tab_mod");
                    537:        asir_assert(ARG1(arg),O_VECT,"dp_nf_tab_mod");
                    538:        asir_assert(ARG2(arg),O_N,"dp_nf_tab_mod");
                    539:        dp_nf_tab_mod((DP)ARG0(arg),(LIST *)BDY((VECT)ARG1(arg)),
                    540:                QTOS((Q)ARG2(arg)),rp);
1.28      noro      541: }
                    542:
1.97    ! noro      543: void Pdp_nf_tab_f(NODE arg,DP *rp)
1.28      noro      544: {
                    545:        asir_assert(ARG0(arg),O_DP,"dp_nf_tab_f");
                    546:        asir_assert(ARG1(arg),O_VECT,"dp_nf_tab_f");
                    547:        dp_nf_tab_f((DP)ARG0(arg),(LIST *)BDY((VECT)ARG1(arg)),rp);
1.8       noro      548: }
1.1       noro      549:
1.97    ! noro      550: void Pdp_ord(NODE arg,Obj *rp)
1.1       noro      551: {
1.46      noro      552:        struct order_spec *spec;
1.51      noro      553:        LIST v;
                    554:        struct oLIST f;
                    555:        Num homo;
                    556:        int modular;
                    557:
                    558:        f.id = O_LIST; f.body = 0;
1.59      noro      559:        if ( !arg && !current_option )
1.46      noro      560:                *rp = dp_current_spec->obj;
1.1       noro      561:        else {
1.53      noro      562:                if ( current_option )
                    563:                        parse_gr_option(&f,current_option,&v,&homo,&modular,&spec);
1.51      noro      564:                else if ( !create_order_spec(0,(Obj)ARG0(arg),&spec) )
                    565:                        error("dp_ord : invalid order specification");
1.46      noro      566:                initd(spec); *rp = spec->obj;
1.1       noro      567:        }
                    568: }
                    569:
1.97    ! noro      570: void Pdp_ptod(NODE arg,DP *rp)
1.1       noro      571: {
1.53      noro      572:        P p;
1.1       noro      573:        NODE n;
                    574:        VL vl,tvl;
1.53      noro      575:        struct oLIST f;
                    576:        int ac;
                    577:        LIST v;
                    578:        Num homo;
                    579:        int modular;
                    580:        struct order_spec *ord;
1.1       noro      581:
                    582:        asir_assert(ARG0(arg),O_P,"dp_ptod");
1.53      noro      583:        p = (P)ARG0(arg);
                    584:        ac = argc(arg);
                    585:        if ( ac == 1 ) {
                    586:                if ( current_option ) {
                    587:                        f.id = O_LIST; f.body = mknode(1,p);
                    588:                        parse_gr_option(&f,current_option,&v,&homo,&modular,&ord);
1.54      noro      589:                        initd(ord);
1.53      noro      590:                } else
                    591:                        error("dp_ptod : invalid argument");
                    592:        } else {
                    593:                asir_assert(ARG1(arg),O_LIST,"dp_ptod");
                    594:                v = (LIST)ARG1(arg);
                    595:        }
                    596:        for ( vl = 0, n = BDY(v); n; n = NEXT(n) ) {
1.1       noro      597:                if ( !vl ) {
                    598:                        NEWVL(vl); tvl = vl;
                    599:                } else {
                    600:                        NEWVL(NEXT(tvl)); tvl = NEXT(tvl);
                    601:                }
                    602:                VR(tvl) = VR((P)BDY(n));
                    603:        }
                    604:        if ( vl )
                    605:                NEXT(tvl) = 0;
1.53      noro      606:        ptod(CO,vl,p,rp);
1.64      noro      607: }
                    608:
1.97    ! noro      609: void Phomogenize(NODE arg,P *rp)
1.64      noro      610: {
                    611:        P p;
                    612:        DP d,h;
                    613:        NODE n;
                    614:        V hv;
                    615:        VL vl,tvl,last;
                    616:        struct oLIST f;
                    617:        LIST v;
                    618:
                    619:        asir_assert(ARG0(arg),O_P,"homogenize");
                    620:        p = (P)ARG0(arg);
                    621:        asir_assert(ARG1(arg),O_LIST,"homogenize");
                    622:        v = (LIST)ARG1(arg);
                    623:        asir_assert(ARG2(arg),O_P,"homogenize");
                    624:        hv = VR((P)ARG2(arg));
                    625:        for ( vl = 0, n = BDY(v); n; n = NEXT(n) ) {
                    626:                if ( !vl ) {
                    627:                        NEWVL(vl); tvl = vl;
                    628:                } else {
                    629:                        NEWVL(NEXT(tvl)); tvl = NEXT(tvl);
                    630:                }
                    631:                VR(tvl) = VR((P)BDY(n));
                    632:        }
                    633:        if ( vl ) {
                    634:                last = tvl;
                    635:                NEXT(tvl) = 0;
                    636:        }
                    637:        ptod(CO,vl,p,&d);
                    638:        dp_homo(d,&h);
                    639:        NEWVL(NEXT(last)); last = NEXT(last);
                    640:        VR(last) = hv; NEXT(last) = 0;
                    641:        dtop(CO,vl,h,rp);
1.1       noro      642: }
                    643:
1.97    ! noro      644: void Pdp_ltod(NODE arg,DPV *rp)
1.52      noro      645: {
                    646:        NODE n;
                    647:        VL vl,tvl;
1.53      noro      648:        LIST f,v;
                    649:        int sugar,i,len,ac,modular;
                    650:        Num homo;
                    651:        struct order_spec *ord;
1.52      noro      652:        DP *e;
                    653:        NODE nd,t;
                    654:
1.53      noro      655:        ac = argc(arg);
1.52      noro      656:        asir_assert(ARG0(arg),O_LIST,"dp_ptod");
1.53      noro      657:        f = (LIST)ARG0(arg);
                    658:        if ( ac == 1 ) {
                    659:                if ( current_option ) {
                    660:                        parse_gr_option(f,current_option,&v,&homo,&modular,&ord);
1.54      noro      661:                        initd(ord);
1.53      noro      662:                } else
                    663:                        error("dp_ltod : invalid argument");
                    664:        } else {
                    665:                asir_assert(ARG1(arg),O_LIST,"dp_ptod");
                    666:                v = (LIST)ARG1(arg);
                    667:        }
                    668:        for ( vl = 0, n = BDY(v); n; n = NEXT(n) ) {
1.52      noro      669:                if ( !vl ) {
                    670:                        NEWVL(vl); tvl = vl;
                    671:                } else {
                    672:                        NEWVL(NEXT(tvl)); tvl = NEXT(tvl);
                    673:                }
                    674:                VR(tvl) = VR((P)BDY(n));
                    675:        }
                    676:        if ( vl )
                    677:                NEXT(tvl) = 0;
1.53      noro      678:
                    679:        nd = BDY(f);
1.52      noro      680:        len = length(nd);
                    681:        e = (DP *)MALLOC(len*sizeof(DP));
                    682:        sugar = 0;
                    683:        for ( i = 0, t = nd; i < len; i++, t = NEXT(t) ) {
                    684:                ptod(CO,vl,(P)BDY(t),&e[i]);
                    685:                if ( e[i] )
                    686:                        sugar = MAX(sugar,e[i]->sugar);
                    687:        }
                    688:        MKDPV(len,e,*rp);
                    689: }
                    690:
1.97    ! noro      691: void Pdp_dtop(NODE arg,P *rp)
1.1       noro      692: {
                    693:        NODE n;
                    694:        VL vl,tvl;
                    695:
                    696:        asir_assert(ARG0(arg),O_DP,"dp_dtop");
                    697:        asir_assert(ARG1(arg),O_LIST,"dp_dtop");
                    698:        for ( vl = 0, n = BDY((LIST)ARG1(arg)); n; n = NEXT(n) ) {
                    699:                if ( !vl ) {
                    700:                        NEWVL(vl); tvl = vl;
                    701:                } else {
                    702:                        NEWVL(NEXT(tvl)); tvl = NEXT(tvl);
                    703:                }
                    704:                VR(tvl) = VR((P)BDY(n));
                    705:        }
                    706:        if ( vl )
                    707:                NEXT(tvl) = 0;
                    708:        dtop(CO,vl,(DP)ARG0(arg),rp);
                    709: }
                    710:
                    711: extern LIST Dist;
                    712:
1.97    ! noro      713: void Pdp_ptozp(NODE arg,Obj *rp)
1.1       noro      714: {
1.60      ohara     715:        Q t;
                    716:     NODE tt,p;
                    717:     NODE n,n0;
                    718:     char *key;
                    719:        DP pp;
                    720:        LIST list;
                    721:     int get_factor=0;
                    722:
1.1       noro      723:        asir_assert(ARG0(arg),O_DP,"dp_ptozp");
1.60      ohara     724:
                    725:     /* analyze the option */
                    726:     if ( current_option ) {
                    727:       for ( tt = current_option; tt; tt = NEXT(tt) ) {
                    728:         p = BDY((LIST)BDY(tt));
                    729:         key = BDY((STRING)BDY(p));
                    730:         /*  value = (Obj)BDY(NEXT(p)); */
                    731:         if ( !strcmp(key,"factor") )  get_factor=1;
                    732:         else {
                    733:           error("ptozp: unknown option.");
                    734:         }
                    735:       }
                    736:     }
                    737:
                    738:        dp_ptozp3((DP)ARG0(arg),&t,&pp);
                    739:
                    740:     /* printexpr(NULL,t); */
                    741:        /* if the option factor is given, then it returns the answer
                    742:        in the format [zpoly, num] where num*zpoly is equal to the argument.*/
                    743:     if (get_factor) {
                    744:          n0 = mknode(2,pp,t);
                    745:       MKLIST(list,n0);
                    746:          *rp = (Obj)list;
                    747:     } else
                    748:       *rp = (Obj)pp;
1.1       noro      749: }
                    750:
1.97    ! noro      751: void Pdp_ptozp2(NODE arg,LIST *rp)
1.1       noro      752: {
                    753:        DP p0,p1,h,r;
                    754:        NODE n0;
                    755:
                    756:        p0 = (DP)ARG0(arg); p1 = (DP)ARG1(arg);
                    757:        asir_assert(p0,O_DP,"dp_ptozp2");
                    758:        asir_assert(p1,O_DP,"dp_ptozp2");
1.10      noro      759:        dp_ptozp2(p0,p1,&h,&r);
1.1       noro      760:        NEWNODE(n0); BDY(n0) = (pointer)h;
                    761:        NEWNODE(NEXT(n0)); BDY(NEXT(n0)) = (pointer)r;
                    762:        NEXT(NEXT(n0)) = 0;
                    763:        MKLIST(*rp,n0);
                    764: }
                    765:
1.97    ! noro      766: void Pdp_prim(NODE arg,DP *rp)
1.1       noro      767: {
                    768:        DP t;
                    769:
                    770:        asir_assert(ARG0(arg),O_DP,"dp_prim");
                    771:        dp_prim((DP)ARG0(arg),&t); dp_ptozp(t,rp);
                    772: }
                    773:
1.97    ! noro      774: void Pdp_mod(NODE arg,DP *rp)
1.1       noro      775: {
                    776:        DP p;
                    777:        int mod;
                    778:        NODE subst;
                    779:
                    780:        asir_assert(ARG0(arg),O_DP,"dp_mod");
                    781:        asir_assert(ARG1(arg),O_N,"dp_mod");
                    782:        asir_assert(ARG2(arg),O_LIST,"dp_mod");
                    783:        p = (DP)ARG0(arg); mod = QTOS((Q)ARG1(arg));
                    784:        subst = BDY((LIST)ARG2(arg));
                    785:        dp_mod(p,mod,subst,rp);
                    786: }
                    787:
1.97    ! noro      788: void Pdp_rat(NODE arg,DP *rp)
1.1       noro      789: {
                    790:        asir_assert(ARG0(arg),O_DP,"dp_rat");
                    791:        dp_rat((DP)ARG0(arg),rp);
                    792: }
                    793:
1.9       noro      794: extern int DP_Multiple;
                    795:
1.97    ! noro      796: void Pdp_nf(NODE arg,DP *rp)
1.1       noro      797: {
                    798:        NODE b;
                    799:        DP *ps;
                    800:        DP g;
                    801:        int full;
                    802:
1.61      noro      803:        do_weyl = 0; dp_fcoeffs = 0;
1.1       noro      804:        asir_assert(ARG0(arg),O_LIST,"dp_nf");
                    805:        asir_assert(ARG1(arg),O_DP,"dp_nf");
                    806:        asir_assert(ARG2(arg),O_VECT,"dp_nf");
                    807:        asir_assert(ARG3(arg),O_N,"dp_nf");
                    808:        if ( !(g = (DP)ARG1(arg)) ) {
                    809:                *rp = 0; return;
                    810:        }
                    811:        b = BDY((LIST)ARG0(arg)); ps = (DP *)BDY((VECT)ARG2(arg));
                    812:        full = (Q)ARG3(arg) ? 1 : 0;
1.16      noro      813:        dp_nf_z(b,g,ps,full,DP_Multiple,rp);
1.1       noro      814: }
                    815:
1.97    ! noro      816: void Pdp_weyl_nf(NODE arg,DP *rp)
1.11      noro      817: {
                    818:        NODE b;
                    819:        DP *ps;
                    820:        DP g;
                    821:        int full;
                    822:
                    823:        asir_assert(ARG0(arg),O_LIST,"dp_weyl_nf");
                    824:        asir_assert(ARG1(arg),O_DP,"dp_weyl_nf");
                    825:        asir_assert(ARG2(arg),O_VECT,"dp_weyl_nf");
                    826:        asir_assert(ARG3(arg),O_N,"dp_weyl_nf");
                    827:        if ( !(g = (DP)ARG1(arg)) ) {
                    828:                *rp = 0; return;
                    829:        }
                    830:        b = BDY((LIST)ARG0(arg)); ps = (DP *)BDY((VECT)ARG2(arg));
                    831:        full = (Q)ARG3(arg) ? 1 : 0;
1.12      noro      832:        do_weyl = 1;
1.16      noro      833:        dp_nf_z(b,g,ps,full,DP_Multiple,rp);
                    834:        do_weyl = 0;
                    835: }
                    836:
                    837: /* nf computation using field operations */
                    838:
1.97    ! noro      839: void Pdp_nf_f(NODE arg,DP *rp)
1.16      noro      840: {
                    841:        NODE b;
                    842:        DP *ps;
                    843:        DP g;
                    844:        int full;
                    845:
                    846:        do_weyl = 0;
                    847:        asir_assert(ARG0(arg),O_LIST,"dp_nf_f");
                    848:        asir_assert(ARG1(arg),O_DP,"dp_nf_f");
                    849:        asir_assert(ARG2(arg),O_VECT,"dp_nf_f");
                    850:        asir_assert(ARG3(arg),O_N,"dp_nf_f");
                    851:        if ( !(g = (DP)ARG1(arg)) ) {
                    852:                *rp = 0; return;
                    853:        }
                    854:        b = BDY((LIST)ARG0(arg)); ps = (DP *)BDY((VECT)ARG2(arg));
                    855:        full = (Q)ARG3(arg) ? 1 : 0;
                    856:        dp_nf_f(b,g,ps,full,rp);
                    857: }
                    858:
1.97    ! noro      859: void Pdp_weyl_nf_f(NODE arg,DP *rp)
1.16      noro      860: {
                    861:        NODE b;
                    862:        DP *ps;
                    863:        DP g;
                    864:        int full;
                    865:
                    866:        asir_assert(ARG0(arg),O_LIST,"dp_weyl_nf_f");
                    867:        asir_assert(ARG1(arg),O_DP,"dp_weyl_nf_f");
                    868:        asir_assert(ARG2(arg),O_VECT,"dp_weyl_nf_f");
                    869:        asir_assert(ARG3(arg),O_N,"dp_weyl_nf_f");
                    870:        if ( !(g = (DP)ARG1(arg)) ) {
                    871:                *rp = 0; return;
                    872:        }
                    873:        b = BDY((LIST)ARG0(arg)); ps = (DP *)BDY((VECT)ARG2(arg));
                    874:        full = (Q)ARG3(arg) ? 1 : 0;
                    875:        do_weyl = 1;
                    876:        dp_nf_f(b,g,ps,full,rp);
1.12      noro      877:        do_weyl = 0;
1.11      noro      878: }
                    879:
1.97    ! noro      880: void Pdp_nf_mod(NODE arg,DP *rp)
1.13      noro      881: {
                    882:        NODE b;
                    883:        DP g;
                    884:        DP *ps;
                    885:        int mod,full,ac;
                    886:        NODE n,n0;
                    887:
1.14      noro      888:        do_weyl = 0;
1.13      noro      889:        ac = argc(arg);
1.14      noro      890:        asir_assert(ARG0(arg),O_LIST,"dp_nf_mod");
                    891:        asir_assert(ARG1(arg),O_DP,"dp_nf_mod");
                    892:        asir_assert(ARG2(arg),O_VECT,"dp_nf_mod");
                    893:        asir_assert(ARG3(arg),O_N,"dp_nf_mod");
                    894:        asir_assert(ARG4(arg),O_N,"dp_nf_mod");
1.13      noro      895:        if ( !(g = (DP)ARG1(arg)) ) {
                    896:                *rp = 0; return;
                    897:        }
                    898:        b = BDY((LIST)ARG0(arg)); ps = (DP *)BDY((VECT)ARG2(arg));
                    899:        full = QTOS((Q)ARG3(arg)); mod = QTOS((Q)ARG4(arg));
                    900:        for ( n0 = n = 0; b; b = NEXT(b) ) {
                    901:                NEXTNODE(n0,n);
                    902:                BDY(n) = (pointer)QTOS((Q)BDY(b));
                    903:        }
                    904:        if ( n0 )
                    905:                NEXT(n) = 0;
                    906:        dp_nf_mod(n0,g,ps,mod,full,rp);
                    907: }
                    908:
1.97    ! noro      909: void Pdp_true_nf(NODE arg,LIST *rp)
1.1       noro      910: {
                    911:        NODE b,n;
                    912:        DP *ps;
                    913:        DP g;
                    914:        DP nm;
                    915:        P dn;
                    916:        int full;
                    917:
1.61      noro      918:        do_weyl = 0; dp_fcoeffs = 0;
1.1       noro      919:        asir_assert(ARG0(arg),O_LIST,"dp_true_nf");
                    920:        asir_assert(ARG1(arg),O_DP,"dp_true_nf");
                    921:        asir_assert(ARG2(arg),O_VECT,"dp_true_nf");
                    922:        asir_assert(ARG3(arg),O_N,"dp_nf");
                    923:        if ( !(g = (DP)ARG1(arg)) ) {
                    924:                nm = 0; dn = (P)ONE;
                    925:        } else {
                    926:                b = BDY((LIST)ARG0(arg)); ps = (DP *)BDY((VECT)ARG2(arg));
                    927:                full = (Q)ARG3(arg) ? 1 : 0;
                    928:                dp_true_nf(b,g,ps,full,&nm,&dn);
                    929:        }
                    930:        NEWNODE(n); BDY(n) = (pointer)nm;
                    931:        NEWNODE(NEXT(n)); BDY(NEXT(n)) = (pointer)dn;
                    932:        NEXT(NEXT(n)) = 0; MKLIST(*rp,n);
                    933: }
                    934:
1.97    ! noro      935: DP *dp_true_nf_and_quotient(NODE b,DP g,DP *ps,DP *rp,P *dnp);
        !           936:
        !           937: void Pdp_true_nf_and_quotient(NODE arg,LIST *rp)
1.67      noro      938: {
                    939:        NODE b,n;
1.97    ! noro      940:        DP *ps;
1.67      noro      941:        DP g;
                    942:        DP nm;
1.97    ! noro      943:        VECT quo;
1.67      noro      944:        P dn;
                    945:        int full;
                    946:
                    947:        do_weyl = 0; dp_fcoeffs = 0;
1.97    ! noro      948:        asir_assert(ARG0(arg),O_LIST,"dp_true_nf_and_quotient");
        !           949:        asir_assert(ARG1(arg),O_DP,"dp_true_nf_and_quotient");
        !           950:        asir_assert(ARG2(arg),O_VECT,"dp_true_nf_and_quotient");
1.67      noro      951:        if ( !(g = (DP)ARG1(arg)) ) {
                    952:                nm = 0; dn = (P)ONE;
                    953:        } else {
                    954:                b = BDY((LIST)ARG0(arg));
                    955:                ps = (DP *)BDY((VECT)ARG2(arg));
1.97    ! noro      956:                NEWVECT(quo); quo->len = ((VECT)ARG2(arg))->len;
        !           957:                quo->body = (pointer *)dp_true_nf_and_quotient(b,g,ps,&nm,&dn);
1.67      noro      958:        }
1.97    ! noro      959:        n = mknode(3,nm,dn,quo);
1.69      noro      960:        MKLIST(*rp,n);
1.67      noro      961: }
                    962:
1.73      noro      963: DP *dp_true_nf_and_quotient_marked (NODE b,DP g,DP *ps,DP *hps,DP *rp,P *dnp);
                    964:
1.97    ! noro      965: void Pdp_true_nf_and_quotient_marked(NODE arg,LIST *rp)
1.73      noro      966: {
                    967:        NODE b,n;
                    968:        DP *ps,*hps;
                    969:        DP g;
                    970:        DP nm;
                    971:        VECT quo;
                    972:        P dn;
                    973:        int full;
                    974:
                    975:        do_weyl = 0; dp_fcoeffs = 0;
                    976:        asir_assert(ARG0(arg),O_LIST,"dp_true_nf_and_quotient_marked");
                    977:        asir_assert(ARG1(arg),O_DP,"dp_true_nf_and_quotient_marked");
                    978:        asir_assert(ARG2(arg),O_VECT,"dp_true_nf_and_quotient_marked");
                    979:        asir_assert(ARG3(arg),O_VECT,"dp_true_nf_and_quotient_marked");
                    980:        if ( !(g = (DP)ARG1(arg)) ) {
                    981:                nm = 0; dn = (P)ONE;
                    982:        } else {
                    983:                b = BDY((LIST)ARG0(arg));
                    984:                ps = (DP *)BDY((VECT)ARG2(arg));
                    985:                hps = (DP *)BDY((VECT)ARG3(arg));
                    986:                NEWVECT(quo); quo->len = ((VECT)ARG2(arg))->len;
                    987:                quo->body = (pointer *)dp_true_nf_and_quotient_marked(b,g,ps,hps,&nm,&dn);
                    988:        }
                    989:        n = mknode(3,nm,dn,quo);
                    990:        MKLIST(*rp,n);
                    991: }
                    992:
1.79      noro      993: DP *dp_true_nf_and_quotient_marked_mod (NODE b,DP g,DP *ps,DP *hps,int mod,DP *rp,P *dnp);
                    994:
1.97    ! noro      995: void Pdp_true_nf_and_quotient_marked_mod(NODE arg,LIST *rp)
1.79      noro      996: {
                    997:        NODE b,n;
                    998:        DP *ps,*hps;
                    999:        DP g;
                   1000:        DP nm;
                   1001:        VECT quo;
                   1002:        P dn;
                   1003:        int full,mod;
                   1004:
                   1005:        do_weyl = 0; dp_fcoeffs = 0;
                   1006:        asir_assert(ARG0(arg),O_LIST,"dp_true_nf_and_quotient_marked_mod");
                   1007:        asir_assert(ARG1(arg),O_DP,"dp_true_nf_and_quotient_marked_mod");
                   1008:        asir_assert(ARG2(arg),O_VECT,"dp_true_nf_and_quotient_marked_mod");
                   1009:        asir_assert(ARG3(arg),O_VECT,"dp_true_nf_and_quotient_marked_mod");
                   1010:        asir_assert(ARG4(arg),O_N,"dp_true_nf_and_quotient_marked_mod");
                   1011:        if ( !(g = (DP)ARG1(arg)) ) {
                   1012:                nm = 0; dn = (P)ONE;
                   1013:        } else {
                   1014:                b = BDY((LIST)ARG0(arg));
                   1015:                ps = (DP *)BDY((VECT)ARG2(arg));
                   1016:                hps = (DP *)BDY((VECT)ARG3(arg));
                   1017:                mod = QTOS((Q)ARG4(arg));
                   1018:                NEWVECT(quo); quo->len = ((VECT)ARG2(arg))->len;
                   1019:                quo->body = (pointer *)dp_true_nf_and_quotient_marked_mod(b,g,ps,hps,mod,&nm,&dn);
                   1020:        }
                   1021:        n = mknode(3,nm,dn,quo);
                   1022:        MKLIST(*rp,n);
                   1023: }
                   1024:
1.97    ! noro     1025: void Pdp_true_nf_marked(NODE arg,LIST *rp)
        !          1026: {
        !          1027:        NODE b,n;
        !          1028:        DP *ps,*hps;
        !          1029:        DP g;
        !          1030:        DP nm;
        !          1031:        Q cont;
        !          1032:        P dn;
        !          1033:        int full;
        !          1034:
        !          1035:        do_weyl = 0; dp_fcoeffs = 0;
        !          1036:        asir_assert(ARG0(arg),O_LIST,"dp_true_nf_marked");
        !          1037:        asir_assert(ARG1(arg),O_DP,"dp_true_nf_marked");
        !          1038:        asir_assert(ARG2(arg),O_VECT,"dp_true_nf_marked");
        !          1039:        asir_assert(ARG3(arg),O_VECT,"dp_true_nf_marked");
        !          1040:        if ( !(g = (DP)ARG1(arg)) ) {
        !          1041:                nm = 0; dn = (P)ONE;
        !          1042:        } else {
        !          1043:                b = BDY((LIST)ARG0(arg));
        !          1044:                ps = (DP *)BDY((VECT)ARG2(arg));
        !          1045:                hps = (DP *)BDY((VECT)ARG3(arg));
        !          1046:                dp_true_nf_marked(b,g,ps,hps,&nm,&cont,&dn);
        !          1047:        }
        !          1048:        n = mknode(3,nm,cont,dn);
        !          1049:        MKLIST(*rp,n);
        !          1050: }
        !          1051:
        !          1052: void Pdp_true_nf_marked_mod(NODE arg,LIST *rp)
1.70      noro     1053: {
                   1054:        NODE b,n;
                   1055:        DP *ps,*hps;
                   1056:        DP g;
                   1057:        DP nm;
                   1058:        P dn;
                   1059:        int mod;
                   1060:
                   1061:        do_weyl = 0; dp_fcoeffs = 0;
                   1062:        asir_assert(ARG0(arg),O_LIST,"dp_true_nf_marked_mod");
                   1063:        asir_assert(ARG1(arg),O_DP,"dp_true_nf_marked_mod");
                   1064:        asir_assert(ARG2(arg),O_VECT,"dp_true_nf_marked_mod");
                   1065:        asir_assert(ARG3(arg),O_VECT,"dp_true_nf_marked_mod");
                   1066:        asir_assert(ARG4(arg),O_N,"dp_true_nf_marked_mod");
                   1067:        if ( !(g = (DP)ARG1(arg)) ) {
                   1068:                nm = 0; dn = (P)ONE;
                   1069:        } else {
                   1070:                b = BDY((LIST)ARG0(arg));
                   1071:                ps = (DP *)BDY((VECT)ARG2(arg));
                   1072:                hps = (DP *)BDY((VECT)ARG3(arg));
                   1073:                mod = QTOS((Q)ARG4(arg));
                   1074:                dp_true_nf_marked_mod(b,g,ps,hps,mod,&nm,&dn);
                   1075:        }
                   1076:        n = mknode(2,nm,dn);
                   1077:        MKLIST(*rp,n);
                   1078: }
                   1079:
1.97    ! noro     1080: void Pdp_weyl_nf_mod(NODE arg,DP *rp)
1.8       noro     1081: {
                   1082:        NODE b;
                   1083:        DP g;
                   1084:        DP *ps;
                   1085:        int mod,full,ac;
1.9       noro     1086:        NODE n,n0;
1.8       noro     1087:
                   1088:        ac = argc(arg);
1.14      noro     1089:        asir_assert(ARG0(arg),O_LIST,"dp_weyl_nf_mod");
                   1090:        asir_assert(ARG1(arg),O_DP,"dp_weyl_nf_mod");
                   1091:        asir_assert(ARG2(arg),O_VECT,"dp_weyl_nf_mod");
                   1092:        asir_assert(ARG3(arg),O_N,"dp_weyl_nf_mod");
                   1093:        asir_assert(ARG4(arg),O_N,"dp_weyl_nf_mod");
1.8       noro     1094:        if ( !(g = (DP)ARG1(arg)) ) {
                   1095:                *rp = 0; return;
                   1096:        }
                   1097:        b = BDY((LIST)ARG0(arg)); ps = (DP *)BDY((VECT)ARG2(arg));
                   1098:        full = QTOS((Q)ARG3(arg)); mod = QTOS((Q)ARG4(arg));
1.9       noro     1099:        for ( n0 = n = 0; b; b = NEXT(b) ) {
                   1100:                NEXTNODE(n0,n);
                   1101:                BDY(n) = (pointer)QTOS((Q)BDY(b));
                   1102:        }
                   1103:        if ( n0 )
                   1104:                NEXT(n) = 0;
1.13      noro     1105:        do_weyl = 1;
                   1106:        dp_nf_mod(n0,g,ps,mod,full,rp);
                   1107:        do_weyl = 0;
1.8       noro     1108: }
                   1109:
1.97    ! noro     1110: void Pdp_true_nf_mod(NODE arg,LIST *rp)
1.8       noro     1111: {
                   1112:        NODE b;
                   1113:        DP g,nm;
                   1114:        P dn;
                   1115:        DP *ps;
                   1116:        int mod,full;
                   1117:        NODE n;
                   1118:
1.11      noro     1119:        do_weyl = 0;
1.8       noro     1120:        asir_assert(ARG0(arg),O_LIST,"dp_nf_mod");
                   1121:        asir_assert(ARG1(arg),O_DP,"dp_nf_mod");
                   1122:        asir_assert(ARG2(arg),O_VECT,"dp_nf_mod");
                   1123:        asir_assert(ARG3(arg),O_N,"dp_nf_mod");
                   1124:        asir_assert(ARG4(arg),O_N,"dp_nf_mod");
                   1125:        if ( !(g = (DP)ARG1(arg)) ) {
                   1126:                nm = 0; dn = (P)ONEM;
                   1127:        } else {
                   1128:                b = BDY((LIST)ARG0(arg)); ps = (DP *)BDY((VECT)ARG2(arg));
                   1129:                full = QTOS((Q)ARG3(arg)); mod = QTOS((Q)ARG4(arg));
                   1130:                dp_true_nf_mod(b,g,ps,mod,full,&nm,&dn);
                   1131:        }
                   1132:        NEWNODE(n); BDY(n) = (pointer)nm;
                   1133:        NEWNODE(NEXT(n)); BDY(NEXT(n)) = (pointer)dn;
                   1134:        NEXT(NEXT(n)) = 0; MKLIST(*rp,n);
1.1       noro     1135: }
                   1136:
1.97    ! noro     1137: void Pdp_tdiv(NODE arg,DP *rp)
1.1       noro     1138: {
                   1139:        MP m,mr,mr0;
                   1140:        DP p;
                   1141:        Q c;
                   1142:        N d,q,r;
                   1143:        int sgn;
                   1144:
                   1145:        asir_assert(ARG0(arg),O_DP,"dp_tdiv");
                   1146:        asir_assert(ARG1(arg),O_N,"dp_tdiv");
                   1147:        p = (DP)ARG0(arg); d = NM((Q)ARG1(arg)); sgn = SGN((Q)ARG1(arg));
                   1148:        if ( !p )
                   1149:                *rp = 0;
                   1150:        else {
                   1151:                for ( mr0 = 0, m = BDY(p); m; m = NEXT(m) ) {
                   1152:                        divn(NM((Q)m->c),d,&q,&r);
                   1153:                        if ( r ) {
                   1154:                                *rp = 0; return;
                   1155:                        } else {
                   1156:                                NEXTMP(mr0,mr); NTOQ(q,SGN((Q)m->c)*sgn,c);
                   1157:                                mr->c = (P)c; mr->dl = m->dl;
                   1158:                        }
                   1159:                }
                   1160:                NEXT(mr) = 0; MKDP(p->nv,mr0,*rp); (*rp)->sugar = p->sugar;
                   1161:        }
                   1162: }
                   1163:
1.97    ! noro     1164: void Pdp_red_coef(NODE arg,DP *rp)
1.1       noro     1165: {
                   1166:        MP m,mr,mr0;
                   1167:        P q,r;
                   1168:        DP p;
                   1169:        P mod;
                   1170:
                   1171:        p = (DP)ARG0(arg); mod = (P)ARG1(arg);
                   1172:        asir_assert(p,O_DP,"dp_red_coef");
                   1173:        asir_assert(mod,O_P,"dp_red_coef");
                   1174:        if ( !p )
                   1175:                *rp = 0;
                   1176:        else {
                   1177:                for ( mr0 = 0, m = BDY(p); m; m = NEXT(m) ) {
                   1178:                        divsrp(CO,m->c,mod,&q,&r);
                   1179:                        if ( r ) {
                   1180:                                NEXTMP(mr0,mr); mr->c = r; mr->dl = m->dl;
                   1181:                        }
                   1182:                }
                   1183:                if ( mr0 ) {
                   1184:                        NEXT(mr) = 0; MKDP(p->nv,mr0,*rp); (*rp)->sugar = p->sugar;
                   1185:                } else
                   1186:                        *rp = 0;
                   1187:        }
                   1188: }
                   1189:
1.97    ! noro     1190: void Pdp_redble(NODE arg,Q *rp)
1.1       noro     1191: {
                   1192:        asir_assert(ARG0(arg),O_DP,"dp_redble");
                   1193:        asir_assert(ARG1(arg),O_DP,"dp_redble");
                   1194:        if ( dp_redble((DP)ARG0(arg),(DP)ARG1(arg)) )
                   1195:                *rp = ONE;
                   1196:        else
                   1197:                *rp = 0;
                   1198: }
                   1199:
1.97    ! noro     1200: void Pdp_red_mod(NODE arg,LIST *rp)
1.1       noro     1201: {
                   1202:        DP h,r;
                   1203:        P dmy;
                   1204:        NODE n;
                   1205:
1.11      noro     1206:        do_weyl = 0;
1.1       noro     1207:        asir_assert(ARG0(arg),O_DP,"dp_red_mod");
                   1208:        asir_assert(ARG1(arg),O_DP,"dp_red_mod");
                   1209:        asir_assert(ARG2(arg),O_DP,"dp_red_mod");
                   1210:        asir_assert(ARG3(arg),O_N,"dp_red_mod");
                   1211:        dp_red_mod((DP)ARG0(arg),(DP)ARG1(arg),(DP)ARG2(arg),QTOS((Q)ARG3(arg)),
                   1212:                &h,&r,&dmy);
                   1213:        NEWNODE(n); BDY(n) = (pointer)h;
                   1214:        NEWNODE(NEXT(n)); BDY(NEXT(n)) = (pointer)r;
                   1215:        NEXT(NEXT(n)) = 0; MKLIST(*rp,n);
                   1216: }
1.13      noro     1217:
1.97    ! noro     1218: void Pdp_subd(NODE arg,DP *rp)
1.1       noro     1219: {
                   1220:        DP p1,p2;
                   1221:
                   1222:        p1 = (DP)ARG0(arg); p2 = (DP)ARG1(arg);
                   1223:        asir_assert(p1,O_DP,"dp_subd");
                   1224:        asir_assert(p2,O_DP,"dp_subd");
                   1225:        dp_subd(p1,p2,rp);
                   1226: }
                   1227:
1.97    ! noro     1228: void Pdp_symb_add(NODE arg,DP *rp)
1.80      noro     1229: {
                   1230:        DP p1,p2,r;
                   1231:        NODE s0;
                   1232:        MP mp0,mp;
                   1233:        int nv;
                   1234:
                   1235:        p1 = (DP)ARG0(arg); p2 = (DP)ARG1(arg);
                   1236:        asir_assert(p1,O_DP,"dp_symb_add");
                   1237:        asir_assert(p2,O_DP,"dp_symb_add");
1.94      noro     1238:        if ( !p1 ) { *rp = p2; return; }
                   1239:        else if ( !p2 ) { *rp = p1; return; }
1.80      noro     1240:        if ( p1->nv != p2->nv )
                   1241:                error("dp_sumb_add : invalid input");
                   1242:        nv = p1->nv;
                   1243:        s0 = symb_merge(dp_dllist(p1),dp_dllist(p2),nv);
                   1244:        for ( mp0 = 0; s0; s0 = NEXT(s0) ) {
                   1245:                NEXTMP(mp0,mp); mp->dl = (DL)BDY(s0); mp->c = (P)ONE;
                   1246:        }
                   1247:        NEXT(mp) = 0;
                   1248:        MKDP(nv,mp0,r); r->sugar = MAX(p1->sugar,p2->sugar);
                   1249:        *rp = r;
                   1250: }
                   1251:
1.97    ! noro     1252: void Pdp_mul_trunc(NODE arg,DP *rp)
1.32      noro     1253: {
                   1254:        DP p1,p2,p;
                   1255:
                   1256:        p1 = (DP)ARG0(arg); p2 = (DP)ARG1(arg); p = (DP)ARG2(arg);
                   1257:        asir_assert(p1,O_DP,"dp_mul_trunc");
                   1258:        asir_assert(p2,O_DP,"dp_mul_trunc");
                   1259:        asir_assert(p,O_DP,"dp_mul_trunc");
                   1260:        comm_muld_trunc(CO,p1,p2,BDY(p)->dl,rp);
                   1261: }
                   1262:
1.97    ! noro     1263: void Pdp_quo(NODE arg,DP *rp)
1.32      noro     1264: {
                   1265:        DP p1,p2;
                   1266:
                   1267:        p1 = (DP)ARG0(arg); p2 = (DP)ARG1(arg);
                   1268:        asir_assert(p1,O_DP,"dp_quo");
                   1269:        asir_assert(p2,O_DP,"dp_quo");
                   1270:        comm_quod(CO,p1,p2,rp);
                   1271: }
                   1272:
1.97    ! noro     1273: void Pdp_weyl_mul(NODE arg,DP *rp)
1.12      noro     1274: {
                   1275:        DP p1,p2;
                   1276:
                   1277:        p1 = (DP)ARG0(arg); p2 = (DP)ARG1(arg);
1.32      noro     1278:        asir_assert(p1,O_DP,"dp_weyl_mul"); asir_assert(p2,O_DP,"dp_weyl_mul");
1.12      noro     1279:        do_weyl = 1;
                   1280:        muld(CO,p1,p2,rp);
1.13      noro     1281:        do_weyl = 0;
                   1282: }
                   1283:
1.97    ! noro     1284: void Pdp_weyl_act(NODE arg,DP *rp)
1.96      noro     1285: {
                   1286:        DP p1,p2;
                   1287:
                   1288:        p1 = (DP)ARG0(arg); p2 = (DP)ARG1(arg);
                   1289:        asir_assert(p1,O_DP,"dp_weyl_act"); asir_assert(p2,O_DP,"dp_weyl_act");
                   1290:        weyl_actd(CO,p1,p2,rp);
                   1291: }
                   1292:
                   1293:
1.97    ! noro     1294: void Pdp_weyl_mul_mod(NODE arg,DP *rp)
1.13      noro     1295: {
                   1296:        DP p1,p2;
                   1297:        Q m;
                   1298:
                   1299:        p1 = (DP)ARG0(arg); p2 = (DP)ARG1(arg); m = (Q)ARG2(arg);
                   1300:        asir_assert(p1,O_DP,"dp_weyl_mul_mod");
                   1301:        asir_assert(p2,O_DP,"dp_mul_mod");
                   1302:        asir_assert(m,O_N,"dp_mul_mod");
                   1303:        do_weyl = 1;
                   1304:        mulmd(CO,QTOS(m),p1,p2,rp);
1.12      noro     1305:        do_weyl = 0;
                   1306: }
                   1307:
1.97    ! noro     1308: void Pdp_red(NODE arg,LIST *rp)
1.1       noro     1309: {
                   1310:        NODE n;
1.4       noro     1311:        DP head,rest,dmy1;
1.1       noro     1312:        P dmy;
                   1313:
1.11      noro     1314:        do_weyl = 0;
1.1       noro     1315:        asir_assert(ARG0(arg),O_DP,"dp_red");
                   1316:        asir_assert(ARG1(arg),O_DP,"dp_red");
                   1317:        asir_assert(ARG2(arg),O_DP,"dp_red");
1.4       noro     1318:        dp_red((DP)ARG0(arg),(DP)ARG1(arg),(DP)ARG2(arg),&head,&rest,&dmy,&dmy1);
1.1       noro     1319:        NEWNODE(n); BDY(n) = (pointer)head;
                   1320:        NEWNODE(NEXT(n)); BDY(NEXT(n)) = (pointer)rest;
                   1321:        NEXT(NEXT(n)) = 0; MKLIST(*rp,n);
                   1322: }
                   1323:
1.97    ! noro     1324: void Pdp_weyl_red(NODE arg,LIST *rp)
1.11      noro     1325: {
                   1326:        NODE n;
                   1327:        DP head,rest,dmy1;
                   1328:        P dmy;
                   1329:
                   1330:        asir_assert(ARG0(arg),O_DP,"dp_weyl_red");
                   1331:        asir_assert(ARG1(arg),O_DP,"dp_weyl_red");
                   1332:        asir_assert(ARG2(arg),O_DP,"dp_weyl_red");
1.12      noro     1333:        do_weyl = 1;
1.11      noro     1334:        dp_red((DP)ARG0(arg),(DP)ARG1(arg),(DP)ARG2(arg),&head,&rest,&dmy,&dmy1);
1.12      noro     1335:        do_weyl = 0;
1.11      noro     1336:        NEWNODE(n); BDY(n) = (pointer)head;
                   1337:        NEWNODE(NEXT(n)); BDY(NEXT(n)) = (pointer)rest;
                   1338:        NEXT(NEXT(n)) = 0; MKLIST(*rp,n);
                   1339: }
                   1340:
1.97    ! noro     1341: void Pdp_sp(NODE arg,DP *rp)
1.1       noro     1342: {
                   1343:        DP p1,p2;
                   1344:
1.11      noro     1345:        do_weyl = 0;
1.1       noro     1346:        p1 = (DP)ARG0(arg); p2 = (DP)ARG1(arg);
                   1347:        asir_assert(p1,O_DP,"dp_sp"); asir_assert(p2,O_DP,"dp_sp");
                   1348:        dp_sp(p1,p2,rp);
                   1349: }
                   1350:
1.97    ! noro     1351: void Pdp_weyl_sp(NODE arg,DP *rp)
1.11      noro     1352: {
                   1353:        DP p1,p2;
                   1354:
                   1355:        p1 = (DP)ARG0(arg); p2 = (DP)ARG1(arg);
                   1356:        asir_assert(p1,O_DP,"dp_weyl_sp"); asir_assert(p2,O_DP,"dp_sp");
1.12      noro     1357:        do_weyl = 1;
1.11      noro     1358:        dp_sp(p1,p2,rp);
1.12      noro     1359:        do_weyl = 0;
1.11      noro     1360: }
                   1361:
1.97    ! noro     1362: void Pdp_sp_mod(NODE arg,DP *rp)
1.1       noro     1363: {
                   1364:        DP p1,p2;
                   1365:        int mod;
                   1366:
1.11      noro     1367:        do_weyl = 0;
1.1       noro     1368:        p1 = (DP)ARG0(arg); p2 = (DP)ARG1(arg);
                   1369:        asir_assert(p1,O_DP,"dp_sp_mod"); asir_assert(p2,O_DP,"dp_sp_mod");
                   1370:        asir_assert(ARG2(arg),O_N,"dp_sp_mod");
                   1371:        mod = QTOS((Q)ARG2(arg));
                   1372:        dp_sp_mod(p1,p2,mod,rp);
                   1373: }
                   1374:
1.97    ! noro     1375: void Pdp_lcm(NODE arg,DP *rp)
1.1       noro     1376: {
                   1377:        int i,n,td;
                   1378:        DL d1,d2,d;
                   1379:        MP m;
                   1380:        DP p1,p2;
                   1381:
                   1382:        p1 = (DP)ARG0(arg); p2 = (DP)ARG1(arg);
                   1383:        asir_assert(p1,O_DP,"dp_lcm"); asir_assert(p2,O_DP,"dp_lcm");
                   1384:        n = p1->nv; d1 = BDY(p1)->dl; d2 = BDY(p2)->dl;
                   1385:        NEWDL(d,n);
                   1386:        for ( i = 0, td = 0; i < n; i++ ) {
1.24      noro     1387:                d->d[i] = MAX(d1->d[i],d2->d[i]); td += MUL_WEIGHT(d->d[i],i);
1.1       noro     1388:        }
                   1389:        d->td = td;
                   1390:        NEWMP(m); m->dl = d; m->c = (P)ONE; NEXT(m) = 0;
                   1391:        MKDP(n,m,*rp); (*rp)->sugar = td;       /* XXX */
                   1392: }
                   1393:
1.97    ! noro     1394: void Pdp_hm(NODE arg,DP *rp)
1.1       noro     1395: {
                   1396:        DP p;
                   1397:
                   1398:        p = (DP)ARG0(arg); asir_assert(p,O_DP,"dp_hm");
                   1399:        dp_hm(p,rp);
                   1400: }
                   1401:
1.97    ! noro     1402: void Pdp_ht(NODE arg,DP *rp)
1.1       noro     1403: {
                   1404:        DP p;
                   1405:        MP m,mr;
                   1406:
                   1407:        p = (DP)ARG0(arg); asir_assert(p,O_DP,"dp_ht");
1.52      noro     1408:        dp_ht(p,rp);
1.1       noro     1409: }
                   1410:
1.97    ! noro     1411: void Pdp_hc(NODE arg,P *rp)
1.1       noro     1412: {
                   1413:        asir_assert(ARG0(arg),O_DP,"dp_hc");
                   1414:        if ( !ARG0(arg) )
                   1415:                *rp = 0;
                   1416:        else
                   1417:                *rp = BDY((DP)ARG0(arg))->c;
                   1418: }
                   1419:
1.97    ! noro     1420: void Pdp_rest(NODE arg,DP *rp)
1.1       noro     1421: {
                   1422:        asir_assert(ARG0(arg),O_DP,"dp_rest");
                   1423:        if ( !ARG0(arg) )
                   1424:                *rp = 0;
                   1425:        else
                   1426:                dp_rest((DP)ARG0(arg),rp);
                   1427: }
                   1428:
1.97    ! noro     1429: void Pdp_td(NODE arg,Q *rp)
1.1       noro     1430: {
                   1431:        DP p;
                   1432:
                   1433:        p = (DP)ARG0(arg); asir_assert(p,O_DP,"dp_td");
                   1434:        if ( !p )
                   1435:                *rp = 0;
                   1436:        else
                   1437:                STOQ(BDY(p)->dl->td,*rp);
                   1438: }
                   1439:
1.97    ! noro     1440: void Pdp_sugar(NODE arg,Q *rp)
1.1       noro     1441: {
                   1442:        DP p;
                   1443:
                   1444:        p = (DP)ARG0(arg); asir_assert(p,O_DP,"dp_sugar");
                   1445:        if ( !p )
                   1446:                *rp = 0;
                   1447:        else
                   1448:                STOQ(p->sugar,*rp);
1.30      ohara    1449: }
                   1450:
1.97    ! noro     1451: void Pdp_initial_term(NODE arg,Obj *rp)
1.49      noro     1452: {
                   1453:        struct order_spec *ord;
                   1454:        Num homo;
                   1455:        int modular,is_list;
                   1456:        LIST v,f,l,initiallist;
                   1457:        NODE n;
                   1458:
                   1459:        f = (LIST)ARG0(arg);
                   1460:        if ( f && OID(f) == O_LIST )
                   1461:                is_list = 1;
                   1462:        else {
                   1463:                n = mknode(1,f); MKLIST(l,n); f = l;
                   1464:                is_list = 0;
                   1465:        }
1.54      noro     1466:        if ( current_option ) {
1.53      noro     1467:                parse_gr_option(f,current_option,&v,&homo,&modular,&ord);
1.54      noro     1468:                initd(ord);
                   1469:        } else
1.49      noro     1470:                ord = dp_current_spec;
                   1471:        initiallist = dp_initial_term(f,ord);
                   1472:        if ( !is_list )
                   1473:                *rp = (Obj)BDY(BDY(initiallist));
                   1474:        else
                   1475:                *rp = (Obj)initiallist;
                   1476: }
                   1477:
1.97    ! noro     1478: void Pdp_order(NODE arg,Obj *rp)
1.49      noro     1479: {
                   1480:        struct order_spec *ord;
                   1481:        Num homo;
                   1482:        int modular,is_list;
                   1483:        LIST v,f,l,ordlist;
                   1484:        NODE n;
                   1485:
                   1486:        f = (LIST)ARG0(arg);
                   1487:        if ( f && OID(f) == O_LIST )
                   1488:                is_list = 1;
                   1489:        else {
                   1490:                n = mknode(1,f); MKLIST(l,n); f = l;
                   1491:                is_list = 0;
                   1492:        }
1.54      noro     1493:        if ( current_option ) {
1.53      noro     1494:                parse_gr_option(f,current_option,&v,&homo,&modular,&ord);
1.54      noro     1495:                initd(ord);
                   1496:        } else
1.49      noro     1497:                ord = dp_current_spec;
                   1498:        ordlist = dp_order(f,ord);
                   1499:        if ( !is_list )
                   1500:                *rp = (Obj)BDY(BDY(ordlist));
                   1501:        else
                   1502:                *rp = (Obj)ordlist;
                   1503: }
                   1504:
1.97    ! noro     1505: void Pdp_set_sugar(NODE arg,Q *rp)
1.30      ohara    1506: {
                   1507:        DP p;
                   1508:        Q q;
                   1509:        int i;
                   1510:
                   1511:        p = (DP)ARG0(arg);
                   1512:        q = (Q)ARG1(arg);
                   1513:        if ( p && q) {
                   1514:                asir_assert(p,O_DP,"dp_set_sugar");
                   1515:                asir_assert(q,O_N, "dp_set_sugar");
                   1516:                i = QTOS(q);
                   1517:                if (p->sugar < i) {
                   1518:                        p->sugar = i;
                   1519:                }
                   1520:        }
                   1521:        *rp = 0;
1.1       noro     1522: }
                   1523:
1.97    ! noro     1524: void Pdp_cri1(NODE arg,Q *rp)
1.1       noro     1525: {
                   1526:        DP p1,p2;
                   1527:        int *d1,*d2;
                   1528:        int i,n;
                   1529:
                   1530:        p1 = (DP)ARG0(arg); p2 = (DP)ARG1(arg);
                   1531:        asir_assert(p1,O_DP,"dp_cri1"); asir_assert(p2,O_DP,"dp_cri1");
                   1532:        n = p1->nv; d1 = BDY(p1)->dl->d; d2 = BDY(p2)->dl->d;
                   1533:        for ( i = 0; i < n; i++ )
                   1534:                if ( d1[i] > d2[i] )
                   1535:                        break;
                   1536:        *rp = i == n ? ONE : 0;
                   1537: }
                   1538:
1.97    ! noro     1539: void Pdp_cri2(NODE arg,Q *rp)
1.1       noro     1540: {
                   1541:        DP p1,p2;
                   1542:        int *d1,*d2;
                   1543:        int i,n;
                   1544:
                   1545:        p1 = (DP)ARG0(arg); p2 = (DP)ARG1(arg);
                   1546:        asir_assert(p1,O_DP,"dp_cri2"); asir_assert(p2,O_DP,"dp_cri2");
                   1547:        n = p1->nv; d1 = BDY(p1)->dl->d; d2 = BDY(p2)->dl->d;
                   1548:        for ( i = 0; i < n; i++ )
                   1549:                if ( MIN(d1[i],d2[i]) >= 1 )
                   1550:                        break;
                   1551:        *rp = i == n ? ONE : 0;
                   1552: }
                   1553:
1.97    ! noro     1554: void Pdp_minp(NODE arg,LIST *rp)
1.1       noro     1555: {
                   1556:        NODE tn,tn1,d,dd,dd0,p,tp;
                   1557:        LIST l,minp;
                   1558:        DP lcm,tlcm;
                   1559:        int s,ts;
                   1560:
                   1561:        asir_assert(ARG0(arg),O_LIST,"dp_minp");
                   1562:        d = BDY((LIST)ARG0(arg)); minp = (LIST)BDY(d);
                   1563:        p = BDY(minp); p = NEXT(NEXT(p)); lcm = (DP)BDY(p); p = NEXT(p);
                   1564:        if ( !ARG1(arg) ) {
                   1565:                s = QTOS((Q)BDY(p)); p = NEXT(p);
                   1566:                for ( dd0 = 0, d = NEXT(d); d; d = NEXT(d) ) {
                   1567:                        tp = BDY((LIST)BDY(d)); tp = NEXT(NEXT(tp));
                   1568:                        tlcm = (DP)BDY(tp); tp = NEXT(tp);
                   1569:                        ts = QTOS((Q)BDY(tp)); tp = NEXT(tp);
                   1570:                        NEXTNODE(dd0,dd);
                   1571:                        if ( ts < s ) {
                   1572:                                BDY(dd) = (pointer)minp;
                   1573:                                minp = (LIST)BDY(d); lcm = tlcm; s = ts;
                   1574:                        } else if ( ts == s ) {
                   1575:                                if ( compd(CO,lcm,tlcm) > 0 ) {
                   1576:                                        BDY(dd) = (pointer)minp;
                   1577:                                        minp = (LIST)BDY(d); lcm = tlcm; s = ts;
                   1578:                                } else
                   1579:                                        BDY(dd) = BDY(d);
                   1580:                        } else
                   1581:                                BDY(dd) = BDY(d);
                   1582:                }
                   1583:        } else {
                   1584:                for ( dd0 = 0, d = NEXT(d); d; d = NEXT(d) ) {
                   1585:                        tp = BDY((LIST)BDY(d)); tp = NEXT(NEXT(tp));
                   1586:                        tlcm = (DP)BDY(tp);
                   1587:                        NEXTNODE(dd0,dd);
                   1588:                        if ( compd(CO,lcm,tlcm) > 0 ) {
                   1589:                                BDY(dd) = (pointer)minp; minp = (LIST)BDY(d); lcm = tlcm;
                   1590:                        } else
                   1591:                                BDY(dd) = BDY(d);
                   1592:                }
                   1593:        }
                   1594:        if ( dd0 )
                   1595:                NEXT(dd) = 0;
                   1596:        MKLIST(l,dd0); MKNODE(tn,l,0); MKNODE(tn1,minp,tn); MKLIST(*rp,tn1);
                   1597: }
                   1598:
1.97    ! noro     1599: void Pdp_criB(NODE arg,LIST *rp)
1.1       noro     1600: {
                   1601:        NODE d,ij,dd,ddd;
                   1602:        int i,j,s,n;
                   1603:        DP *ps;
                   1604:        DL ts,ti,tj,lij,tdl;
                   1605:
                   1606:        asir_assert(ARG0(arg),O_LIST,"dp_criB"); d = BDY((LIST)ARG0(arg));
                   1607:        asir_assert(ARG1(arg),O_N,"dp_criB"); s = QTOS((Q)ARG1(arg));
                   1608:        asir_assert(ARG2(arg),O_VECT,"dp_criB"); ps = (DP *)BDY((VECT)ARG2(arg));
                   1609:        if ( !d )
                   1610:                *rp = (LIST)ARG0(arg);
                   1611:        else {
                   1612:                ts = BDY(ps[s])->dl;
                   1613:                n = ps[s]->nv;
                   1614:                NEWDL(tdl,n);
                   1615:                for ( dd = 0; d; d = NEXT(d) ) {
                   1616:                        ij = BDY((LIST)BDY(d));
                   1617:                        i = QTOS((Q)BDY(ij)); ij = NEXT(ij);
                   1618:                        j = QTOS((Q)BDY(ij)); ij = NEXT(ij);
                   1619:                        lij = BDY((DP)BDY(ij))->dl;
                   1620:                        ti = BDY(ps[i])->dl; tj = BDY(ps[j])->dl;
                   1621:                        if ( lij->td != lcm_of_DL(n,lij,ts,tdl)->td
                   1622:                                || !dl_equal(n,lij,tdl)
                   1623:                                || (lij->td == lcm_of_DL(n,ti,ts,tdl)->td
                   1624:                                        && dl_equal(n,tdl,lij))
                   1625:                                || (lij->td == lcm_of_DL(n,tj,ts,tdl)->td
                   1626:                                        && dl_equal(n,tdl,lij)) ) {
                   1627:                                MKNODE(ddd,BDY(d),dd);
                   1628:                                dd = ddd;
                   1629:                        }
                   1630:                }
                   1631:                MKLIST(*rp,dd);
                   1632:        }
                   1633: }
                   1634:
1.97    ! noro     1635: void Pdp_nelim(NODE arg,Q *rp)
1.1       noro     1636: {
                   1637:        if ( arg ) {
                   1638:                asir_assert(ARG0(arg),O_N,"dp_nelim");
                   1639:                dp_nelim = QTOS((Q)ARG0(arg));
                   1640:        }
                   1641:        STOQ(dp_nelim,*rp);
                   1642: }
                   1643:
1.97    ! noro     1644: void Pdp_mag(NODE arg,Q *rp)
1.1       noro     1645: {
                   1646:        DP p;
                   1647:        int s;
                   1648:        MP m;
                   1649:
                   1650:        p = (DP)ARG0(arg);
                   1651:        asir_assert(p,O_DP,"dp_mag");
                   1652:        if ( !p )
                   1653:                *rp = 0;
                   1654:        else {
                   1655:                for ( s = 0, m = BDY(p); m; m = NEXT(m) )
                   1656:                        s += p_mag(m->c);
                   1657:                STOQ(s,*rp);
                   1658:        }
                   1659: }
                   1660:
                   1661: extern int kara_mag;
                   1662:
1.97    ! noro     1663: void Pdp_set_kara(NODE arg,Q *rp)
1.1       noro     1664: {
                   1665:        if ( arg ) {
                   1666:                asir_assert(ARG0(arg),O_N,"dp_set_kara");
                   1667:                kara_mag = QTOS((Q)ARG0(arg));
                   1668:        }
                   1669:        STOQ(kara_mag,*rp);
                   1670: }
                   1671:
1.97    ! noro     1672: void Pdp_homo(NODE arg,DP *rp)
1.1       noro     1673: {
                   1674:        asir_assert(ARG0(arg),O_DP,"dp_homo");
                   1675:        dp_homo((DP)ARG0(arg),rp);
                   1676: }
                   1677:
1.97    ! noro     1678: void Pdp_dehomo(NODE arg,DP *rp)
1.1       noro     1679: {
1.8       noro     1680:        asir_assert(ARG0(arg),O_DP,"dp_dehomo");
                   1681:        dp_dehomo((DP)ARG0(arg),rp);
                   1682: }
                   1683:
1.97    ! noro     1684: void Pdp_gr_flags(NODE arg,LIST *rp)
1.8       noro     1685: {
                   1686:        Obj name,value;
                   1687:        NODE n;
1.1       noro     1688:
1.8       noro     1689:        if ( arg ) {
                   1690:                asir_assert(ARG0(arg),O_LIST,"dp_gr_flags");
                   1691:                n = BDY((LIST)ARG0(arg));
                   1692:                while ( n ) {
                   1693:                        name = (Obj)BDY(n); n = NEXT(n);
                   1694:                        if ( !n )
                   1695:                                break;
                   1696:                        else {
                   1697:                                value = (Obj)BDY(n); n = NEXT(n);
                   1698:                        }
                   1699:                        dp_set_flag(name,value);
1.1       noro     1700:                }
                   1701:        }
1.8       noro     1702:        dp_make_flaglist(rp);
                   1703: }
                   1704:
1.29      noro     1705: extern int DP_Print, DP_PrintShort;
1.8       noro     1706:
1.97    ! noro     1707: void Pdp_gr_print(NODE arg,Q *rp)
1.8       noro     1708: {
                   1709:        Q q;
1.29      noro     1710:        int s;
1.8       noro     1711:
                   1712:        if ( arg ) {
                   1713:                asir_assert(ARG0(arg),O_N,"dp_gr_print");
1.29      noro     1714:                q = (Q)ARG0(arg);
                   1715:                s = QTOS(q);
                   1716:                switch ( s ) {
                   1717:                        case 0:
                   1718:                                DP_Print = 0; DP_PrintShort = 0;
                   1719:                                break;
                   1720:                        case 1:
                   1721:                                DP_Print = 1;
                   1722:                                break;
1.41      noro     1723:                        case 2:
1.29      noro     1724:                                DP_Print = 0; DP_PrintShort = 1;
1.43      noro     1725:                                break;
1.41      noro     1726:                        default:
                   1727:                                DP_Print = s; DP_PrintShort = 0;
1.29      noro     1728:                                break;
                   1729:                }
                   1730:        } else {
                   1731:                if ( DP_Print ) {
                   1732:                        STOQ(1,q);
                   1733:                } else if ( DP_PrintShort ) {
                   1734:                        STOQ(2,q);
                   1735:                } else
                   1736:                        q = 0;
                   1737:        }
1.8       noro     1738:        *rp = q;
1.1       noro     1739: }
                   1740:
1.46      noro     1741: void parse_gr_option(LIST f,NODE opt,LIST *v,Num *homo,
                   1742:        int *modular,struct order_spec **ord)
                   1743: {
                   1744:        NODE t,p;
                   1745:        Q m;
                   1746:        char *key;
                   1747:        Obj value,dmy;
                   1748:        int ord_is_set = 0;
                   1749:        int modular_is_set = 0;
                   1750:        int homo_is_set = 0;
1.47      noro     1751:        VL vl,vl0;
1.46      noro     1752:        LIST vars;
1.47      noro     1753:        char xiname[BUFSIZ];
                   1754:        NODE x0,x;
                   1755:        DP d;
                   1756:        P xi;
                   1757:        int nv,i;
1.46      noro     1758:
                   1759:        /* extract vars */
                   1760:        vars = 0;
                   1761:        for ( t = opt; t; t = NEXT(t) ) {
                   1762:                p = BDY((LIST)BDY(t));
                   1763:                key = BDY((STRING)BDY(p));
                   1764:                value = (Obj)BDY(NEXT(p));
                   1765:                if ( !strcmp(key,"v") ) {
                   1766:                        /* variable list */
                   1767:                        vars = (LIST)value;
                   1768:                        break;
                   1769:                }
                   1770:        }
1.48      noro     1771:        if ( vars ) {
                   1772:                *v = vars; pltovl(vars,&vl);
                   1773:        } else {
                   1774:                for ( t = BDY(f); t; t = NEXT(t) )
                   1775:                        if ( BDY(t) && OID((Obj)BDY(t))==O_DP )
                   1776:                                break;
                   1777:                if ( t ) {
                   1778:                        /* f is DP list */
                   1779:                        /* create dummy var list */
                   1780:                        d = (DP)BDY(t);
                   1781:                        nv = NV(d);
                   1782:                        for ( i = 0, vl0 = 0, x0 = 0; i < nv; i++ ) {
                   1783:                                NEXTVL(vl0,vl);
                   1784:                                NEXTNODE(x0,x);
                   1785:                                sprintf(xiname,"x%d",i);
                   1786:                                makevar(xiname,&xi);
                   1787:                                x->body = (pointer)xi;
                   1788:                                vl->v = VR((P)xi);
                   1789:                        }
                   1790:                        if ( vl0 ) {
                   1791:                                NEXT(vl) = 0;
                   1792:                                NEXT(x) = 0;
                   1793:                        }
                   1794:                        MKLIST(vars,x0);
                   1795:                        *v = vars;
                   1796:                        vl = vl0;
                   1797:                } else {
                   1798:                        get_vars((Obj)f,&vl); vltopl(vl,v);
1.47      noro     1799:                }
1.46      noro     1800:        }
                   1801:
                   1802:        for ( t = opt; t; t = NEXT(t) ) {
                   1803:                p = BDY((LIST)BDY(t));
                   1804:                key = BDY((STRING)BDY(p));
                   1805:                value = (Obj)BDY(NEXT(p));
                   1806:                if ( !strcmp(key,"v") ) {
                   1807:                        /* variable list; ignore */
                   1808:                } else if ( !strcmp(key,"order") ) {
                   1809:                        /* order spec */
1.51      noro     1810:                        if ( !vl )
                   1811:                                error("parse_gr_option : variables must be specified");
1.46      noro     1812:                        create_order_spec(vl,value,ord);
                   1813:                        ord_is_set = 1;
                   1814:                } else if ( !strcmp(key,"block") ) {
                   1815:                        create_order_spec(0,value,ord);
1.51      noro     1816:                        ord_is_set = 1;
1.46      noro     1817:                } else if ( !strcmp(key,"matrix") ) {
                   1818:                        create_order_spec(0,value,ord);
1.51      noro     1819:                        ord_is_set = 1;
1.46      noro     1820:                } else if ( !strcmp(key,"sugarweight") ) {
                   1821:                        /* weight */
                   1822:                        Pdp_set_weight(NEXT(p),&dmy);
                   1823:                } else if ( !strcmp(key,"homo") ) {
                   1824:                        *homo = (Num)value;
                   1825:                        homo_is_set = 1;
                   1826:                } else if ( !strcmp(key,"trace") ) {
                   1827:                        m = (Q)value;
                   1828:                        if ( !m )
                   1829:                                *modular = 0;
                   1830:                        else if ( PL(NM(m))>1 || (PL(NM(m)) == 1
                   1831:                                && BD(NM(m))[0] >= 0x80000000) )
                   1832:                                error("parse_gr_option : too large modulus");
                   1833:                        else
                   1834:                                *modular = QTOS(m);
                   1835:                        modular_is_set = 1;
                   1836:                } else
                   1837:                        error("parse_gr_option : not implemented");
                   1838:        }
                   1839:        if ( !ord_is_set ) create_order_spec(0,0,ord);
                   1840:        if ( !modular_is_set ) *modular = 0;
                   1841:        if ( !homo_is_set ) *homo = 0;
                   1842: }
                   1843:
1.97    ! noro     1844: void Pdp_gr_main(NODE arg,LIST *rp)
1.1       noro     1845: {
1.8       noro     1846:        LIST f,v;
1.46      noro     1847:        VL vl;
1.8       noro     1848:        Num homo;
                   1849:        Q m;
1.46      noro     1850:        int modular,ac;
                   1851:        struct order_spec *ord;
1.8       noro     1852:
1.11      noro     1853:        do_weyl = 0;
1.8       noro     1854:        asir_assert(ARG0(arg),O_LIST,"dp_gr_main");
1.46      noro     1855:        f = (LIST)ARG0(arg);
1.25      noro     1856:        f = remove_zero_from_list(f);
                   1857:        if ( !BDY(f) ) {
                   1858:                *rp = f; return;
                   1859:        }
1.53      noro     1860:        if ( (ac = argc(arg)) == 5 ) {
1.46      noro     1861:                asir_assert(ARG1(arg),O_LIST,"dp_gr_main");
                   1862:                asir_assert(ARG2(arg),O_N,"dp_gr_main");
                   1863:                asir_assert(ARG3(arg),O_N,"dp_gr_main");
1.49      noro     1864:                v = (LIST)ARG1(arg);
1.46      noro     1865:                homo = (Num)ARG2(arg);
                   1866:                m = (Q)ARG3(arg);
                   1867:                if ( !m )
                   1868:                        modular = 0;
                   1869:                else if ( PL(NM(m))>1 || (PL(NM(m)) == 1 && BD(NM(m))[0] >= 0x80000000) )
                   1870:                        error("dp_gr_main : too large modulus");
                   1871:                else
                   1872:                        modular = QTOS(m);
                   1873:                create_order_spec(0,ARG4(arg),&ord);
1.53      noro     1874:        } else if ( current_option )
                   1875:                parse_gr_option(f,current_option,&v,&homo,&modular,&ord);
1.46      noro     1876:        else if ( ac == 1 )
                   1877:                parse_gr_option(f,0,&v,&homo,&modular,&ord);
1.8       noro     1878:        else
1.46      noro     1879:                error("dp_gr_main : invalid argument");
                   1880:        dp_gr_main(f,v,homo,modular,0,ord,rp);
1.63      noro     1881: }
                   1882:
1.97    ! noro     1883: void Pdp_interreduce(NODE arg,LIST *rp)
1.63      noro     1884: {
                   1885:        LIST f,v;
                   1886:        VL vl;
                   1887:        int ac;
                   1888:        struct order_spec *ord;
                   1889:
                   1890:        do_weyl = 0;
                   1891:        asir_assert(ARG0(arg),O_LIST,"dp_interreduce");
                   1892:        f = (LIST)ARG0(arg);
                   1893:        f = remove_zero_from_list(f);
                   1894:        if ( !BDY(f) ) {
                   1895:                *rp = f; return;
                   1896:        }
                   1897:        if ( (ac = argc(arg)) == 3 ) {
                   1898:                asir_assert(ARG1(arg),O_LIST,"dp_interreduce");
                   1899:                v = (LIST)ARG1(arg);
                   1900:                create_order_spec(0,ARG2(arg),&ord);
                   1901:        }
                   1902:        dp_interreduce(f,v,0,ord,rp);
1.16      noro     1903: }
                   1904:
1.97    ! noro     1905: void Pdp_gr_f_main(NODE arg,LIST *rp)
1.16      noro     1906: {
                   1907:        LIST f,v;
                   1908:        Num homo;
1.26      noro     1909:        int m,field,t;
1.46      noro     1910:        struct order_spec *ord;
1.26      noro     1911:        NODE n;
1.16      noro     1912:
                   1913:        do_weyl = 0;
                   1914:        asir_assert(ARG0(arg),O_LIST,"dp_gr_f_main");
                   1915:        asir_assert(ARG1(arg),O_LIST,"dp_gr_f_main");
                   1916:        asir_assert(ARG2(arg),O_N,"dp_gr_f_main");
                   1917:        f = (LIST)ARG0(arg); v = (LIST)ARG1(arg);
1.25      noro     1918:        f = remove_zero_from_list(f);
                   1919:        if ( !BDY(f) ) {
                   1920:                *rp = f; return;
                   1921:        }
1.16      noro     1922:        homo = (Num)ARG2(arg);
1.27      noro     1923: #if 0
                   1924:        asir_assert(ARG3(arg),O_N,"dp_gr_f_main");
1.26      noro     1925:        m = QTOS((Q)ARG3(arg));
                   1926:        if ( m )
                   1927:                error("dp_gr_f_main : trace lifting is not implemented yet");
1.46      noro     1928:        create_order_spec(0,ARG4(arg),&ord);
1.27      noro     1929: #else
                   1930:        m = 0;
1.46      noro     1931:        create_order_spec(0,ARG3(arg),&ord);
1.27      noro     1932: #endif
1.26      noro     1933:        field = 0;
                   1934:        for ( n = BDY(f); n; n = NEXT(n) ) {
                   1935:                t = get_field_type(BDY(n));
                   1936:                if ( !t )
                   1937:                        continue;
                   1938:                if ( t < 0 )
                   1939:                        error("dp_gr_f_main : incosistent coefficients");
                   1940:                if ( !field )
                   1941:                        field = t;
                   1942:                else if ( t != field )
                   1943:                        error("dp_gr_f_main : incosistent coefficients");
                   1944:        }
1.46      noro     1945:        dp_gr_main(f,v,homo,m?1:0,field,ord,rp);
1.1       noro     1946: }
                   1947:
1.97    ! noro     1948: void Pdp_f4_main(NODE arg,LIST *rp)
1.1       noro     1949: {
1.8       noro     1950:        LIST f,v;
1.46      noro     1951:        struct order_spec *ord;
1.1       noro     1952:
1.11      noro     1953:        do_weyl = 0;
1.8       noro     1954:        asir_assert(ARG0(arg),O_LIST,"dp_f4_main");
                   1955:        asir_assert(ARG1(arg),O_LIST,"dp_f4_main");
                   1956:        f = (LIST)ARG0(arg); v = (LIST)ARG1(arg);
1.25      noro     1957:        f = remove_zero_from_list(f);
                   1958:        if ( !BDY(f) ) {
                   1959:                *rp = f; return;
                   1960:        }
1.46      noro     1961:        create_order_spec(0,ARG2(arg),&ord);
                   1962:        dp_f4_main(f,v,ord,rp);
1.22      noro     1963: }
                   1964:
                   1965: /* dp_gr_checklist(list of dp) */
                   1966:
1.97    ! noro     1967: void Pdp_gr_checklist(NODE arg,LIST *rp)
1.22      noro     1968: {
                   1969:        VECT g;
                   1970:        LIST dp;
                   1971:        NODE r;
1.23      noro     1972:        int n;
1.22      noro     1973:
                   1974:        do_weyl = 0;
                   1975:        asir_assert(ARG0(arg),O_LIST,"dp_gr_checklist");
1.23      noro     1976:        asir_assert(ARG1(arg),O_N,"dp_gr_checklist");
                   1977:        n = QTOS((Q)ARG1(arg));
                   1978:        gbcheck_list(BDY((LIST)ARG0(arg)),n,&g,&dp);
1.22      noro     1979:        r = mknode(2,g,dp);
                   1980:        MKLIST(*rp,r);
1.1       noro     1981: }
                   1982:
1.97    ! noro     1983: void Pdp_f4_mod_main(NODE arg,LIST *rp)
1.1       noro     1984: {
1.8       noro     1985:        LIST f,v;
                   1986:        int m;
1.46      noro     1987:        struct order_spec *ord;
1.8       noro     1988:
1.11      noro     1989:        do_weyl = 0;
1.17      noro     1990:        asir_assert(ARG0(arg),O_LIST,"dp_f4_mod_main");
                   1991:        asir_assert(ARG1(arg),O_LIST,"dp_f4_mod_main");
                   1992:        asir_assert(ARG2(arg),O_N,"dp_f4_mod_main");
1.8       noro     1993:        f = (LIST)ARG0(arg); v = (LIST)ARG1(arg); m = QTOS((Q)ARG2(arg));
1.25      noro     1994:        f = remove_zero_from_list(f);
                   1995:        if ( !BDY(f) ) {
                   1996:                *rp = f; return;
                   1997:        }
1.20      noro     1998:        if ( !m )
                   1999:                error("dp_f4_mod_main : invalid argument");
1.46      noro     2000:        create_order_spec(0,ARG3(arg),&ord);
                   2001:        dp_f4_mod_main(f,v,m,ord,rp);
1.8       noro     2002: }
1.1       noro     2003:
1.97    ! noro     2004: void Pdp_gr_mod_main(NODE arg,LIST *rp)
1.8       noro     2005: {
                   2006:        LIST f,v;
                   2007:        Num homo;
                   2008:        int m;
1.46      noro     2009:        struct order_spec *ord;
1.8       noro     2010:
1.11      noro     2011:        do_weyl = 0;
1.8       noro     2012:        asir_assert(ARG0(arg),O_LIST,"dp_gr_mod_main");
                   2013:        asir_assert(ARG1(arg),O_LIST,"dp_gr_mod_main");
                   2014:        asir_assert(ARG2(arg),O_N,"dp_gr_mod_main");
                   2015:        asir_assert(ARG3(arg),O_N,"dp_gr_mod_main");
1.11      noro     2016:        f = (LIST)ARG0(arg); v = (LIST)ARG1(arg);
1.25      noro     2017:        f = remove_zero_from_list(f);
                   2018:        if ( !BDY(f) ) {
                   2019:                *rp = f; return;
                   2020:        }
1.11      noro     2021:        homo = (Num)ARG2(arg); m = QTOS((Q)ARG3(arg));
1.20      noro     2022:        if ( !m )
                   2023:                error("dp_gr_mod_main : invalid argument");
1.46      noro     2024:        create_order_spec(0,ARG4(arg),&ord);
                   2025:        dp_gr_mod_main(f,v,homo,m,ord,rp);
1.33      noro     2026: }
                   2027:
1.97    ! noro     2028: void Pnd_f4(NODE arg,LIST *rp)
1.40      noro     2029: {
                   2030:        LIST f,v;
1.87      noro     2031:        int m,homo,retdp;
                   2032:        Obj val;
1.46      noro     2033:        struct order_spec *ord;
1.40      noro     2034:
                   2035:        do_weyl = 0;
1.94      noro     2036:        nd_rref2 = 0;
1.76      noro     2037:        asir_assert(ARG0(arg),O_LIST,"nd_f4");
                   2038:        asir_assert(ARG1(arg),O_LIST,"nd_f4");
                   2039:        asir_assert(ARG2(arg),O_N,"nd_f4");
1.40      noro     2040:        f = (LIST)ARG0(arg); v = (LIST)ARG1(arg);
                   2041:        f = remove_zero_from_list(f);
                   2042:        if ( !BDY(f) ) {
                   2043:                *rp = f; return;
                   2044:        }
                   2045:        m = QTOS((Q)ARG2(arg));
1.46      noro     2046:        create_order_spec(0,ARG3(arg),&ord);
1.87      noro     2047:        homo = retdp = 0;
                   2048:        if ( get_opt("homo",&val) && val ) homo = 1;
                   2049:        if ( get_opt("dp",&val) && val ) retdp = 1;
1.94      noro     2050:        if ( get_opt("rref2",&val) && val ) nd_rref2 = 1;
1.87      noro     2051:        nd_gr(f,v,m,homo,retdp,1,ord,rp);
1.40      noro     2052: }
                   2053:
1.97    ! noro     2054: void Pnd_gr(NODE arg,LIST *rp)
1.33      noro     2055: {
                   2056:        LIST f,v;
1.87      noro     2057:        int m,homo,retdp;
                   2058:        Obj val;
1.46      noro     2059:        struct order_spec *ord;
1.33      noro     2060:
                   2061:        do_weyl = 0;
                   2062:        asir_assert(ARG0(arg),O_LIST,"nd_gr");
                   2063:        asir_assert(ARG1(arg),O_LIST,"nd_gr");
1.36      noro     2064:        asir_assert(ARG2(arg),O_N,"nd_gr");
1.33      noro     2065:        f = (LIST)ARG0(arg); v = (LIST)ARG1(arg);
                   2066:        f = remove_zero_from_list(f);
                   2067:        if ( !BDY(f) ) {
                   2068:                *rp = f; return;
                   2069:        }
                   2070:        m = QTOS((Q)ARG2(arg));
1.46      noro     2071:        create_order_spec(0,ARG3(arg),&ord);
1.87      noro     2072:        homo = retdp = 0;
                   2073:        if ( get_opt("homo",&val) && val ) homo = 1;
                   2074:        if ( get_opt("dp",&val) && val ) retdp = 1;
                   2075:        nd_gr(f,v,m,homo,retdp,0,ord,rp);
1.58      noro     2076: }
                   2077:
1.97    ! noro     2078: void Pnd_gr_postproc(NODE arg,LIST *rp)
1.58      noro     2079: {
                   2080:        LIST f,v;
                   2081:        int m,do_check;
                   2082:        struct order_spec *ord;
                   2083:
                   2084:        do_weyl = 0;
                   2085:        asir_assert(ARG0(arg),O_LIST,"nd_gr");
                   2086:        asir_assert(ARG1(arg),O_LIST,"nd_gr");
                   2087:        asir_assert(ARG2(arg),O_N,"nd_gr");
                   2088:        f = (LIST)ARG0(arg); v = (LIST)ARG1(arg);
                   2089:        f = remove_zero_from_list(f);
                   2090:        if ( !BDY(f) ) {
                   2091:                *rp = f; return;
                   2092:        }
                   2093:        m = QTOS((Q)ARG2(arg));
                   2094:        create_order_spec(0,ARG3(arg),&ord);
                   2095:        do_check = ARG4(arg) ? 1 : 0;
                   2096:        nd_gr_postproc(f,v,m,ord,do_check,rp);
1.36      noro     2097: }
                   2098:
1.97    ! noro     2099: void Pnd_gr_recompute_trace(NODE arg,LIST *rp)
1.86      noro     2100: {
                   2101:        LIST f,v,tlist;
                   2102:        int m;
                   2103:        struct order_spec *ord;
                   2104:
                   2105:        do_weyl = 0;
                   2106:        asir_assert(ARG0(arg),O_LIST,"nd_gr_recompute_trace");
                   2107:        asir_assert(ARG1(arg),O_LIST,"nd_gr_recompute_trace");
                   2108:        asir_assert(ARG2(arg),O_N,"nd_gr_recompute_trace");
                   2109:        f = (LIST)ARG0(arg); v = (LIST)ARG1(arg);
                   2110:        m = QTOS((Q)ARG2(arg));
                   2111:        create_order_spec(0,ARG3(arg),&ord);
                   2112:        tlist = (LIST)ARG4(arg);
                   2113:        nd_gr_recompute_trace(f,v,m,ord,tlist,rp);
                   2114: }
1.89      noro     2115:
1.90      noro     2116: Obj nd_btog_one(LIST f,LIST v,int m,struct order_spec *ord,LIST tlist,int pos);
                   2117: Obj nd_btog(LIST f,LIST v,int m,struct order_spec *ord,LIST tlist);
                   2118:
1.97    ! noro     2119: void Pnd_btog(NODE arg,Obj *rp)
1.89      noro     2120: {
                   2121:        LIST f,v,tlist;
1.90      noro     2122:        int m,ac,pos;
1.89      noro     2123:        struct order_spec *ord;
                   2124:
                   2125:        do_weyl = 0;
                   2126:        asir_assert(ARG0(arg),O_LIST,"nd_btog");
                   2127:        asir_assert(ARG1(arg),O_LIST,"nd_btog");
                   2128:        asir_assert(ARG2(arg),O_N,"nd_btog");
                   2129:        f = (LIST)ARG0(arg); v = (LIST)ARG1(arg);
                   2130:        m = QTOS((Q)ARG2(arg));
                   2131:        create_order_spec(0,ARG3(arg),&ord);
                   2132:        tlist = (LIST)ARG4(arg);
1.90      noro     2133:        if ( (ac = argc(arg)) == 6 ) {
                   2134:                asir_assert(ARG5(arg),O_N,"nd_btog");
                   2135:                pos = QTOS((Q)ARG5(arg));
                   2136:                *rp = nd_btog_one(f,v,m,ord,tlist,pos);
                   2137:        } else if ( ac == 5 )
                   2138:                *rp = nd_btog(f,v,m,ord,tlist);
                   2139:        else
                   2140:                error("nd_btog : argument mismatch");
1.89      noro     2141: }
1.86      noro     2142:
1.97    ! noro     2143: void Pnd_weyl_gr_postproc(NODE arg,LIST *rp)
1.75      noro     2144: {
                   2145:        LIST f,v;
                   2146:        int m,do_check;
                   2147:        struct order_spec *ord;
                   2148:
                   2149:        do_weyl = 1;
                   2150:        asir_assert(ARG0(arg),O_LIST,"nd_gr");
                   2151:        asir_assert(ARG1(arg),O_LIST,"nd_gr");
                   2152:        asir_assert(ARG2(arg),O_N,"nd_gr");
                   2153:        f = (LIST)ARG0(arg); v = (LIST)ARG1(arg);
                   2154:        f = remove_zero_from_list(f);
                   2155:        if ( !BDY(f) ) {
1.80      noro     2156:                *rp = f; do_weyl = 0; return;
1.75      noro     2157:        }
                   2158:        m = QTOS((Q)ARG2(arg));
                   2159:        create_order_spec(0,ARG3(arg),&ord);
                   2160:        do_check = ARG4(arg) ? 1 : 0;
                   2161:        nd_gr_postproc(f,v,m,ord,do_check,rp);
1.80      noro     2162:        do_weyl = 0;
1.75      noro     2163: }
                   2164:
1.97    ! noro     2165: void Pnd_gr_trace(NODE arg,LIST *rp)
1.36      noro     2166: {
                   2167:        LIST f,v;
                   2168:        int m,homo;
1.46      noro     2169:        struct order_spec *ord;
1.36      noro     2170:
                   2171:        do_weyl = 0;
                   2172:        asir_assert(ARG0(arg),O_LIST,"nd_gr_trace");
                   2173:        asir_assert(ARG1(arg),O_LIST,"nd_gr_trace");
                   2174:        asir_assert(ARG2(arg),O_N,"nd_gr_trace");
                   2175:        asir_assert(ARG3(arg),O_N,"nd_gr_trace");
                   2176:        f = (LIST)ARG0(arg); v = (LIST)ARG1(arg);
                   2177:        f = remove_zero_from_list(f);
                   2178:        if ( !BDY(f) ) {
                   2179:                *rp = f; return;
                   2180:        }
                   2181:        homo = QTOS((Q)ARG2(arg));
                   2182:        m = QTOS((Q)ARG3(arg));
1.46      noro     2183:        create_order_spec(0,ARG4(arg),&ord);
1.62      noro     2184:        nd_gr_trace(f,v,m,homo,0,ord,rp);
                   2185: }
                   2186:
1.97    ! noro     2187: void Pnd_f4_trace(NODE arg,LIST *rp)
1.62      noro     2188: {
                   2189:        LIST f,v;
                   2190:        int m,homo;
                   2191:        struct order_spec *ord;
                   2192:
                   2193:        do_weyl = 0;
                   2194:        asir_assert(ARG0(arg),O_LIST,"nd_gr_trace");
                   2195:        asir_assert(ARG1(arg),O_LIST,"nd_gr_trace");
                   2196:        asir_assert(ARG2(arg),O_N,"nd_gr_trace");
                   2197:        asir_assert(ARG3(arg),O_N,"nd_gr_trace");
                   2198:        f = (LIST)ARG0(arg); v = (LIST)ARG1(arg);
                   2199:        f = remove_zero_from_list(f);
                   2200:        if ( !BDY(f) ) {
                   2201:                *rp = f; return;
                   2202:        }
                   2203:        homo = QTOS((Q)ARG2(arg));
                   2204:        m = QTOS((Q)ARG3(arg));
                   2205:        create_order_spec(0,ARG4(arg),&ord);
                   2206:        nd_gr_trace(f,v,m,homo,1,ord,rp);
1.11      noro     2207: }
                   2208:
1.97    ! noro     2209: void Pnd_weyl_gr(NODE arg,LIST *rp)
1.38      noro     2210: {
                   2211:        LIST f,v;
1.87      noro     2212:        int m,homo,retdp;
                   2213:        Obj val;
1.46      noro     2214:        struct order_spec *ord;
1.38      noro     2215:
                   2216:        do_weyl = 1;
                   2217:        asir_assert(ARG0(arg),O_LIST,"nd_weyl_gr");
                   2218:        asir_assert(ARG1(arg),O_LIST,"nd_weyl_gr");
                   2219:        asir_assert(ARG2(arg),O_N,"nd_weyl_gr");
                   2220:        f = (LIST)ARG0(arg); v = (LIST)ARG1(arg);
                   2221:        f = remove_zero_from_list(f);
                   2222:        if ( !BDY(f) ) {
1.80      noro     2223:                *rp = f; do_weyl = 0; return;
1.38      noro     2224:        }
                   2225:        m = QTOS((Q)ARG2(arg));
1.46      noro     2226:        create_order_spec(0,ARG3(arg),&ord);
1.87      noro     2227:        homo = retdp = 0;
                   2228:        if ( get_opt("homo",&val) && val ) homo = 1;
                   2229:        if ( get_opt("dp",&val) && val ) retdp = 1;
                   2230:        nd_gr(f,v,m,homo,retdp,0,ord,rp);
1.80      noro     2231:        do_weyl = 0;
1.38      noro     2232: }
                   2233:
1.97    ! noro     2234: void Pnd_weyl_gr_trace(NODE arg,LIST *rp)
1.38      noro     2235: {
                   2236:        LIST f,v;
                   2237:        int m,homo;
1.46      noro     2238:        struct order_spec *ord;
1.38      noro     2239:
                   2240:        do_weyl = 1;
                   2241:        asir_assert(ARG0(arg),O_LIST,"nd_weyl_gr_trace");
                   2242:        asir_assert(ARG1(arg),O_LIST,"nd_weyl_gr_trace");
                   2243:        asir_assert(ARG2(arg),O_N,"nd_weyl_gr_trace");
                   2244:        asir_assert(ARG3(arg),O_N,"nd_weyl_gr_trace");
                   2245:        f = (LIST)ARG0(arg); v = (LIST)ARG1(arg);
                   2246:        f = remove_zero_from_list(f);
                   2247:        if ( !BDY(f) ) {
1.80      noro     2248:                *rp = f; do_weyl = 0; return;
1.38      noro     2249:        }
                   2250:        homo = QTOS((Q)ARG2(arg));
                   2251:        m = QTOS((Q)ARG3(arg));
1.46      noro     2252:        create_order_spec(0,ARG4(arg),&ord);
1.65      noro     2253:        nd_gr_trace(f,v,m,homo,0,ord,rp);
1.80      noro     2254:        do_weyl = 0;
1.38      noro     2255: }
1.39      noro     2256:
1.83      noro     2257: void Pnd_nf(NODE arg,Obj *rp)
1.39      noro     2258: {
1.83      noro     2259:        Obj f;
1.39      noro     2260:        LIST g,v;
1.46      noro     2261:        struct order_spec *ord;
1.39      noro     2262:
                   2263:        do_weyl = 0;
                   2264:        asir_assert(ARG1(arg),O_LIST,"nd_nf");
                   2265:        asir_assert(ARG2(arg),O_LIST,"nd_nf");
                   2266:        asir_assert(ARG4(arg),O_N,"nd_nf");
1.83      noro     2267:        f = (Obj)ARG0(arg);
                   2268:        g = (LIST)ARG1(arg); g = remove_zero_from_list(g);
                   2269:        if ( !BDY(g) ) {
                   2270:                *rp = f; return;
                   2271:        }
                   2272:        v = (LIST)ARG2(arg);
                   2273:        create_order_spec(0,ARG3(arg),&ord);
                   2274:        nd_nf_p(f,g,v,QTOS((Q)ARG4(arg)),ord,rp);
                   2275: }
                   2276:
                   2277: void Pnd_weyl_nf(NODE arg,Obj *rp)
                   2278: {
                   2279:        Obj f;
                   2280:        LIST g,v;
                   2281:        struct order_spec *ord;
                   2282:
                   2283:        do_weyl = 1;
                   2284:        asir_assert(ARG1(arg),O_LIST,"nd_weyl_nf");
                   2285:        asir_assert(ARG2(arg),O_LIST,"nd_weyl_nf");
                   2286:        asir_assert(ARG4(arg),O_N,"nd_weyl_nf");
                   2287:        f = (Obj)ARG0(arg);
1.39      noro     2288:        g = (LIST)ARG1(arg); g = remove_zero_from_list(g);
                   2289:        if ( !BDY(g) ) {
                   2290:                *rp = f; return;
                   2291:        }
                   2292:        v = (LIST)ARG2(arg);
1.46      noro     2293:        create_order_spec(0,ARG3(arg),&ord);
                   2294:        nd_nf_p(f,g,v,QTOS((Q)ARG4(arg)),ord,rp);
1.39      noro     2295: }
                   2296:
1.11      noro     2297: /* for Weyl algebra */
                   2298:
1.97    ! noro     2299: void Pdp_weyl_gr_main(NODE arg,LIST *rp)
1.11      noro     2300: {
                   2301:        LIST f,v;
                   2302:        Num homo;
                   2303:        Q m;
1.49      noro     2304:        int modular,ac;
1.46      noro     2305:        struct order_spec *ord;
1.11      noro     2306:
1.49      noro     2307:
1.11      noro     2308:        asir_assert(ARG0(arg),O_LIST,"dp_weyl_gr_main");
1.49      noro     2309:        f = (LIST)ARG0(arg);
1.25      noro     2310:        f = remove_zero_from_list(f);
                   2311:        if ( !BDY(f) ) {
                   2312:                *rp = f; return;
                   2313:        }
1.53      noro     2314:        if ( (ac = argc(arg)) == 5 ) {
1.49      noro     2315:                asir_assert(ARG1(arg),O_LIST,"dp_weyl_gr_main");
                   2316:                asir_assert(ARG2(arg),O_N,"dp_weyl_gr_main");
                   2317:                asir_assert(ARG3(arg),O_N,"dp_weyl_gr_main");
                   2318:                v = (LIST)ARG1(arg);
                   2319:                homo = (Num)ARG2(arg);
                   2320:                m = (Q)ARG3(arg);
                   2321:                if ( !m )
                   2322:                        modular = 0;
                   2323:                else if ( PL(NM(m))>1 || (PL(NM(m)) == 1 && BD(NM(m))[0] >= 0x80000000) )
                   2324:                        error("dp_weyl_gr_main : too large modulus");
                   2325:                else
                   2326:                        modular = QTOS(m);
                   2327:                create_order_spec(0,ARG4(arg),&ord);
1.53      noro     2328:        } else if ( current_option )
                   2329:                parse_gr_option(f,current_option,&v,&homo,&modular,&ord);
1.49      noro     2330:        else if ( ac == 1 )
                   2331:                parse_gr_option(f,0,&v,&homo,&modular,&ord);
1.11      noro     2332:        else
1.49      noro     2333:                error("dp_weyl_gr_main : invalid argument");
1.12      noro     2334:        do_weyl = 1;
1.46      noro     2335:        dp_gr_main(f,v,homo,modular,0,ord,rp);
1.16      noro     2336:        do_weyl = 0;
                   2337: }
                   2338:
1.97    ! noro     2339: void Pdp_weyl_gr_f_main(NODE arg,LIST *rp)
1.16      noro     2340: {
                   2341:        LIST f,v;
                   2342:        Num homo;
1.46      noro     2343:        struct order_spec *ord;
1.16      noro     2344:
                   2345:        asir_assert(ARG0(arg),O_LIST,"dp_weyl_gr_main");
                   2346:        asir_assert(ARG1(arg),O_LIST,"dp_weyl_gr_main");
                   2347:        asir_assert(ARG2(arg),O_N,"dp_weyl_gr_main");
                   2348:        asir_assert(ARG3(arg),O_N,"dp_weyl_gr_main");
                   2349:        f = (LIST)ARG0(arg); v = (LIST)ARG1(arg);
1.25      noro     2350:        f = remove_zero_from_list(f);
                   2351:        if ( !BDY(f) ) {
                   2352:                *rp = f; return;
                   2353:        }
1.16      noro     2354:        homo = (Num)ARG2(arg);
1.46      noro     2355:        create_order_spec(0,ARG3(arg),&ord);
1.16      noro     2356:        do_weyl = 1;
1.46      noro     2357:        dp_gr_main(f,v,homo,0,1,ord,rp);
1.12      noro     2358:        do_weyl = 0;
1.11      noro     2359: }
                   2360:
1.97    ! noro     2361: void Pdp_weyl_f4_main(NODE arg,LIST *rp)
1.11      noro     2362: {
                   2363:        LIST f,v;
1.46      noro     2364:        struct order_spec *ord;
1.11      noro     2365:
                   2366:        asir_assert(ARG0(arg),O_LIST,"dp_weyl_f4_main");
                   2367:        asir_assert(ARG1(arg),O_LIST,"dp_weyl_f4_main");
                   2368:        f = (LIST)ARG0(arg); v = (LIST)ARG1(arg);
1.25      noro     2369:        f = remove_zero_from_list(f);
                   2370:        if ( !BDY(f) ) {
                   2371:                *rp = f; return;
                   2372:        }
1.46      noro     2373:        create_order_spec(0,ARG2(arg),&ord);
1.12      noro     2374:        do_weyl = 1;
1.46      noro     2375:        dp_f4_main(f,v,ord,rp);
1.12      noro     2376:        do_weyl = 0;
1.11      noro     2377: }
                   2378:
1.97    ! noro     2379: void Pdp_weyl_f4_mod_main(NODE arg,LIST *rp)
1.11      noro     2380: {
                   2381:        LIST f,v;
                   2382:        int m;
1.46      noro     2383:        struct order_spec *ord;
1.11      noro     2384:
                   2385:        asir_assert(ARG0(arg),O_LIST,"dp_weyl_f4_main");
                   2386:        asir_assert(ARG1(arg),O_LIST,"dp_weyl_f4_main");
                   2387:        asir_assert(ARG2(arg),O_N,"dp_f4_main");
                   2388:        f = (LIST)ARG0(arg); v = (LIST)ARG1(arg); m = QTOS((Q)ARG2(arg));
1.25      noro     2389:        f = remove_zero_from_list(f);
                   2390:        if ( !BDY(f) ) {
                   2391:                *rp = f; return;
                   2392:        }
1.20      noro     2393:        if ( !m )
                   2394:                error("dp_weyl_f4_mod_main : invalid argument");
1.46      noro     2395:        create_order_spec(0,ARG3(arg),&ord);
1.12      noro     2396:        do_weyl = 1;
1.46      noro     2397:        dp_f4_mod_main(f,v,m,ord,rp);
1.12      noro     2398:        do_weyl = 0;
1.11      noro     2399: }
                   2400:
1.97    ! noro     2401: void Pdp_weyl_gr_mod_main(NODE arg,LIST *rp)
1.11      noro     2402: {
                   2403:        LIST f,v;
                   2404:        Num homo;
                   2405:        int m;
1.46      noro     2406:        struct order_spec *ord;
1.11      noro     2407:
                   2408:        asir_assert(ARG0(arg),O_LIST,"dp_weyl_gr_mod_main");
                   2409:        asir_assert(ARG1(arg),O_LIST,"dp_weyl_gr_mod_main");
                   2410:        asir_assert(ARG2(arg),O_N,"dp_weyl_gr_mod_main");
                   2411:        asir_assert(ARG3(arg),O_N,"dp_weyl_gr_mod_main");
1.8       noro     2412:        f = (LIST)ARG0(arg); v = (LIST)ARG1(arg);
1.25      noro     2413:        f = remove_zero_from_list(f);
                   2414:        if ( !BDY(f) ) {
                   2415:                *rp = f; return;
                   2416:        }
1.8       noro     2417:        homo = (Num)ARG2(arg); m = QTOS((Q)ARG3(arg));
1.20      noro     2418:        if ( !m )
                   2419:                error("dp_weyl_gr_mod_main : invalid argument");
1.46      noro     2420:        create_order_spec(0,ARG4(arg),&ord);
1.12      noro     2421:        do_weyl = 1;
1.46      noro     2422:        dp_gr_mod_main(f,v,homo,m,ord,rp);
1.12      noro     2423:        do_weyl = 0;
1.1       noro     2424: }
1.8       noro     2425:
1.57      noro     2426: VECT current_dl_weight_vector_obj;
1.24      noro     2427: int *current_dl_weight_vector;
                   2428:
1.97    ! noro     2429: void Pdp_set_weight(NODE arg,VECT *rp)
1.24      noro     2430: {
                   2431:        VECT v;
                   2432:        int i,n;
1.45      noro     2433:        NODE node;
1.24      noro     2434:
                   2435:        if ( !arg )
                   2436:                *rp = current_dl_weight_vector_obj;
                   2437:        else if ( !ARG0(arg) ) {
                   2438:                current_dl_weight_vector_obj = 0;
                   2439:                current_dl_weight_vector = 0;
                   2440:                *rp = 0;
                   2441:        } else {
1.45      noro     2442:                if ( OID(ARG0(arg)) != O_VECT && OID(ARG0(arg)) != O_LIST )
                   2443:                        error("dp_set_weight : invalid argument");
                   2444:                if ( OID(ARG0(arg)) == O_VECT )
                   2445:                        v = (VECT)ARG0(arg);
                   2446:                else {
                   2447:                        node = (NODE)BDY((LIST)ARG0(arg));
                   2448:                        n = length(node);
                   2449:                        MKVECT(v,n);
                   2450:                        for ( i = 0; i < n; i++, node = NEXT(node) )
                   2451:                                BDY(v)[i] = BDY(node);
                   2452:                }
1.24      noro     2453:                current_dl_weight_vector_obj = v;
                   2454:                n = v->len;
                   2455:                current_dl_weight_vector = (int *)CALLOC(n,sizeof(int));
                   2456:                for ( i = 0; i < n; i++ )
                   2457:                        current_dl_weight_vector[i] = QTOS((Q)v->body[i]);
                   2458:                *rp = v;
                   2459:        }
                   2460: }
                   2461:
1.77      noro     2462: VECT current_module_weight_vector_obj;
                   2463: int *current_module_weight_vector;
                   2464:
1.97    ! noro     2465: void Pdp_set_module_weight(NODE arg,VECT *rp)
1.77      noro     2466: {
                   2467:        VECT v;
                   2468:        int i,n;
                   2469:        NODE node;
                   2470:
                   2471:        if ( !arg )
                   2472:                *rp = current_module_weight_vector_obj;
                   2473:        else if ( !ARG0(arg) ) {
                   2474:                current_module_weight_vector_obj = 0;
                   2475:                current_module_weight_vector = 0;
                   2476:                *rp = 0;
                   2477:        } else {
                   2478:                if ( OID(ARG0(arg)) != O_VECT && OID(ARG0(arg)) != O_LIST )
                   2479:                        error("dp_module_set_weight : invalid argument");
                   2480:                if ( OID(ARG0(arg)) == O_VECT )
                   2481:                        v = (VECT)ARG0(arg);
                   2482:                else {
                   2483:                        node = (NODE)BDY((LIST)ARG0(arg));
                   2484:                        n = length(node);
                   2485:                        MKVECT(v,n);
                   2486:                        for ( i = 0; i < n; i++, node = NEXT(node) )
                   2487:                                BDY(v)[i] = BDY(node);
                   2488:                }
                   2489:                current_module_weight_vector_obj = v;
                   2490:                n = v->len;
                   2491:                current_module_weight_vector = (int *)CALLOC(n,sizeof(int));
                   2492:                for ( i = 0; i < n; i++ )
                   2493:                        current_module_weight_vector[i] = QTOS((Q)v->body[i]);
                   2494:                *rp = v;
                   2495:        }
                   2496: }
                   2497:
1.93      noro     2498: extern Obj current_top_weight;
1.92      noro     2499: extern Obj nd_top_weight;
1.71      noro     2500:
1.92      noro     2501: void Pdp_set_top_weight(NODE arg,Obj *rp)
1.71      noro     2502: {
                   2503:        VECT v;
1.92      noro     2504:        MAT m;
                   2505:        Obj obj;
                   2506:        int i,j,n,id,row,col;
                   2507:        Q *mi;
1.71      noro     2508:        NODE node;
                   2509:
                   2510:        if ( !arg )
1.92      noro     2511:                *rp = current_top_weight;
1.71      noro     2512:        else if ( !ARG0(arg) ) {
1.93      noro     2513:                reset_top_weight();
1.71      noro     2514:                *rp = 0;
                   2515:        } else {
1.92      noro     2516:                id = OID(ARG0(arg));
                   2517:                if ( id != O_VECT && id != O_MAT && id != O_LIST )
1.71      noro     2518:                        error("dp_set_top_weight : invalid argument");
1.92      noro     2519:                if ( id == O_LIST ) {
1.71      noro     2520:                        node = (NODE)BDY((LIST)ARG0(arg));
                   2521:                        n = length(node);
                   2522:                        MKVECT(v,n);
                   2523:                        for ( i = 0; i < n; i++, node = NEXT(node) )
                   2524:                                BDY(v)[i] = BDY(node);
1.97    ! noro     2525:                    obj = (Obj)v;
1.92      noro     2526:                } else
                   2527:                    obj = ARG0(arg);
                   2528:                if ( OID(obj) == O_VECT ) {
                   2529:                        v = (VECT)obj;
                   2530:                    for ( i = 0; i < v->len; i++ )
                   2531:                            if ( !INT(BDY(v)[i]) || (BDY(v)[i] && SGN((Q)BDY(v)[i]) < 0) )
                   2532:                                    error("dp_set_top_weight : each element must be a non-negative integer");
                   2533:                } else {
                   2534:                        m = (MAT)obj; row = m->row; col = m->col;
                   2535:                    for ( i = 0; i < row; i++ )
                   2536:                                for ( j = 0, mi = (Q *)BDY(m)[i]; j < col; j++ )
                   2537:                                if ( !INT(mi[j]) || (mi[j] && SGN((Q)mi[j]) < 0) )
                   2538:                                        error("dp_set_top_weight : each element must be a non-negative integer");
                   2539:                }
                   2540:         current_top_weight = obj;
                   2541:                nd_top_weight = obj;
                   2542:                *rp = current_top_weight;
1.71      noro     2543:        }
                   2544: }
                   2545:
1.72      noro     2546: LIST get_denomlist();
                   2547:
                   2548: void Pdp_get_denomlist(LIST *rp)
                   2549: {
                   2550:        *rp = get_denomlist();
                   2551: }
                   2552:
1.24      noro     2553: static VECT current_weyl_weight_vector_obj;
                   2554: int *current_weyl_weight_vector;
1.15      noro     2555:
1.97    ! noro     2556: void Pdp_weyl_set_weight(NODE arg,VECT *rp)
1.15      noro     2557: {
                   2558:        VECT v;
1.85      noro     2559:        NODE node;
1.15      noro     2560:        int i,n;
                   2561:
                   2562:        if ( !arg )
1.24      noro     2563:                *rp = current_weyl_weight_vector_obj;
1.78      noro     2564:        else if ( !ARG0(arg) ) {
                   2565:                current_weyl_weight_vector_obj = 0;
                   2566:                current_weyl_weight_vector = 0;
                   2567:                *rp = 0;
                   2568:        } else {
1.85      noro     2569:                if ( OID(ARG0(arg)) != O_VECT && OID(ARG0(arg)) != O_LIST )
                   2570:                        error("dp_weyl_set_weight : invalid argument");
                   2571:                if ( OID(ARG0(arg)) == O_VECT )
                   2572:                        v = (VECT)ARG0(arg);
                   2573:                else {
                   2574:                        node = (NODE)BDY((LIST)ARG0(arg));
                   2575:                        n = length(node);
                   2576:                        MKVECT(v,n);
                   2577:                        for ( i = 0; i < n; i++, node = NEXT(node) )
                   2578:                                BDY(v)[i] = BDY(node);
                   2579:                }
1.24      noro     2580:                current_weyl_weight_vector_obj = v;
1.15      noro     2581:                n = v->len;
1.24      noro     2582:                current_weyl_weight_vector = (int *)CALLOC(n,sizeof(int));
1.15      noro     2583:                for ( i = 0; i < n; i++ )
1.24      noro     2584:                        current_weyl_weight_vector[i] = QTOS((Q)v->body[i]);
1.15      noro     2585:                *rp = v;
                   2586:        }
1.25      noro     2587: }
                   2588:
1.82      noro     2589: NODE mono_raddec(NODE ideal);
                   2590:
                   2591: void Pdp_mono_raddec(NODE arg,LIST *rp)
                   2592: {
                   2593:        NODE ideal,rd,t,t1,r,r1,u;
                   2594:        VL vl0,vl;
                   2595:        int nv,i,bpi;
                   2596:        int *s;
                   2597:        DP dp;
                   2598:        P *v;
                   2599:        LIST l;
                   2600:
                   2601:        ideal = BDY((LIST)ARG0(arg));
                   2602:        if ( !ideal ) *rp = (LIST)ARG0(arg);
                   2603:        else {
                   2604:                t = BDY((LIST)ARG1(arg));
                   2605:                nv = length(t);
1.97    ! noro     2606:                v = (P *)MALLOC(nv*sizeof(P));
1.82      noro     2607:                for ( vl0 = 0, i = 0; t; t = NEXT(t), i++ ) {
                   2608:                        NEXTVL(vl0,vl); VR(vl) = VR((P)BDY(t));
                   2609:                        MKV(VR(vl),v[i]);
                   2610:                }
                   2611:                if ( vl0 ) NEXT(vl) = 0;
                   2612:                for ( t = 0, r = ideal; r; r = NEXT(r) ) {
                   2613:                        ptod(CO,vl0,BDY(r),&dp); MKNODE(t1,dp,t); t = t1;
                   2614:                }
                   2615:                rd = mono_raddec(t);
                   2616:                r = 0;
                   2617:                bpi = (sizeof(int)/sizeof(char))*8;
                   2618:                for ( u = rd; u; u = NEXT(u) ) {
                   2619:                        s = (int *)BDY(u);
                   2620:                        for ( i = nv-1, t = 0; i >= 0; i-- )
                   2621:                                if ( s[i/bpi]&(1<<(i%bpi)) ) {
                   2622:                                        MKNODE(t1,v[i],t); t = t1;
                   2623:                                }
                   2624:                        MKLIST(l,t); MKNODE(r1,l,r); r = r1;
                   2625:                }
                   2626:                MKLIST(*rp,r);
                   2627:        }
                   2628: }
                   2629:
1.84      noro     2630: void Pdp_mono_reduce(NODE arg,LIST *rp)
                   2631: {
                   2632:        NODE t,t0,t1,r0,r;
                   2633:        int i,n;
                   2634:        DP m;
                   2635:        DP *a;
                   2636:
                   2637:        t0 = BDY((LIST)ARG0(arg));
                   2638:        t1 = BDY((LIST)ARG1(arg));
                   2639:        n = length(t0);
                   2640:        a = (DP *)MALLOC(n*sizeof(DP));
                   2641:        for ( i = 0; i < n; i++, t0 = NEXT(t0) ) a[i] = (DP)BDY(t0);
                   2642:        for ( t = t1; t; t = NEXT(t) ) {
                   2643:                m = (DP)BDY(t);
                   2644:                for ( i = 0; i < n; i++ )
                   2645:                        if ( a[i] && dp_redble(a[i],m) ) a[i] = 0;
                   2646:        }
                   2647:        for ( i = n-1, r0 = 0; i >= 0; i-- )
                   2648:                if ( a[i] ) { NEXTNODE(r0,r); BDY(r) = a[i]; }
                   2649:        if ( r0 ) NEXT(r) = 0;
                   2650:        MKLIST(*rp,r0);
                   2651: }
                   2652:
1.94      noro     2653: #define BLEN (8*sizeof(unsigned long))
                   2654:
                   2655: void showmat2(unsigned long **a,int row,int col)
                   2656: {
                   2657:   int i,j;
                   2658:
                   2659:   for ( i = 0; i < row; i++, putchar('\n') )
                   2660:     for ( j = 0; j < col; j++ )
                   2661:            if ( a[i][j/BLEN] & (1L<<(j%BLEN)) ) putchar('1');
                   2662:       else putchar('0');
                   2663: }
                   2664:
                   2665: int rref2(unsigned long **a,int row,int col)
                   2666: {
                   2667:   int i,j,k,l,s,wcol,wj;
                   2668:   unsigned long bj;
                   2669:   unsigned long *ai,*ak,*as,*t;
                   2670:   int *pivot;
                   2671:
                   2672:   wcol = (col+BLEN-1)/BLEN;
                   2673:   pivot = (int *)MALLOC_ATOMIC(row*sizeof(int));
                   2674:   i = 0;
                   2675:   for ( j = 0; j < col; j++ ) {
                   2676:          wj = j/BLEN; bj = 1L<<(j%BLEN);
                   2677:     for ( k = i; k < row; k++ )
                   2678:          if ( a[k][wj] & bj ) break;
                   2679:     if ( k == row ) continue;
                   2680:     pivot[i] = j;
                   2681:     if ( k != i ) {
                   2682:      t = a[i]; a[i] = a[k]; a[k] = t;
                   2683:          }
                   2684:          ai = a[i];
                   2685:     for ( k = i+1; k < row; k++ ) {
                   2686:            ak = a[k];
                   2687:            if ( ak[wj] & bj ) {
                   2688:              for ( l = wj; l < wcol; l++ )
                   2689:                      ak[l] ^= ai[l];
                   2690:            }
                   2691:          }
                   2692:        i++;
                   2693:   }
                   2694:   for ( k = i-1; k >= 0; k-- ) {
                   2695:     j = pivot[k]; wj = j/BLEN; bj = 1L<<(j%BLEN);
                   2696:          ak = a[k];
                   2697:     for ( s = 0; s < k; s++ ) {
                   2698:            as = a[s];
                   2699:       if ( as[wj] & bj ) {
                   2700:         for ( l = wj; l < wcol; l++ )
                   2701:                      as[l] ^= ak[l];
                   2702:            }
                   2703:          }
                   2704:   }
                   2705:   return i;
                   2706: }
                   2707:
                   2708: void Pdp_rref2(NODE arg,VECT *rp)
                   2709: {
                   2710:   VECT f,term,ret;
                   2711:   int row,col,wcol,size,nv,i,j,rank,td;
                   2712:   unsigned long **mat;
                   2713:   unsigned long *v;
                   2714:   DL d;
                   2715:   DL *t;
                   2716:   DP dp;
                   2717:   MP m,m0;
                   2718:
                   2719:   f = (VECT)ARG0(arg);
                   2720:   row = f->len;
                   2721:   term = (VECT)ARG1(arg);
                   2722:   col = term->len;
                   2723:   mat = (unsigned long **)MALLOC(row*sizeof(unsigned long *));
                   2724:   size = sizeof(unsigned long)*((col+BLEN-1)/BLEN);
                   2725:   nv = ((DP)term->body[0])->nv;
                   2726:   t = (DL *)MALLOC(col*sizeof(DL));
                   2727:   for ( i = 0; i < col; i++ ) t[i] = BDY((DP)BDY(term)[i])->dl;
                   2728:   for ( i = 0; i < row; i++ ) {
                   2729:     v = mat[i] = (unsigned long *)MALLOC_ATOMIC_IGNORE_OFF_PAGE(size);
                   2730:        bzero(v,size);
                   2731:        for ( j = 0, m = BDY((DP)BDY(f)[i]); m; m = NEXT(m) ) {
                   2732:          d = m->dl;
                   2733:          for ( ; !dl_equal(nv,d,t[j]); j++ );
                   2734:          v[j/BLEN] |= 1L <<(j%BLEN);
                   2735:        }
                   2736:   }
                   2737:   rank = rref2(mat,row,col);
                   2738:   MKVECT(ret,rank);
                   2739:   *rp = ret;
                   2740:   for ( i = 0; i < rank; i++ ) {
                   2741:     v = mat[i];
                   2742:        m0 = 0;
                   2743:        td = 0;
                   2744:     for ( j = 0; j < col; j++ ) {
                   2745:          if ( v[j/BLEN] & (1L<<(j%BLEN)) ) {
                   2746:            NEXTMP(m0,m);
                   2747:                m->dl = t[j];
                   2748:                m->c = (P)ONE;
                   2749:            td = MAX(td,m->dl->td);
                   2750:          }
                   2751:        }
                   2752:        NEXT(m) = 0;
                   2753:        MKDP(nv,m0,dp);
                   2754:        dp->sugar = td;
                   2755:     BDY(ret)[i] = (pointer)dp;
                   2756:   }
                   2757: }
                   2758:
1.95      noro     2759: #define HDL(f) (BDY(f)->dl)
                   2760:
                   2761: NODE sumi_criB(int nv,NODE d,DP *f,int m)
                   2762: {
                   2763:  LIST p;
                   2764:  NODE r0,r;
                   2765:  int p0,p1;
                   2766:  DL p2,lcm;
                   2767:
                   2768:  NEWDL(lcm,nv);
                   2769:  r0 = 0;
                   2770:  for ( ; d; d = NEXT(d) ) {
                   2771:        p = (LIST)BDY(d);
                   2772:        p0 = QTOS((Q)ARG0(BDY(p)));
                   2773:        p1 = QTOS((Q)ARG1(BDY(p)));
                   2774:        p2 = HDL((DP)ARG2(BDY(p)));
                   2775:     if(!_dl_redble(HDL((DP)f[m]),p2,nv) ||
                   2776:      dl_equal(nv,lcm_of_DL(nv,HDL(f[p0]),HDL(f[m]),lcm),p2) ||
                   2777:      dl_equal(nv,lcm_of_DL(nv,HDL(f[p1]),HDL(f[m]),lcm),p2) ) {
                   2778:          NEXTNODE(r0,r);
                   2779:          BDY(r) = p;
                   2780:        }
                   2781:  }
                   2782:  if ( r0 ) NEXT(r) = 0;
                   2783:  return r0;
                   2784: }
                   2785:
                   2786: NODE sumi_criFMD(int nv,DP *f,int m)
                   2787: {
                   2788:   DL *a;
                   2789:   DL l1,dl1,dl2;
                   2790:   int i,j,k,k2;
                   2791:   NODE r,r1,nd;
                   2792:   MP mp;
                   2793:   DP u;
                   2794:   Q iq,mq;
                   2795:   LIST list;
                   2796:
                   2797:   /* a[i] = lcm(LT(f[i]),LT(f[m])) */
                   2798:   a = (DL *)ALLOCA(m*sizeof(DL));
                   2799:   for ( i = 0; i < m; i++ ) {
                   2800:    a[i] = lcm_of_DL(nv,HDL(f[i]),HDL(f[m]),0);
                   2801:   }
                   2802:   r = 0;
                   2803:   for( i = 0; i < m; i++) {
                   2804:    l1 = a[i];
                   2805:    if ( !l1 ) continue;
                   2806:    /* Tkm = Tim (k<i) */
                   2807:    for( k = 0; k < i; k++)
                   2808:      if( dl_equal(nv,l1,a[k]) ) break;
                   2809:    if( k == i ){
                   2810:      /* Tk|Tim && Tkm != Tim (k<m) */
                   2811:         for ( k2 = 0; k2 < m; k2++ )
                   2812:           if ( _dl_redble(HDL(f[k2]),l1,nv) &&
                   2813:             !dl_equal(nv,l1,a[k2]) ) break;
                   2814:         if ( k2 == m ) {
                   2815:        dl1 = HDL(f[i]); dl2 = HDL(f[m]);
                   2816:        for ( k2 = 0; k2 < nv; k2++ )
                   2817:          if ( dl1->d[k2] && dl2->d[k2] ) break;
                   2818:        if ( k2 < nv ) {
                   2819:          NEWMP(mp); mp->dl = l1; C(mp) = (P)ONE;
                   2820:          NEXT(mp) = 0; MKDP(nv,mp,u); u->sugar = l1->td;
                   2821:             STOQ(i,iq); STOQ(m,mq);
                   2822:             nd = mknode(3,iq,mq,u);
                   2823:             MKLIST(list,nd);
                   2824:             MKNODE(r1,list,r);
                   2825:             r = r1;
                   2826:          }
                   2827:        }
                   2828:    }
                   2829:  }
                   2830:  return r;
                   2831: }
                   2832:
                   2833: LIST sumi_updatepairs(LIST d,DP *f,int m)
                   2834: {
                   2835:   NODE old,new,t;
                   2836:   LIST l;
                   2837:   int nv;
                   2838:
                   2839:   nv = f[0]->nv;
                   2840:   old = sumi_criB(nv,BDY(d),f,m);
                   2841:   new = sumi_criFMD(nv,f,m);
                   2842:   if ( !new ) new = old;
                   2843:   else {
                   2844:     for ( t = new ; NEXT(t); t = NEXT(t) );
                   2845:        NEXT(t) = old;
                   2846:   }
                   2847:   MKLIST(l,new);
                   2848:   return l;
                   2849: }
                   2850:
                   2851: VECT ltov(LIST l)
                   2852: {
                   2853:   NODE n;
                   2854:   int i,len;
                   2855:   VECT v;
                   2856:
                   2857:   n = BDY(l);
                   2858:   len = length(n);
                   2859:   MKVECT(v,len);
                   2860:   for ( i = 0; i < len; i++, n = NEXT(n) )
                   2861:     BDY(v)[i] = BDY(n);
                   2862:   return v;
                   2863: }
                   2864:
                   2865: DL subdl(int nv,DL d1,DL d2)
                   2866: {
                   2867:   int i;
                   2868:   DL d;
                   2869:
                   2870:   NEWDL(d,nv);
                   2871:   d->td = d1->td-d2->td;
                   2872:   for ( i = 0; i < nv; i++ )
                   2873:     d->d[i] = d1->d[i]-d2->d[i];
                   2874:   return d;
                   2875: }
                   2876:
                   2877: DP dltodp(int nv,DL d)
                   2878: {
                   2879:   MP mp;
                   2880:   DP dp;
                   2881:
                   2882:   NEWMP(mp); mp->dl = d; C(mp) = (P)ONE;
                   2883:   NEXT(mp) = 0; MKDP(nv,mp,dp); dp->sugar = d->td;
                   2884:   return dp;
                   2885: }
                   2886:
                   2887: LIST sumi_simplify(int nv,DL t,DP p,NODE f2,int simp)
                   2888: {
                   2889:   DL d,h,hw;
                   2890:   DP u,w,dp;
                   2891:   int n,i,last;
                   2892:   LIST *v;
                   2893:   LIST list;
                   2894:   NODE s,r;
                   2895:
                   2896:   d = t; u = p;
                   2897:   /* only the last history is used */
                   2898:   if ( f2 && simp && t->td != 0 ) {
                   2899:     adddl(nv,t,HDL(p),&h);
                   2900:     n = length(f2);
                   2901:     last = 1;
                   2902:     if ( simp > 1 ) last = n;
                   2903:     v = (LIST *)ALLOCA(n*sizeof(LIST));
                   2904:     for ( r = f2, i = 0; r; r = NEXT(r), i++ ) v[n-i-1] = BDY(r);
                   2905:     for ( i = 0; i < last; i++ ) {
                   2906:       for ( s = BDY((LIST)v[i]); s; s = NEXT(s) ) {
                   2907:            w = (DP)BDY(s); hw = HDL(w);
                   2908:         if ( _dl_redble(hw,h,nv) ) {
                   2909:                  u = w;
                   2910:                  d = subdl(nv,h,hw);
                   2911:                  goto fin;
                   2912:            }
                   2913:       }
                   2914:     }
                   2915:   }
                   2916: fin:
                   2917:   dp = dltodp(nv,d);
                   2918:   r = mknode(2,dp,u);
                   2919:   MKLIST(list,r);
                   2920:   return list;
                   2921: }
                   2922:
                   2923: LIST sumi_symbolic(NODE l,int q,NODE f2,DP *g,int simp)
                   2924: {
                   2925:    int nv;
                   2926:    NODE t,r;
                   2927:    NODE f0,f,fd0,fd,done0,done,red0,red;
                   2928:    DL h,d;
                   2929:    DP mul;
                   2930:    int m;
                   2931:    LIST tp,l0,l1,l2,l3,list;
                   2932:    VECT v0,v1,v2,v3;
                   2933:
                   2934:    nv = ((DP)BDY(l))->nv;
                   2935:    t = 0;
                   2936:
                   2937:    f0 = 0; fd0 = 0; done0 = 0; red0 = 0;
                   2938:
                   2939:    for ( ; l; l = NEXT(l) ) {
                   2940:      t = symb_merge(t,dp_dllist((DP)BDY(l)),nv);
                   2941:      NEXTNODE(fd0,fd); BDY(fd) = BDY(l);
                   2942:    }
                   2943:
                   2944:    while ( t ) {
                   2945:         h = (DL)BDY(t);
                   2946:         NEXTNODE(done0,done); BDY(done) = dltodp(nv,h);
                   2947:         t = NEXT(t);
                   2948:      for(m = 0; m < q; m++)
                   2949:           if ( _dl_redble(HDL(g[m]),h,nv) ) break;
                   2950:      if ( m == q ) {
                   2951:      } else {
                   2952:           d = subdl(nv,h,HDL(g[m]));
                   2953:        tp = sumi_simplify(nv,d,g[m],f2,simp);
                   2954:
                   2955:           muldm(CO,ARG1(BDY(tp)),BDY((DP)ARG0(BDY(tp))),&mul);
                   2956:        t = symb_merge(t,NEXT(dp_dllist(mul)),nv);
                   2957:
                   2958:           NEXTNODE(f0,f); BDY(f) = tp;
                   2959:           NEXTNODE(fd0,fd); BDY(fd) = mul;
                   2960:           NEXTNODE(red0,red); BDY(red) = mul;
                   2961:      }
                   2962:    }
                   2963:    if ( fd0 ) NEXT(fd) = 0; MKLIST(l0,fd0);
                   2964:    v0 = ltov(l0);
                   2965:    if ( done0 ) NEXT(done) = 0; MKLIST(l1,done0);
                   2966:    v1 = ltov(l1);
                   2967:    if ( f0 ) NEXT(f) = 0; MKLIST(l2,f0);
                   2968:    v2 = ltov(l2);
                   2969:    if ( red0 ) NEXT(red) = 0; MKLIST(l3,red0);
                   2970:    v3 = ltov(l3);
                   2971:    r = mknode(4,v0,v1,v2,v3);
                   2972:    MKLIST(list,r);
                   2973:    return list;
                   2974: }
                   2975:
                   2976: void Psumi_symbolic(NODE arg,LIST *rp)
                   2977: {
                   2978:   NODE l,f2;
                   2979:   DP *g;
                   2980:   int q,simp;
                   2981:
                   2982:   l = BDY((LIST)ARG0(arg));
                   2983:   q = QTOS((Q)ARG1(arg));
                   2984:   f2 = BDY((LIST)ARG2(arg));
                   2985:   g = (DP *)BDY((VECT)ARG3(arg));
                   2986:   simp = QTOS((Q)ARG4(arg));
                   2987:   *rp = sumi_symbolic(l,q,f2,g,simp);
                   2988: }
                   2989:
                   2990: void Psumi_updatepairs(NODE arg,LIST *rp)
                   2991: {
                   2992:    LIST d,l;
                   2993:    DP *f;
                   2994:    int m;
                   2995:
                   2996:    d = (LIST)ARG0(arg);
                   2997:    f = (DP *)BDY((VECT)ARG1(arg));
                   2998:    m = QTOS((Q)ARG2(arg));
                   2999:    *rp = sumi_updatepairs(d,f,m);
                   3000: }
                   3001:
1.25      noro     3002: LIST remove_zero_from_list(LIST l)
                   3003: {
                   3004:        NODE n,r0,r;
                   3005:        LIST rl;
                   3006:
                   3007:        asir_assert(l,O_LIST,"remove_zero_from_list");
                   3008:        n = BDY(l);
                   3009:        for ( r0 = 0; n; n = NEXT(n) )
                   3010:                if ( BDY(n) ) {
                   3011:                        NEXTNODE(r0,r);
                   3012:                        BDY(r) = BDY(n);
                   3013:                }
                   3014:        if ( r0 )
                   3015:                NEXT(r) = 0;
                   3016:        MKLIST(rl,r0);
                   3017:        return rl;
1.26      noro     3018: }
                   3019:
                   3020: int get_field_type(P p)
                   3021: {
                   3022:        int type,t;
                   3023:        DCP dc;
                   3024:
                   3025:        if ( !p )
                   3026:                return 0;
                   3027:        else if ( NUM(p) )
                   3028:                return NID((Num)p);
                   3029:        else {
                   3030:                type = 0;
                   3031:                for ( dc = DC(p); dc; dc = NEXT(dc) ) {
                   3032:                        t = get_field_type(COEF(dc));
                   3033:                        if ( !t )
                   3034:                                continue;
                   3035:                        if ( t < 0 )
                   3036:                                return t;
                   3037:                        if ( !type )
                   3038:                                type = t;
                   3039:                        else if ( t != type )
                   3040:                                return -1;
                   3041:                }
                   3042:                return type;
1.52      noro     3043:        }
                   3044: }
                   3045:
                   3046: void Pdpv_ord(NODE arg,Obj *rp)
                   3047: {
                   3048:        int ac,id;
                   3049:        LIST shift;
                   3050:
                   3051:        ac = argc(arg);
                   3052:        if ( ac ) {
                   3053:                id = QTOS((Q)ARG0(arg));
                   3054:                if ( ac > 1 && ARG1(arg) && OID((Obj)ARG1(arg))==O_LIST )
                   3055:                        shift = (LIST)ARG1(arg);
                   3056:                else
                   3057:                        shift = 0;
                   3058:                create_modorder_spec(id,shift,&dp_current_modspec);
                   3059:        }
                   3060:        *rp = dp_current_modspec->obj;
                   3061: }
                   3062:
                   3063: void Pdpv_ht(NODE arg,LIST *rp)
                   3064: {
                   3065:        NODE n;
                   3066:        DP ht;
                   3067:        int pos;
                   3068:        DPV p;
                   3069:        Q q;
                   3070:
                   3071:        asir_assert(ARG0(arg),O_DPV,"dpv_ht");
                   3072:        p = (DPV)ARG0(arg);
                   3073:        pos = dpv_hp(p);
                   3074:        if ( pos < 0 )
                   3075:                ht = 0;
                   3076:        else
                   3077:                dp_ht(BDY(p)[pos],&ht);
                   3078:        STOQ(pos,q);
                   3079:        n = mknode(2,q,ht);
                   3080:        MKLIST(*rp,n);
                   3081: }
                   3082:
                   3083: void Pdpv_hm(NODE arg,LIST *rp)
                   3084: {
                   3085:        NODE n;
                   3086:        DP ht;
                   3087:        int pos;
                   3088:        DPV p;
                   3089:        Q q;
                   3090:
                   3091:        asir_assert(ARG0(arg),O_DPV,"dpv_hm");
                   3092:        p = (DPV)ARG0(arg);
                   3093:        pos = dpv_hp(p);
                   3094:        if ( pos < 0 )
                   3095:                ht = 0;
                   3096:        else
                   3097:                dp_hm(BDY(p)[pos],&ht);
                   3098:        STOQ(pos,q);
                   3099:        n = mknode(2,q,ht);
                   3100:        MKLIST(*rp,n);
                   3101: }
                   3102:
                   3103: void Pdpv_hc(NODE arg,LIST *rp)
                   3104: {
                   3105:        NODE n;
                   3106:        P hc;
                   3107:        int pos;
                   3108:        DPV p;
                   3109:        Q q;
                   3110:
                   3111:        asir_assert(ARG0(arg),O_DPV,"dpv_hc");
                   3112:        p = (DPV)ARG0(arg);
                   3113:        pos = dpv_hp(p);
                   3114:        if ( pos < 0 )
                   3115:                hc = 0;
                   3116:        else
                   3117:                hc = BDY(BDY(p)[pos])->c;
                   3118:        STOQ(pos,q);
                   3119:        n = mknode(2,q,hc);
                   3120:        MKLIST(*rp,n);
                   3121: }
                   3122:
                   3123: int dpv_hp(DPV p)
                   3124: {
                   3125:        int len,i,maxp,maxw,w,slen;
                   3126:        int *shift;
                   3127:        DP *e;
                   3128:
                   3129:        len = p->len;
                   3130:        e = p->body;
                   3131:        slen = dp_current_modspec->len;
                   3132:        shift = dp_current_modspec->degree_shift;
                   3133:        switch ( dp_current_modspec->id ) {
                   3134:                case ORD_REVGRADLEX:
                   3135:                        for ( maxp = -1, i = 0; i < len; i++ )
                   3136:                                if ( !e[i] ) continue;
                   3137:                                else if ( maxp < 0 ) {
                   3138:                                        maxw = BDY(e[i])->dl->td+(i<slen?shift[i]:0); maxp = i;
                   3139:                                } else {
                   3140:                                        w = BDY(e[i])->dl->td+(i<slen?shift[i]:0);
                   3141:                                        if ( w >= maxw ) {
                   3142:                                                maxw = w; maxp = i;
                   3143:                                        }
                   3144:                                }
                   3145:                        return maxp;
                   3146:                case ORD_GRADLEX:
                   3147:                        for ( maxp = -1, i = 0; i < len; i++ )
                   3148:                                if ( !e[i] ) continue;
                   3149:                                else if ( maxp < 0 ) {
                   3150:                                        maxw = BDY(e[i])->dl->td+(i<slen?shift[i]:0); maxp = i;
                   3151:                                } else {
                   3152:                                        w = BDY(e[i])->dl->td+(i<slen?shift[i]:0);
                   3153:                                        if ( w > maxw ) {
                   3154:                                                maxw = w; maxp = i;
                   3155:                                        }
                   3156:                                }
                   3157:                        return maxp;
                   3158:                        break;
                   3159:                case ORD_LEX:
                   3160:                        for ( i = 0; i < len; i++ )
                   3161:                                if ( e[i] ) return i;
                   3162:                        return -1;
                   3163:                        break;
1.26      noro     3164:        }
1.15      noro     3165: }
1.81      noro     3166:
                   3167: int get_opt(char *key0,Obj *r) {
                   3168:    NODE tt,p;
                   3169:    char *key;
                   3170:
                   3171:    if ( current_option ) {
                   3172:      for ( tt = current_option; tt; tt = NEXT(tt) ) {
                   3173:        p = BDY((LIST)BDY(tt));
                   3174:        key = BDY((STRING)BDY(p));
                   3175:        /*  value = (Obj)BDY(NEXT(p)); */
                   3176:        if ( !strcmp(key,key0) )  {
                   3177:             *r = (Obj)BDY(NEXT(p));
                   3178:             return 1;
                   3179:           }
                   3180:      }
                   3181:    }
                   3182:    return 0;
                   3183: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>