code_prm.sa


Generated by gen_html_sa_files from ICSI. Contact gomes@icsi.berkeley.edu for details
 

partial class KCODE{VERT}

partial class KCODE{VERT} is -- class for KNOT, TCODE, RTCODE attr k:ARRAY{VERT}; -- Note. -- k[*] -- sep={normal}: vertex of the projection. -- (x,y):coord. of the point. -- sep={normal,band}: vertex of the projection and end of a band. -- (x,y):coord. of the point. -- sep={crossing, under/over}: crossing pt. -- (x,y):coord. of the crossing pt. -- sep={separator,ks}:start of a knot. -- (x,y):=(0,0) -- sep={separator,ke}:end of a knot. -- (x,y):=(0,0) -- sep={separator,ts}:start of a band. -- (x,y):=(0,0) -- sep={separator,te}:end of a band. -- (x,y):=(0,0) --sep={separator,endc}:end of the code. -- (x,y):=(0,0) create:SAME is res::=new; res.k:=|#VERT(VERTEXC::code_e)|; return res; end; clone:SAME is res:SAME:=#; res.k:=#(k.size); loop i::=k.ind!; res.k[i]:=k[i].clone; end; return res; end; aget(i:CARD):VERT is return k[i]; end; aget(i:INT):VERT is return k[i.card]; end; aset(i:CARD, v:VERT) is k[i]:=v; end; aset(i:INT, v:VERT) is k[i.card]:=v; end; size:CARD is return k.size; end; length:CARD is -- code length __except terminator__. return k.size-1; end; has_ind(i:CARD):BOOL is return k.has_ind(i); end; has_ind(i:INT):BOOL is return i.is_non_neg and has_ind(i.card); end; numbers_count(inout cr,inout cr_p,inout cr_n, inout compo,inout band:INT) is -- # of crossings, knot , band in [stp..enp]. cr:=0; cr_p:=0; cr_n:=0; compo:=0; band:=0; loop cod::=k.elt!.sep; if VERTEXC::crossing.in(cod) then cr:=cr+1; if VERTEXC::positive.in(cod) then cr_p:=cr_p+1; elsif VERTEXC::negative.in(cod) then cr_n:=cr_n+1; end; elsif VERTEXC::ks.in(cod) then compo:=compo+1; elsif VERTEXC::ts.in(cod) then band:=band+1; end; end; cr:=cr/2; cr_p:=cr_p/2; cr_n:=cr_n/2; end; number_crossing:INT is -- # of crossings cr,cp,cn,k0,b0:INT; numbers_count(inout cr,inout cp,inout cn,inout k0,inout b0); return cr; end; number_positive_crossing:INT is cr,cp,cn,k0,b0:INT; numbers_count(inout cr,inout cp,inout cn,inout k0,inout b0); return cp; end; number_negative_crossing:INT is cr,cp,cn,k0,b0:INT; numbers_count(inout cr,inout cp,inout cn,inout k0,inout b0); return cn; end; number_writhe:INT is cr,cp,cn,k0,b0:INT; numbers_count(inout cr,inout cp,inout cn,inout k0,inout b0); return cp-cn; end; number_compo:INT is cr,cp,cn,k0,b0:INT; numbers_count(inout cr,inout cp,inout cn,inout k0,inout b0); return k0; end; endOfString(i:INT, dir:INT):INT is cod:VERTEXC; if ~has_ind(i) then return i; end; if dir=1.int then cod:=VERTEXC::enp; else cod:=VERTEXC::stp; end; loop while!(has_ind(i) and (cod*[i].sep).is_empty); i:=i+dir; end; return i; end; has_band:BOOL is return size>2 and VERTEXC::te.in(k[k.size-2].sep); end; has_band(p1,p2:INT):BOOL is -- true if segment p1--p2 has band_attach pts. loop i::=p1.upto!(p2); if VERTEXC::band.in([i].sep) then return true; end; end; return false; end; bandStart:INT is -- k.size-1 if band is not exist if k.size<2 then return k.size.int-1; end; if ~VERTEXC::te.in(k[k.size-2].sep) then return k.size.int-1; end; loop i::=0.upto!(k.size-1); if VERTEXC::ts.in(k[i].sep) then return i.int; end; end; raise "bansStart: missing band start.\n"; end; compoStart(c:INT):INT is -- start point of c-th component. -- return -1, if #compo<c. i:INT:=0.int; loop c1::=1.int.up!; if (c1=c) then return i; end; i:=endOfString(i,1.int)+1.int; if i>=length.int then return -1; end; end; end; -------------- add/delete ------------------ CodeIn(v:VERT, i:CARD) pre (i<=k.size) is -- move up and insert. 'normal vertex,(x=0,y=0),work=0. --k:=k.resize(k.size+1); --loop j::=(k.size-2).downto!(i); k[j+1]:=k[j]; end; --k[i]:=v; k:=ARRAY_EXT{VERT}::insert_at(i,k,v); end; CodeIn(c:VERTEXC, i:CARD) is CodeIn(#VERT(c),i); end; CodeIn(c:VERTEXC, i:INT) pre i.is_neg.not is CodeIn(c,i.card); end; CodeIn(i:CARD) is CodeIn(#VERT,i); end; append(a:SAME) is --s::=k.size-1; k:=k.resize(s+a.k.size); --loop i::=0.upto!(a.k.size-1); k[i+s]:=a.k[i]; end; k:=self.append(a).k; end; append(a:SAME):SAME is --res:SAME:=clone; res.append(a); return res; s::=k.size-1; res:SAME:=#; res.k:=#(s+a.k.size); res.k.copy(k); res.k.copy(s,a.k); return res; end; append(v:VERT) is CodeIn(v,k.size-1); end; CodeDel(i:CARD) pre (i<k.size) is -- del the code not search for companion --loop j::=i.upto!(k.size-2); k[j]:=k[j+1]; end; --k:=k.resize(k.size-1); k:=ARRAY_EXT{VERT}::delete_at(i,k); end; CodeDel(i:INT) pre (i.is_zero.not) is CodeDel(i.card); end; cp(inout dist:INT, s_beg,s_end:INT, s_knot:SAME) is j:INT; d_end:INT:=dist+s_end-s_beg; if (d_end+1)>k.size.int then k:=k.resize(d_end.card+1); end; loop j:=s_beg.upto!(s_end); [dist]:=s_knot[j]; dist:=dist+1; end; end; CodeSplice(stp1,enp1,stp2,enp2:INT) is -- splice the code stp1..enp1 and stp2..enp2, stp1<enp1, stp2<enp2 i:INT; k1:SAME; k1:=#; if (stp1.is_non_neg)and(stp1<=enp1)and(enp1<size.int-1)and (stp2.is_non_neg)and(stp2<=enp2)and(enp2<size.int-1)and (enp1.min(enp2)<stp1.max(stp2)) then k1:=clone; -- i:=0; cp(0,minINT(stp1,stp2)-1); i:=stp1.min(stp2); cp(inout i,stp1,enp1,k1); cp(inout i,stp2,enp2,k1); cp(inout i,enp1.min(enp2)+1,stp1.max(stp2)-1,k1); cp(inout i,enp1.max(enp2)+1,k1.size.int-1,k1); end; end; -- StringSplice(i,j:INT) is -- Splice and connect strings contains i and j. -- Must be (end point of i)=(start of j) -- not implemented. CodeRev(p1,p2:INT) is -- Reverse Knot[] codes between p1,p2, needed 0<=p1,p2<=maxK Kcode:VERT; i:INT; if (p1.is_non_neg)and(p1<p2)and(p2<size.int-1) then loop while!(p1<p2); -- swap Kcode:=[p1]; [p1]:=[p2]; [p2]:=Kcode; p1:=p1+1.int; p2:=p2-1; end; end; end; revK(i:INT) is -- ori. reverse the string j0, j1:INT; j0:=endOfString(i,-1)+1; j1:=endOfString(i,1.int)-1; CodeRev(j0,j1); end; rotBack1(stp, enp:INT) is -- rotate back component of stp--enp by 1 if ~(VERTEXC::ks.in(k[stp].sep) and VERTEXC::ke.in(k[enp].sep) ) then return; end; loop i::=(stp+1).upto!(enp-2); k[i]:=k[i+1]; end; k[enp-1]:=k[stp+1].clone; end; rotComponent(stp, enp:INT, stp1:INT) is -- rotate back component of stp--enp -- move stp1 to head if ~(VERTEXC::ks.in([stp].sep) and VERTEXC::ke.in([enp].sep) ) then return; end; if (stp1<=stp)or(enp<=stp1) then return; end; CodeRev(stp+1,enp-2); CodeRev(stp+1,stp+enp-stp1-1); CodeRev(stp+enp-stp1,enp-2); [enp-1]:=[stp+1].clone; end; flip is loop i::=k.ind!; if VERTEXC::crossing.in([i].sep) then [i].sep:=[i].sep.xor(VERTEXC::cross_exg); end; end; end; private bad(message:BOOL,num:CARD, i:INT) is if message then #OUT+"Bad code: "+num.str+", i="+i.str+"\n"; end; end; end; -- partial class KCODE{VERT}

