view v1.c @ 0:e0bbaa717f41 draft default tip

lol J
author Jordi Gutiérrez Hermoso <jordigh@octave.org>
date Mon, 25 Nov 2013 11:56:30 -0500
parents
children
line wrap: on
line source

/* Copyright 1990-2011, Jsoftware Inc.  All rights reserved. */
/* License in license.txt.                                   */
/*                                                                         */
/* Verbs: Match Associates                                                 */

#include "j.h"


static B jtmatchsub(J,I,I,I,I,A,A,B*,B,B);
static F2(jtmatchs);

#define MCS(q,af,wf)  ((1<q?16:q?8:0)+(af?2:0)+(wf?1:0))
#define QLOOP         b=b1; DO(q, if(u[i]!=v[i]){b=b0; break;}); *x++=b;
#define EQV(T)        \
 {T h,*u=(T*)av,*v=(T*)wv;                                                   \
  q=k/sizeof(T);                                                             \
  switch(MCS(q,af,wf)){                                                      \
   case MCS(1,0,0):              *x++=*u  ==*v?b1:b0; break;                 \
   case MCS(1,0,1): h=*u; if(b1)DO(mn, *x++=h   ==*v++;) else DO(mn, *x++=h   !=*v++;)  break;  \
   case MCS(1,1,0): h=*v; if(b1)DO(mn, *x++=*u++==h;   ) else DO(mn, *x++=*u++!=h;   ); break;  \
   case MCS(1,1,1): if(b1){                                                  \
                     if(1==n)      DO(m,               *x++=*u++==*v++;  )   \
                     else if(af<wf)DO(m, h=*u++; DO(n, *x++=h   ==*v++;);)   \
                     else          DO(m, h=*v++; DO(n, *x++=*u++==h;   ););  \
                    }else{                                                   \
                     if(1==n)      DO(m,               *x++=*u++!=*v++;  )   \
                     else if(af<wf)DO(m, h=*u++; DO(n, *x++=h   !=*v++;);)   \
                     else          DO(m, h=*v++; DO(n, *x++=*u++!=h;   ););  \
                    } break;                                                 \
   case MCS(2,0,0):        QLOOP;               break;                       \
   case MCS(2,0,1): DO(mn, QLOOP;       v+=q;); break;                       \
   case MCS(2,1,0): DO(mn, QLOOP; u+=q;      ); break;                       \
   case MCS(2,1,1): if(1==n)      DO(m,       QLOOP; u+=q;   v+=q;)          \
                    else if(af<wf)DO(m, DO(n, QLOOP; v+=q;); u+=q;)          \
                    else          DO(m, DO(n, QLOOP; u+=q;); v+=q;); break;  \
 }}

static B eqv(I af,I wf,I m,I n,I k,C*av,C*wv,B*x,B b0,B b1){B b,*xx=x;I c,d,mn=m*n,q;
 if     (0==k%sizeof(I)  )EQV(I)
#if SY_64
 else if(0==k%sizeof(int))EQV(int)
#endif
 else if(0==k%sizeof(S)  )EQV(S)
 else if(1==k)            EQV(C)
 else{
  c=af?k:0; d=wf?k:0;
  if(1==n)      DO(m,       *x++=memcmp(av,wv,k)?b0:b1; av+=c;   wv+=d;)
  else if(af<wf)DO(m, DO(n, *x++=memcmp(av,wv,k)?b0:b1; wv+=k;); av+=k;)
  else          DO(m, DO(n, *x++=memcmp(av,wv,k)?b0:b1; av+=k;); wv+=k;);
 }
 R mn?xx[mn-1]:b1;
}    /* what memcmp should have been */

B jtequ(J jt,A a,A w){A x;B b; 
 RZ(a&&w);
 if(a==w)R 1;
 if(SPARSE&(AT(a)|AT(w))&&AR(a)&&AR(w)){RZ(x=matchs(a,w)); R*BAV(x);}
 R level(a)==level(w)&&matchsub(0L,0L,1L,1L,a,w,&b,C0,C1);
}

