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




-- Knot diagram --> braid word
-- braid word --> knot diagram


class BRAID2KNOT

class BRAID2KNOT is -- word[] --> Knot[] shared height, width:INT; shared d, ds:INT; -- frame of crossings shared v0,vlu,vll,vru,vrl:VERTEXK; shared dx,dy,dxy,vc:VERTEXK; shared dlu,dll,dru,drl: VERTEXK; setString(inout Knot:KNOT,tbl:BRAID_TABLE) is v1,v2:VERTEXK; Knot:=#; ch:CARD:=tbl.index; cw:CARD:=tbl.length; if cw=0 then -- trivial braid v1:=v0; loop j::=1.upto!(ch); ki::=Knot.bandStart.card; Knot.CodeIn(VERTEXC::knot_s, ki); ki:=ki+1; Knot.CodeIn(v1,ki); ki:=ki+1; Knot.CodeIn(v1+dx,ki); ki:=ki+1; Knot.CodeIn(VERTEXC::knot_e, ki); ki:=ki+1; v1:=v1+dy; end; return; end; -- Assume that cw>0. v1:=v0; loop i::=0.upto!(cw-1); v2:=v1; loop j::=1.upto!(ch); ki::=Knot.bandStart.card; Knot.CodeIn(VERTEXC::knot_s, ki); ki:=ki+1; Knot.CodeIn(v2,ki); ki:=ki+1; if j>1 and tbl.crossTbl[i][j-1]=1.int then Knot.CodeIn(v2-dy+vc,ki); Knot[ki].sep:=VERTEXC::cross_over; ki:=ki+1; Knot.CodeIn(v2-dy+dx,ki); ki:=ki+1; elsif j>1 and tbl.crossTbl[i][j-1]=-1 then Knot.CodeIn(v2-dy+vc,ki); Knot[ki].sep:=VERTEXC::cross_under; ki:=ki+1; Knot.CodeIn(v2-dy+dx,ki); ki:=ki+1; elsif j<ch and tbl.crossTbl[i][j]=1.int then Knot.CodeIn(v2+vc,ki); Knot[ki].sep:=VERTEXC::cross_under; ki:=ki+1; Knot.CodeIn(v2+dxy,ki); ki:=ki+1; elsif j<ch and tbl.crossTbl[i][j]=-1 then Knot.CodeIn(v2+vc,ki); Knot[ki].sep:=VERTEXC::cross_over; ki:=ki+1; Knot.CodeIn(v2+dxy,ki); ki:=ki+1; else Knot.CodeIn(v2+dx,ki); ki:=ki+1; end; Knot.CodeIn(VERTEXC::knot_e, ki); ki:=ki+1; v2:=v2+dy; end; v1:=v1+dx; end; end; setClosing(inout Knot:KNOT,cw,ch:CARD,close:BOOL) is v1,v2,v3,v4,v5,v6: VERTEXK; if cw=0 then cw:=1; end; ki:CARD; if close then ---- closed braid v4:=vlu; v3:=vru; v5:=vll; v6:=v0; v1:=vrl.minus(d*ch,0.int); v2:=vrl; ki:=0; loop i::=1.upto!(ch); Knot.CodeIn(VERTEXC::knot_s, ki); ki:=ki+1; Knot.CodeIn(v5,ki); ki:=ki+1; v5:=v5+dll; Knot.CodeIn(v6,ki); ki:=ki+1; v6:=v6+dy; Knot.CodeIn(VERTEXC::knot_e, ki); ki:=ki+1; end; v4:=vlu; v3:=vru; v5:=vll; v6:=v0; v1:=vrl.minus(d*ch,0.int); v2:=vrl; ki:=Knot.bandStart.card; loop i::=1.upto!(ch); Knot.CodeIn(VERTEXC::knot_s, ki); ki:=ki+1; Knot.CodeIn(v1,ki); ki:=ki+1; v1:=v1+dy; Knot.CodeIn(v2,ki); ki:=ki+1; v2:=v2+drl; Knot.CodeIn(v3,ki); ki:=ki+1; v3:=v3+dru; Knot.CodeIn(v4,ki); ki:=ki+1; v4:=v4+dlu; Knot.CodeIn(v5,ki); ki:=ki+1; v5:=v5+dll; Knot.CodeIn(VERTEXC::knot_e, ki); ki:=ki+1; end; else v1:=v0-dx; v2:=v0; --left side ki:=0; loop i::=1.upto!(ch); Knot.CodeIn(VERTEXC::knot_s, ki); ki:=ki+1; Knot.CodeIn(v1,ki); ki:=ki+1; Knot.CodeIn(v2,ki); ki:=ki+1; Knot.CodeIn(VERTEXC::knot_e, ki); ki:=ki+1; v1:=v1+dy; v2:=v2+dy; end; v1:=v0+dx*cw.max(1); v2:=v1+dx; -- right side loop i::=1.upto!(ch); Knot.CodeIn(VERTEXC::knot_s, ki); ki:=ki+1; Knot.CodeIn(v1,ki); ki:=ki+1; Knot.CodeIn(v2,ki); ki:=ki+1; Knot.CodeIn(VERTEXC::knot_e, ki); ki:=ki+1; v1:=v1+dy; v2:=v2+dy; end; return; end; end; setw(cw,ch:CARD) pre ch>1 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) if cw=0 then cw:=1; end; w, h:INT; -- width/hight of crossings dx:=#((width-2.int*d*ch.int)/cw.int,0.int); dy:=#(0.int,(height-ds-d*(ch.int-1))/(ch.int-1)); if dx.x>ds then dx.x:=ds; end; if dy.y>ds then dy.y:=ds; end; dxy:=dx+dy; vc:=dxy/2.int; -- w,h is width/height of closed braid diagram w:=d*2.int*ch.int+dx.x*cw.int; h:=(d+dy.y)*(ch.int-1)+ds; -- left/right, upper/lower width of closing strings dlu:=#(d,-d); dru:=#(-d,-d); dll:=dy.plus(d,0.int); drl:=dy.plus(-d,0.int); -- left/right, upper/lower corner of diagram vlu:=#(0.int,0.int); vru:=vlu.plus(w,0.int); vll:=vlu.plus(0.int,-h); vrl:=vll.plus(w,0.int); -- v0=left lower of braid word v0:=vll.plus(d*ch, 0.int); end; Braid2Knot(word:BRAID, inout Knot:KNOT, pack:BOOL, close:BOOL):BOOL is -- Get a braid diagram "Knot" from the braid "word". Knot:=#; if word.index=0 then return true; end; if word.check.not then return true; end; -- if pack and BRAID_REDUCTION::wordReduction(inout word) then ; end; --nothing if word.index=1 then if close then Knot:=KNOT_TEST::trivial; else ki::=0; Knot.CodeIn(VERTEXC::knot_s, ki); ki:=ki+1; Knot.CodeIn(0.int,0.int,ki); ki:=ki+1; Knot.CodeIn(30.int,0.int,ki); ki:=ki+1; Knot.CodeIn(VERTEXC::knot_e, ki); ki:=ki+1; end; Knot.shiftToInside; return true; end; -- Assume that word.index>1. -- set position of crossings tbl:BRAID_TABLE:=#(word); if pack then tbl.pack; end; -- set width/height: d ds,dx,dy d:=2.int; ds:=16.int; height:=(ds+(tbl.index.int-1)*(d+ds)).max(KNOTXW::GraphHeight-20); width:=(tbl.length.int*ds+tbl.index.int*d*2).max(KNOTXW::GraphWidth-20); d:=12.int; ds:=32.int; setw(tbl.length,tbl.index); if (dy.y<ds)or(dx.x<ds) then d:=8.int; ds:=24.int; setw(tbl.length,tbl.index); end; if (dy.y<ds)or(dx.x<ds) then d:=4.int; ds:=16.int; setw(tbl.length,tbl.index); end; if (dy.y<ds)or(dx.x<ds) then d:=2.int; ds:=16.int; setw(tbl.length,tbl.index); end; -- set diagram setString(inout Knot,tbl); setClosing(inout Knot,tbl.length,tbl.index,close); Knot.concat; Knot.edge_clean; Knot.shiftToInside; return true; end; end; -- BRAID2KNOT