partial class KCODE_CMP{VERT}

partial class KCODE_CMP{VERT} is -- Use with include KCODE{VERT}; -- attr of VERT has sep,companion check(print_message:BOOL):BOOL is i,i1,i2:INT; ic:INT; code:VERTEXC; msw::=print_message; res:BOOL:=true; if void(self) then bad(msw,0,0.int);return false; end; if void(k) then bad(msw,1,0.int);return false; end; if k.size=1 then -- TCODE is trivial end; loop i:=(0.upto!(k.size-1)).int; code:=[i].sep; ic:=[i].companion; if VERTEXC::gs.in(code) then --10 elsif VERTEXC::ge.in(code) then --20 elsif VERTEXC::ks.in(code) then --30 i2:=endOfString(i,1.int); i1:=endOfString(i2,-1); if i/=[ic].companion then bad(msw,30,i); res:=false; elsif has_ind(i2).not then bad(msw,31,i); res:=false; elsif has_ind(i1).not then bad(msw,32,i); res:=false; elsif i/=i1 then bad(msw,33,i); res:=false; elsif ~VERTEXC::ke.in([i2].sep) then bad(msw,34,i); res:=false; elsif ~VERTEXC::ks.in([i1].sep) then bad(msw,35,i); res:=false; elsif i2/=[i].companion then bad(msw,36,i); res:=false; end; elsif VERTEXC::ke.in(code) then --40 i1:=endOfString(i,-1); i2:=endOfString(i1,1.int); if i/=[ic].companion then bad(msw,40,i); res:=false; elsif has_ind(i2).not then bad(msw,41,i); res:=false; elsif has_ind(i1).not then bad(msw,42,i); res:=false; elsif i/=i2 then bad(msw,43,i); res:=false; elsif ~VERTEXC::ke.in([i2].sep) then bad(msw,44,i); res:=false; elsif ~VERTEXC::ks.in([i1].sep) then bad(msw,45,i); res:=false; elsif i1/=[i].companion then bad(msw,46,i); res:=false; end; elsif VERTEXC::ts.in(code) then --50 i2:=endOfString(i,1.int); i1:=endOfString(i2,-1); if i/=[ic].companion then bad(msw,50,i); res:=false; elsif has_ind(i2).not then bad(msw,51,i); res:=false; elsif has_ind(i1).not then bad(msw,52,i); res:=false; elsif i/=i1 then bad(msw,53,i); res:=false; elsif ~VERTEXC::te.in([i2].sep) then bad(msw,54,i); res:=false; elsif ~VERTEXC::ts.in([i1].sep) then bad(msw,55,i); res:=false; elsif ~VERTEXC::band.in([ic].sep) then bad(msw,56,i);res:=false; end; elsif VERTEXC::te.in(code) then --60 i1:=endOfString(i,-1); i2:=endOfString(i1,1.int); if i/=[ic].companion then bad(msw,60,i); res:=false; elsif has_ind(i2).not then bad(msw,61,i); res:=false; elsif has_ind(i1).not then bad(msw,62,i); res:=false; elsif i/=i2 then bad(msw,63,i); res:=false; elsif ~VERTEXC::te.in([i2].sep) then bad(msw,64,i);res:=false; elsif ~VERTEXC::ts.in([i1].sep) then bad(msw,65,i);res:=false; elsif ~VERTEXC::band.in([ic].sep) then bad(msw,66,i);res:=false; end; elsif VERTEXC::crossing.in(code) then --70 if i/=[ic].companion then bad(msw,70,i); res:=false; end; elsif VERTEXC::band.in(code) then --80 elsif VERTEXC::endc.in(code) then --90 if i/=(k.size-1).int then bad(msw,90,i); res:=false; end; end; end; if VERTEXC::code_e/=[size-1].sep then bad(msw,1,size.int-1); res:=false; end; return res; end; printD is -- print for debug cod:VERTEXC; #OUT+" companion,sep \n"; loop i::=0.upto!(k.size-1); #OUT+i.str+":"+[i].companion.str+" "; -- +k[i].gen.str+" "+k[i].compo.str+" "; cod:=[i].sep; if VERTEXC::normal.in(cod) then #OUT+"n"; end; if VERTEXC::ks.in(cod) then #OUT+"["; end; if VERTEXC::ke.in(cod) then #OUT+"]"; end; if VERTEXC::ts.in(cod) then #OUT+"("; end; if VERTEXC::te.in(cod) then #OUT+")"; end; if VERTEXC::band.in(cod) then #OUT+"b"; end; if VERTEXC::crossing.in(cod) then #OUT+"c"; end; if VERTEXC::under.in(cod) then #OUT+"u"; end; if VERTEXC::over.in(cod) then #OUT+"o"; end; if VERTEXC::positive.in(cod) then #OUT+"+"; end; if VERTEXC::negative.in(cod) then #OUT+"-"; end; if VERTEXC::endc.in(cod) then #OUT+"/"; end; #OUT+"\n"; end; end; numbers_seg_count(stp,enp:INT, inout cr,inout cr_p,inout cr_n, inout compo,inout band:INT) is -- # of crossings, knot , band in [stp..enp] cr:=0; cr_p:=0; cr_n:=0; compo:=0; band:=0; loop i::=stp.upto!(enp); if stp<[i].companion and [i].companion<enp then cod::=[i].sep; if VERTEXC::crossing.in(cod) then cr:=cr+1; end; if VERTEXC::positive.in(cod) then cr_p:=cr_p+1; elsif VERTEXC::negative.in(cod) then cr_n:=cr_n+1; elsif VERTEXC::ks.in(cod) then compo:=compo+1; elsif VERTEXC::ts.in(cod) then band:=band+1; end; end; end; cr:=cr/2.int; cr_p:=cr_p/2.int; cr_n:=cr_n/2.int; end; numbers_self_count(stp:INT, inout cr, inout cr_p,inout cr_n:INT) pre VERTEXC::ks.in(k[stp].sep) or VERTEXC::ts.in(k[stp].sep) is -- self crossings enp::=endOfString(stp,1.int); k0,b0:INT; numbers_seg_count(stp,enp, inout cr,inout cr_p,inout cr_n, inout k0,inout b0); end; number_self_crossing(stp:INT):INT is cr,cp,cn:INT; numbers_self_count(stp,inout cr,inout cp,inout cn); return cr; end; number_self_writhe(stp:INT):INT is cr,cp,cn:INT; numbers_self_count(stp,inout cr,inout cp,inout cn); return cp-cn; end; CodeInCmp(v:VERT, i:INT) is -- CodeIn with trimming companion [k.size-1].companion:=-1; -- endcode k:=k.resize(k.size+1); loop j::=(k.size.int-1).downto!(i+1); [j]:=[j-1]; if has_ind([j].companion) then [[j].companion].companion:=j; end; end; [k.size-1].companion:=0.int; -- endcode [i]:=v; end; CodeInCmp(v:VERT, i,n:INT) is -- CodeIn with trimming companion [k.size-1].companion:=-1; -- endcode k:=k.resize((k.size.int+n).card); loop j:INT:=(k.size.int-1).downto!(i+n); [j]:=[j-n]; if has_ind([j].companion) then [[j].companion].companion:=j; end; end; [k.size-1].companion:=0.int; -- endcode loop j:INT:=i.upto!(i+n-1); [j]:=v.clone; end; end; CodeInCmp(i:INT) is CodeInCmp(#VERT(-1),i); end; CodeInCmp(i,n:INT) is CodeInCmp(#VERT(-1),i,n); end; CodeDelCmp(i:INT) is -- CodeDel with trimming companion if (i<k.size.int-1)and has_ind([i].companion) then [[i].companion].companion:=-1; end; [k.size-1].companion:=-1; -- endcode loop j::=i.upto!(k.size.int-2); [j]:=[j+1]; if has_ind([j].companion) then [[j].companion].companion:=j; end; end; k:=k.resize(k.size-1); [size-1].companion:=0.int; -- endcode end; compoDelCmp(stp:INT) is if ~ VERTEXC::ks.in([stp].sep) then return; end; enp::=endOfString(stp,1.int); loop [stp.up!]:=[(enp+1).upto!(length.int)]; end; k:=k.resize(k.size+stp.card-enp.card-1); loop i::=k.ind!; c::=[i].companion; if c<stp then elsif stp<=c and c<=enp then c:=-1; else c:=c-enp+stp-1; end; [i].companion:=c; end; loop i::=(k.size-1).downto!(0); if ~has_ind([i].companion) then CodeDelCmp(i.int); end; end; end; expCmp_n(pt:INT, s1,s2,s3:INT):INT is if pt<s1 then return pt; elsif pt<s2 then return pt+s3-s2; elsif pt<s3 then return pt+s1-s2; else return pt; end; end; exgCmp(s1,s2,s3:INT) pre (s1.is_non_neg)and(s1<=s2)and(s2<=s3)and(s3<=length.int) is -- Exchange blocks (s1..s2-1) and (s2..s3-1). -- Assume that 0<= s1 <= s2 <= s3 <= length if s1=s2 then return; end; CodeRev(s1,s2-1); CodeRev(s2,s3-1); CodeRev(s1,s3-1); loop i::=0.upto!(k.size-2); [i].companion:=expCmp_n([i].companion,s1,s2,s3); end; end; rotOvCmp(stp:INT):INT is -- return moved length -- move start points until -- the first crossing of the specified component -- is over cross enp,p1:INT; if ~VERTEXC::ks.in([stp].sep) then return 0; end; p1:=stp+1; enp:=[stp].companion; loop while!(VERTEXC::over.in([p1].sep) or VERTEXC::under.in([p1+1].sep)) ; p1:=p1+1; end; if VERTEXC::under.in([p1].sep) and VERTEXC::over.in([p1+1].sep) then exgCmp(stp+1,p1+1,enp); end; return p1-stp; end; rotateToOverCmp is -- Attach "rotOV" to each component. -- move start points until -- the first crossing of each component is overcross. tPtr,i:INT; tPtr:=0.int; loop i:=rotOvCmp(tPtr); tPtr:=[tPtr].companion+1.int; until!(VERTEXC::endc.in([tPtr].sep)); end; end; sCompoCmp(stp:INT) is --move sepcified component to the top of TCode --stp points a head of a component. move the component to the first if (~ VERTEXC::ks.in([stp].sep))or(stp.is_zero) then return; end; exgCmp(0.int, stp, [stp].companion+1); end; revKCmp_num(n,j0,j1:INT):INT is if n<j0 then return n; elsif n<=j1 then return j0+j1-n; else return n; end; end; revKCmp(i:INT) is -- ori. reverse the string j0, j1,j:INT; j0:=endOfString(i,-1)+1; j1:=endOfString(i,1.int)-1; if j0<j1 then CodeRev(j0,j1); loop i:=j0.upto!(j1); j:=revKCmp_num([i].companion,j0,j1); [j].companion:=i; if j0<=j and j<=j1 then else [i].sep:=[i].sep.xor(VERTEXC::cross_exs); [j].sep:=[j].sep.xor(VERTEXC::cross_exs); end; end; end; end; end; -- partial class KCODE_CMP{VERT}