set_tcode_alg.sa
Generated by gen_html_sa_files from ICSI. Contact gomes@icsi.berkeley.edu for details
class SET_TCODE_ALG
class SET_TCODE_ALG is
-- 2001/02 merge codes on knot and theta curve
-- 1989/8 Kouji Kodama
-- make TCODE for Theta curve.
-------------------set relator fron TCode----------------
shared stp,gen,compo,i:INT;
shared cod:VERTEXC;
shared TCode:TCODE;
shared Knot:KNOT;
SetTCode(knot:KNOT,out tcode:TCODE):BOOL is
Knot:=knot.clone;
TCode:=#;
if (setupK and SetTCode0 and SetTCodeC
and tgIdent_end and tgIdent_band and tgIdent_trivial and delG
and DelBandUCross ) then
tcode:=TCode;
TCode:=#; Knot:=#;
return tcode.check(true);
else tcode:=TCode; TCode:=#; Knot:=#; return false;
end;
end;
SetTCode_Theta(knot:KNOT,out tcode:TCODE):BOOL is
TCode:=#;
Knot:=knot.clone;
if (setupK_Theta and SetTCode0 and SetTCodeC
and SetTCodeC_Theta_vert
--and tgIdent_end
and tgIdent_band and tgIdent_trivial and delG
and DelBandUCross ) then
tcode:=TCode;
TCode:=#; Knot:=#;
return tcode.check(true);
else tcode:=TCode; TCode:=#; Knot:=#; return false;
end;
end;
------------------------set TCode from knot data ----------------------
setupK:BOOL is
-- change Knot near ts/te.
if void(Knot) or void(Knot.k) then return false; end;
if ~Knot.is_proper then return false; end;
if Knot.CrossSet then ; end;
loop i::=0.upto!(Knot.length-1);
cod:=Knot[i].sep;
if VERTEXC::ts.in(cod) then
Knot[i].x:=Knot[i+1].x; Knot[i].y:=Knot[i+1].y;
elsif VERTEXC::te.in(cod) then
Knot[i].x:=Knot[i-1].x; Knot[i].y:=Knot[i-1].y;
end;
end;
return true;
end;
setupK_Theta:BOOL is
-- separate theta graph to 3-strings.
if void(Knot) or void(Knot.k) then return false; end;
if ~Knot.is_proper then return false; end;
if Knot.CrossSet then ; end;
if ~Knot.is_theta then return false; end;
s1::=Knot.bandStart; s2::=Knot.endOfString(s1,1.int);
b1::=Knot.cmpOf(s1); b2::=Knot.cmpOf(s2);
Knot[b1].sep:=VERTEXC::normal;
Knot[b2].sep:=VERTEXC::normal;
k00::=0.int; k01::=Knot.endOfString(k00,1.int);
kn:KNOT:=#;
-- append 1st sring by forward b1..b2.
i:INT:=k00; kn.append(Knot[i].clone);
i:=b1;
loop
kn.append(Knot[i].clone);
if i=b2 then break!; elsif i=k01-1 then i:=k00+2; else i:=i+1; end;
end;
i:=k01;kn.append(Knot[i].clone);
-- append 2nd string by backward b1..b2.
i:=k00;kn.append(Knot[i].clone);
i:=b1;
loop
kn.append(Knot[i].clone);
if i=b2 then break!; elsif i=k00+1 then i:=k01-2; else i:=i-1; end;
end;
i:=k01;kn.append(Knot[i].clone);
-- append 3rd string from band.
i:=k00;kn.append(Knot[i].clone);
i:=s1+1;
loop
kn.append(Knot[i].clone);
if i=s2-1 then break!; else i:=i+1; end;
end;
i:=k01;kn.append(Knot[i].clone);
--
Knot:=kn;
return true;
end;
SetTCode0:BOOL is
tp:INT;
tp:=-1; compo:=0.int; gen:=0.int; stp:=0.int;
loop i:=0.upto!(Knot.length-1).int;
cod:=Knot[i].sep;
if (VERTEXC::normal /= cod) then
tp:=tp+1;
TCode.CodeIn(tp.card);
TCode[tp].sep:=cod;
TCode[tp].linkPtr:=i;
TCode[tp].companion:=0.int;
if VERTEXC::ks.in(cod) then
stp:=tp; compo:=compo+1; gen:=gen+1;
elsif VERTEXC::ke.in(cod) then
TCode[tp].companion:=stp; TCode[stp].companion:=tp;
elsif VERTEXC::ts.in(cod) then compo:=compo+1; gen:=gen+1;
end;
TCode[tp].gen:=gen;
TCode[tp].compo:=compo;
if VERTEXC::under.in(cod) then gen:=gen+1; end;
end;
end;
return true;
end;
SetTCodeCrossSgn(i1,i2,j1,j2:INT):BOOL is
-- set sign at the crossing
v1::=Knot[j1+1]-Knot[j1]; v2::=Knot[j2+1]-Knot[j2];
if (v1.outer(v2).is_neg) then
TCode[i1].sep:=TCode[i1].sep+VERTEXC::positive;
TCode[i2].sep:=TCode[i2].sep+VERTEXC::positive;
else
TCode[i1].sep:=TCode[i1].sep+VERTEXC::negative;
TCode[i2].sep:=TCode[i2].sep+VERTEXC::negative;
end;
return true;
end;
SetTCodeBandSgn(i1,i2,j1,j2:INT):BOOL is
-- set sign at the band-end
d:INT:=Knot.band_attach_sgn(j1);
if (d.is_pos) then
TCode[i1].sep:=TCode[i1].sep+VERTEXC::positive;
TCode[i2].sep:=TCode[i2].sep+VERTEXC::positive;
else
TCode[i1].sep:=TCode[i1].sep+VERTEXC::negative;
TCode[i2].sep:=TCode[i2].sep+VERTEXC::negative;
end;
return true;
end;
SetTCodeCmp(i1,inout i2, inout j1, inout j2:INT):BOOL is
j1:=TCode[i1].linkPtr; i2:=0.int;
loop
i2:=i2+1; j2:=TCode[i2].linkPtr;
if (TCode.size-1).int<=i2 then break!;
elsif ((i1/=i2) and Knot.Match2(j1,j2)) then break!;
end;
end;
TCode[i1].companion:=i2; TCode[i2].companion:=i1;
return true;
end;
SetTCodeC:BOOL is
-- set companion and sign at crossings and bands
i1,i2,j1,j2:INT;
loop i1:=0.upto!(TCode.size-1).int;
if VERTEXC::under.in(TCode[i1].sep) then
if ~(SetTCodeCmp(i1,inout i2, inout j1, inout j2)
and SetTCodeCrossSgn(i1,i2,j1,j2)) then
return false;
end;
elsif VERTEXC::band.in(TCode[i1].sep) then
if ~(SetTCodeCmp(i1,inout i2, inout j1, inout j2)
and SetTCodeBandSgn(i1,i2,j1,j2)) then
return false;
end;
end;
end;
return true;
end;
SetTCodeC_Theta_vert:BOOL is
-- sign of vertex rotation
t10::=TCode.compoStart(1.int); t11::=TCode.endOfString(t10.int,1.int);
k10::=Knot.compoStart(1.int); k11::=Knot.endOfString(k10.int,1.int);
k20::=Knot.compoStart(2.int); k21::=Knot.endOfString(k20.int,1.int);
k30::=Knot.compoStart(3.int); k31::=Knot.endOfString(k30.int,1.int);
rot:INT;
v1,v2,v3:VERTEXK;
v1:=Knot[k10+1]-Knot[k10];
v2:=Knot[k20+1]-Knot[k20];
v3:=Knot[k30+1]-Knot[k30];
rot:=v1.rotation(v2,v3);
if rot.is_pos then Knot[k10].sep:=Knot[k10].sep+VERTEXC::positive;
else Knot[k10].sep:=Knot[k10].sep+VERTEXC::negative;
end;
if rot.is_pos then TCode[t10].sep:=TCode[t10].sep+VERTEXC::positive;
else TCode[t10].sep:=TCode[t10].sep+VERTEXC::negative;
end;
v1:=Knot[k11-1]-Knot[k11];
v2:=Knot[k21-1]-Knot[k21];
v3:=Knot[k31-1]-Knot[k31];
rot:=v1.rotation(v2,v3);
if rot.is_pos then Knot[k11].sep:=Knot[k11].sep+VERTEXC::positive;
else Knot[k11].sep:=Knot[k11].sep+VERTEXC::negative;
end;
if rot.is_pos then TCode[t11].sep:=TCode[t11].sep+VERTEXC::positive;
else TCode[t11].sep:=TCode[t11].sep+VERTEXC::negative;
end;
return true;
end;
tgIdent1(inout g1,inout g2:INT) is
if g1>g2 then g3::=g1; g1:=g2; g2:=g3; end;
loop j::=0.upto!(TCode.length);
if TCode[j].gen=g2 then TCode[j].gen:=g1; end;
end;
end;
tgIdent_end:BOOL is
-- Gen trimming.
-- "identify gen at the beginning and ending of knot code\n".
-- Don't use for Theta curve
i,j,i1,i2,j1,j2,g1,g2,g3:INT;
i:=0;
loop
if (VERTEXC::endc.in(TCode[i].sep) or
VERTEXC::ts.in(TCode[i].sep) ) then break!; end;
g1:=TCode[i].gen;
i:=TCode[i].companion; g2:=TCode[i].gen;
tgIdent1(inout g1,inout g2);
i:=i+1;
end;
return true;
end;
tgIdent_band:BOOL is
-- Gen trimming.
-- adjust generator number on band
i,j,i1,i2,j1,j2,g1,g2,g3:INT;
if TCode.has_band then
-- #OUT+"tgIdent: band\n";
-- Saddle-bands induce identification of generators.
j1:=TCode.bandStart;
loop while!(VERTEXC::ts.in(TCode[j1].sep));
j2:=TCode.endOfString(j1,1.int);
i1:=TCode[j1].companion; -- start
i2:=TCode[j2].companion; -- end
-- #OUT+"Identify gemerator at the start of band.\n";
g1:=TCode[i1].gen; g2:=TCode[j1].gen;
tgIdent1(inout g1,inout g2);
-- If band is orientable,
-- then identify generator at the end of band.
if (VERTEXC::positive.in(TCode[i1].sep) =
VERTEXC::positive.in(TCode[i2].sep)) then
g1:=TCode[i2].gen; g2:=TCode[j2].gen;
tgIdent1(inout g1,inout g2);
end;
j1:=j2+1;
end;
-- Saddle-bands induce identification of components.
loop i:=0.upto!(TCode.length).int;
if VERTEXC::band.in(TCode[i].sep) then
g1:=TCode[i].compo; g2:=TCode[TCode[i].companion].compo;
if g1>g2 then g3:=g1; g1:=g2; g2:=g3; end;
loop j:=0.upto!(TCode.length).int;
if TCode[j].compo=g2 then TCode[j].compo:=g1; end;
end;
end;
end;
-- #OUT+"identify gen. at crossings under bands\n";
tst::=TCode.bandStart;
loop i:=0.upto!(TCode.length).int;
if (VERTEXC::under.in(TCode[i].sep)
and (tst<TCode[i].companion)) then
g1:=TCode[i].gen; g2:=TCode[i+1].gen;
tgIdent1(inout g1,inout g2);
end;
end;
end; -- on Bands
return true;
end;
tgIdent_trivial:BOOL is
-- Gen trimming.
-- identify generators along trivial relation: a b a~ a~ or a a a~ b~
i,j,i1,i2,j1,j2,g1,g2,g3:INT;
i:=0.int;
loop while!(i<TCode.length.int) ;
if VERTEXC::under.in(TCode[i].sep) then
g1:=TCode[i].gen; g2:=TCode[i+1].gen;
g3:=TCode[TCode[i].companion].gen;
if ((g1=g3) /= (g2=g3)) then
tgIdent1(inout g1,inout g2); i:=0.int;
end;
end;
i:=i+1;
end;
-- #OUT+"tgIdent:\n"; TCode.printD;
return true;
end;
delG:BOOL is
-- adjust generator number
i,g,l,gm,lm:INT;
flgG::=#ARRAY{BOOL}(TCode.size);
flgG.to_val(true);
gm:=0.int;
loop i:=0.upto!(TCode.length-1).int;
flgG[TCode[i].gen.card]:=false; gm:=gm.max(TCode[i].gen);
end;
g:=gm;
loop while!(g.is_pos);
if flgG[g.card] then
gm:=gm-1;
loop i:=0.upto!(TCode.length).int;
if TCode[i].gen>g then TCode[i].gen:=TCode[i].gen-1; end;
end;
end;
g:=g-1;
end;
TCode[TCode.length].gen:=gm;
flgG:=#(TCode.size);
flgG.to_val(true);
lm:=0.int;
loop i:=0.upto!(TCode.length-1).int ;
flgG[TCode[i].compo.card]:=false; lm:=lm.max(TCode[i].compo);
end;
l:=lm;
loop while!(l.is_pos);
if flgG[l.card] then
lm:=lm-1;
loop i:=0.upto!(TCode.length).int;
if TCode[i].compo>l then
TCode[i].compo:=TCode[i].compo-1;
end;
end;
end;
l:=l-1;
end;
TCode[TCode.length].compo:=lm;
return true;
end;
DelBandUCross:BOOL is
-- delete crossings under band
i,i1,j:INT;
if ~TCode.has_band then return true; end;
tst::=TCode.bandStart;
i:=0.int;
loop while!(i<TCode.length.int);
if (VERTEXC::under.in(TCode[i].sep)
and (tst < TCode[i].companion)) then
j:=TCode[i].companion;
if j<i then i1:=i; i:=j; j:=i1; end;
TCode.CodeDel(j.card);
loop i1:=0.upto!(TCode.length).int ;
if j<TCode[i1].companion then
TCode[i1].companion:=TCode[i1].companion-1;
end;
end;
if i<tst then tst:=tst-1; end;
TCode.CodeDel(i.card);
loop i1:=0.upto!(TCode.length).int ;
if i<TCode[i1].companion then
TCode[i1].companion:=TCode[i1].companion-1;
end;
end;
else i:=i+1;
end;
end;
return true;
end;
end;