static B jteqf(J jt,A a,A w){A p,q;B b;V*u=VAV(a),*v=VAV(w);
 if(!(AT(a)==AT(w)&&u->id==v->id))R 0;
 p=u->f; q=v->f; if(!(!p&&!q||p&&q&&matchsub(0L,0L,1L,1L,p,q,&b,C0,C1)))R 0;
 p=u->g; q=v->g; if(!(!p&&!q||p&&q&&matchsub(0L,0L,1L,1L,p,q,&b,C0,C1)))R 0;
 p=u->h; q=v->h;    R !p&&!q||p&&q&&matchsub(0L,0L,1L,1L,p,q,&b,C0,C1);
}

#define EQA(a,w)  matchsub(0L,0L,1L,1L,a,w,&b,C0,C1)
#define EQQ(a,w)  (equ(a.n,w.n)&&equ(a.d,w.d))

#define INNERT(T,f)                  \
 {T*u=(T*)av,*v=(T*)wv;              \
  if(1==n)      DO(m,       x[j]=b1; DO(c, if(!f(u[i],v[i])){x[j]=b0; break;}); u+=p; v+=q; ++j;  )  \
  else if(af>wf)DO(m, DO(n, x[j]=b1; DO(c, if(!f(u[i],v[i])){x[j]=b0; break;}); u+=p; ++j;); v+=q;)  \
  else          DO(m, DO(n, x[j]=b1; DO(c, if(!f(u[i],v[i])){x[j]=b0; break;}); v+=q; ++j;); u+=p;)  \
 }

#define INNERT2(aa,ww,f)             \
 {A1*u=(A1*)av,*v=(A1*)wv;           \
  if(1==n)      DO(m,       x[j]=b1; DO(c, if(!f((A)AABS(u[i],aa),(A)AABS(v[i],ww))){x[j]=b0; break;}); u+=p; v+=q; ++j;  )  \
  else if(af>wf)DO(m, DO(n, x[j]=b1; DO(c, if(!f((A)AABS(u[i],aa),(A)AABS(v[i],ww))){x[j]=b0; break;}); u+=p; ++j;); v+=q;)  \
  else          DO(m, DO(n, x[j]=b1; DO(c, if(!f((A)AABS(u[i],aa),(A)AABS(v[i],ww))){x[j]=b0; break;}); v+=q; ++j;); u+=p;)  \
 }

static B jtmatchsub(J jt,I af,I wf,I m,I n,A a,A w,B*x,B b0,B b1){B b,c0;C*av,*wv;I at,c,j=0,mn,p,q,t,wt;
 p=AR(a)-af; at=AT(a); mn=m&&n?m*n:0;
 q=AR(w)-wf; wt=AT(w); RE(t=maxtype(at,wt)); c0=!jt->ct&&t&FL+CMPX;
 c=(af>wf?AN(a):AN(w))/(mn?mn:1); b=p!=q||ICMP(af+AS(a),wf+AS(w),p)||c&&!HOMO(at,wt);
 if(b||!c||a==w){memset(x,b?b0:b1,mn); R b?b0:b1;}
 if(t&FUNC)R eqf(a,w)?b1:b0;
 if(t!=at)RZ(a=t&XNUM?xcvt(XMEXMT,a):cvt(t,a)) else if(c0)RZ(a=cvt0(a)); 
 if(t!=wt)RZ(w=t&XNUM?xcvt(XMEXMT,w):cvt(t,w)) else if(c0)RZ(w=cvt0(w)); 
 p=af?c:0; av=CAV(a);
 q=wf?c:0; wv=CAV(w);
 switch(c0?0:t){
  default:   R eqv(af,wf,m,n,c*bp(t),av,wv,x,b0,b1);
  case FL:   INNERT(D,teq);    R mn?x[mn-1]:b1;
  case CMPX: INNERT(Z,zeq);    R mn?x[mn-1]:b1;
  case XNUM: INNERT(X,equ);    R mn?x[mn-1]:b1;
  case RAT:  INNERT(Q,EQQ);    R mn?x[mn-1]:b1;
  case BOX:  switch(2*ARELATIVE(a)+ARELATIVE(w)){
   default:  INNERT(A,EQA);    R mn?x[mn-1]:b1;
   case 1:   INNERT2(0,w,EQA); R mn?x[mn-1]:b1;
   case 2:   INNERT2(a,0,EQA); R mn?x[mn-1]:b1;
   case 3:   INNERT2(a,w,EQA); R mn?x[mn-1]:b1;
}}}

