=================================================================== RCS file: /home/cvs/OpenXM_contrib2/asir2000/builtin/pf.c,v retrieving revision 1.1.1.1 retrieving revision 1.8 diff -u -p -r1.1.1.1 -r1.8 --- OpenXM_contrib2/asir2000/builtin/pf.c 1999/12/03 07:39:07 1.1.1.1 +++ OpenXM_contrib2/asir2000/builtin/pf.c 2004/06/27 03:15:57 1.8 @@ -1,4 +1,52 @@ -/* $OpenXM: OpenXM/src/asir99/builtin/pf.c,v 1.1.1.1 1999/11/10 08:12:26 noro Exp $ */ +/* + * Copyright (c) 1994-2000 FUJITSU LABORATORIES LIMITED + * All rights reserved. + * + * FUJITSU LABORATORIES LIMITED ("FLL") hereby grants you a limited, + * non-exclusive and royalty-free license to use, copy, modify and + * redistribute, solely for non-commercial and non-profit purposes, the + * computer program, "Risa/Asir" ("SOFTWARE"), subject to the terms and + * conditions of this Agreement. For the avoidance of doubt, you acquire + * only a limited right to use the SOFTWARE hereunder, and FLL or any + * third party developer retains all rights, including but not limited to + * copyrights, in and to the SOFTWARE. + * + * (1) FLL does not grant you a license in any way for commercial + * purposes. You may use the SOFTWARE only for non-commercial and + * non-profit purposes only, such as academic, research and internal + * business use. + * (2) The SOFTWARE is protected by the Copyright Law of Japan and + * international copyright treaties. If you make copies of the SOFTWARE, + * with or without modification, as permitted hereunder, you shall affix + * to all such copies of the SOFTWARE the above copyright notice. + * (3) An explicit reference to this SOFTWARE and its copyright owner + * shall be made on your publication or presentation in any form of the + * results obtained by use of the SOFTWARE. + * (4) In the event that you modify the SOFTWARE, you shall notify FLL by + * e-mail at risa-admin@sec.flab.fujitsu.co.jp of the detailed specification + * for such modification or the source code of the modified part of the + * SOFTWARE. + * + * THE SOFTWARE IS PROVIDED AS IS WITHOUT ANY WARRANTY OF ANY KIND. FLL + * MAKES ABSOLUTELY NO WARRANTIES, EXPRESSED, IMPLIED OR STATUTORY, AND + * EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT OF THIRD PARTIES' + * RIGHTS. NO FLL DEALER, AGENT, EMPLOYEES IS AUTHORIZED TO MAKE ANY + * MODIFICATIONS, EXTENSIONS, OR ADDITIONS TO THIS WARRANTY. + * UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, TORT, CONTRACT, + * OR OTHERWISE, SHALL FLL BE LIABLE TO YOU OR ANY OTHER PERSON FOR ANY + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, PUNITIVE OR CONSEQUENTIAL + * DAMAGES OF ANY CHARACTER, INCLUDING, WITHOUT LIMITATION, DAMAGES + * ARISING OUT OF OR RELATING TO THE SOFTWARE OR THIS AGREEMENT, DAMAGES + * FOR LOSS OF GOODWILL, WORK STOPPAGE, OR LOSS OF DATA, OR FOR ANY + * DAMAGES, EVEN IF FLL SHALL HAVE BEEN INFORMED OF THE POSSIBILITY OF + * SUCH DAMAGES, OR FOR ANY CLAIM BY ANY OTHER PARTY. EVEN IF A PART + * OF THE SOFTWARE HAS BEEN DEVELOPED BY A THIRD PARTY, THE THIRD PARTY + * DEVELOPER SHALL HAVE NO LIABILITY IN CONNECTION WITH THE USE, + * PERFORMANCE OR NON-PERFORMANCE OF THE SOFTWARE. + * + * $OpenXM: OpenXM_contrib2/asir2000/builtin/pf.c,v 1.7 2004/06/22 09:17:21 noro Exp $ +*/ #include "ca.h" #include "math.h" #include "parse.h" @@ -17,8 +65,11 @@ void simplify_pow(PFINS,Obj *); void Pfunctor(),Pargs(),Pfunargs(),Pvtype(),Pcall(),Pdeval(); void Pregister_handler(); +void Peval_quote(); +void Pmapat(); struct ftab puref_tab[] = { + {"mapat",Pmapat,-99999999}, {"functor",Pfunctor,1}, {"args",Pargs,1}, {"funargs",Pfunargs,1}, @@ -26,10 +77,11 @@ struct ftab puref_tab[] = { {"call",Pcall,2}, {"vtype",Pvtype,1}, {"deval",Pdeval,1}, + {"eval_quote",Peval_quote,1}, {0,0,0}, }; -#if PARI +#if defined(PARI) int p_pi(),p_e(); int p_log(),p_exp(),p_pow(); int p_sin(),p_cos(),p_tan(),p_asin(),p_acos(),p_atan(); @@ -232,9 +284,15 @@ Obj *rp; pf = ins->pf; ad = ins->ad; a0 = ad[0].arg; a1 = ad[1].arg; if ( !a1 ) *rp = (Obj)ONE; - else if ( !a0 ) - *rp = 0; - else if ( NUM(a1) && INT(a1) ) + else if ( !a0 ) { + if ( RATN(a1) && SGN((Q)a1)>0 ) + *rp = 0; + else if ( RATN(a1) && SGN((Q)a1) < 0 ) + error("simplify_pow : division by 0"); + else { + instov(ins,&v); MKV(v,t); *rp = (Obj)t; + } + } else if ( NUM(a1) && INT(a1) ) arf_pwr(CO,a0,a1,rp); else { instov(ins,&v); MKV(v,t); *rp = (Obj)t; @@ -260,7 +318,7 @@ P *rp; else { ins = (PFINS)VR(p)->priv; pf = ins->pf; t = (FUNC)MALLOC(sizeof(struct oFUNC)); - t->name = pf->name; t->id = A_PURE; t->argc = pf->argc; + t->name = t->fullname = pf->name; t->id = A_PURE; t->argc = pf->argc; t->f.puref = pf; makesrvar(t,rp); } @@ -310,10 +368,10 @@ LIST *rp; else { ins = (PFINS)VR(p)->priv; ad = ins->ad; pf = ins->pf; t = (FUNC)MALLOC(sizeof(struct oFUNC)); - t->name = pf->name; t->id = A_PURE; t->argc = pf->argc; + t->name = t->fullname = pf->name; t->id = A_PURE; t->argc = pf->argc; t->f.puref = pf; makesrvar(t,&f); - n0 = 0; NEXTNODE(n0,n); BDY(n) = (pointer)f; + n = n0 = 0; NEXTNODE(n0,n); BDY(n) = (pointer)f; for ( i = 0; i < pf->argc; i++ ) { NEXTNODE(n0,n); BDY(n) = (pointer)ad[i].arg; } @@ -364,9 +422,7 @@ Q *rp; } } -void Pcall(arg,rp) -NODE arg; -Obj *rp; +void Pcall(NODE arg,Obj *rp) { P p; V v; @@ -382,6 +438,84 @@ Obj *rp; *rp = (Obj)bevalf((FUNC)v->priv,BDY((LIST)ARG1(arg))); } +/* at=position of arg to be used for iteration */ + +void Pmapat(NODE arg,Obj *rp) +{ + LIST args; + NODE node,rest,t0,t,n,r,r0; + P fpoly; + V fvar; + FUNC f; + VECT v,rv; + MAT m,rm; + LIST rl; + int len,row,col,i,j,pos; + Obj iter; + pointer val; + + if ( argc(arg) < 3 ) + error("mapat : too few arguments"); + + fpoly = (P)ARG0(arg); + if ( !fpoly || OID(fpoly) != O_P ) + error("mapat : invalid function specification"); + fvar = VR(fpoly); + if ( fvar->attr != (pointer)V_SR || !(f=(FUNC)fvar->priv) ) + error("mapat : invalid function specification"); + if ( !INT(ARG1(arg)) ) + error("mapat : invalid position"); + pos = QTOS((Q)ARG1(arg)); + node = NEXT(NEXT(arg)); + len = length(node); + if ( pos >= len ) + error("evalmapatf : invalid position"); + r0 = 0; + for ( i = 0, t = node; i < pos; i++, t = NEXT(t) ) { + NEXTNODE(r0,r); + BDY(r) = BDY(t); + } + NEXTNODE(r0,r); + iter = BDY(t); rest = NEXT(t); + if ( !iter ) { + *rp = bevalf(f,node); + return; + } + switch ( OID(iter) ) { + case O_VECT: + v = (VECT)iter; len = v->len; MKVECT(rv,len); + for ( i = 0; i < len; i++ ) { + BDY(r) = BDY(v)[i]; NEXT(r) = rest; + BDY(rv)[i] = bevalf(f,r0); + } + *rp = (Obj)rv; + break; + case O_MAT: + m = (MAT)iter; row = m->row; col = m->col; MKMAT(rm,row,col); + for ( i = 0; i < row; i++ ) + for ( j = 0; j < col; j++ ) { + BDY(r) = BDY(m)[i][j]; NEXT(r) = rest; + BDY(rm)[i][j] = bevalf(f,r0); + } + *rp = (Obj)rm; + break; + case O_LIST: + n = BDY((LIST)iter); + for ( t0 = t = 0; n; n = NEXT(n) ) { + BDY(r) = BDY(n); NEXT(r) = rest; + NEXTNODE(t0,t); BDY(t) = bevalf(f,r0); + } + if ( t0 ) + NEXT(t) = 0; + MKLIST(rl,t0); + *rp = (Obj)rl; + break; + default: + *rp = bevalf(f,node); + break; + } +} + void Pdeval(arg,rp) NODE arg; Obj *rp; @@ -390,3 +524,10 @@ Obj *rp; devalr(CO,(Obj)ARG0(arg),rp); } +void Peval_quote(arg,rp) +NODE arg; +Obj *rp; +{ + asir_assert(ARG0(arg),O_QUOTE,"eval_quote"); + *rp = eval((FNODE)BDY((QUOTE)ARG0(arg))); +}