class BRAIDTC2BRAID

class BRAIDTC2BRAID is ------------- TCode[] --> word[] ----------- shared cTbl:ARRAY{INT}; shared str:INT; chk_cTbl(TCode:TCODE) is 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.str; 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.int-1)and(word.w[wi.card].abs<(str-1))) ; wi:=wi+1; end; if (wi<word.size.int) 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; sBase:INT; cTbl:=#(TCode.size); cTbl.to_val(0.int); word:=#; word.index:=0; loop tp::=0; loop while!( (tp<TCode.length) and cTbl[tp].is_pos ); tp:=tp+1; end; if tp>=TCode.length then break!; end; word.index:=word.index+1; sBase:=word.index.int; str:=sBase; loop loop while!(cTbl[tp].is_zero) ; -- Seifert circle cTbl[tp]:=str; if VERTEXC::crossing.in(TCode[tp].sep) then tp:=TCode[tp].companion.card+1; elsif VERTEXC::ks.in(TCode[tp].sep) then tp:=tp+1; elsif VERTEXC::ke.in(TCode[tp].sep) then tp:=TCode[tp].companion.card; 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.card+1; end; str:=cTbl[tp1]; until!( TCode.length<=(tp+1) or (cTbl[tp].is_zero and VERTEXC::crossing.in(TCode[tp].sep) and str.is_pos) ); 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.int<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.int-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.card+1; else tp0:=tp0+1; end; elsif VERTEXC::ke.in(TCode[tp0].sep) then tp0:=TCode[tp0].companion.card; elsif VERTEXC::ks.in(TCode[tp0].sep) then tp0:=tp0+1; end; end; tp:=tp0; wi:=0.int; 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.card,str); wi:=wi+1; else word.insert(wi.card,-str); wi:=wi+1; end; end; tp:=TCode[tp].companion.card+1; elsif VERTEXC::ke.in(TCode[tp].sep) then tp:=TCode[tp].companion.card; 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 cTbl:=#(TCode.size); cTbl.to_val(0.int); index:=0.int; loop tp::=0; loop while!( (tp<TCode.length)and cTbl[tp].is_pos );tp:=tp+1; end; if tp>=TCode.length then break!; end; index:=index+1; loop while!( cTbl[tp].is_non_pos ); -- Seifert circle cTbl[tp]:=index; if VERTEXC::crossing.in(TCode[tp].sep) then tp:=TCode[tp].companion.card+1; elsif VERTEXC::ks.in(TCode[tp].sep) then tp:=tp+1; elsif VERTEXC::ke.in(TCode[tp].sep) then tp:=TCode[tp].companion.card; 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.card); 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.card+1]; else str:=-1; end; end; Unify(inout TCode:TCODE, side:BOOL):BOOL is uFlg:BOOL; tp0, tp1, tp2, str, str0, str1, str2:INT; cop::=VERTEXC::cross_po; cup::=VERTEXC::cross_pu; com::=VERTEXC::cross_no; cum::=VERTEXC::cross_nu; str:=1.int; loop while!(str<=index) ; -- #OUT+"Unify:2 inde:="+index.str+" str="+str.str+"\n"; tp0:=0.int; loop until!(cTbl[tp0.card]=str); tp0:=tp0+1; end; nextC(TCode,side, inout tp0, inout str0); uFlg:=false; if str0.is_pos 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.card].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.card+1]:=str1; cTbl[tp1.card+2]:=str2; cTbl[tp2.card-2]:=str1; cTbl[tp2.card-1]:=str2; end; end; if uFlg then str:=1; else str:=str+1; end; end; return true; end; TCode2BraidTC(inout TCode:TCODE):BOOL is cTbl:=#; SeifertCircuit(TCode); reply:BOOL:=Unify(inout TCode,right) and Unify(inout TCode,left); cTbl:=#; return reply; 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; if ~TCode2BraidTC(inout TCode) then return false; end; return true; end; end; -- class KNOT2BRAIDTC