static F2(jtmatchs){A ae,ax,p,q,we,wx,x;B*b,*pv,*qv;D d;I acr,an=0,ar,c,j,k,m,n,r,*s,*v,wcr,wn=0,wr;P*ap,*wp;
 RZ(a&&w);
 ar=AR(a); acr=jt->rank?jt->rank[0]:ar; r=ar;
 wr=AR(w); wcr=jt->rank?jt->rank[1]:wr; jt->rank=0;
 if(ar>acr||wr>wcr)R rank2ex(a,w,0L,acr,wcr,jtmatchs);
 if(ar!=wr||memcmp(AS(a),AS(w),r*SZI)||!HOMO(AT(a),AT(w)))R zero;
 GA(x,B01,r,1L,0L); b=BAV(x); memset(b,C0,r);
 if(SPARSE&AT(a)){ap=PAV(a); x=SPA(ap,a); v=AV(x); an=AN(x); DO(an, b[v[i]]=1;);}
 if(SPARSE&AT(w)){wp=PAV(w); x=SPA(wp,a); v=AV(x); wn=AN(x); DO(wn, b[v[i]]=1;);} 
 c=0; DO(r, c+=b[i];);
 if(an<c||DENSE&AT(a))RZ(a=reaxis(ifb(r,b),a)); ap=PAV(a); ae=SPA(ap,e); ax=SPA(ap,x); m=*AS(ax);
 if(wn<c||DENSE&AT(w))RZ(w=reaxis(ifb(r,b),w)); wp=PAV(w); we=SPA(wp,e); wx=SPA(wp,x); n=*AS(wx);
 RZ(x=indexof(SPA(ap,i),SPA(wp,i))); v=AV(x);
 GA(p,B01,m,1,0); pv=BAV(p);
 GA(q,B01,n,1,0); qv=BAV(q); 
 memset(pv,C1,m); DO(n, j=*v++; if(j<m)pv[j]=qv[i]=0; else qv[i]=1;);
 if(memchr(pv,C1,m)&&!all1(eq(we,repeat(p,ax))))R zero;
 if(memchr(qv,C1,n)&&!all1(eq(ae,repeat(q,wx))))R zero;
 j=0; DO(m, if(pv[i])++j;);
 k=0; DO(n, if(qv[i])++k; qv[i]=!qv[i];);
 if(!equ(from(repeat(q,x),ax),repeat(q,wx)))R zero;
 x=SPA(ap,a); v=AV(x); s=AS(a); d=1.0; DO(AN(x), d*=s[v[i]];);
 R d==m+k&&d==n+j||equ(ae,we)?one:zero;
}    /* a -:"r w on sparse arrays */


F2(jtmatch){A z;I af,f,m,n,*s,wf;
 RZ(a&&w);
 if(SPARSE&(AT(a)|AT(w)))R matchs(a,w);
 af=jt->rank?AR(a)-jt->rank[0]:0;
 wf=jt->rank?AR(w)-jt->rank[1]:0; jt->rank=0;
 if(af>wf){f=af; s=AS(a); RE(m=prod(wf,s)); RE(n=prod(af-wf,wf+s));}
 else     {f=wf; s=AS(w); RE(m=prod(af,s)); RE(n=prod(wf-af,af+s));}
 GA(z,B01,m*n,f,s); matchsub(af,wf,m,n,a,w,BAV(z),C0,C1);
 R z;
}    /* a -:"r w */

F2(jtnotmatch){A z;I af,f,m,n,*s,wf;
 RZ(a&&w);
 if(SPARSE&(AT(a)|AT(w)))R not(matchs(a,w));
 af=jt->rank?AR(a)-jt->rank[0]:0;
 wf=jt->rank?AR(w)-jt->rank[1]:0; jt->rank=0;
 if(af>wf){f=af; s=AS(a); RE(m=prod(wf,s)); RE(n=prod(af-wf,wf+s));}
 else     {f=wf; s=AS(w); RE(m=prod(af,s)); RE(n=prod(wf-af,af+s));}
 GA(z,B01,m*n,f,s); matchsub(af,wf,m,n,a,w,BAV(z),C1,C0);
 R z;
}    /* a -.@-:"r w */