version 1.83, 2005/10/26 10:44:50 |
version 1.88, 2005/11/01 07:24:11 |
|
|
* DEVELOPER SHALL HAVE NO LIABILITY IN CONNECTION WITH THE USE, |
* DEVELOPER SHALL HAVE NO LIABILITY IN CONNECTION WITH THE USE, |
* PERFORMANCE OR NON-PERFORMANCE OF THE SOFTWARE. |
* PERFORMANCE OR NON-PERFORMANCE OF THE SOFTWARE. |
* |
* |
* $OpenXM: OpenXM_contrib2/asir2000/builtin/strobj.c,v 1.82 2005/10/26 08:39:58 noro Exp $ |
* $OpenXM: OpenXM_contrib2/asir2000/builtin/strobj.c,v 1.87 2005/10/31 10:03:48 noro Exp $ |
*/ |
*/ |
#include "ca.h" |
#include "ca.h" |
#include "parse.h" |
#include "parse.h" |
Line 88 void Pquote_is_integer(),Pquote_is_rational(),Pquote_i |
|
Line 88 void Pquote_is_integer(),Pquote_is_rational(),Pquote_i |
|
void Pquote_is_dependent(),Pquote_is_function(); |
void Pquote_is_dependent(),Pquote_is_function(); |
void Pquote_normalize(); |
void Pquote_normalize(); |
void Pquote_normalize_comp(); |
void Pquote_normalize_comp(); |
|
void Pquote_normalize_unify(); |
|
|
void Pquote_to_funargs(),Pfunargs_to_quote(),Pget_function_name(); |
void Pquote_to_funargs(),Pfunargs_to_quote(),Pget_function_name(); |
void Pquote_unify(),Pget_quote_id(),Pquote_match_rewrite(); |
void Pquote_unify(),Pget_quote_id(),Pquote_match_rewrite(); |
void Pquote_to_nary(),Pquote_to_bin(); |
void Pquote_to_nary(),Pquote_to_bin(); |
|
void fnode_do_assign(NODE arg); |
void do_assign(NODE arg); |
void do_assign(NODE arg); |
void fnodetotex_tb(FNODE f,TB tb); |
void fnodetotex_tb(FNODE f,TB tb); |
char *symbol_name(char *name); |
char *symbol_name(char *name); |
Line 127 struct ftab str_tab[] = { |
|
Line 129 struct ftab str_tab[] = { |
|
{"quote_is_dependent",Pquote_is_dependent,2}, |
{"quote_is_dependent",Pquote_is_dependent,2}, |
|
|
{"quote_normalize",Pquote_normalize,-2}, |
{"quote_normalize",Pquote_normalize,-2}, |
{"quote_normalize_comp",Pquote_normalize_comp,2,0x3}, |
{"quote_normalize_comp",Pquote_normalize_comp,2}, |
|
|
{"quote_to_nary",Pquote_to_nary,1}, |
{"quote_to_nary",Pquote_to_nary,1}, |
{"quote_to_bin",Pquote_to_bin,2}, |
{"quote_to_bin",Pquote_to_bin,2}, |
Line 137 struct ftab str_tab[] = { |
|
Line 139 struct ftab str_tab[] = { |
|
{"flatten_quote",Pflatten_quote,-2}, |
{"flatten_quote",Pflatten_quote,-2}, |
{"quote_to_funargs",Pquote_to_funargs,1}, |
{"quote_to_funargs",Pquote_to_funargs,1}, |
{"quote_unify",Pquote_unify,2}, |
{"quote_unify",Pquote_unify,2}, |
|
{"quote_normalize_unify",Pquote_normalize_unify,2}, |
{"quote_match_rewrite",Pquote_match_rewrite,-4}, |
{"quote_match_rewrite",Pquote_match_rewrite,-4}, |
{"funargs_to_quote",Pfunargs_to_quote,1}, |
{"funargs_to_quote",Pfunargs_to_quote,1}, |
{"get_function_name",Pget_function_name,1}, |
{"get_function_name",Pget_function_name,1}, |
Line 646 void Pquote_unify(NODE arg,Q *rp) |
|
Line 649 void Pquote_unify(NODE arg,Q *rp) |
|
*rp = 0; |
*rp = 0; |
} |
} |
|
|
|
void Pquote_normalize_unify(NODE arg,Q *rp) |
|
{ |
|
QUOTE fq,pq; |
|
FNODE f,p; |
|
int ret; |
|
NODE r; |
|
|
|
fq = (QUOTE)ARG0(arg); Pquote_normalize(mknode(2,fq,0),&fq); f = (FNODE)BDY(fq); |
|
pq = (QUOTE)ARG1(arg); Pquote_normalize(mknode(2,pq,0),&pq); p = (FNODE)BDY(pq); |
|
ret = fnode_normalize_unify(f,p,&r); |
|
if ( ret ) { |
|
fnode_do_assign(r); |
|
*rp = ONE; |
|
} else |
|
*rp = 0; |
|
} |
|
|
FNODE rewrite_fnode(FNODE,NODE); |
FNODE rewrite_fnode(FNODE,NODE); |
|
|
extern Obj VOIDobj; |
extern Obj VOIDobj; |
Line 704 void do_assign(NODE arg) |
|
Line 724 void do_assign(NODE arg) |
|
} |
} |
} |
} |
|
|
|
/* [[index,fnode],...] */ |
|
|
|
void fnode_do_assign(NODE arg) |
|
{ |
|
NODE t,pair; |
|
int pv; |
|
FNODE f; |
|
QUOTE value; |
|
|
|
for ( t = arg; t; t = NEXT(t) ) { |
|
pair = (NODE)BDY(t); |
|
pv = (int)BDY(pair); |
|
f = (FNODE)(BDY(NEXT(pair))); |
|
MKQUOTE(value,f); |
|
ASSPV(pv,value); |
|
} |
|
} |
|
|
/* |
/* |
/* consistency check and merge |
/* consistency check and merge |
*/ |
*/ |
Line 1942 void Pquote_normalize(NODE arg,QUOTE *rp) |
|
Line 1980 void Pquote_normalize(NODE arg,QUOTE *rp) |
|
if ( !q || OID(q) != O_QUOTE ) { |
if ( !q || OID(q) != O_QUOTE ) { |
*rp = q; |
*rp = q; |
return; |
return; |
} else { |
} else if ( q->normalized && (q->expanded || !expand) ) |
|
*rp = q; |
|
else { |
f = fnode_normalize(BDY(q),expand); |
f = fnode_normalize(BDY(q),expand); |
MKQUOTE(r,f); |
MKQUOTE(r,f); |
|
r->normalized = 1; |
|
if ( expand ) r->expanded = 1; |
*rp = r; |
*rp = r; |
} |
} |
} |
} |
|
|
void Pquote_normalize_comp(NODE arg,Q *rp) |
void Pquote_normalize_comp(NODE arg,Q *rp) |
{ |
{ |
|
QUOTE q1,q2; |
FNODE f1,f2; |
FNODE f1,f2; |
int r; |
int r; |
|
|
f1 = BDY((QUOTE)ARG0(arg)); |
q1 = (QUOTE)ARG0(arg); f1 = (FNODE)BDY(q1); |
f2 = BDY((QUOTE)ARG1(arg)); |
q2 = (QUOTE)ARG1(arg); f2 = (FNODE)BDY(q2); |
f1 = fnode_normalize(f1,0); |
if ( !q1->normalized ) f1 = fnode_normalize(f1,0); |
f2 = fnode_normalize(f2,0); |
if ( !q2->normalized ) f2 = fnode_normalize(f2,0); |
r = fnode_normalize_comp(f1,f2); |
r = fnode_normalize_comp(f1,f2); |
STOQ(r,*rp); |
STOQ(r,*rp); |
} |
} |
Line 2488 int fnode_normalize_comp(FNODE f1,FNODE f2) |
|
Line 2531 int fnode_normalize_comp(FNODE f1,FNODE f2) |
|
FNODE b1,b2,e1,e2,g; |
FNODE b1,b2,e1,e2,g; |
Num ee,ee1,c1,c2; |
Num ee,ee1,c1,c2; |
|
|
if ( IS_ZERO(f1) ) |
|
if ( IS_ZERO(f2) ) return 0; |
|
else return -1; |
|
else if ( IS_ZERO(f2) ) return 1; |
|
|
|
if ( IS_NARYADD(f1) || IS_NARYADD(f2) ) { |
if ( IS_NARYADD(f1) || IS_NARYADD(f2) ) { |
f1 = to_naryadd(f1); f2 = to_naryadd(f2); |
f1 = to_naryadd(f1); f2 = to_naryadd(f2); |
n1 = (NODE)FA1(f1); n2 = (NODE)FA1(f2); |
n1 = (NODE)FA1(f1); n2 = (NODE)FA1(f2); |
Line 2501 int fnode_normalize_comp(FNODE f1,FNODE f2) |
|
Line 2539 int fnode_normalize_comp(FNODE f1,FNODE f2) |
|
else { |
else { |
n1 = NEXT(n1); n2 = NEXT(n2); |
n1 = NEXT(n1); n2 = NEXT(n2); |
} |
} |
if ( n1 ) return 1; |
return n1?1:(n2?-1:0); |
else if ( n2 ) return -1; |
|
else return 0; |
|
} |
} |
if ( IS_NARYMUL(f1) || IS_NARYMUL(f2) ) { |
if ( IS_NARYMUL(f1) || IS_NARYMUL(f2) ) { |
fnode_coef_body(f1,&c1,&b1); |
fnode_coef_body(f1,&c1,&b1); |
Line 2516 int fnode_normalize_comp(FNODE f1,FNODE f2) |
|
Line 2552 int fnode_normalize_comp(FNODE f1,FNODE f2) |
|
n1 = NEXT(n1); n2 = NEXT(n2); |
n1 = NEXT(n1); n2 = NEXT(n2); |
} |
} |
if ( !n1 || !n2 ) { |
if ( !n1 || !n2 ) { |
if ( n1 ) return 1; |
return n1?1:(n2?-1:0); |
else if ( n2 ) return -1; |
|
else return 0; |
|
} |
} |
fnode_base_exp(BDY(n1),&b1,&e1); |
fnode_base_exp(BDY(n1),&b1,&e1); |
fnode_base_exp(BDY(n2),&b2,&e2); |
fnode_base_exp(BDY(n2),&b2,&e2); |
Line 2535 int fnode_normalize_comp(FNODE f1,FNODE f2) |
|
Line 2569 int fnode_normalize_comp(FNODE f1,FNODE f2) |
|
subnum(0,eval(e1),eval(e2),&ee); |
subnum(0,eval(e1),eval(e2),&ee); |
r = compnum(0,ee,0); |
r = compnum(0,ee,0); |
if ( r > 0 ) { |
if ( r > 0 ) { |
/* e1>e2 */ |
|
g = mkfnode(3,I_BOP,pwrfs,b1,mkfnode(1,I_FORMULA,ee)); |
g = mkfnode(3,I_BOP,pwrfs,b1,mkfnode(1,I_FORMULA,ee)); |
MKNODE(n1,g,n1); |
MKNODE(n1,g,n1); |
} else if ( r < 0 ) { |
} else if ( r < 0 ) { |
/* e1<e2 */ |
chsgnnum(ee,&ee1); |
chsgnnum(ee,&ee1); ee = ee1; |
g = mkfnode(3,I_BOP,pwrfs,b1,mkfnode(1,I_FORMULA,ee1)); |
g = mkfnode(3,I_BOP,pwrfs,b1,mkfnode(1,I_FORMULA,ee)); |
MKNODE(n2,g,n2); |
MKNODE(n2,g,n2); |
|
} |
} |
} else { |
} else { |
r = fnode_normalize_comp(e1,e2); |
r = fnode_normalize_comp(e1,e2); |
Line 2584 int fnode_normalize_comp(FNODE f1,FNODE f2) |
|
Line 2616 int fnode_normalize_comp(FNODE f1,FNODE f2) |
|
else { |
else { |
n1 = NEXT(n1); n2 = NEXT(n2); |
n1 = NEXT(n1); n2 = NEXT(n2); |
} |
} |
if ( n1 ) return 1; |
return n1?1:(n2?-1:0); |
else if ( n2 ) return -1; |
|
else return 0; |
|
} |
} |
break; |
break; |
case I_PVAR: |
case I_PVAR: |
Line 2625 int fnode_normalize_comp_pwr(FNODE f1,FNODE f2) |
|
Line 2655 int fnode_normalize_comp_pwr(FNODE f1,FNODE f2) |
|
else if ( r < 0 ) |
else if ( r < 0 ) |
return fnode_normalize_comp(mkfnode(1,I_FORMULA,0),e2); |
return fnode_normalize_comp(mkfnode(1,I_FORMULA,0),e2); |
} else return fnode_normalize_comp(e1,e2); |
} else return fnode_normalize_comp(e1,e2); |
|
} |
|
|
|
NODE append_node(NODE a1,NODE a2) |
|
{ |
|
NODE t,t0; |
|
|
|
if ( !a1 ) |
|
return a2; |
|
else { |
|
for ( t0 = 0; a1; a1 = NEXT(a1) ) { |
|
NEXTNODE(t0,t); BDY(t) = BDY(a1); |
|
} |
|
NEXT(t) = a2; |
|
return t0; |
|
} |
|
} |
|
|
|
int fnode_normalize_unify(FNODE f,FNODE pat,NODE *rp) |
|
{ |
|
NODE m,m1,m2,base,exp,fa,pa,n; |
|
LIST l; |
|
QUOTE qp,qf; |
|
FNODE fbase,fexp,a; |
|
FUNC ff,pf; |
|
int r; |
|
|
|
switch ( pat->id ) { |
|
case I_PVAR: |
|
/* [[pat,f]] */ |
|
*rp = mknode(1,mknode(2,(int)FA0(pat),f),0); |
|
return 1; |
|
|
|
case I_FORMULA: |
|
if ( !arf_comp(CO,(Obj)FA0(f),(Obj)FA0(pat)) ) { |
|
*rp = 0; return 1; |
|
} else |
|
return 0; |
|
|
|
case I_BOP: |
|
/* OPNAME should be "^" */ |
|
if ( !IS_BINARYPWR(pat) ) |
|
error("fnode_normalize_unify : invalid BOP"); |
|
if ( IS_BINARYPWR(f) ) { |
|
fbase = FA1(f); fexp = FA2(f); |
|
} else { |
|
fbase = f; fexp = mkfnode(1,I_FORMULA,ONE); |
|
} |
|
if ( !fnode_normalize_unify(fbase,FA1(pat),&base) ) return 0; |
|
a = rewrite_fnode(FA2(pat),base); |
|
if ( !fnode_normalize_unify(fexp,a,&exp) ) return 0; |
|
else { |
|
*rp = append_node(base,exp); |
|
return 1; |
|
} |
|
break; |
|
|
|
case I_FUNC: |
|
if ( f->id != I_FUNC ) return 0; |
|
ff = (FUNC)FA0(f); pf = (FUNC)FA0(pat); |
|
if ( strcmp(ff->fullname,pf->fullname) ) return 0; |
|
/* FA1(f) and FA1(pat) are I_LIST */ |
|
fa = (NODE)FA0((FNODE)FA1(f)); |
|
pa = (NODE)FA0((FNODE)FA1(pat)); |
|
m = 0; |
|
while ( fa && pa ) { |
|
a = rewrite_fnode(BDY(pa),m); |
|
if ( !fnode_normalize_unify(BDY(fa),a,&m1) ) return 0; |
|
m = append_node(m1,m); |
|
fa = NEXT(fa); pa = NEXT(pa); |
|
} |
|
if ( fa || pa ) return 0; |
|
else { |
|
*rp = m; |
|
return 1; |
|
} |
|
|
|
case I_NARYOP: |
|
if ( IS_NARYADD(pat) ) |
|
return fnode_normalize_unify_naryadd(f,pat,rp); |
|
else if ( IS_NARYMUL(pat) ) |
|
return fnode_normalize_unify_narymul(f,pat,rp); |
|
else |
|
error("fnode_normalize_unify : invalid NARYOP"); |
|
break; |
|
|
|
default: |
|
error("fnode_normalize_unify : invalid pattern"); |
|
} |
|
} |
|
|
|
/* remove i-th element */ |
|
|
|
FNODE fnode_removeith_naryadd(FNODE p,int i) |
|
{ |
|
int k,l; |
|
NODE t,r0,r,a; |
|
|
|
a = (NODE)FA1(p); |
|
l = length(a); |
|
if ( i < 0 || i >= l ) error("fnode_removeith_naryadd: invalid index"); |
|
else if ( i == 0 ) |
|
return fnode_node_to_naryadd(NEXT(a)); |
|
else { |
|
for ( r0 = 0, k = 0, t = a; k < i; k++, t = NEXT(t) ) { |
|
NEXTNODE(r0,r); |
|
BDY(r) = BDY(t); |
|
} |
|
t = NEXT(t); |
|
NEXT(r) = 0; |
|
return fnode_node_to_naryadd(r0); |
|
} |
|
|
|
} |
|
|
|
/* a0,...,a(i-1) */ |
|
FNODE fnode_left_narymul(FNODE p,int i) |
|
{ |
|
int k,l; |
|
NODE t,r0,r,a; |
|
|
|
a = (NODE)FA1(p); |
|
l = length(a); |
|
if ( i < 0 || i >= l ) error("fnode_left_narymul : invalid index"); |
|
if ( i == 0 ) return mkfnode(1,I_FORMULA,ONE); |
|
else if ( i == 1 ) return (FNODE)BDY(a); |
|
else { |
|
for ( r0 = 0, k = 0, t = a; k < i; k++, t = NEXT(t) ) { |
|
NEXTNODE(r0,r); |
|
BDY(r) = BDY(t); |
|
} |
|
NEXT(r) = 0; |
|
return fnode_node_to_narymul(r0); |
|
} |
|
} |
|
|
|
/* a(i+1),...,a(l-1) */ |
|
FNODE fnode_right_narymul(FNODE p,int i) |
|
{ |
|
NODE a,t; |
|
int l,k; |
|
|
|
a = (NODE)FA1(p); |
|
l = length(a); |
|
if ( i < 0 || i >= l ) error("fnode_right_narymul : invalid index"); |
|
if ( i == l-1 ) return mkfnode(1,I_FORMULA,ONE); |
|
else { |
|
for ( k = 0, t = a; k <= i; k++, t = NEXT(t) ); |
|
return fnode_node_to_narymul(t); |
|
} |
|
} |
|
|
|
int fnode_normalize_unify_naryadd(FNODE f,FNODE p,NODE *rp) |
|
{ |
|
int fl,pl,fi,pi; |
|
NODE fa,pa,t,s,m,m1; |
|
FNODE fr,pr,prr,pivot; |
|
|
|
f = to_naryadd(f); |
|
fa = (NODE)FA1(f); fl = length(fa); |
|
pa = (NODE)FA1(p); pl = length(pa); |
|
if ( fl < pl ) return 0; |
|
else if ( pl == 1 ) { |
|
if ( fl == 1 ) |
|
return fnode_normalize_unify(BDY(fa),BDY(pa),rp); |
|
else |
|
return 0; |
|
} else { |
|
for ( t = pa, pi = 0; t; t = NEXT(t), pi++ ) |
|
if ( ((FNODE)BDY(t))->id != I_PVAR ) break; |
|
if ( !t ) { |
|
/* all are I_PVAR */ |
|
m = 0; |
|
for ( t = pa, s = fa; NEXT(t); t = NEXT(t), s = NEXT(s) ) { |
|
fnode_normalize_unify(BDY(s),BDY(t),&m1); |
|
m = append_node(m1,m); |
|
} |
|
if ( !NEXT(s) ) |
|
fr = (FNODE)BDY(s); |
|
else |
|
fr = mkfnode(2,I_NARYOP,FA0(f),s); |
|
fnode_normalize_unify(fr,BDY(t),&m1); |
|
*rp = append_node(m1,m); |
|
return 1; |
|
} else { |
|
pivot = (FNODE)BDY(t); |
|
pr = fnode_removeith_naryadd(p,pi); |
|
for ( s = fa, fi = 0; s; s = NEXT(s), fi++ ) { |
|
if ( fnode_normalize_unify(BDY(s),pivot,&m) ) { |
|
fr = fnode_removeith_naryadd(f,fi); |
|
prr = rewrite_fnode(pr,m); |
|
if ( fnode_normalize_unify(fr,prr,&m1) ) { |
|
*rp = append_node(m,m1); |
|
return 1; |
|
} |
|
} |
|
} |
|
return 0; |
|
} |
|
} |
|
} |
|
|
|
int fnode_normalize_unify_narymul(FNODE f,FNODE p,NODE *rp) |
|
{ |
|
int fl,pl,fi,pi; |
|
NODE fa,pa,t,s,m,m1; |
|
FNODE fr,pr,pleft,pleft1,pright,pright1,fleft,fright,pivot; |
|
|
|
f = to_narymul(f); |
|
fa = (NODE)FA1(f); fl = length(fa); |
|
pa = (NODE)FA1(p); pl = length(pa); |
|
if ( fl < pl ) return 0; |
|
else if ( pl == 1 ) { |
|
if ( fl == 1 ) |
|
return fnode_normalize_unify(BDY(fa),BDY(pa),rp); |
|
else |
|
return 0; |
|
} else { |
|
for ( t = pa, pi = 0; t; t = NEXT(t), pi++ ) |
|
if ( ((FNODE)BDY(t))->id != I_PVAR ) break; |
|
if ( !t ) { |
|
/* all are I_PVAR */ |
|
m = 0; |
|
for ( t = pa, s = fa; NEXT(t); t = NEXT(t), s = NEXT(s) ) { |
|
pr = rewrite_fnode(BDY(t),m); |
|
if ( !fnode_normalize_unify(BDY(s),pr,&m1) ) return 0; |
|
m = append_node(m1,m); |
|
} |
|
if ( !NEXT(s) ) |
|
fr = (FNODE)BDY(s); |
|
else |
|
fr = mkfnode(2,I_NARYOP,FA0(f),s); |
|
pr = rewrite_fnode(BDY(t),m); |
|
if ( !fnode_normalize_unify(fr,pr,&m1) ) return 0; |
|
*rp = append_node(m1,m); |
|
return 1; |
|
} else { |
|
pivot = (FNODE)BDY(t); |
|
pleft = fnode_left_narymul(p,pi); |
|
pright = fnode_right_narymul(p,pi); |
|
/* XXX : incomplete */ |
|
for ( s = fa, fi = 0; s; s = NEXT(s), fi++ ) { |
|
if ( fnode_normalize_unify(BDY(s),pivot,&m) ) { |
|
fleft = fnode_left_narymul(f,fi); |
|
pleft1 = rewrite_fnode(pleft,m); |
|
if ( fnode_normalize_unify(fleft,pleft1,&m1) ) { |
|
m = append_node(m1,m); |
|
fright = fnode_right_narymul(f,fi); |
|
pright1 = rewrite_fnode(pright,m); |
|
if ( fnode_normalize_unify(fright,pright1,&m1) ) { |
|
*rp = append_node(m1,m); |
|
return 1; |
|
} |
|
} |
|
} |
|
} |
|
return 0; |
|
} |
|
} |
} |
} |