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 vx,vy,vxy,vc:VERTEXK; 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 si0:INT; wi:INT; -- word pos:INT; -- position of the crossing v:VERTEXK; -- 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.card; Knot.CodeIn(VERTEXC::knot_s, ki); ki:=ki+1; Knot.CodeIn(VERTEXC::knot_e, ki); loop Knot.CodeIn(vll+dll*(si-1), ki); ki:=ki+1; if indTbl[si.card].is_zero then indTbl[si.card]:=compo; else break!; 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.int then -- #OUT+"wi="+wi.str+" word.size="+word.size.str+"\n"; break!; elsif (word.w[wi.card].abs=si) then -- set crossing -- #OUT+"addCompo: set crossing1\n"; v:=v0+dxy.transform(posTbl[wi.card],si-1); if posTbl[wi.card]>(pos+1) then Knot.CodeIn(v, ki); ki:=ki+1; elsif (si0=(si-1)) then ki:=ki-1; Knot.CodeDel(ki); end; Knot.CodeIn(v+vc, ki); if word.w[wi.card].is_pos then Knot[ki].sep:=VERTEXC::cross_under; else Knot[ki].sep:=VERTEXC::cross_over; end; ki:=ki+1; Knot.CodeIn(v+dxy, ki); ki:=ki+1; si0:=si; si:=si+1; pos:=posTbl[wi.card]; elsif (word.w[wi.card].abs+1)=si then -- set crossing -- #OUT+"addCompo: set crossing2\n"; v:=v0+dxy.transform(posTbl[wi.card],si-2); if posTbl[wi.card]>(pos+1) then Knot.CodeIn(v+dy, ki); ki:=ki+1; elsif (si0=(si+1)) then ki:=ki-1; Knot.CodeDel(ki); end; Knot.CodeIn(v+vc, ki); if word.w[wi.card].is_pos then Knot[ki].sep:=VERTEXC::cross_over; else Knot[ki].sep:=VERTEXC::cross_under; end; ki:=ki+1; Knot.CodeIn(v+dx, ki); ki:=ki+1; si0:=si; si:=si-1; pos:=posTbl[wi.card]; else end; if (si<1.int)or(word.index.int<si) then raise "BRAID2KNOT::addCompo: Error in add crossings.\n"; end; end; Knot.CodeIn(vrl+drl*(si-1), ki); ki:=ki+1; Knot.CodeIn(vru+dru*(si-1), ki); ki:=ki+1; Knot.CodeIn(vlu+dlu*(si-1), 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:INT; maxPos:=0.int; loop wi::=word.ind!; if maxPos<posTbl[wi] then maxPos:=posTbl[wi]; end; end; dx:=#((width-2.int*d*(word.index.int+1))/(maxPos+1),0.int); dy:=#(0.int,(height-ds-d*word.index.int-d)/word.index.int); if dx.x>ds then dx.x:=ds; end; if dy.y>ds then dy.y:=ds; end; dlu:=#(d,-d); dru:=#(-d,-d); dll:=dy.plus(d,0.int); drl:=dy.plus(-d,0.int); -- width/hight of crossings dxy:=dx+dy; vc:=dxy/2.int; -- w,h is width/height of closed braid diagram w:=d*2.int*word.index.int+dx.x*(maxPos+1); h:=(d+dy.y)*(word.index.int-1)+ds; -- left/right, upper/lower corner of diagram vlu:=#(((width-w)/2.int).max(30.int),(-(height-h)/2.int).min(-30)); 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*word.index, 0.int); 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; loop wi::=word.ind!; if word[wi].abs>=word.index.int 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.int; end; if BRAID_CNV::packBraid then loop wi:INT:=word.ind!.int; pos:INT:=-1; loop wi1:INT:=0.int.upto!(wi-1) ; if ( ((word[wi1.card].abs-word[wi.card].abs).abs<=1.int) and (pos<posTbl[wi1.card])) then pos:=posTbl[wi1.card]; end; end; posTbl[wi.card]:=pos+1; end; end; -- set width -- d ds,dx,dy d:=2.int; ds:=16.int; height:=(ds+(word.index.int+1)*(d+ds)).max(KNOTXW::GraphHeight-20); width:=(word.size.int*ds+(word.index.int+1)*d*2).max(KNOTXW::GraphWidth-20); d:=12.int; ds:=32.int; setw(word); if (dy.y<ds)or(dx.x<ds) then d:=8.int; ds:=24.int; setw(word); end; if (dy.y<ds)or(dx.x<ds) then d:=4.int; ds:=16.int; setw(word); end; if (dy.y<ds)or(dx.x<ds) then d:=2.int; ds:=16.int; setw(word); end; -- set components/strings indTbl:=#(word.index+1); -- [0..word.index] indTbl.to_val(0.int); Knot:=#; compo:=0.int; loop si::=0; loop si:=si+1; until!( (si>word.index) or (indTbl[si].is_zero)); end; if si>word.index then break!; end; addCompo(word,si.int,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 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; 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); 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; tmpSw:BOOL:=packBraid; packBraid:=false; -- Don't pack the word. reply:=reply and(BRAID_CNV::error.is_zero) and BRAID2KNOT::Braid2Knot(Word,inout Knot) and (BRAID_CNV::error.is_zero); 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.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 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