braid.sa
Generated by gen_html_sa_files from ICSI. Contact gomes@icsi.berkeley.edu for details
-- This code is "GPL"ed.
--
-- Braid group. from module BRAID.msi
-- 1998.7.2 K.Kodama
class BRAID
class BRAID is
include WORD create->word_create, clone->word_clone, str->word_str,
printD->word_printD, check->word_check,
reverse->word_reverse, inverse->word_inverse,
append->word_append,insert->word_insert;
attr index:CARD;
create:SAME is
res::=new; res.index:=0; res.w:=#; return res;
end;
create(ind:CARD):SAME is
res::=new; res.index:=ind; res.w:=#; return res;
end;
create(s:STR):SAME is
-- convert STR to BRAID.
-- format: " 4 : 2 -1 3 -2 -3 2 1 endcode"
-- index^ ^^^^^^^^^^^^^^^^braid word
res:SAME:=#;
sc:STR_CURSOR:=#(s);
res.index:=sc.card;
if res.index<0 then res:=#; return res; end;
str:STR:=STRINGSK::splitStr(inout sc);
if str/=":" then res:=#; return res; end;
s:=sc.get_remainder;--get_rest_str;
i::=s.search("endcode");
if s.has_ind(i).not then res:=#; return res; end;
s:=s.head(i);
res.w:=word_create(s).w;
loop
if res.w.elt!.abs>=res.index.int then res:=#; return res; end;
end;
return res;
end;
clone:SAME is
res:SAME:=word_clone; res.index:=index; return res;
end;
str:STR is
-- convert BRAID to STR
s:STR:=index.str+" : "+word_str+" endcode ";
return s;
end;
printD is
-- print for debug/check
#OUT+"braid "+str+"\n";
end;
check:BOOL is
if ~word_check then return false;
end;
loop e::=w.elt!; if e.abs>=index.int then return false; end; end;
return true;
end;
trackString(s:INT):INT is
aw:INT;
loop i::=0.upto!(w.size-1);
aw:=w[i].abs;
if aw=s then s:=s+1; elsif (aw+1)=s then s:=s-1; else ; end;
end;
return s;
end;
is_PureBraid:BOOL is
loop i::=1.upto!(index-1);
--if i/=trackString(i.int) then return false; end;
if i/=trackString(i.int).card then return false; end;
end;
return true;
end;
maxIndexInWord:INT is
-- m= max index of generator +1. i.e. word \in B_m
return (maxGen+1).int;
end;
reverse:SAME is
-- reverse order of elements
b:SAME:=word_reverse; b.index:=index; return b;
end;
inverse:SAME is
-- inverse as group
res:SAME:=word_inverse; res.index:=index; return res;
end;
append(b:SAME) is
index:=index.max(b.index); w:=w.append(b.w);
end;
append(b:SAME):SAME is
res:SAME:=clone; res.append(b); return res;
end;
append(s:INT) is
index:=index.max(s.abs.card+1);
--w:=w.resize(w.size+1); w[w.size-1]:=s;
w:=w.append(|s|);
end;
append(s:INT):SAME is
res:SAME:=clone; res.append(s); return res;
end;
insert(pos:CARD,b:SAME):SAME is
res:SAME:=word_insert(pos,b); res.index:=index.max(b.index);
return res;
end;
insert(pos:CARD, s:INT):SAME is
res:SAME:=word_insert(pos,s); res.index:=index.max((s.abs+1).card);
return res;
end;
insert(pos:CARD, s:INT) is
res::=insert(pos,s); index:=res.index; w:=res.w;
end;
perm:PERM is
-- get permutation [1..index]
perm:PERM:=#(index); wr::=reverse;
loop j::=wr.w.elt!.abs.card; perm.swap(j,j+1); end;
return perm;
end;
end; -- class BRAID
class BRAID_REDUCTION
class BRAID_REDUCTION is
-----------------word reduction------------------------------
reduction1(inout word:BRAID):BOOL is
-- true if R1-move as a closed braid
rFlg:BOOL:=false;
stTbl:ARRAY{INT}:=#(word.index+2); stTbl.to_val(0.int);
posTbl:ARRAY{INT}:=#(word.index+2); posTbl.to_val(0.int); -- position of the crossing
loop wi::=word.w.ind!; -- count word
i::=word.w[wi].abs; stTbl[i]:=stTbl[i]+1; posTbl[i]:=wi.int;
end;
si:CARD:=1;
loop while!(si<=word.index);
if (stTbl[si].is_one)and( stTbl[si-1].is_zero or stTbl[si+1].is_zero ) 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.card>si then
if word.w[wi].is_pos then word.w[wi]:=word.w[wi]-1;
else word.w[wi]:=word.w[wi]+1.int;
end;
end;
end;
word.index:=word.index-1;
word.delete(posTbl[si].card);
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:=false;
wi:INT:=0.int;
loop while!(wi<word.size.int);
wi1::=wi-1;
loop
if wi1.is_neg then wi1:=word.size.int-1; end;
if (word.w[wi1.card].abs-word.w[wi.card].abs).abs<=1.int then break!; end;
wi1:=wi1-1;
end;
if (word.w[wi1.card]+word.w[wi.card]).is_zero then rFlg:=true; -- r2 move
w1, w2:INT;
if wi<wi1 then w1:=wi; w2:=wi1; else w1:=wi1; w2:=wi; end;
word.delete(w2.card); word.delete(w1.card); -- Note that w1<w2.
if wi1<wi then wi:=wi-1; end;
if word.size.int<=wi then wi:=0.int; 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 #OUT+"r1\n"; end;
word:=word.cancel;
if reduction2(inout word) then #OUT+"r2\n"; 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
--Artin's normal form for braid word.
--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.
-- This code is "GPL"ed.
--
--1998.7.2 K.Kodama
--
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:CARD;
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
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.int);
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.is_pos then Aw:=Aw.insert(0,k0);
else Aw:=Aw.insert(0,-k0);
end;
if g.is_pos then twistP(inout Di,k0); else twistN(inout Di,k0); end;
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;
D:BRAID:=#(word.index);
Di:BRAID:=#(word.index);
Ai:BRAID:=word.clone;
loop i::=(1.upto!(word.index-1)).int ;
CnvReducedNormalForm(i,inout Ai,inout Di);
if ~ reduce then cnvRA2A(i,inout Di); end;
D:=D*Di;
end;
word:=D;
return true;
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.
w0:BRAID:=word.clone;
E:BRAID:=#(word.index);
cw1:BRAID:=#(word.index);
loop i::=word.index.downto!(1);
i1::=word.trackString(i.int).card;
if i/=i1 then
cw1:=#(word.index);
loop cw::=i1.upto!(i-1); cw1.append(-cw.int); 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;
return true;
end;
end; -- class ARTIN_FORM