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

-- 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:INT; -- frame of crossings shared v0,vlu,vll,vru,vrl:VERTEXK; shared dx,dy,dxy,vc:VERTEXK; shared dlu,dll,dru,drl: VERTEXK; shared crossTbl:ARRAY{ARRAY{INT}}; setString(inout Knot:KNOT,cw,ch:CARD) is Knot:=#; v1:VERTEXK:=#(v0.x, v0.y); v2:VERTEXK:=#(v1.x+d, v1.y); loop j::=1.upto!(ch); ki::=Knot.bandStart.card; Knot.CodeIn(VERTEXC::knot_s, ki); ki:=ki+1; Knot.CodeIn(VERTEXC::knot_e, ki); Knot.CodeIn(v1,ki); ki:=ki+1; Knot.CodeIn(v2,ki); v1:=v1+dy; v2:=v2+dy; end; v1:=#(v0.x+d, v0.y); loop i::=0.upto!(cw); v2:=v1; loop j::=1.upto!(ch); ki::=Knot.bandStart.card; Knot.CodeIn(VERTEXC::knot_s, ki); ki:=ki+1; Knot.CodeIn(VERTEXC::knot_e, ki); Knot.CodeIn(v2,ki); ki:=ki+1; if j>1 and 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); elsif j>1 and 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); elsif j<ch and 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); elsif j<ch and crossTbl[i][j]=-1 then Knot.CodeIn(v2+vc,ki); Knot[ki].sep:=VERTEXC::cross_over; ki:=ki+1; Knot.CodeIn(v2+dxy,ki); else Knot.CodeIn(v2+dx,ki); end; v2:=v2+dy; end; v1:=v1+dx; end; v2:=#(v1.x+d, v1.y); loop j::=1.upto!(ch); ki::=Knot.bandStart.card; Knot.CodeIn(VERTEXC::knot_s, ki); ki:=ki+1; Knot.CodeIn(VERTEXC::knot_e, ki); Knot.CodeIn(v1,ki); ki:=ki+1; Knot.CodeIn(v2,ki); v1:=v1+dy; v2:=v2+dy; end; end; setClosing(inout Knot:KNOT,cw,ch:CARD) is v1:VERTEXK:=#(v0.x+d+d, v0.y); v1:=v1+dx*(cw+1); v2:VERTEXK:=v1.plus(d*(ch-1),0.int); v3:VERTEXK:=v2.plus(0.int,(dy.y+d)*(ch-1)+ds); v6:VERTEXK:=#(v0.x,v0.y); v5:VERTEXK:=v6+(v1-v2); v4:VERTEXK:=v5+(v3-v2); loop i::=1.upto!(ch); ki::=Knot.bandStart.card; Knot.CodeIn(VERTEXC::knot_s, ki); ki:=ki+1; Knot.CodeIn(VERTEXC::knot_e, ki); if i<ch then Knot.CodeIn(v1,ki); ki:=ki+1; end; Knot.CodeIn(v2,ki); ki:=ki+1; Knot.CodeIn(v3,ki); ki:=ki+1; Knot.CodeIn(v4,ki); ki:=ki+1; Knot.CodeIn(v5,ki); ki:=ki+1; if i<ch then Knot.CodeIn(v6,ki); ki:=ki+1; end; v1:=v1+dy; v2:=v2+drl; v3:=v3+dru; v6:=v6+dy; v5:=v5+dll; v4:=v4+dlu; end; end; setw(cw,ch:CARD) 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:INT; -- width/hight of crossings dx:=#((width-2.int*d*ch.int-d)/(cw.int+1),0.int); dy:=#(0.int,(height-ds-d*ch.int)/(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+1); 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:=#(((width-w)/2.int).max(d),-(((height-h)/2.int).max(d))); 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-1), 0.int); end; Braid2Knot(word:BRAID, inout Knot:KNOT, pack:BOOL, close:BOOL):BOOL is -- Get braid diagram "Knot" from braid "word". -- Check if the word is correct. if word.index=0 then Knot:=#; return true; end; loop wi::=word.ind!; if word[wi].abs>=word.index.int then Knot:=#; return true; end; end; if word.index=1 then Knot:=KNOT_TEST::trivial; Knot.shiftToInside; return true; end; -- reduce the word if pack and BRAID_REDUCTION::wordReduction(inout word) then ; end; --nothing -- set position of crossings ch:CARD:=word.index; cw:CARD:=word.size; -- max index of crossTbl[cw][*]!=0 crossTbl:=#(cw+1); -- array of array of 1/0/-1; loop i::=crossTbl.ind!; crossTbl[i]:=#(ch+1); loop j::=crossTbl[i].ind!; crossTbl[i][j]:=0.int; end; if i<cw then crossTbl[i][word[i].abs]:=word[i].sgn; end; end; if pack then i::=0; j::=1; loop if i>=crossTbl.size then break!; end; if (i>0)and crossTbl[i][j].is_non_zero then -- crossing if crossTbl[i-1][j].is_zero and crossTbl[i-1][j-1].is_zero and crossTbl[i-1][j+1].is_zero then -- move crossing crossTbl[i-1][j]:=crossTbl[i][j]; crossTbl[i][j]:=0.int; i:=i-1; else -- check next slot j:=j+1; if j=ch then j:=1; i:=i+1; end; end; else -- not crossing. check next slot j:=j+1; if j=ch then j:=1; i:=i+1; end; end; end; end; -- pack crossTbl[0][0]:=1.int; -- check -- set width/height: d ds,dx,dy cw:=0; -- max index of crossTbl[cw][*]!=0 loop i::=crossTbl.ind!; loop if crossTbl[i].elt!.is_non_zero then cw:=i; end; end; end; d:=2.int; ds:=16.int; height:=(ds+(ch.int+1)*(d+ds)).max(KNOTXW::GraphHeight-20); width:=(cw.int*ds+(ch.int+1)*d*2).max(KNOTXW::GraphWidth-20); d:=12.int; ds:=32.int; setw(cw,ch); if (dy.y<ds)or(dx.x<ds) then d:=8.int; ds:=24.int; setw(cw,ch); end; if (dy.y<ds)or(dx.x<ds) then d:=4.int; ds:=16.int; setw(cw,ch); end; if (dy.y<ds)or(dx.x<ds) then d:=2.int; ds:=16.int; setw(cw,ch); end; -- set diagram setString(inout Knot,cw,ch); if close then setClosing(inout Knot,cw,ch); end; Knot.concat; Knot.edge_clean; Knot.shiftToInside; crossTbl:=#; return true; end; Braid2Knot(word:BRAID, inout Knot:KNOT):BOOL is reply::=Braid2Knot(word, inout Knot, false,true); return reply; 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; shared packBraid:BOOL:=true; shared closeBraid:BOOL:=true; 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; if BRAID_REDUCTION::wordReduction(inout braid) then ; end; 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):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 reply:BOOL:=true; Word:BRAID:=#(str); word:BRAID:=Word.clone; HISTORY::put(Knot); BRAID_CNV::error:=0.int; reply:=reply and (BRAID_CNV::error.is_zero) and ARTIN_FORM::GArtinNormalForm(inout word,reduce); Word:=word.clone; reply:=reply and(BRAID_CNV::error.is_zero) and BRAID2KNOT::Braid2Knot(Word,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; str0:STR:=""+str; word:BRAID:=#(str); BRAID_CNV::error:=0.int; --reply:=Str2Word(str, out word)and(BRAID_CNV::error=0); reply:=reply and ARTIN_FORM::GArtinNormalForm(inout word,reduce)and(BRAID_CNV::error.is_zero); str:=word.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):BOOL is -- get reduced word str0:STR:=""+str; reply:BOOL:=true; word:BRAID:=#(str); BRAID_CNV::error:=0.int; -- reply:=Str2Word(str,out word) and(BRAID_CNV::error=0); reply:=reply and BRAID_REDUCTION::wordReduction(inout word) and(BRAID_CNV::error=0.int); 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