braidcnv.sa
Generated by gen_html_sa_files from ICSI. Contact gomes@icsi.berkeley.edu for details
-- memo: dia -- braid --str
-- This code is "GPL"ed.
------------- braid ---------------
-- 1999/2 K.Kodama
-- use ArtinFormM.
-- 1998/7 K.Kodama
-- Module of primitive functions BraidPrim
--1998/4 K.Kodama
-- History
-- 1996/10 K.Kodama
--LINUX version
--
--1992/4 Kodama
--MS-DOS version
class BRAID_REDUCTION
class BRAID_REDUCTION is
-----------------word reduction------------------------------
reduction1(inout word:BRAID):BOOL is
-- true if R1-move
rFlg:BOOL;
si, wi, i:INT;
stTbl:ARRAY{INT}:=#(word.index+2);
posTbl:ARRAY{INT}:=#(word.index+2); -- position of the crossing
rFlg:=false; stTbl.to_val(0); posTbl.to_val(0); -- clear
loop wi:=word.w.ind!; -- count word
si:=word.w[wi].abs; stTbl[si]:=stTbl[si]+1; posTbl[si]:=wi;
end;
si:=1;
loop while!(si<=word.index);
if ((stTbl[si]=1)and
((stTbl[si-1]=0) or(stTbl[si+1]=0))) then
rFlg:=true; -- r1 move
loop i:=1.upto!(word.index);
if posTbl[si]<posTbl[i] then posTbl[i]:=posTbl[i]-1; end;
end;
loop wi:=word.w.ind!;
if word.w[wi].abs>si then
if word.w[wi]>0 then word.w[wi]:=word.w[wi]-1;
else word.w[wi]:=word.w[wi]+1;
end;
end;
end;
word.index:=word.index-1;
word.delete(posTbl[si]);
loop i:=si.upto!(word.index+1);
stTbl[i]:=stTbl[i+1];
posTbl[i]:=posTbl[i+1];
end;
if si>1 then si:=si-1; end;
else si:=si+1;
end;
end;
-- word.checkD;
return rFlg;
end;
reduction2(inout word:BRAID):BOOL is
-- true if R2-move
rFlg:BOOL;
wi, wi1, wi2, w1, w2, i:INT;
rFlg:=false;
wi:=0;
loop while!(wi<word.size);
wi1:=wi-1;
loop
if wi1<0 then wi1:=word.size-1; end;
if (word.w[wi1].abs-word.w[wi].abs).abs<=1 then break!; end;
wi1:=wi1-1;
end;
if (word.w[wi1]+word.w[wi]=0) then rFlg:=true; -- r2 move
if wi<wi1 then w1:=wi; w2:=wi1; else w1:=wi1; w2:=wi; end;
word.delete(w2); word.delete(w1); -- Note that w1<w2.
if wi1<wi then wi:=wi-1; end;
if word.size<=wi then wi:=0; end;
else
wi:=wi+1;
end;
end;
-- #OUT+"r2\n"; word.checkD;
return rFlg;
end;
wordReduction(inout word:BRAID):BOOL is
reply:BOOL;
word:=word.cancel;
if reduction1(inout word) then ; end;
word:=word.cancel;
if reduction2(inout word) then ; end;
reply:= ~(reduction1(inout word) or reduction2(inout word));
if ~ reply then
#OUT+"Error in reduction ?\n";
end;
return reply;
end;
end; -- class BRAID_REDUCTION
class ARTIN_FORM
class ARTIN_FORM is
-- This code is "GPL"ed.
--
--Artin's normal form for braid word.
--1998.7.2 K.Kodama
--
--c.f. Artin,E.
-- "Braid groups, generators and relations,solution of word problem"
-- Theorie der Zopfe, Abh.Math.Sem.Univ.Hamburg 4(1926),47-72
--c.f. Artin,E.
-- Theory of braids, Ann. of Math.(2)48(1947),101-126.
shared Aw,Dw:BRAID;
shared spos:BRAID; -- position of "i"-th string
shared j:INT;
shared p,p1:INT;
-- shared k0,g,gd:INT;
checkD(D:BRAID, j:INT):BOOL is
-- check j(=position of i-th string) in the word D.
pd,gd:INT;
loop pd:=D.w.ind!;
gd:=D[pd];
if j=gd.abs then j:=j+1;
elsif j=gd.abs+1 then j:=j-1;
else
BRAID_CNV::error:=1; return false;
end;
end;
return true;
end;
twistP(inout Di:BRAID,k0:INT) is
-- positive twist "k0" and "k0+1"th string
gd:INT;
Dw:BRAID:=#(Di.index);
-- #OUT+"k0,j,Di: "+k0.str+" "+j.str+" "+Di.str+"\n";
loop pd::=Di.w.ind!;
gd:=Di.w[pd];
if (gd=k0-1)and(j=k0-1) then Dw.append(-(k0-1));
elsif (gd=-(k0-1))and(j=k0-1) then
Dw.append(-(k0-1)); Dw.append(-k0); Dw.append(-k0);
elsif (gd=k0-1)and(j=k0) then
Dw.append(k0); Dw.append(k0); Dw.append(k0-1);
elsif (gd=-(k0-1))and(j=k0) then Dw.append(k0-1);
elsif (gd=k0)and(j=k0) then
Dw.append(k0-1); Dw.append(k0-1); Dw.append(k0);
elsif (gd=-(k0))and(j=k0) then Dw.append(k0);
elsif (gd=k0)and(j=k0+1) then Dw.append(-k0);
elsif (gd=-k0)and(j=k0+1) then
Dw.append(-k0); Dw.append(-(k0-1)); Dw.append(-(k0-1));
else Dw.append(gd);
end;
if j=gd.abs then j:=j+1; elsif j=gd.abs+1 then j:=j-1; else
raise "twistP bad crossing code "+pd.str+"\n";
end;
end;
Di:=Dw.cancel;
end;
twistN(inout Di:BRAID,k0:INT) is
-- negative twist "k0" and "k0+1"th string
gd:INT;
Dw:BRAID:=#(Di.index);
loop pd::=Di.w.ind!;
gd:=Di[pd];
if (gd=k0-1)and(j=k0-1) then
Dw.append(k0-1);Dw.append(k0); Dw.append(k0)
elsif (gd=-(k0-1))and(j=k0-1) then Dw.append(k0-1);
elsif (gd=k0-1)and(j=k0) then Dw.append(-(k0-1));
elsif (gd=-(k0-1))and(j=k0) then
Dw.append(-k0); Dw.append(-k0); Dw.append(-(k0-1));
elsif (gd=k0)and(j=k0) then Dw.append(-k0);
elsif (gd=-(k0))and(j=k0) then
Dw.append(-(k0-1)); Dw.append(-(k0-1)); Dw.append(-k0);
elsif (gd=k0)and(j=k0+1) then
Dw.append(k0); Dw.append(k0-1); Dw.append(k0-1);
elsif (gd=-k0)and(j=k0+1) then Dw.append(k0);
else Dw.append(gd);
end;
if j=gd.abs then j:=j+1; elsif j=gd.abs+1 then j:=j-1;
else
raise "twistN bad crossing code "+pd.str+"\n";
end;
end;
Di:=Dw.cancel;
end;
CnvReducedNormalForm(i:INT, inout Ai:BRAID, inout Di:BRAID) is
Ai:=Ai.cancel;
g,k0:INT;
-- set spos[]. spos[*] track the i-th string.
spos:BRAID:=#;
j:=i;
loop p::=Ai.w.ind!;
spos.append(j);
if Ai[p].abs=j then j:=j+1; elsif Ai[p].abs=j-1 then j:=j-1; end;
end;
spos.append(j); spos.append(0);
if i/=j then #OUT+"not pure braid.\n"; end;
-- #OUT+"i,Ai,spos:"+i.str+" "+Ai.str+" "+spos.str+"\n";
Aw:=#(Ai.index); Di:=#(Ai.index);
loop pa::=(Ai.size-1).downto!(0);
-- #OUT+"2-loop";
-- Ai[pa+1]:=0; WrWord(Ai); WrWord(Di); WrWord(Aw);
j:=spos[pa]; g:=Ai[pa];
if g.abs=j then Di:=Di.insert(0,g);
elsif g.abs+1=j then Di:=Di.insert(0,g);
else
if j>g.abs then k0:=g.abs+1; else k0:=g.abs; end;
if g>0 then Aw:=Aw.insert(0,k0);
else Aw:=Aw.insert(0,-k0);
end;
if g>0 then twistP(inout Di,k0); else twistN(inout Di,k0); end;
end;
if BRAID_CNV::error/=0 then return; end;
end;
Aw:=Aw.cancel; Ai:=Aw.clone; Di:=Di.cancel;
if ~ checkD(Di,i) then
raise "CnvReducedNormalForm: twist. bad crossing code.\n";
end;
end;
cnvRA2A(i:INT, inout di:BRAID) is
-- Convert from "Reduced Normal" form to "Normal" form.
j:INT;
w:BRAID:=#(di.index);
di:=di.cancel; j:=i;
loop p::=di.w.ind!;
if -di[p]=j then w:=w.append(i).append(j+1);
elsif di[p]=j-1 then w:=w.append(i).append(-j);
end;
if di[p].abs=j then j:=j+1; else j:=j-1; end;
end;
di:=w;
end;
private PureArtinNormalForm(inout word:BRAID, reduce:BOOL):BOOL is
if ~ word.is_PureBraid then
#OUT+"Not a pure braid.\n"; return false;
end;
BRAID_CNV::error:=0;
D:BRAID:=#(word.index);
Di:BRAID:=#(word.index);
Ai:BRAID:=word.clone;
loop i::=1.upto!(word.index-1) ;
CnvReducedNormalForm(i,inout Ai,inout Di);
if ~ reduce then cnvRA2A(i,inout Di); end;
D:=D*Di;
if BRAID_CNV::error/=0 then return false; end;
end;
if BRAID_CNV::error=0 then word:=D; end;
return BRAID_CNV::error=0;
end;
GArtinNormalForm(inout word:BRAID, reduce:BOOL):BOOL is
-- Generalized Normal form.
-- For pure braid w, wE,
-- A be Normal form of wE, A E~ is Gen. A. form.
i1:INT;
w0:BRAID:=word.clone;
E:BRAID:=#(word.index);
cw1:BRAID:=#(word.index);
loop i::=word.index.downto!(1);
i1:=word.trackString(i);
if i/=i1 then
cw1:=#(word.index);
loop cw::=i1.upto!(i-1); cw1.append(-cw); end;
word:=word*cw1; E:=E*cw1;
end;
end;
Aw:=#(word.index); Dw:=#(word.index);
if PureArtinNormalForm(inout word,reduce) then ; end;
Aw:=#; Dw:=#;
word:=word/E;
if BRAID_CNV::error/=0 then word:=w0; end;
return BRAID_CNV::error=0;
end;
end; -- class ARTIN_FORM
-- Knot diagram --> braid word
-- braid word --> knot diagram
-- FROM BraidPrim IMPORT error, length,Word2Str,Str2Word, AppendWord,
-- BRAIDmaxLen,BRAIDmaxIndex,BRAIDmaxSLen,
-- braidWord,braidWordStr,wordCancel;
-- FROM ArtinFormM IMPORT GArtinNormalForm;
class BRAID2KNOT
class BRAID2KNOT is
-- word[] --> Knot[]
shared height, width:INT;
shared d, ds, dx, dy, dxc, dyc:INT; -- frame of crossings
shared xl, xr:INT; -- x: left-right
shared yu, yl:INT; -- y: upper-lower
shared x0, y0 :INT; -- origin for crossings
shared indTbl:ARRAY{INT}; -- array[0..BRAIDmaxIndex+1]
shared posTbl:ARRAY{INT}; -- position of the crossing
shared compo:INT; -- component
addCompo(word:BRAID, si:INT, inout Knot:KNOT) is
ki, si0:INT;
wi:INT; -- word
pos:INT; -- position of the crossing
x, y:INT;
-- si:current string.
-- ki:position in knot.
-- wi:position in word.
-- #OUT+"addCompo: word="+word.str+" si="+si.str+"\n";
compo:=compo+1;
ki:=Knot.bandStart;
Knot.CodeIn(VERTEXC::knot_s, ki); ki:=ki+1;
Knot.CodeIn(VERTEXC::knot_e, ki);
loop
-- x:=xl-d*(si-1); y:=yu+dy*(si-1);
x:=xl+d*(si-1); y:=yl+dy*(si-1);
Knot.CodeIn(x, y, ki); ki:=ki+1;
if indTbl[si]/=0 then break!; else indTbl[si]:=compo; end;
wi:=-1; pos:=-2; si0:=-2;
loop
wi:=wi+1;
-- #OUT+"compo="+compo.str+" wi="+wi.str+"\n"; Knot.checkKnotD;
if wi>=word.size then
-- #OUT+"wi="+wi.str+" word.size="+word.size.str+"\n";
break!;
elsif (word.w[wi].abs=si) then -- set crossing
-- #OUT+"addCompo: set crossing1\n";
x:=x0+dx*(posTbl[wi]); y:=y0+dy*(si-1);
if posTbl[wi]>(pos+1) then Knot.CodeIn(x, y, ki); ki:=ki+1;
elsif (si0=(si-1)) then ki:=ki-1; Knot.CodeDel(ki);
end;
Knot.CodeIn(x+dxc, y+dyc, ki);
if word.w[wi]>0 then Knot[ki].sep:=VERTEXC::cross_under;
else Knot[ki].sep:=VERTEXC::cross_over;
end;
ki:=ki+1;
Knot.CodeIn(x+dx, y+dy, ki); ki:=ki+1;
si0:=si; si:=si+1; pos:=posTbl[wi];
elsif (word.w[wi].abs+1)=si then -- set crossing
-- #OUT+"addCompo: set crossing2\n";
x:=x0+dx*(posTbl[wi]); y:=y0+dy*(si-2);
if posTbl[wi]>(pos+1) then
Knot.CodeIn(x, y+dy, ki); ki:=ki+1;
elsif (si0=(si+1)) then ki:=ki-1; Knot.CodeDel(ki);
end;
Knot.CodeIn(x+dxc, y+dyc, ki);
if word.w[wi]>0 then Knot[ki].sep:=VERTEXC::cross_over;
else Knot[ki].sep:=VERTEXC::cross_under;
end;
ki:=ki+1;
Knot.CodeIn(x+dx, y, ki); ki:=ki+1;
si0:=si; si:=si-1; pos:=posTbl[wi];
else
end;
if (si<1)or(word.index<si) then
raise "BRAID2KNOT::addCompo: Error in add crossings.\n";
end;
end;
-- x:=xr+d*(si-1); y:=yu+dy*(si-1); PointIn(x, y, ki); INC(ki);
-- y:=yl-d*(si-1); PointIn(x, y, ki); INC(ki);
-- x:=xl-d*(si-1); PointIn(x, y, ki); INC(ki);
x:=xr-d*(si-1); y:=yl+dy*(si-1); Knot.CodeIn(x, y, ki); ki:=ki+1;
y:=yu-d*(si-1); Knot.CodeIn(x, y, ki); ki:=ki+1;
x:=xl+d*(si-1); Knot.CodeIn(x, y, ki); ki:=ki+1;
end;
end;
setw(word:BRAID) is
-- set width and origin of braiding
-- d:max interval for closing string.
-- ds:max width of crossing. must be even.
-- dx, dy: width of crossing. (even)
w, h, maxPos, wi:INT;
maxPos:=0;
loop wi:=0.upto!(word.size-1);
if maxPos<posTbl[wi] then maxPos:=posTbl[wi]; end;
end;
dx:=(width-2*d*(word.index+1))/(maxPos+1);
dy:=(height-ds-d*word.index-d)/word.index;
if dx>ds then dx:=ds; end; if dy>ds then dy:=ds; end;
dxc:=dx/2; dyc:=dy/2;
-- xl:=d*index; xr:=xl+d+dx*(maxPos+1)+d; x0:=xl+d;
-- yl:=-(height-d*index); yu:=yl+ds; y0:=yu;
--
-- w,h is width/height of closed braid diagram
w:=d*2*word.index+dx*(maxPos+1); h:=(d+dy)*(word.index-1)+ds;
-- xl/xr = left/right, yu/yl= upper/lower of closed braid diagram
-- (x0,y0)=left lower of braiding
xl:=(width-w)/2; if xl<30 then xl:=30; end;
xr:= xl+w; x0:=xl+d*word.index;
yu:=-(height-h)/2; if yu>-30 then yu:=-30; end;
yl:=yu-h; y0:=yl;
end;
Braid2Knot(word:BRAID, inout Knot:KNOT):BOOL is
-- #OUT+"Braid2Knot:1 word="+word.str+"\n";
-- word --> Knot[]
if word.index=0 then Knot:=#; return true; end;
si:INT; -- string number
wi, wi1:INT;
pos:INT;
loop wi:=word.w.ind!;
if word[wi].abs>=word.index then Knot:=#; return true; end;
end;
indTbl:=#; posTbl:=#;
-- reduce the word
if BRAID_CNV::packBraid
and BRAID_REDUCTION::wordReduction(inout word) then --nothing
end;
-- #OUT+"Braid2Knot:2 word="+word.str+"\n";
-- set position of crossings
posTbl:=#(word.size); loop wi:=posTbl.ind!; posTbl[wi]:=wi; end;
if BRAID_CNV::packBraid then
loop wi:=word.w.ind!;
wi1:=wi-1; pos:=-1;
loop wi1:=0.upto!(wi-1) ;
if ( ((word[wi1].abs-word[wi].abs).abs<=1)
and (pos<posTbl[wi1])) then pos:=posTbl[wi1];
end;
end;
posTbl[wi]:=pos+1;
end;
end;
-- set width
-- d ds,dx,dy
d:=2; ds:=16;
height:=(ds+(word.index+1)*(d+ds)).max(KNOTXW::GraphHeight-20);
width:=(word.size*ds+(word.index+1)*d*2).max(KNOTXW::GraphWidth-20);
d:=12; ds:=32;
setw(word);
if (dy<ds)or(dx<ds) then d:=8; ds:=24; setw(word); end;
if (dy<ds)or(dx<ds) then d:=4; ds:=16; setw(word); end;
if (dy<ds)or(dx<ds) then d:=2; ds:=16; setw(word); end;
-- set components
indTbl:=#(word.index+1); -- [0..word.index]
loop si:=indTbl.ind! ; indTbl[si]:=0; end;
Knot:=#; compo:=0;
loop
si:=0;
loop si:=si+1; until!( (si>word.index) or (indTbl[si]=0)); end;
if si>word.index then break!; end;
addCompo(word,si,inout Knot);
end;
Knot.shiftToInside;
indTbl:=#; posTbl:=#;
return true;
end;
end; -- class BRAID2KNOT
class BRAIDTC2BRAID
class BRAIDTC2BRAID is
------------- TCode[] --> word[] -----------
shared cTbl:ARRAY{INT};
shared tp, tp1, tp0, str, str1, sBase:INT;
chk_cTbl(TCode:TCODE) is
i:INT;
cod:VERTEXC;
#OUT+"ct:";
loop i:=TCode.k.ind!; #OUT+cTbl[i].str; end;
#OUT+"TC:";
loop i:=TCode.k.ind!; #OUT+TCode[i].companion; end;
#OUT+"cd:";
loop i:=TCode.k.ind!;
cod:=TCode[i].sep;
if VERTEXC::crossing.in(cod) then #OUT+" ";
if VERTEXC::over.in(cod) then #OUT+"o"; end;
if VERTEXC::under.in(cod) then #OUT+"u"; end;
if VERTEXC::positive.in(cod) then #OUT+"+"; end;
if VERTEXC::negative.in(cod) then #OUT+"-"; end;
else #OUT+" ";
end;
end;
end;
nextW(word:BRAID,inout wi:INT) is
loop while!((wi<word.size-1)and(word.w[wi].abs<(str-1))) ;
wi:=wi+1;
end;
if (wi<word.size) then wi:=wi+1; end;
-- The condition is the same as: (str>1)and(ABS(word[wi])=(str-1))
end;
TCode2Braid(TCode:TCODE, out word:BRAID):BOOL is
wi:INT;
cTbl:=#(TCode.size);
loop tp:=cTbl.ind!; cTbl[tp]:=0; end;
word:=#; word.index:=0;
loop
tp:=0;
loop while!( (tp<TCode.length)and(0<cTbl[tp])); tp:=tp+1; end;
if tp>=TCode.length then break!; end;
word.index:=word.index+1; sBase:=word.index; str:=sBase;
loop
loop while!(cTbl[tp]<=0) ; -- Seifert circle
cTbl[tp]:=str;
if VERTEXC::crossing.in(TCode[tp].sep) then
tp:=TCode[tp].companion+1;
elsif VERTEXC::ks.in(TCode[tp].sep) then tp:=tp+1;
elsif VERTEXC::ke.in(TCode[tp].sep) then
tp:=TCode[tp].companion;
end;
end;
-- next circle
tp:=0;
loop
tp:=tp+1; tp1:=tp+1;
if VERTEXC::separator.in(TCode[tp1].sep) then
tp1:=TCode[tp1].companion+1;
end;
str:=cTbl[tp1];
until!( (TCode.length)<=(tp+1)or
((cTbl[tp]<=0)and
(VERTEXC::crossing.in(TCode[tp].sep))and
(str>0)) );
end;
if TCode.length<=(tp+1) then break!; end;
if (VERTEXC::over.in(TCode[tp].sep)
=VERTEXC::positive.in(TCode[tp].sep)) then str:=str+1;
else str:=str-1;
end;
if word.index<str then word.index:=word.index+1;
elsif str<sBase then word.index:=word.index+1; str:=str+1;
loop tp1:=TCode.k.ind! ;
if sBase<=cTbl[tp1] then cTbl[tp1]:=cTbl[tp1]+1; end;
end;
else cTbl:=#; return false;
end;
end;
-- chkCt;
loop str:=sBase.upto!(word.index-1) ; -- for each Seifert circle
tp0:=0; loop while!(cTbl[tp0]/=sBase) ; tp0:=tp0+1; end;
loop while!(cTbl[tp0]<str) ;
if VERTEXC::crossing.in(TCode[tp0].sep) then
if cTbl[tp0+1]<cTbl[tp0] then
tp0:=TCode[tp0].companion+1;
else tp0:=tp0+1;
end;
elsif VERTEXC::ke.in(TCode[tp0].sep) then
tp0:=TCode[tp0].companion;
elsif VERTEXC::ks.in(TCode[tp0].sep) then tp0:=tp0+1;
end;
end;
tp:=tp0; wi:=0; nextW(word,inout wi);
loop
if VERTEXC::crossing.in(TCode[tp].sep) then
if cTbl[tp+1]<str then nextW(word,inout wi);
else if VERTEXC::under.in(TCode[tp].sep) then
word.insert(wi,str); wi:=wi+1;
else word.insert(wi,-str); wi:=wi+1;
end;
end;
tp:=TCode[tp].companion+1;
elsif VERTEXC::ke.in(TCode[tp].sep) then
tp:=TCode[tp].companion;
elsif VERTEXC::ks.in(TCode[tp].sep) then tp:=tp+1;
end;
until!(tp=tp0); -- around the Seifert circle
end;
end;
-- #OUT+"TCode2Word\n"; chkW;
end;
cTbl:=#;
return true;
end;
end; -- class BRAIDTC2BRAID
class KNOT2BRAIDTC
class KNOT2BRAIDTC is
shared cTbl:ARRAY{INT}; -- [0..BRAIDmaxT]
shared index:INT;
SeifertCircuit(TCode:TCODE) is
tp:INT;
cTbl:=#(TCode.size);
cTbl.to_val(0);
index:=0;
loop
tp:=0;
loop while!( (tp<TCode.length)and(0<cTbl[tp]) );tp:=tp+1; end;
if tp>=TCode.length then break!; end;
index:=index+1;
loop while!( cTbl[tp]<=0 ); -- Seifert circle
cTbl[tp]:=index;
if VERTEXC::crossing.in(TCode[tp].sep) then
tp:=TCode[tp].companion+1;
elsif VERTEXC::ks.in(TCode[tp].sep) then tp:=tp+1;
elsif VERTEXC::ke.in(TCode[tp].sep) then
tp:=TCode[tp].companion;
end;
end;
end;
end;
const right:BOOL:=true;
const left:BOOL:=false;
InCode(inout TCode:TCODE,tp:INT):BOOL is
cTbl:=cTbl.resize(cTbl.size+1);
loop i::=(cTbl.size-2).downto!(tp);
cTbl[i+1]:=cTbl[i];
end;
TCode.CodeInCmp(tp);
return true;
end;
sideC(TCode:TCODE,side:BOOL,tp:INT):BOOL is
cod:VERTEXC:=TCode[tp].sep;
return ( VERTEXC::crossing.in(cod)
and (side=(
(VERTEXC::cross_po=cod) or (VERTEXC::cross_nu=cod)
)
)
);
end;
nextTp(TCode:TCODE, inout tp:INT) is
tcn:INT;
cod:VERTEXC;
tcn:=TCode[tp].companion; cod:=TCode[tp].sep;
if VERTEXC::crossing.in(cod) then tp:=tcn+1;
elsif VERTEXC::ke.in(cod) then tp:=tcn;
elsif VERTEXC::ks.in(cod) then tp:=tp+1;
end;
end;
nextC(TCode:TCODE, side:BOOL, inout tp, inout str:INT) is
tps:INT:=tp;
loop
if sideC(TCode,side,tp) then break!; end;
nextTp(TCode,inout tp);
if tps=tp then break!; end;
end;
if sideC(TCode,side,tp) then str:=cTbl[tp+1]; else str:=-1; end;
end;
Unify(inout TCode:TCODE, side:BOOL):BOOL is
uFlg:BOOL;
tp0, tp1, tp2, str, str0, str1, str2, i:INT;
cop::=VERTEXC::cross_po;
cup::=VERTEXC::cross_pu;
com::=VERTEXC::cross_no;
cum::=VERTEXC::cross_nu;
str:=1;
loop while!(str<=index) ;
-- #OUT+"Unify:2 inde:="+index.str+" str="+str.str+"\n";
tp0:=-1; loop tp0:=tp0+1; until!(cTbl[tp0]=str); end;
nextC(TCode,side, inout tp0, inout str0);
uFlg:=false;
if str0>0 then
str1:=str0; tp1:=tp0;
loop
-- #OUT+"Unify:3\n";
-- #OUT+"TCode\n"; TCode.checkD;
tp2:=tp1;
loop
tp1:=tp2; nextTp(TCode,inout tp2);
nextC(TCode,side, inout tp2, inout str2);
until!( (tp2=tp0)or(str1/=str2));
end;
if tp2=tp0 then break!; end;
-- out('tp5: tp1,tp2, s1,s2:');
-- WriteInt(tp1,4); WriteInt(tp2,4);
-- WriteInt(str1,4); WriteInt(str2,4);
-- chkCt;
uFlg:=true; tp2:=TCode[tp2].companion;
if ~ (InCode(inout TCode,tp1+1)
and InCode(inout TCode,tp1+1)) then
return false;
end;
if tp1<tp2 then tp2:=tp2+2; end;
if tp1<tp0 then tp0:=tp0+2; end;
if ~(InCode(inout TCode,tp2)
and InCode(inout TCode,tp2)) then return false; end;
if tp2<tp1 then tp1:=tp1+2; end;
if tp2<tp0 then tp0:=tp0+2; end;
tp2:=tp2+2;
if side=right then
TCode[tp1+1].sep:=cop;
TCode[tp1+2].sep:=com;
TCode[tp2-1].sep:=cup;
TCode[tp2-2].sep:=cum;
else
TCode[tp1+1].sep:=com;
TCode[tp1+2].sep:=cop;
TCode[tp2-1].sep:=cum;
TCode[tp2-2].sep:=cup;
end;
TCode[tp1+1].companion:=tp2-1;
TCode[tp1+2].companion:=tp2-2;
TCode[tp2-1].companion:=tp1+1;
TCode[tp2-2].companion:=tp1+2;
loop i:=TCode.k.ind! ;
if cTbl[i]=str2 then cTbl[i]:=str1; end;
end;
cTbl[tp1+1]:=str1;
cTbl[tp1+2]:=str2;
cTbl[tp2-2]:=str1;
cTbl[tp2-1]:=str2;
end;
end;
if uFlg then str:=1; else str:=str+1; end;
end;
return true;
end;
Knot2BraidTC(Knot:KNOT,out TCode:TCODE):BOOL is
-- #OUT+"Knot2BraidTC:\n";
if ~Knot.is_proper then return false; end;
if Knot.has_band then
#OUT+"Band is not supported.\n"; return false;
end;
if Knot.CrossSet then ; end;
TCode:=#;
if ~ Knot.SetTCode(out TCode) then return false; end;
cTbl:=#;
SeifertCircuit(TCode);
reply:BOOL:=Unify(inout TCode,right) and Unify(inout TCode,left);
cTbl:=#;
return reply;
end;
end; -- class KNOT2BRAIDTC
class BRAID_CNV
class BRAID_CNV is
shared error:INT;
shared packBraid:BOOL:=true;
Knot2BraidWord(Knot:KNOT,out str:STR):BOOL is
-- #OUT+"Knot2BraidWord:\n";
TCode:TCODE:=#;
reply:BOOL:=Knot.CrossSet;
reply:=reply and KNOT2BRAIDTC::Knot2BraidTC(Knot,out TCode);
-- #OUT+"Knot2BraidWord:\n"; TCode.checkD;
Word:BRAID:=#;
reply:=reply and BRAIDTC2BRAID::TCode2Braid(TCode,out Word);
str:="";
if ~ reply then Word:=#; end;
str:=Word.str;
return reply;
end;
BraidWord2Knot(str:STR, inout Knot:KNOT):BOOL is
HISTORY::put(Knot);
-- #OUT+"BraidWord2Knot: str="+str+"\n";
Word:BRAID:=#(str);
reply:BOOL:= BRAID2KNOT::Braid2Knot(Word,inout Knot);
if ~ reply then HISTORY::back(inout Knot); end;
return reply;
end;
BraidWordA2Knot(str:STR, inout Knot:KNOT, reduce:BOOL):BOOL is
reply:BOOL:=true;
Word:BRAID:=#(str);
word:BRAID:=Word.clone;
HISTORY::put(Knot);
BRAID_CNV::error:=0;
reply:=reply and (BRAID_CNV::error=0)
and ARTIN_FORM::GArtinNormalForm(inout word,reduce);
Word:=word.clone;
tmpSw:BOOL:=packBraid;
packBraid:=false; -- Don't pack the word.
reply:=reply and(BRAID_CNV::error=0) and
BRAID2KNOT::Braid2Knot(Word,inout Knot) and (BRAID_CNV::error=0);
packBraid:=tmpSw;
if ~ reply then HISTORY::back(inout Knot); end;
return reply;
end;
BraidWord2ArtinNormalFormS(inout str:STR, reduce:BOOL):BOOL is
reply:BOOL:=true;
str0:STR:=""+str;
word:BRAID:=#(str);
BRAID_CNV::error:=0;
--reply:=Str2Word(str, out word)and(BRAID_CNV::error=0);
reply:=reply and ARTIN_FORM::GArtinNormalForm(inout word,reduce)
and(BRAID_CNV::error=0);
str:=word.str;
--reply:=reply and Word2Str(word,out str) and (BRAID_CNV::error=0);
if ~ reply then str:=str0;
#OUT+"Fail to convert the word.\n";
end;
return reply;
end;
BraidWord2ArtinNormalForm(inout str:STR):BOOL is
reply:BOOL;
reply:= BraidWord2ArtinNormalFormS(inout str,false);
return reply;
end;
BraidWord2RArtinNormalForm(inout str:STR):BOOL is
reply:BOOL;
reply:= BraidWord2ArtinNormalFormS(inout str,true);
return reply;
end;
BraidWord2RBraidWord(inout str:STR):BOOL is
str0:STR:=""+str;
reply:BOOL:=true;
word:BRAID:=#(str);
BRAID_CNV::error:=0;
-- reply:=Str2Word(str,out word) and(BRAID_CNV::error=0);
reply:=reply and BRAID_REDUCTION::wordReduction(inout word)
and(BRAID_CNV::error=0);
str:=word.str;
--reply:=reply and Word2Str(word,out str) and (BRAID_CNV::error=0);
if ~ reply then str:=str0;
#OUT+"Fail to convert the word.\n";
end;
return reply;
end;
SetBraid(inout Knot:KNOT) is
wordStr:STR:="";
if Knot2BraidWord(Knot,out wordStr)
and BraidWord2Knot(wordStr,inout Knot) then
end;
end;
SetBraidArtinNormalForm(inout Knot:KNOT) is
wordStr:STR:="";
if Knot2BraidWord(Knot, out wordStr)
and BraidWordA2Knot(wordStr,inout Knot,false) then; end;
end;
SetBraidRArtinNormalForm(inout Knot:KNOT) is
wordStr:STR:="";
if Knot2BraidWord(Knot,out wordStr)
and BraidWordA2Knot(wordStr,inout Knot,true) then; end;
end;
end; -- class BRAID_CNV