class BRAID_CNV

class BRAID_CNV is shared error:INT; TCode2Braid(TCode:TCODE, out braid:BRAID):BOOL is tcode:TCODE:=TCode.clone; braid:=#; if ~KNOT2BRAIDTC::TCode2BraidTC(inout tcode) then return false; end; if ~BRAIDTC2BRAID::TCode2Braid(tcode,out braid) then return false; end; braid:=BRAID_REDUCTION::wordReduction(braid, true); return true; end; 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); if ~ reply then Word:=#; end; str:=Word.str; return reply; end; BraidWord2Knot(str:STR, inout Knot:KNOT,packBraid,closeBraid:BOOL):BOOL is HISTORY::put(Knot); -- #OUT+"BraidWord2Knot: str="+str+"\n"; word:BRAID:=#(str); reply:BOOL:= BRAID2KNOT::Braid2Knot(word,inout Knot,packBraid,closeBraid); if ~ reply then HISTORY::back(inout Knot); end; return reply; end; BraidWordA2Knot(str:STR, inout Knot:KNOT, reduce:BOOL):BOOL is HISTORY::put(Knot); reply:BOOL:=true; BRAID_CNV::error:=0.int; word:BRAID:=#(str); reply:=reply and (BRAID_CNV::error.is_zero); word1::=ARTIN_FORM::GArtinNormalForm(word,reduce); reply:=reply and(BRAID_CNV::error.is_zero) and BRAID2KNOT::Braid2Knot(word1,inout Knot,false,true) and (BRAID_CNV::error.is_zero); if ~ reply then HISTORY::back(inout Knot); end; return reply; end; BraidWord2ArtinNormalFormS(inout str:STR, reduce:BOOL):BOOL is reply:BOOL:=true; BRAID_CNV::error:=0.int; str0:STR:=""+str; word:BRAID:=#(str); --reply:=Str2Word(str, out word)and(BRAID_CNV::error=0); word1::=ARTIN_FORM::GArtinNormalForm(word,reduce); str:=word1.str; 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,close:BOOL):BOOL is -- get reduced word str0:STR:=""+str; reply:BOOL:=true; word:BRAID:=#BRAID(str); word:=BRAID_REDUCTION::wordReduction(word,close); str:=word.str; BRAID_CNV::error:=0.int; -- reply:=Str2Word(str,out word) and(BRAID_CNV::error=0); reply:=reply and(BRAID_CNV::error=0.int); --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,true,true) 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