Skip to content

Instantly share code, notes, and snippets.

@m1el
Last active February 11, 2023 05:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save m1el/d514a353cccde531c298b725043404af to your computer and use it in GitHub Desktop.
Save m1el/d514a353cccde531c298b725043404af to your computer and use it in GitHub Desktop.
program BBfind;
uses crt , dos;
const dm=5; { TM dimension. Must be 2,3,4,5 or 6 }
reversal={true} false; { Reversal / Normal TM }
SameDir ={true} false; { Dir(0) = Dir(1) limitation }
Destructive={true} false;{ Destructive TM: value_1=1 limitation }
slow_scan=true {false}; { slow/fast scan }
slow_sc0=true;
slow_sc2=true;
slow_0=slow_scan and slow_sc0;
slow_2=slow_scan and slow_sc2;
IgnoreFirstZero=true; { scan only machines, writing 1 at first step }
dm_2=dm+dm;
dm_2r=dm_2 -
2*(ord(reversal)+ord(SameDir))*(1-ord(Destructive)) -
4*ord(Destructive);
dm_2rR=dm_2r-2*ord(reversal);
dm2sqr=dm_2r*dm_2r {dm_2}; { limit size for rule finder }
dm2qub=longint(dm2sqr)*dm_2r*2+ 1900;
{ limit step for rule finder and size of used arrays }
{ 4 --> 2024, 5 --> 3000, 6 --> 4440 }
{ t_low=0; t_mid=40000; t_hig=80000; }
{ start, midle and end tape position }
cmax=100+dm2qub; { Upper limit for steps }
mmax= 250; { Upper limit for used tape }
s_sz= 100; { Stack size }
dum = 99; { undefined state }
dump_max= 400; { how many dump steps }
rmax= 3000; { Upper limit for rules }
{ 2000 is small for some machines !!! }
sr_lmax= 31; { max len for approved shift rules }
showmax= 20; { How many proved machines to show from any group }
bmax= 64; { Limit for basic rulei and exones arrays }
{ Test results: }
e_max=21;
nm_end=1; { normal finish }
mem_ov=2; { tape overflow }
too_lng=3; { time overflow }
{ Hard tests for infinite loops: }
b_loop=4; { back-track test, halt state unrechable }
i_loop=5; { invariant states }
c_loop=6; { in place circle }
s_loop=7; { closed sub-graph in TM graph, halt unrechable }
m_loop=8; { moving left or right infinite }
lNct_l=9; { simple linear counter with 1 repeating word }
modf_l=10; { finite transition graph (modulo version) }
pfin_l=11; { finite position formula - binary or similar counters }
swpf_l=12; { swiming position test - binary or similar counters }
exH0_l=13; { Exones chaotick loop 0 }
exH1_l=14; { Exones chaotick loop 1 }
ex0f_l=15; { finite exones graph loop }
ex1f_l=16; { finite exones + intrones graph loop }
exS0_l=17; { Exones special loop 0 }
exS1_l=18; { Exones special loop 1 }
exS2_l=19; { Exones special loop 2 }
BLfinl=20; { finite transition graph }
col0_e=21; { Collatz like function }
spec_max=10; { spectrum limit }
type t_arr=array[1..dm_2] of byte;
machine=record A,B,C:t_arr end;
TDescr = record { full state of the machine }
{ v:byte;} { value under the head }
md:byte; { move direction }
{ only 1 of v/md must be used ! }
s:byte; { current state }
l,r:string; { left and right parts of the tape }
c:longint; { step counter }
p:longint; { tape position }
af:boolean; { false/true - full_state/formula }
d_c,d_p: string[40]; { delta c/p for formulas }
{l_mark,r_mark:string[40];} { mark strings for exone proofs }
rn:longint; { rule number }
rname, rname0, rname1:string[4]; { rule names }
smax:byte;
end;
THistory = array[0..cmax] of TDescr;
TRule = record { description for a shift rule }
{ syntax: *aS>b(c0)* --> *(c1)aS>b* }
{ *(c0)b<Sa* --> *b<Sa(c1)* }
id:word;
md:byte; { move direction }
s:byte; { state }
a{,b},c0,c1:string; { rule patterns }
c:longint; { step needed }
p:longint; { position moves }
used:boolean;
allowed:boolean;
spectrum:array[1..spec_max] of longint;
end;
TRuleArr = array[0..rmax] of TRule;
TBRuleEl = record
c0,c1:string; { patterns }
c:longint; { steps needed }
ucnt:longint; { usage counter }
end;
TBRule = record
id:word;
md:byte; { move direction }
s:byte; { state }
a:string; { lead rule pattern }
Patts:array[0..bmax] of TBRuleEl;
Patt_cnt:longint;
ucnt:longint; { usage counter }
nice:longint;
m_id:longint; { main pattern index }
end;
TBRuleArr = array[0..bmax] of TBRule;
var Stack:array[0..s_sz] of machine;
s_ct:0..s_sz;
SH:THistory; { History for rule finding }
SH_cnt:longint;
MH:THistory; { Macro History }
MH_cnt:longint;
BH:THistory; { Basic Macro History }
BH_cnt:longint;
MMH:THistory; { Main Macro History }
MMH_cnt:longint;
BMH:THistory; { Bin_Macro History }
BMH_cnt:longint;
EMH:THistory; { Exone macro history }
EMH_cnt:longint;
ClMH:THistory; { Collatz macro history }
ClMH_cnt:longint;
SRules:TRuleArr; { Approved shift rules }
SR_cnt:longint;
SSRules:TRuleArr; { Special approved shift rules }
SSR_cnt:longint;
ASRules:TRuleArr; { All shift rules }
ASR_cnt:longint;
BSRules:TBRuleArr; { Basic shift rules }
BSR_cnt:longint;
OSRules:TRuleArr; { Opposite shift rules (to MainRule) }
OSR_cnt, OSR_main:longint;
ms_cnt:longint;
A,B,C:t_arr; { Current machine }
CD:TDescr; { Current full description }
CM:TDescr; { Current macro description }
CB:TDescr; { Current basic macro description }
CMM:TDescr;{ Current main macro }
BMM:TDescr;{ Current bin_macro }
CEM:TDescr;{ Current exone macro }
Cl_M:TDescr;{ Current Collatz macro }
m, { Machine counter }
sigma,
old_sec:longint;
t_record, s_record: longint;
e_state:byte;
e_cnt:array[1..e_max] of longint;
sh_ct1, sh_ct2:byte;
a1:byte; { position of Halt state }
tnr,tnr1,trc,ttm,tproof,tsrec:text;
{ files for nonregular/record/other/proved machines }
var
rec_cnt:longint; RevS:string;
function SD_str(s,md:byte):string;
begin
if md=0
then SD_str:='<'+chr(s+ord('@'))
else SD_str:=chr(s+ord('@'))+'>';
end;
function RevStr(s:string):string;
var w:string; i,n:byte;
function RevCh(c:char):char;
begin
case c of
'[':c:=']';
']':c:='[';
'{':c:='}';
'}':c:='{';
'(':c:=')';
')':c:='(';
end;
RevCh:=c;
end;
begin
w[0]:=s[0];
n:=ord(s[0]);
for i:=1 to n do w[i]:=RevCh(s[n-i+1]);
RevStr:=w;
end;
function TD_str(var D:TDescr):string;
begin with D do TD_str:=RevStr(l)+SD_str(s,md)+r end;
{ -------------------------------------------------- }
type
TPosStat = array[0..1,1..dm] of longint;
TPSCnt = array[-mmax..mmax] of longint;
var
PosStat : array[-mmax..mmax] of TPosStat;
PosSCnt : TPSCnt;
pst_min, pst_max:longint;
PosAl,PosBl,PosAr,PosBr:longint;
procedure ClPosStat;
var i,j,k:longint;
begin
for i:=-mmax to mmax do begin
PosSCnt[i]:=0;
for j:=0 to 1 do
for k:=1 to dm do PosStat[i][j,k]:=0;
end;
end;
function TuchPS(TPS1,TPS0:TPosStat):boolean;
var s,k:longint;
begin
s:=0;
for k:=1 to dm do begin
s:=s+TPS0[1,k];
s:=s+TPS1[0,k];
end;
TuchPS:=s>0;
end;
function cmpPos(i,j:longint):boolean;
var OK:boolean; k:longint;
function NotSame(m,n:longint):boolean;
begin NotSame:=(m*n=0) and (m+n>0) end;
begin
OK:=true;
for k:=1 to dm do begin
if NotSame(PosStat[i][1,k],PosStat[j][1,k]) then OK:=false;
if NotSame(PosStat[i-1][0,k],PosStat[j-1][0,k]) then OK:=false;
end;
cmpPos:=OK;
end;
procedure EvalPosAB(var a,b:longint; sign:longint);
var
i,j,lim,k,k0,j0,jm:longint;
ta:array[byte] of boolean;
begin
a:=-1; k0:=-1; i:=1;
if sign=1 then lim:=pst_max else lim:=-pst_min;
while i<=lim div 2 do begin
for j:=0 to 255 do ta[j]:=false;
for j:=1 to lim do ta[j]:=cmpPos(j*sign,(j+i)*sign);
for j:=1 to lim-i do {if (PosSCnt[j*sign]<=3) then} begin
k:=0;
while ta[j+k] do inc(k);
if (k>=i) and (k+i>k0) then begin
k0:=k+i;
jm:=999;
for j0:=j+i-1 downto j do if PosSCnt[j0*sign]<=jm then begin
jm:=PosSCnt[j0*sign];
{ This is not needed !!! }
{if jm<dm-2 then}
begin a:=j0; b:=a+i end;
end;
end;
end;
inc(i);
end;
end;
procedure EvalPSCnt;
var i,k:longint;
begin
pst_min:=mmax; pst_max:=-mmax;
for i:=-mmax to mmax do PosSCnt[i]:=0;
for i:=-mmax to mmax do if TuchPS(PosStat[i],PosStat[i+1]) then begin
if i>pst_max then pst_max:=i;
if i<pst_min then pst_min:=i;
end;
for i:=pst_min+1 to pst_max do for k:=1 to dm do begin
if PosStat[i,1,k]>0 then inc(PosSCnt[i]);
if PosStat[i-1,0,k]>0 then inc(PosSCnt[i]);
end;
EvalPosAB(PosAl,PosBl,-1);
EvalPosAB(PosAr,PosBr, 1);
end;
procedure WrPosStat(var f:text);
var i,k:longint;
begin
{ EvalPSCnt; }
writeln(f,' ---- PosStats: ---- ');
for i:=pst_min+1 to pst_max do begin
write(f,i:4,' [>');
write(f,i,'] ');
for k:=1 to dm do if PosStat[i][1,k]>0 then write(f,'*') else write(f,'-');
write(f,' [',i,'<] ');
for k:=1 to dm do if PosStat[i-1][0,k]>0 then write(f,'*') else write(f,'-');
writeln(f,' [',PosSCnt[i],']');
end;
writeln(f,'L_patt: ',PosAl,' ',PosBl);
writeln(f,'R_patt: ',PosAr,' ',PosBr);
writeln(f);
end;
{ -------------------------------------------------- }
function nod(i,j:longint):longint;
begin
if i*j=0
then if i>0 then nod:=i else nod:=j
else if i>j
then nod:=nod(i-j,j)
else nod:=nod(j-i,i);
end;
function nok(i,j:longint):longint;
begin
nok:=i*j div nod(i,j);
end;
{ -------------------------------------------------- }
function get_sec:longint;
var d,y,h,m,s,s1:word; l:longint;
begin
getdate(y,m,d,s1);
l:=d;
gettime(h,m,s,s1);
l:=l*24+h;
l:=l*60+m;
l:=l*60+s;
get_sec:=l;
end;
procedure table(x,y:byte);
begin
gotoxy(x,y );write('.__________.');
gotoxy(x,y+1);write('|A ---- |');
gotoxy(x,y+2);write('| ---- |');
gotoxy(x,y+3);write('|B ---- |');
gotoxy(x,y+4);write('| ---- |');
gotoxy(x,y+5);write('|C ---- |');
gotoxy(x,y+6);write('| ---- |');
gotoxy(x,y+7);write('|c= |');
gotoxy(x,y+8);write('|m= |');
gotoxy(x,y+9);write('.__________.');
end;
procedure wr_mash(x,y:byte);
procedure wr_a(a:t_arr; b:byte);
var i:byte;
begin for i:=b to b+dm-1 do if a[i]=dum then write('x') else write(a[i]) end;
begin
gotoxy(x+3,y+1); wr_a(A,1);
gotoxy(x+3,y+2); wr_a(A,dm+1);
gotoxy(x+3,y+3); wr_a(B,1);
gotoxy(x+3,y+4); wr_a(B,dm+1);
gotoxy(x+3,y+5); wr_a(C,1);
gotoxy(x+3,y+6); wr_a(C,dm+1);
end;
procedure push(w:char);
begin
Stack[s_ct].A:=A; Stack[s_ct].B:=B; Stack[s_ct].C:=C;
{ gotoxy(s_ct+1,24); write(w); }
inc(s_ct);
end;
procedure pull;
begin
dec(s_ct);
{ gotoxy(s_ct+1,24); write(' '); }
A:=Stack[s_ct].A; B:=Stack[s_ct].B; C:=Stack[s_ct].C;
end;
procedure init_0;
var l:longint;
begin
{
table(14, 1); table(26, 1); table(38, 1); sh_ct1:=14;
table(14,12); table(26,12); table(38,12); sh_ct2:=14;
}
m:=0; t_record:=0; s_record:=0;
gotoxy(1,1);
{
writeln('M=000000000');
writeln('nrm='); writeln('mov=');
writeln('tov='); writeln('b_t=');
writeln('i_t='); writeln('c_l=');
writeln('s_l='); writeln('m_l=');
writeln('lNc=');
writeln('gMl=');
writeln('p_l='); writeln('pSl=');
}
{ writeln('brl='); writeln('bil='); }
{
writeln('eH0='); writeln('eH1=');
writeln('e0l='); writeln('e1l=');
writeln('eS0='); writeln('eS1=');
writeln('eS2=');
writeln('B-L=');
writeln('cl0=');
}
for l:=1 to e_max do e_cnt[l]:=0;
end;
procedure SetTMStdin();
var i,j:byte;
sz:word;
s:string;
procedure SetStd0(i,j:byte);
begin
if s[j+2]='-'
then A[i]:=0
else A[i]:=ord(s[j+2])-ord('@');
if s[j+1]='L'
then B[i]:=0 else B[i]:=1;
if s[j]='0'
then C[i]:=0 else C[i]:=1;
end;
begin
sz := 7*dm-1;
while true do begin
if (EOF(Input)) then Halt();
ReadLn(Input, s);
if Length(s) = 0 then continue
else if Length(s) = sz then break
else WriteLn('invalid input length, skipping line');
end;
WriteLn('Read machine from stdin: ', s);
for i:=1 to dm do begin
j:=(i-1)*7;
SetStd0(i,j+1);
SetStd0(dm+i,j+4);
end;
end;
procedure SetTM(s:string);
var i,j:byte;
procedure Set0(i,j:byte);
begin
if s[j]='H'
then A[i]:=0
else A[i]:=ord(s[j])-ord('@');
if s[j+2]='L'
then B[i]:=0 else B[i]:=1;
if s[j+1]='0'
then C[i]:=0 else C[i]:=1;
end;
begin
for i:=1 to dm do begin
j:=(i-1)*9;
Set0(i,j+1);
Set0(dm+i,j+5);
end;
end;
procedure init_t(a1:byte);
const x0=52; x1=x0+1;
var l:longint;
begin
for l:=1 to dm_2 do begin
A[l]:=dum;
B[l]:=dum;
if reversal
then if l<=dm then C[l]:=1 else C[l]:=0
else C[l]:=dum
end;
B[1]:=0;
if SameDir then B[1+dm]:=0;
if IgnoreFirstZero then C[1]:=1;
if a1=dm then begin
A[2]:=0;
if not SameDir then B[2]:=0;
C[2]:=1
end else begin
A[a1]:=0;
if not SameDir then B[a1]:=0;
if not reversal then C[a1]:=1
end;
if Destructive then begin
if reversal or SameDir then begin
writeln;
writeln('Reversal and SameDir must be false !!!');
Halt;
end;
for l:=1 to dm do C[dm+l]:=1;
end;
SetTMStdin();
{ SpecalSubClasses rev0/rev1 }
{ C[1]:=1; C[2]:=1; C[3]:=1; C[4]:=1; C[5]:=1; }
{ C[6]:=0; C[7]:=0; C[8]:=0; C[9]:=0; C[10]:=0; }
{ test some special machines: }
{ PackG_0 hint --> ExCnt>4 in ManyExones check }
{SetTM('C1L A0L H1L F0R D1R C0L A1L E0R F1R F0R D1R B0L | 42699 ExScan bug ');}
{ TM4 record }
{
A[1]:=3; A[2]:=0; A[3]:=1; A[4]:=4;
A[5]:=3; A[6]:=4; A[7]:=2; A[8]:=1;
B[1]:=0; B[2]:=0; B[3]:=1; B[4]:=0;
B[5]:=1; B[6]:=1; B[7]:=1; B[8]:=0;
C[1]:=1; C[2]:=1; C[3]:=1; C[4]:=1;
C[5]:=1; C[6]:=1; C[7]:=0; C[8]:=0;
}
{ TM5 M# 572813 Sigma record for TM5 }
{
A[1]:=3; A[2]:=0; A[3]:=4; A[4]:=1; A[5]:=1;
A[6]:=1; A[7]:=4; A[8]:=3; A[9]:=5; A[10]:=2;
B[1]:=0; B[2]:=0; B[3]:=1; B[4]:=0; B[5]:=0;
B[6]:=0; B[7]:=1; B[8]:=1; B[9]:=1; B[10]:=1;
C[1]:=1; C[2]:=1; C[3]:=1; C[4]:=1; C[5]:=1;
C[6]:=1; C[7]:=0; C[8]:=1; C[9]:=1; C[10]:=1;
}
{ TM5 M# 2001667 (dm+1) CollatzLoop gfin_max=1303 }
{
A[1]:=2; A[2]:=3; A[3]:=4; A[4]:=1; A[5]:=4;
A[6]:=0; A[7]:=5; A[8]:=3; A[9]:=5; A[10]:=2;
B[1]:=0; B[2]:=1; B[3]:=1; B[4]:=1; B[5]:=1;
B[6]:=0; B[7]:=0; B[8]:=0; B[9]:=1; B[10]:=0;
C[1]:=1; C[2]:=1; C[3]:=0; C[4]:=0; C[5]:=1;
C[6]:=1; C[7]:=1; C[8]:=1; C[9]:=1; C[10]:=0;
}
{ TM5 M# 5054949 (dm+1) - hint_1 }
{
A[1]:=2; A[2]:=3; A[3]:=4; A[4]:=4; A[5]:=1;
A[6]:=0; A[7]:=5; A[8]:=3; A[9]:=2; A[10]:=5;
B[1]:=0; B[2]:=1; B[3]:=1; B[4]:=0; B[5]:=0;
B[6]:=0; B[7]:=0; B[8]:=1; B[9]:=0; B[10]:=1;
C[1]:=1; C[2]:=1; C[3]:=0; C[4]:=1; C[5]:=1;
C[6]:=1; C[7]:=1; C[8]:=0; C[9]:=0; C[10]:=0;
}
{ TryBL_Loop examples: }
{ TM5 M# 408483 (dm+1) m_cnt must be at least 4 ! }
{
A[1]:=2; A[2]:=3; A[3]:=4; A[4]:=2; A[5]:=1;
A[6]:=0; A[7]:=2; A[8]:=4; A[9]:=5; A[10]:=3;
B[1]:=0; B[2]:=1; B[3]:=0; B[4]:=0; B[5]:=1;
B[6]:=0; B[7]:=0; B[8]:=1; B[9]:=1; B[10]:=1;
C[1]:=1; C[2]:=1; C[3]:=1; C[4]:=1; C[5]:=1;
C[6]:=1; C[7]:=0; C[8]:=1; C[9]:=1; C[10]:=0;
}
{ TM5 M# 5167582 (dm+1) TIntroneSet.strlen must be ~ 40 ! }
{
A[1]:=2; A[2]:=3; A[3]:=4; A[4]:=1; A[5]:=2;
A[6]:=0; A[7]:=5; A[8]:=3; A[9]:=5; A[10]:=3;
B[1]:=0; B[2]:=1; B[3]:=1; B[4]:=1; B[5]:=1;
B[6]:=0; B[7]:=0; B[8]:=0; B[9]:=1; B[10]:=0;
C[1]:=1; C[2]:=1; C[3]:=1; C[4]:=1; C[5]:=1;
C[6]:=1; C[7]:=1; C[8]:=0; C[9]:=0; C[10]:=1;
}
{ -------------------- }
{ TM5 M# 1602350 (dm+2) solved for rmax=3000 !!! }
{
A[1]:=3; A[2]:=1; A[3]:=4; A[4]:=5; A[5]:=1;
A[6]:=4; A[7]:=0; A[8]:=2; A[9]:=4; A[10]:=4;
B[1]:=0; B[2]:=0; B[3]:=1; B[4]:=1; B[5]:=1;
B[6]:=0; B[7]:=0; B[8]:=0; B[9]:=1; B[10]:=1;
C[1]:=1; C[2]:=0; C[3]:=1; C[4]:=0; C[5]:=1;
C[6]:=0; C[7]:=1; C[8]:=0; C[9]:=1; C[10]:=0;
}
{ TM5 M# 5504459 (dm+2) solved for cmax=4000 !!! }
{
A[1]:=3; A[2]:=4; A[3]:=4; A[4]:=1; A[5]:=2;
A[6]:=5; A[7]:=0; A[8]:=1; A[9]:=5; A[10]:=3;
B[1]:=0; B[2]:=0; B[3]:=1; B[4]:=0; B[5]:=0;
B[6]:=0; B[7]:=0; B[8]:=1; B[9]:=1; B[10]:=1;
C[1]:=1; C[2]:=0; C[3]:=1; C[4]:=1; C[5]:=1;
C[6]:=0; C[7]:=1; C[8]:=1; C[9]:=0; C[10]:=0;
}
{ --------- Last proved -------- }
{ dm_0 }
{
SetTM('C1L A1R H1L C1R D1L E1L B1R D1R A0R C0L | 10224040 | SRec | 20 | 0 4 0 8 0 6');
SetTM('C1L E1R H1L E0L D1L C0L A1R B1R D1R A0R | 10974233 | ---- | 316 | 0 7 5 10 0 17');
SetTM('C1L E1R H1L C1L D1L C0L A1R B0R D1R A0R | 10979960 | ---- | 325 | 0 6 5 9 0 16');
SetTM('C1L E0R H1L D0R D1L A0L A1R A1L B1R D1R | 11554135 | ---- | 654 | 0 0 4 6 2 0');
SetTM('C1L E1R H1L A1L D0R D0L B1L D1R A1L A0R | 21992948 | ---- |1340 | 0 0 3 13 0 5');
SetTM('C1L E1R H1L A1L D0R D0L B1L D1R A0R A0R | 21993025 | ---- |1312 | 0 0 3 13 0 5');
SetTM('C1L E1R H1L A1L D0R D0L B1L D1R A0R A0L | 21993204 | ---- |1625 | 0 0 3 13 0 5');
SetTM('C1L D1R H1L E1L D0R C0L E1R A1R A1L B1L | 22976011 | ---- | 32 | 0 5 4 0 4 9');
}
{ dm_2 }
{
SetTM('C1L C0R D0L H1L D1R E0L C1L E0R A1R B1L | 5585454 | ---- |3000 | 0 0 0 10 0 20');
SetTM('C1L D0R A0L H1L A1R D0L E1R B1L C1L C0R | 23741566 | ---- |3000 | 0 0 0 10 0 20');
SetTM('C1L E0L A1R H1L D0R E1L D1R B1R C0R A0L | 28775330 | SRec | 37 | 0 3 0 0 0 0');
SetTM('C1L D1R A1R H1L D0R E1L B1R D0L C0R E0L | 31305274 | SRec | 5 | 0 0 5 0 0 0');
SetTM('B1L A0R C1L H1L D1R A1L A0L E1R D0L E0R | 47443779 | SRec | 5 | 0 0 5 0 0 0');
}
{ STM_6 }
{
SetTM('C1L D0L H1L F0L D1R F0R E1R C0R F1R D0R B1L A0L | 83157 | ---- | 481 | 0 7 2');
}
{ --------- Not proved --------- }
{ STM_6 }
{
}
{ dm_0 }
{
SetTM('C1L E1L H1L D1L D1R D0L A1L E1R B0L C0R | 827123 | HH-- |3000 | 0 2 6 5 10 13');
SetTM('C1L E0R H1L C0R D1R A0L A1R D1R A1L B0R | 1668912 | H--- |3000 | 0 3 0 14 0 4');
SetTM('C1L A0R H1L E1L D1R B0L A1R C1R C0L D1L | 2523420 | ---- |1946 | 0 40 0 44 6 50');
SetTM('C1L D0R H1L E0L D1R C1L E1L A1R B1L D0L | 3911891 | H--- |1942 | 0 9 0 8 0 22');
SetTM('C1L B0R H1L C0R D1L C0L E0R C1L A0R E1R | 11997798 | ---- |3000 | 2 4 8 8 14 30');
SetTM('C1L D0R H1L E1L C1R A1R E0L D1R B1L C1L | 14788712 | SRec | 10 | 0 3 0 0 0 0');
SetTM('C1L D1R H1L C0L A1R C1L E1R A0R B1L E0L | 18119527 | H--- | 39 | 0 6 0 0 0 0');
SetTM('C1L C0L H1L D1R D0R C1L B1R E1R E1L A1L | 21155496 | SRec | 3 | 0 3 0 0 0 0');
SetTM('C1L B1L H1L E0L D0R C0L A1R D1R A0R B0L | 22046343 | SRec | 4 | 2 4 0 0 0 0');
SetTM('C1L E0L H1L E1L D0R A1L A0L C1R C1R B0L | 22600133 | H--- |3000 | 0 7 4 6 10 0');
}
{ dm_1 }
{
SetTM('B1L H1L C0R C0L E1L D0R C1R D1R B1R A0L | 12689995 | BL_1 |2759 | 0 0 4 6 0 0');
}
{
SetTM('B1L H1L C1R E0R D1L B0R D0L A1L C0R A0L | 5359517 | ---- |3000 | 0 6 10 14 17 21');
SetTM('B1L H1L C1L B1R D1R E1L B1R D0R A1L C0L | 6594274 | ---- | 337 | 0 6 0 14 0 7');
SetTM('B1L H1L C0R D1L D1R C1R E1L E0L A0L B0R | 11530505 | ---- |3000 | 2 0 0 11 3 3');
SetTM('B1L H1L C0R E1L D0R C1R A1L B1R B0L A0L | 11679832 | ---- |1012 | 0 0 0 7 12 0');
SetTM('B1L H1L C0R C1R D1R B1R E1L D1L A0R E0L | 11934239 | SRec | 15 | 0 4 0 0 0 0');
SetTM('B1L H1L C0L C1R D1L C1L E1R D1R A0L E0R | 14521014 | SRec | 3 | 3 0 0 0 0 0');
SetTM('B1L H1L C0L C1L D1L C1L E1R D1R A0L E0R | 14521098 | SRec | 3 | 3 0 0 0 0 0');
SetTM('B1L H1L C0L C1L D1L B1L E1R D1R A0L E0R | 14521100 | SRec | 4 | 0 4 0 0 0 0');
SetTM('B1L H1L C0L B1R D1L C1L E1R D1R A0L E0R | 14521240 | SRec | 4 | 4 0 0 0 0 0');
SetTM('B1L H1L C0L B0L C1R D0R A1L E0R A0R E0R | 15076017 | ---- |2349 | 2 2 3 9 0 0');
}
{ dm_2 }
{
SetTM('C1L E1L E1R H1L D1R C1R B0L D0R A0L A1L | 7119815 | SRec | 13 | 0 4 0 0 0 0');
SetTM('C1L E1R D1R H1L D1L C0L A1R D1L B1R A0R | 12568936 | ---- | 319 | 0 6 0 14 0 7');
SetTM('C1L B0R E0R H1L D0L C1L E1L C0L A1R C0R | 33424333 | ---- |3000 | 2 5 9 7 20 29');
SetTM('C1L D1R E1R H1L D0L C0L B1R A0R A1R E1L | 34364505 | ---- | 481 | 0 6 0 10 0 0');
SetTM('B1L D1L C1R H1L E1R D1R E1L C0R A1L D0L | 43710027 | ---- |3000 | 0 4 4 0 0 20');
SetTM('B1L A0L C1R H1L C0R D0R E1L B0L E0L A1L | 45963385 | ---- |3000 | 3 0 2 0 2 2');
SetTM('B1L A0R C0L H1L C1R D1L E1L A1R B0L D0R | 54769539 | ---- |3000 | 4 6 0 0 18 12');
Type _3N_:
SetTM('C1L D0L A1L H1L D1R E0R B0R C0R C1R B0L | 7915298 | ---- | 112 | 0 6 0 0 0 0');
SetTM('C1L B0R E1R H1L D1L A0L B0L C0L C1R D0R | 14934318 | ---- | 158 | 0 6 0 0 0 0');
SetTM('C1L E0L D1R H1L B0L A0L A1R C0R A1L B0R | 39779768 | ---- | 99 | 0 6 0 0 0 0');
}
{ ----- Not solved examples: -------- }
{ TM5 M# 8450515 (dm+2) TryBL_Loop hint }
{C1L A1L E1R H1L D1R A0L E1L B0R C0L C0R id 8450515}
{
A[1]:=3; A[2]:=5; A[3]:=4; A[4]:=5; A[5]:=3;
A[6]:=1; A[7]:=0; A[8]:=1; A[9]:=2; A[10]:=3;
B[1]:=0; B[2]:=1; B[3]:=1; B[4]:=0; B[5]:=0;
B[6]:=0; B[7]:=0; B[8]:=0; B[9]:=1; B[10]:=1;
C[1]:=1; C[2]:=1; C[3]:=1; C[4]:=1; C[5]:=0;
C[6]:=1; C[7]:=1; C[8]:=0; C[9]:=0; C[10]:=0;
}
{C1L E0L A1R H1L D1R A0L D0R B1R C0L B0R id 3198755 dm_2 }
{
A[1]:=3; A[2]:=1; A[3]:=4; A[4]:=4; A[5]:=3;
A[6]:=5; A[7]:=0; A[8]:=1; A[9]:=2; A[10]:=2;
B[1]:=0; B[2]:=1; B[3]:=1; B[4]:=1; B[5]:=0;
B[6]:=0; B[7]:=0; B[8]:=0; B[9]:=1; B[10]:=1;
C[1]:=1; C[2]:=1; C[3]:=1; C[4]:=0; C[5]:=0;
C[6]:=0; C[7]:=1; C[8]:=0; C[9]:=1; C[10]:=0;
}
{ TM5 M# 827123 BL_Mod ??? }
{
A[1]:=3; A[2]:=0; A[3]:=4; A[4]:=1; A[5]:=2;
A[6]:=5; A[7]:=4; A[8]:=4; A[9]:=5; A[10]:=3;
B[1]:=0; B[2]:=0; B[3]:=1; B[4]:=0; B[5]:=0;
B[6]:=0; B[7]:=0; B[8]:=0; B[9]:=1; B[10]:=1;
C[1]:=1; C[2]:=1; C[3]:=1; C[4]:=1; C[5]:=0;
C[6]:=1; C[7]:=1; C[8]:=0; C[9]:=1; C[10]:=0;
}
{ TM5 M# 1668912 mod 12/16 ??? }
{
A[1]:=3; A[2]:=0; A[3]:=4; A[4]:=1; A[5]:=1;
A[6]:=5; A[7]:=3; A[8]:=1; A[9]:=4; A[10]:=2;
B[1]:=0; B[2]:=0; B[3]:=1; B[4]:=1; B[5]:=0;
B[6]:=1; B[7]:=1; B[8]:=0; B[9]:=1; B[10]:=1;
C[1]:=1; C[2]:=1; C[3]:=1; C[4]:=1; C[5]:=1;
C[6]:=0; C[7]:=0; C[8]:=0; C[9]:=1; C[10]:=0;
}
{ TM5 M# 2523420 BL_mod ??? }
{
A[1]:=3; A[2]:=0; A[3]:=4; A[4]:=1; A[5]:=3;
A[6]:=1; A[7]:=5; A[8]:=2; A[9]:=3; A[10]:=4;
B[1]:=0; B[2]:=0; B[3]:=1; B[4]:=1; B[5]:=0;
B[6]:=1; B[7]:=0; B[8]:=0; B[9]:=1; B[10]:=0;
C[1]:=1; C[2]:=1; C[3]:=1; C[4]:=1; C[5]:=0;
C[6]:=0; C[7]:=1; C[8]:=0; C[9]:=1; C[10]:=1;
}
{ TM5 M# 3911891 BL_mod or pSl_2 ??? }
{
A[1]:=3; A[2]:=0; A[3]:=4; A[4]:=5; A[5]:=2;
A[6]:=4; A[7]:=5; A[8]:=3; A[9]:=1; A[10]:=4;
B[1]:=0; B[2]:=0; B[3]:=1; B[4]:=0; B[5]:=0;
B[6]:=1; B[7]:=0; B[8]:=0; B[9]:=1; B[10]:=0;
C[1]:=1; C[2]:=1; C[3]:=1; C[4]:=1; C[5]:=1;
C[6]:=0; C[7]:=0; C[8]:=1; C[9]:=1; C[10]:=0;
}
{ TM5 M# 51813884 x(n)y(2n)z --> u(n)x(2n)yz }
{
A[1]:=3; A[2]:=0; A[3]:=4; A[4]:=1; A[5]:=3;
A[6]:=2; A[7]:=1; A[8]:=3; A[9]:=5; A[10]:=5;
B[1]:=0; B[2]:=0; B[3]:=1; B[4]:=0; B[5]:=1;
B[6]:=0; B[7]:=0; B[8]:=0; B[9]:=1; B[10]:=1;
C[1]:=1; C[2]:=1; C[3]:=1; C[4]:=0; C[5]:=1;
C[6]:=1; C[7]:=0; C[8]:=1; C[9]:=0; C[10]:=1;
}
{ TM5 M# 6311798 ??? }
{
A[1]:=3; A[2]:=0; A[3]:=4; A[4]:=1; A[5]:=3;
A[6]:=1; A[7]:=4; A[8]:=5; A[9]:=3; A[10]:=2;
B[1]:=0; B[2]:=0; B[3]:=1; B[4]:=0; B[5]:=1;
B[6]:=0; B[7]:=0; B[8]:=0; B[9]:=1; B[10]:=0;
C[1]:=1; C[2]:=1; C[3]:=1; C[4]:=1; C[5]:=1;
C[6]:=1; C[7]:=0; C[8]:=0; C[9]:=0; C[10]:=0;
}
{ TM5 M# 123831 (dm+2) }
{
A[1]:=3; A[2]:=1; A[3]:=4; A[4]:=2; A[5]:=3;
A[6]:=5; A[7]:=0; A[8]:=5; A[9]:=5; A[10]:=1;
B[1]:=0; B[2]:=0; B[3]:=1; B[4]:=1; B[5]:=1;
B[6]:=0; B[7]:=0; B[8]:=1; B[9]:=1; B[10]:=0;
C[1]:=1; C[2]:=1; C[3]:=1; C[4]:=1; C[5]:=1;
C[6]:=1; C[7]:=1; C[8]:=0; C[9]:=1; C[10]:=0;
}
{ --------- end of not solved ---------- }
{ ----------- ShiftRec machines (hand proved) ------------- }
{ TM5 M# 764350 (dm+1) bin_spec ??? }
{
A[1]:=2; A[2]:=3; A[3]:=5; A[4]:=3; A[5]:=4;
A[6]:=0; A[7]:=1; A[8]:=4; A[9]:=2; A[10]:=5;
B[1]:=0; B[2]:=1; B[3]:=0; B[4]:=1; B[5]:=1;
B[6]:=0; B[7]:=0; B[8]:=1; B[9]:=0; B[10]:=0;
C[1]:=1; C[2]:=1; C[3]:=1; C[4]:=0; C[5]:=0;
C[6]:=1; C[7]:=0; C[8]:=1; C[9]:=0; C[10]:=0;
}
s_ct:=0; push('\');
{
table (x0,12); wr_mash(x0,12);
gotoxy(x1,19); write('c=',cmax:6);
gotoxy(x1,20); write('m=',mmax:6);
}
end;
function HTSize(s:string):longint;
begin
HTSize:=length(s)-1;
end;
procedure wr_state(var f:text; var CD:TDescr);
var spc:longint; ws,l1,r1:string;
procedure Ch(var l:string);
begin
case l[1] of
'.':l[1]:='^';
'-':l[1]:='=';
'+':l[1]:='#';
end;
end;
begin
with CD do begin
spc:=20-md+p-HTSize(l); ws:='';
while spc>0 do begin dec(spc); ws:=ws+' ' end;
write(f,p:4,' ',SD_str(s,md),ws);
l1:=l; r1:=r;
if md=0 then Ch(l1) else Ch(r1);
writeln(f,RevStr(l1),r1);
end;
end;
procedure wr_history(var f:text);
var i,lim:longint;
begin
writeln(f);
writeln(f,'--------- Simple History: ---------');
SH[SH_cnt]:=CD;
lim:=SH_cnt; if lim>dump_max then lim:=dump_max;
for i:=0 to lim do begin
write(f,i:4,': ');
wr_state(f,SH[i]);
end;
writeln(f);
writeln(f,'-----------------------------------');
end;
var
p_left,p_right:longint;
function MemUsed(var D:TDescr):longint;
begin
MemUsed:={HTSize(D.l)+HTSize(D.r)} p_right-p_left+1;
end;
{ --- Making a simple step: --- }
type
bitchar=array[0..1] of char;
const
V_str:bitchar=('-','+');
function GetDV(var D:TDescr):byte;
function V(l:string):byte;
begin
if l='.' then V:=0 else if l[1]='-' then V:=0 else V:=1
end;
begin
if D.md=0 then GetDV:=V(D.l) else GetDV:=V(D.r)
end;
procedure Expand(var s:string; n:byte);
begin if s[length(s)]='.' then begin
s[length(s)]:='-';
while length(s)<n do s:=s+'-';
end end;
function GetF(s:string; n1,n2:longint):string;
var w:string;
begin if n2=0 then GetF:='' else begin
w:=copy(s,n1,n2); if w='' then w:='.';
Expand(w,n2); GetF:=w;
end end;
function MSign(s:string):boolean;
var n:byte;
begin
MSign:=true;
for n:=1 to length(s) do if s[n]<>'-' then MSign:=false;
end;
{ -------------- Proof utilities ---------- }
const
EL_base={ord('a')} 128+64;
EL_leter=ord('a');
E_leters=[chr(EL_base)..chr(EL_base+63)];
const
digits=['0'..'9'];
leters=['a'..'z'];
var
pr_fail:boolean;
fin_att:longint;
{ --------- AF primitives ------------ }
{ AF = int | var | var+int | var-int }
{ var = small_leter ('u' - for error ) }
procedure AF_dec(var s:string; n:longint);
var m,i:longint; v,sign:char; ws:string;
procedure make(n:longint);
begin
Str(n,ws);
if n>0 then s:=v+'+'+ws
else if n=0 then s:=v
else s:=v+ws;
end;
begin if s<>'u' then begin
v:=s[1];
if v in digits then begin
val(s,m,i);
if m-n<0 then s:='u' else Str(m-n,s);
end else begin
delete(s,1,1);
if s<>'' then begin
sign:=s[1]; delete(s,1,1);
val(s,m,i);
case sign of
'-':make(0-m-n);
'+':make(m-n)
end;
end else make(0-n)
end;
end end;
procedure AF_inc(var s:string; n:longint);
begin AF_dec(s,-n) end;
function AF_add(s1,s2:string):string;
var s,w:string;
procedure Add(f,sn:string);
var m,i:longint;
begin
s:=f;
val(sn,m,i);
AF_inc(s,m);
end;
begin
if s2[1] in digits then Add(s1,s2)
else if s1[1] in digits then Add(s2,s1)
else if (s1[1]='x') and (s2[1]='x')
then begin { x is special var for modulo arithmetick !!! }
w:=s2; delete(w,1,2);
Add(s1,w);
end else s:='u';
AF_add:=s;
end;
function AF_make_mod(s:string; modulo:longint):string;
var m,i:longint; w:string;
begin
val(s,m,i);
m:=m mod modulo;
if m=0 then m:=modulo;
Str(m,w);
AF_make_mod:='x+'+w;
end;
function AF_adjust_mod(var s:string; modulo:longint):boolean;
var m,i:longint; w:string;
begin
if s='x' then begin
AF_adjust_mod:=true;
Str(modulo,w);
s:='x+'+w;
end else begin
AF_adjust_mod:=false;
w:=s; delete(w,1,2);
val(w,m,i);
m:=m mod modulo;
if m=0 then m:=modulo;
Str(m,w);
s:='x+'+w;
end;
end;
{ ----------------------------------- }
procedure UnpackFirst(var l:string);
var pat,cnt:string; x,y:longint;
begin if l[1]='(' then begin
x:=Pos('|',l);
pat:=copy(l,2,x-2);
y:=Pos(')',l);
cnt:=copy(l,x+1,y-x-1);
if cnt='1'
then l:=pat+copy(l,y+1,length(l)-y)
else begin
AF_dec(cnt,1);
l:=pat+'('+pat+'|'+cnt+')'+copy(l,y+1,length(l)-y)
end;
end end;
function TestForPatt(c1,l:string):byte;
begin
TestForPatt:=0;
if c1=GetF(l,1,length(c1))
then TestForPatt:=1
else if l[1]='('
then if c1=copy(l,2,Pos('|',l)-2)
then TestForPatt:=2;
end;
function TestForROLPatt(c1:string; var l:string):byte;
var n:byte; h,c2,l1,cnt:string;
begin
TestForROLPatt:=0;
if c1=GetF(l,1,length(c1))
then TestForROLPatt:=1
else if l[1]='(' then begin
if c1=copy(l,2,Pos('|',l)-2)
then TestForROLPatt:=2;
end else begin
n:=Pos('(',l);
if (n>1) and (n-1<length(c1)) then begin
h:=copy(l,1,n-1);
l1:=l; delete(l1,1,n-1);
c2:=copy(l1,2,Pos('|',l1)-2);
if c1+h=h+c2 then begin
TestForRolPatt:=3;
delete(l1,1,Pos('|',l1)-1);
cnt:=copy(l1,1,Pos(')',l1));
delete(l1,1,Pos(')',l1));
l:='('+c1+cnt+h+l1;
end;
end;
end;
end;
procedure incS(a:string; var s:string; af:boolean);
begin
if length(a)+length(s)>mmax then
if af then pr_fail:=true else e_state:=mem_ov;
s:=a+s;
while (length(s)>1) and (s[length(s)-1]='-')
do delete(s,length(s)-1,1);
end;
function EatPatt(var c1,l:string; kill:boolean):string;
var pat,cnt,old:string; n,x,y:longint; endt:boolean;
begin
n:=0; old:=l; cnt:='0';
case TestForROLPatt(c1,l) of
1:begin
endt:=false;
repeat
delete(l,1,length(c1));
if l='' then begin
l:='.';
endt:=MSign(c1);
end;
inc(n);
pat:=GetF(l,1,length(c1));
until (pat<>c1) or endt;
if kill and endt then e_state:=m_loop;
Str(n,cnt);
end;
2,3:begin
x:=Pos('|',l);
y:=Pos(')',l);
cnt:=copy(l,x+1,y-x-1);
l:=copy(l,y+1,length(l)-y);
end;
end;
if old=l
then EatPatt:=cnt
else EatPatt:=AF_add(cnt,EatPatt(c1,l,kill));
end;
var
rep_min,rule_min:longint;
procedure IncPatt(var c,l,cnt:string; af:boolean; n:byte);
var i,j:longint;
begin
if cnt[1] in digits
then Val(cnt,i,j) else i:=999;
if i<=rep_min+n
then for j:=1 to i do incS(c,l,af)
else incS('('+c+'|'+cnt+')',l,af);
end;
function ShiftPatt(var r,c0,l,c1:string; af:boolean):string;
var cnt,n,m:string;
begin
n:=EatPatt(c0,r,true);
m:=EatPatt(c1,l,false);
cnt:=AF_add(n,m);
IncPatt(c1,l,cnt,af,0);
ShiftPatt:=n;
end;
{
There is something wrong with procedure PackPatt.
After i apply it, the tov increased by 124 for RTM(5)
The following tests decreased:
c_l with 32, m_l with 48, lNc with 44.
After some improvements this is corrected, but this
mechanism seems to be ensure.
}
const IP_rec:byte=0;
type
TIRule = record
s,md:byte;
l,r,h:string;
end;
var
IPArr: array[byte] of TIRule;
IP_cnt:byte;
function SimStr(s1,s2:string):boolean; forward;
procedure PackPatt(var l,r:string; af:boolean; s,md:byte);
var n,i,k:longint; h,h1,t,t1,cnt:string; succ:boolean; n1:byte;
function IPexist:boolean;
var i:byte;
begin
IPexist:=false;
if IP_cnt>0 then for i:=0 to IP_cnt-1 do
if (IPArr[i].l=t1) and (IPArr[i].h=h) and
(IPArr[i].md=md) and (IPArr[i].s=s) and
SimStr(r,IPArr[i].r)
then IPexist:=true;
end;
procedure Pack;
begin
if TestForPatt(h,t)>0 then begin
cnt:=EatPatt(h,l,false);
if rule_min>0
then IncPatt(h,l,cnt,af,0)
else IncPatt(h,l,cnt,af,9);
succ:=true;
end;
end;
procedure Pack_2;
var succ:boolean;
begin
succ:=true;
while length(h)>=length(h1) do begin
if Pos(h1,h)<>1 then succ:=false;
delete(h,1,length(h1));
end;
if succ and (h='') then begin
cnt:=EatPatt(h1,l,false);
if rule_min>0
then IncPatt(h1,l,cnt,af,0)
else IncPatt(h1,l,cnt,af,9);
end;
end;
begin
n:=Pos('(',l); succ:=false;
if n=0 then begin
n:=length(l);
if n>4 then for i:=1 to (n div 3) do
if (rule_min=0) or (rule_min=i) then begin
h:=copy(l,1,i); t:=l;
delete(t,1,i);
if (not succ) and (Pos(h,t)=1) then begin
t1:=t; k:=1;
while Pos(h,t1)=1 do
begin delete(t1,1,i); inc(k) end;
if length(t1)>1 then begin
n1:=length(t1)-1;
if (Pos(copy(t1,1,n1),h)=1) and
MSign(copy(h,n1+1,length(h)-n1))
then begin inc(k); t1:='.' end;
end;
{ PackPatt tuning }
if (k>dm) or ((k>1) and (rule_min>0)) then begin
if (not IPexist) and (IP_cnt<255) then begin
IPArr[IP_cnt].l:=t1;
IPArr[IP_cnt].r:=r;
IPArr[IP_cnt].h:=h;
IPArr[IP_cnt].s:=s;
IPArr[IP_cnt].md:=md;
inc(IP_cnt);
if IP_cnt>IP_rec then begin
IP_rec:=IP_cnt;
gotoxy(55,3); write('IP_max=',IP_rec,' ');
end;
end;
if IP_cnt<255 then Pack;
end;
end;
end;
end else if n>1 then begin
h:=copy(l,1,n-1); t:=l;
delete(t,1,n-1); t1:=t;
h1:=copy(t,2,Pos('|',t)-2);
Pack_2;
(*
delete(t1,1,Pos(')',t1));
if (rule_min>0) { and (rule_min<>length(h1)) } then
if (Pos(h1,h)=1) and (length(h) mod length(h1)=0)
then h:=h1;
if IPexist then Pack;
*)
end;
end;
procedure MakeDStep(var D:TDescr; s1,v1,d1:byte; macro:byte);
procedure MovV(var l,r:string);
begin
if (v1=1) or (r<>'.') then r:=V_str[v1]+r;
if length(r)>D.smax then D.smax:=length(r);
if l<>'.' then delete(l,1,1);
end;
procedure SetV(var l,r:string);
begin
if (l<>'.') then begin
l[1]:=V_str[v1];
if l='-.' then l:='.'
end else if v1=1 then l:='+.';
if (macro=1) and (ms_cnt>3) {and (rule_min<=dm_2)}
then PackPatt(l,r,D.af,D.s,D.md);
end;
begin with D do begin
if md=0 then UnpackFirst(l) else UnpackFirst(r);
if af and (macro>0)
then begin
d_c:='1';
if d1=0 then d_p:='-1' else d_p:='1';
end
else begin inc(c); p:=p+d1+d1-1; end;
if (not af) and (macro=0) and
(p>-mmax) and (p<mmax) then inc(PosStat[p][md,s]);
s:=s1;
rn:=-1;
if d1=md
then if md=0 then MovV(l,r) else MovV(r,l)
else if md=0 then SetV(l,r) else SetV(r,l);
md:=d1;
if smax>=mmax then if af
then pr_fail:=true else e_state:=mem_ov;
end end;
function VarSCnt(s:string):longint;
var n:longint; w:string;
begin
n:=0; w:=s;
while pos('|',w)>0 do begin
inc(n); delete(w,1,pos('|',w));
end;
VarSCnt:=n;
end;
function SetNextVCnt(var s:string; v:char):char;
var w:string; n:byte; v1:char;
begin
v1:=v;
n:=pos('|',s);
if n>0 then begin
w:=copy(s,1,Pos('|',s));
delete(s,1,pos(')',s));
v1:=SetNextVCnt(s,chr(ord(v)+1));
s:=w+v+')'+s;
end;
SetNextVCnt:=v1;
end;
procedure SetAllVCnt(var s:string; v:char);
var w:string; n:byte;
begin
n:=pos('|',s);
if n>0 then begin
w:=copy(s,1,Pos('|',s));
delete(s,1,pos(')',s));
SetAllVCnt(s,v);
s:=w+v+')'+s;
end;
end;
procedure SetAllModVCnt(var s:string; m:longint);
var w,w1:string; n:byte;
begin
n:=pos('|',s);
if n>0 then begin
w:=copy(s,1,Pos('|',s));
delete(s,1,Pos('|',s));
w1:=copy(s,1,pos(')',s)-1);
delete(s,1,pos(')',s));
SetAllModVCnt(s,m);
s:=w+AF_make_mod(w1,m)+')'+s;
end;
end;
procedure SetVCnt(var s:string; v:string);
var w:string;
begin
w:=copy(s,1,Pos('|',s));
delete(s,1,pos(')',s));
s:=w+v+')'+s;
end;
procedure EraseVCnt(var s:string);
var w:string;
begin
w:=copy(s,1,Pos('(',s)-1);
delete(s,1,pos(')',s));
s:=w+s;
end;
function GetVCnt(s:string):string;
var w:string;
begin
w:=s;
delete(w,1,pos('|',w));
GetVCnt:=copy(w,1,pos(')',w)-1);
end;
function SimStr(s1,s2:string):boolean;
var k,n1,n2:longint; w1,w2:string; succ:boolean;
begin
succ:=true;
k:=VarSCnt(s1);
w1:=s1; w2:=s2;
if k=VarSCnt(s2) then begin
while (k>0) and succ do begin
n1:=pos('|',w1);
n2:=pos('|',w2);
succ:=copy(w1,1,n1)=copy(w2,1,n2);
delete(w1,1,pos(')',w1));
delete(w2,1,pos(')',w2));
dec(k);
end;
if succ then succ:=w1=w2;
end else succ:=false;
SimStr:=succ;
end;
function VarCount(var D:TDescr):longint;
begin
VarCount:=VarSCnt(D.l)+VarSCnt(D.r);
end;
function SimMacro(var D1,D2:TDescr):boolean;
begin
SimMacro:=
SimStr(D1.l,D2.l) and SimStr(D1.r,D2.r)
and (D1.s=D2.s) and (D1.md=D2.md);
end;
function SimMacro2(var D1,D2:TDescr):boolean;
begin
SimMacro2:=
(D1.l=D2.l) and (D1.r=D2.r)
and (D1.s=D2.s) and (D1.md=D2.md);
end;
procedure MakeMStep(var D:TDescr); forward;
const
gfin_max=2000
{ 1600 is good, but small for some Exone proofs for dm_1 set }
{1350} {3000 is max} { 1350 need for Modulo proof };
{ gfin_max=549; }
{ 549 is good for RTM(5), 548 is small }
type
TGNode = record
checked:boolean;
D,Dnext:TDescr;
end;
TGraph = array[0..2*gfin_max] of TGNode;
var
gfin_lim:longint;
CTG:TGraph;
CTG_cnt:longint;
CTGs:TGraph;
CTGs_cnt:longint;
procedure TryL1Cnt(var D:TDescr; maxstep:longint);
var
DF0,DF1:TDescr; i:longint; succ:boolean; lf:string;
GTN:TGNode;
procedure Test(l1:string);
var l:string;
begin
l:=l1;
while VarSCnt(l)>0 do begin
lf:=GetVCnt(l);
if ((length(lf)>1) and (lf[2]='-')) or (lf='u') then succ:=false;
EraseVCnt(l);
end;
end;
begin
DF0:=D;
with DF0 do begin
af:=true; p:=0; c:=0;
SetNextVCnt(l,SetNextVCnt(r,'a'));
end;
DF1:=DF0;
i:=0; succ:=false; pr_fail:=false;
while (not succ) and (not pr_fail) and (i<=maxstep) do begin
GTN.D:=DF1;
MakeMStep(DF1);
GTN.DNext:=DF1;
GTN.checked:=true;
if i<gfin_max then begin
CTG[i]:=GTN;
CTG_cnt:=i+1;
end;
if not pr_fail then succ:=SimMacro(DF1,DF0);
inc(i);
end;
if succ and (not pr_fail) then begin
with DF1 do begin Test(l); Test(r) end;
if succ then begin
e_state:=lNct_l;
end;
end;
end;
procedure wr_grapf(var f:text; var CTG:TGraph; CTG_cnt:longint; all:boolean);
var i:longint;
function tr(l:string):string;
var s:string; i:byte;
begin
s:=l;
for i:=1 to length(s) do
if ord(s[i])>=EL_base then
s[i]:=chr(ord(s[i])+EL_leter-EL_base);
tr:=s;
end;
begin
writeln(f,'Closed transition graph proof follows:');
if all
then writeln(f,' ind rule l_mark/r_mark LsdR')
else writeln(f,' ind rule LsdR');
for i:=0 to CTG_cnt-1 do with CTG[i] do begin
with D do begin
write(f,i:4,rn:5,': ');
{ if all then write(f,l_mark:10,'/',r_mark:10,' '); }
write(f,RevStr(tr(l))+SD_str(s,md)+tr(r):25);
end;
if checked
then with DNext do writeln(f,' --> ',RevStr(tr(l)),SD_str(s,md),tr(r))
else writeln(f);
end;
end;
procedure CollatzLoop(
var CD:TDescr; var MH:THistory;
var MH_cnt:longint; lim:longint); forward;
procedure TryModFin(var D0:TDescr; v_max:longint);
var DF,DF1:TDescr; i,modulo:longint; lf:string; reps:boolean;
function ChangeCtrs(l,l1:string):boolean;
var w,w1:string;
begin
if VarSCnt(l)>0 then w:=GetVCnt(l) else w:='*';
if VarSCnt(l1)>0 then w1:=GetVCnt(l1) else w1:='*';
ChangeCtrs:=w<>w1;
end;
function ZCheck(var l:string):boolean;
begin
if VarSCnt(l)>0 then begin
lf:=GetVCnt(l);
ZCheck:=AF_adjust_mod(lf,modulo);
SetVCnt(l,lf);
end else ZCheck:=false;
end;
procedure Form(var l:string; modul:longint);
var lf:string;
begin if VarSCnt(l)>0 then begin
lf:=GetVCnt(l);
if lf[1]<>'x' then lf:=AF_make_mod(lf,modul);
SetVCnt(l,lf);
end end;
function OldVertex(var CTG:TGraph; CTG_cnt:longint):boolean;
var j:longint;
begin
OldVertex:=false;
for j:=0 to CTG_cnt-1 do if SimMacro2(DF,CTG[j].D)
then OldVertex:=true;
end;
procedure AddVertex(var CTG:TGraph; var CTG_cnt:longint);
begin
if not OldVertex(CTG,CTG_cnt) then if CTG_cnt<gfin_max then begin
CTG[CTG_cnt].D:=DF;
CTG[CTG_cnt].checked:=false;
inc(CTG_cnt);
end else pr_fail:=true;
end;
procedure MakeModStep(var DF:TDescr; modul:longint);
begin
MakeMStep(DF);
Form(DF.l,modul); Form(DF.r,modul);
if VarCount(DF)>v_max then pr_fail:=true;
end;
procedure EvalModulo;
function EvalDiff(s1,s2:string; m:longint):longint;
var c1,c2,w1,w2:string; m1,m2,i:longint;
begin
if VarSCnt(s1)=0
then EvalDiff:=m
else begin
c1:=GetVCnt(s1);
c2:=GetVCnt(s2);
w1:=s1; w2:=s2;
delete(w1,1,Pos(')',w1));
delete(w2,1,Pos(')',w2));
delete(c1,1,1);
delete(c2,1,1);
if c1='' then m1:=0 else val(c1,m1,i);
if c2='' then m2:=0 else val(c2,m2,i);
{ writeln(ttm,'m1=',m1,' m2=',m2); }
m1:=m1-m2; if m1<0 then m1:=-m1;
{ writeln(ttm,'delta=',m1,' m=',m); }
if m1=0 then i:=m else i:=nok(m,m1);
{ writeln(ttm,'new_mod=',i); }
EvalDiff:=EvalDiff(w1,w2,i);
end;
end;
const i_max=200;
begin
DF:=D0;
with DF do begin
af:=true; p:=0; c:=0;
SetAllModVCnt(l,1000); SetAllModVCnt(r,1000);
end;
pr_fail:=false;
i:=0; DF1:=DF;
repeat
MakeModStep(DF,1000);
inc(i);
until (i=i_max) or SimMacro(DF,DF1) or pr_fail;
if (i<i_max) and (not pr_fail) then begin
modulo:=EvalDiff(DF.l,DF1.l,1);
modulo:=EvalDiff(DF.r,DF1.r,modulo);
end else modulo:=0;
end;
begin
gotoxy(55,5); write('M_m=',m,'/',v_max div 2);
EvalModulo;
if modulo>0 then begin
{
writeln(ttm,'M=',m,' ModTry=',modulo,' rule_min=',rule_min);
}
DF:=D0;
with DF do begin
af:=true; p:=0; c:=0;
SetAllModVCnt(l,modulo); SetAllModVCnt(r,modulo);
end;
pr_fail:=false;
CTG_cnt:=1; i:=0;
with CTG[0] do begin D:=DF; checked:=false end;
{
writeln(ttm);
writeln(ttm,'Original: ',TD_str(D0));
writeln(ttm,'Formula: ',TD_str(DF));
writeln(ttm); flush(ttm);
}
repeat
DF:=CTG[i].D; CTG[i].checked:=true;
CTGs_cnt:=1; CTGs[0].D:=DF;
repeat
DF1:=DF;
MakeModStep(DF,modulo);
reps:=OldVertex(CTGs,CTGs_cnt);
if not reps then AddVertex(CTGs,CTGs_cnt);
until ChangeCtrs(DF.l,DF1.l) or ChangeCtrs(DF.r,DF1.r)
or reps
or OldVertex(CTG,CTG_cnt)
or pr_fail;
CTG[i].DNext:=DF;
if not pr_fail then
if ZCheck(DF.l) then begin
ZCheck(DF.r);
AddVertex(CTG,CTG_cnt);
EraseVCnt(DF.l);
AddVertex(CTG,CTG_cnt);
end else if ZCheck(DF.r) then begin
AddVertex(CTG,CTG_cnt);
EraseVCnt(DF.r);
AddVertex(CTG,CTG_cnt);
end else AddVertex(CTG,CTG_cnt);
inc(i)
until (i=CTG_cnt) or pr_fail;
if pr_fail then begin
{wr_grapf(ttm,CTG,CTG_cnt,false);}
if DF.s=0 then CollatzLoop(Cl_M,ClMH,ClMH_cnt,cmax div 20);
end else begin
e_state:=modf_l;
writeln(ttm,'M=',m,' modulo=',modulo,' r_min=',rule_min,' g_max=',CTG_cnt);
flush(ttm);
end;
end;
end;
const max_att=2;
procedure TryInfinity(var D:TDescr);
var vc0,vc1,i:longint; succ,fail:boolean;
D1:TDescr; vcm:longint;
begin
if (e_state=0)
then begin
vc0:=VarCount(D);
vcm:=vc0; D1:=D;
if { true } vc0>0 then begin
succ:=false; fail:=false; i:=MH_cnt;
while (not succ) and (not fail) and (i>0) do begin
dec(i);
vc1:=VarCount(MH[i]);
if vc1<vc0
then fail:=true
else if vc1=vc0
then succ:=SimMacro(D,MH[i])
else if vc1>vcm then begin vcm:=vc1; D1:=MH[i] end;
end;
if succ and (not fail) then if vc0>0 then begin
inc(fin_att);
{ a..z variables are usable }
if (vc0<10 {27}) and (fin_att<max_att) then TryL1Cnt(D,MH_cnt-i);
{ Try to prove linear seq MH[i] ... --> D }
if e_state=0 then begin
if (gfin_lim>1600) or
((gfin_lim>600 {1000}) and (rule_min>0))
then begin
if (e_state in [0,mem_ov,too_lng])
and (
((vcm>vc0) and (fin_att<20*max_att)) or
{ ((vcm=3)) or }
((vcm>=vc0) and (fin_att<2*max_att))
)
and (vcm<6{10})
and (D.c>50)
then begin
{
writeln(ttm,'---- vc0/vcm= ',vc0,'|',vcm,' fin_att=',fin_att,' delta_i=',MH_cnt-i);
writeln(ttm,'Previous: ',TD_str(MH[i]));
writeln(ttm,'Current: ',TD_str(D1));
flush(ttm);
}
TryModFin(D1,vcm+vcm);
end;
end;
end;
end{ else e_state:=c_loop };
end;
end;
end;
function SuccBStep(var D:TDescr):boolean;
var fail:boolean; i:longint;
function Test(var l,r:string):boolean;
var a0,c0a:string; j:longint; succ:boolean;
begin
succ:=false;
with BSRules[i] do begin
a0:=GetF(l,1,length(a));
if a0=a then for j:=0 to Patt_cnt-1 do
if not succ then begin
c0a:=GetF(r,1,length(Patts[j].c0));
if c0a=Patts[j].c0 then begin
succ:=true;
inc(ucnt); inc(Patts[j].ucnt);
D.rname:=Chr(ord('a')+id)+chr(ord('0')+j);
delete(l,1,length(a));
if l='' then l:='.';
delete(r,1,length(c0a));
if r='' then r:='.';
if r='.' then begin
inc(ucnt,1 {10} ); inc(Patts[j].ucnt,1 {10});
end;
D.c:=D.c+Patts[j].c;
if D.md=1
then D.p:=D.p+length(c0a)
else D.p:=D.p-length(c0a);
incS(Patts[j].c1,l,D.af);
incS(a,l,D.af);
end;
end;
end;
Test:=succ;
end;
begin
fail:=true;
i:=0; D.rname:='--';
while fail and (i<BSR_cnt) do begin
with BSRules[i] do
if (D.md=md) and (D.s=s) then if md=1
then fail:=not Test(D.l,D.r)
else fail:=not Test(D.r,D.l);
inc(i);
end;
SuccBStep:=not fail;
end;
function SuccMStep(var D:TDescr; var SRules:TRuleArr; SR_cnt:longint):boolean;
var fail:boolean; i,cnt,j:longint; wr,fcnt:string;
function Test(var l,r:string):boolean;
var a0:string; SR:TRule; rep:longint;
procedure Mul(var s:string);
var w:string; i:longint;
begin
w:=s;
if rep>1 then for i:=1 to rep-1 do s:=s+w;
end;
begin
SR:=SRules[i];
with SR do begin
if rule_min>0 then begin
rep:=rule_min div length(c0);
p:=p*rep; c:=c*rep;
Mul(c0); Mul(c1);
end;
Test:=false;
a0:=GetF(l,1,length(a));
if a0=a then begin
wr:=r;
if TestForROLPatt(c0,wr)>0 then begin
SRules[i].used:=true;
Test:=true;
D.rn:=id;
delete(l,1,length(a));
if l='' then l:='.';
r:=wr;
fcnt:=ShiftPatt(r,c0,l,c1,D.af);
if D.af then begin
Str(p,wr); D.d_p:=wr+'*('+fcnt+')';
Str(c,wr); D.d_c:=wr+'*('+fcnt+')';
end else begin
val(fcnt,cnt,j);
if cnt>1 then inc(ms_cnt);
D.p:=D.p+p*cnt; D.c:=D.c+c*cnt;
if cnt<spec_max
then inc(SRules[i].spectrum[cnt])
else inc(SRules[i].spectrum[spec_max]);
end;
incS(a,l,D.af);
end;
end;
end end;
begin
fail:=true;
i:=0;
while fail and (i<SR_cnt) do begin
with SRules[i] do
if (D.md=md) and (D.s=s) and
((rule_min=0) or (rule_min mod length(c0) = 0)) and
allowed
then if p>0
then fail:=not Test(D.l,D.r)
else fail:=not Test(D.r,D.l);
inc(i);
end;
SuccMStep:=not fail;
end;
{----------------------------------}
procedure wr_bmhistory(var f:text; lmax:longint); forward;
procedure wr_exones(var f:text); forward;
procedure wr_mmhistory(var f:text; lmax:longint);
var i,lim:longint;
begin
MMH[MMH_cnt]:=CMM;
lim:=lmax;
if lim>MMH_cnt then lim:=MMH_cnt;
writeln(f);
writeln(f,'First ',lmax,' main macro steps:');
writeln(f,' ind rules p c LsdR');
for i:=0 to lim do with MMH[i] do begin
write(f,i:4,' ',rname0+' '+rname1:7,p:6,c:10,': ');
writeln(f,RevStr(l),SD_str(s,md),r);
end;
writeln(f);
if OSR_main>=0 then wr_bmhistory(f,3000);
wr_exones(f);
end;
procedure wr_bhistory(var f:text; lmax:longint);
var i,lim:longint; rn0:string;
begin
BH[BH_cnt]:=CB;
writeln(f);
writeln(f,'First ',lmax,' basic steps:');
writeln(f,' ind rule p c LsdR');
lim:=lmax;
if lim>BH_cnt then lim:=BH_cnt;
for i:=0 to lim do with BH[i] do begin
if rname[1] in ['A'..'Z']
then rn0:=' '+rname
else rn0:=rname+' ';
write(f,i:4,' ',rn0,p:6,c:10,': ');
writeln(f,RevStr(l),SD_str(s,md),r);
end;
writeln(f);
for i:=1 to BH_cnt do
if BH[i].rname[1] in ['a'..'z'] then begin
if BH[i-1].rname[1] in ['A'..'Z'] then writeln(f);
write(f,BH[i].rname);
end;
writeln(f);
end;
procedure wr_macro_history(
var f:text;
var CM:TDescr; var MH:THistory; MH_cnt:longint;
lmax:longint);
var i,lim:longint;
begin
MH[MH_cnt]:=CM;
writeln(f);
writeln(f,'First ',lmax,' macro steps:');
writeln(f,' ind rule c LsdR');
lim:=lmax;
if lim>MH_cnt then lim:=MH_cnt;
for i:=0 to lim do with MH[i] do begin
write(f,i:4,rn:5,c:10,': ');
writeln(f,RevStr(l),SD_str(s,md),r);
end;
writeln(f);
end;
procedure wr_mhistory(var f:text; lmax:longint);
begin wr_macro_history(f,CM,MH,MH_cnt,lmax) end;
procedure wr_brule(var f:text; var Rule:TBRule);
var sd:string; k:word;
begin with Rule do begin
write(f,'ucnt c Rule[',id:2,']: ');
sd:=SD_str(s,md);
if md=0
then write(f, '*(c0)'+sd+a+'*':12,' --> *'+sd+a+'(c1)*')
else write(f,'*'+RevStr(a)+sd+'(c0)*':12,' --> *(c1)'+RevStr(a)+sd+'*');
writeln(f);
if Patt_cnt>0 then for k:=0 to Patt_cnt-1 do with Patts[k] do begin
write(f,ucnt:4,c:4,' ');
if md=0
then writeln(f,RevStr(c0):23,' --> ',c1)
else writeln(f, c0:23,' --> ',RevStr(c1));
end;
writeln(f);
end end;
procedure wr_rule(
var f:text; var Rule:TRule; all,full:boolean);
var ws,l1,r1:string; k:word;
begin
with Rule do if
used or (all and (length(c0)+length(a)<26))
then begin
if full then write(f,id:4,p:4,c:4,': ');
l1:=SD_str(s,md); ws:=l1;
if p<0 then begin ws[1]:=l1[2]; ws[2]:=l1[1] end;
l1:='*'+RevStr(a)+ws+'('+c0+')*';
r1:='*('+RevStr(c1)+')'+RevStr(a)+ws+'*';
if p<0 then begin l1:=RevStr(l1); r1:=RevStr(r1) end;
ws:=l1;
if full then while length(ws)<20 do ws:=' '+ws;
ws:=ws+' -> '+r1;
if full then while length(ws)<44 do ws:=ws+' ';
write(f,ws);
if full then begin
write(f,' sp> ');
if (not all) and used then
for k:=1 to spec_max do write(f,spectrum[k]:4);
end;
writeln(f);
end;
end;
procedure wr_rules(
var f:text; name:string; var Rules:TRuleArr; R_cnt:longint; all:boolean);
var i:word;
begin
writeln(f);
if not all then name:='used '+name;
writeln(f,'List of the '+name+' rules:');
writeln(f,' ind p c pattern1 pattern2');
if R_cnt>0 then for i:=0 to R_cnt-1 do wr_rule(f,Rules[i],all,true);
end;
procedure SortRules;
var i,j:longint; WR:TRule;
function LessR(var R1,R2:TRule):boolean;
begin
if length(R1.c0)<length(R2.c0)
then LessR:=true
else if length(R1.c0)>length(R2.c0)
then LessR:=false
else LessR:=length(R1.a)>length(R2.a)
end;
begin
if SR_cnt>1 then for i:=0 to SR_cnt-2 do
for j:=i+1 to SR_cnt-1 do
if LessR(SRules[i],SRules[j]) then begin
WR:=SRules[i]; SRules[i]:=SRules[j]; SRules[j]:=WR
end;
end;
procedure SortBRules(id:longint);
var i,j:longint; WR:TBRuleEl;
begin with BSRules[id] do
for i:=0 to Patt_cnt-2 do
for j:=i+1 to Patt_cnt-1 do
if length(Patts[i].c0)<length(Patts[j].c0) then begin
WR:=Patts[i]; Patts[i]:=Patts[j]; Patts[j]:=WR
end;
end;
procedure ShiftTest;
var
i,p_min,p_max:longint;
OK,BRuleFound,BStatRep:boolean;
sst:array[1..dm] of longint;
R0:TRule; { new simple rule }
a0,a1,c0,c1:string;
procedure SetRule(a0,c0,c1:string; f_use:boolean);
var i:word;
function Repeated(s1,s2:string):boolean;
var succ:boolean;
begin
succ:=true;
while succ and (length(s1)<=length(s2)) do begin
succ:=Pos(s1,s2)=1;
delete(s2,1,length(s1));
end;
Repeated:=succ and (s2='');
end;
function Sim(s1,s2:string; appr:boolean):boolean;
begin
if appr
then Sim:=(s1=s2)
else Sim:=Repeated(s1,s2);
end;
function MemberR(var R:TRule; var RA:TRuleArr; rc:longint; appr:boolean):boolean;
var i:longint;
begin
MemberR:=false;
if rc>0 then for i:=0 to rc-1 do with RA[i] do
if (s=R.s) and (md=R.md) and
(a=R.a) and
Sim(c0,R.c0,appr) and Sim(c1,R.c1,appr)
then MemberR:=true;
end;
procedure AddRule(var R0:TRule; rep:byte);
var i:byte; ws:string; R1:TRule;
begin
R1:=R0;
with R1 do begin
c:=c*rep; p:=p*rep;
ws:=''; for i:=1 to rep do ws:=ws+c0; c0:=ws;
ws:=''; for i:=1 to rep do ws:=ws+c1; c1:=ws;
end;
if not MemberR(R1,SRules,SR_cnt,true) and (SR_cnt<rmax) then begin
R1.id:=SR_cnt;
SRules[SR_cnt]:=R1;
inc(SR_cnt);
end;
end;
function eqROL(s0,s1:string):boolean;
var OK:boolean;
begin
OK:=s0=s1;
eqROL:=OK;
end;
procedure Follow(var R0,R1:TRule);
var nok0,f0,f1:longint; s0,s1:string;
procedure SetS(Var c,s:string; var rep:longint);
var k:byte;
begin
rep:=nok0 div length(c); s:='';
for k:=1 to rep do s:=s+c;
end;
begin if R0.p*R1.p<0 then begin
nok0:=nok(length(R0.c0),length(R1.c1));
if nok0<sr_lmax then begin
SetS(R0.c0,s0,f0);
SetS(R1.c1,s1,f1);
if eqROL(s0,s1) then begin
AddRule(R0,f0);
AddRule(R1,f1);
end;
end;
end end;
procedure ApproveRule;
var i:longint;
begin
if ASR_cnt>0 then for i:=0 to ASR_cnt-1 do begin
Follow(R0,ASRules[i]);
Follow(ASRules[i],R0);
end;
end;
procedure AddRule0;
begin
if not MemberR(R0,ASRules,ASR_cnt,false) and (ASR_cnt<rmax) then begin
ApproveRule;
R0.id:=ASR_cnt;
ASRules[ASR_cnt]:=R0;
inc(ASR_cnt);
end;
end;
function GetBaseRule(s,d:byte; a:string):longint;
var i,j:longint;
begin
j:=-1;
if BSR_cnt>0 then for i:=0 to BSR_cnt-1 do
if (BSRules[i].s=s) and
(BSRules[i].md=d) and
(BSRules[i].a=a) then j:=i;
if j>=0
then GetBaseRule:=j
else if BSR_cnt<=bmax then begin
j:=BSR_cnt; inc(BSR_cnt);
GetBaseRule:=j;
BSRules[j].s:=s;
BSRules[j].md:=d;
BSRules[j].a:=a;
BSRules[j].id:=j;
BSRules[j].Patt_cnt:=0;
end else GetBaseRule:=j;
end;
procedure AddBaseRule;
var id,i:longint; newrule,noaditive:boolean;
procedure AditiveTest;
var i:longint; cp:string; R:TRule; succ:boolean;
begin
R:=R0;
repeat
cp:=R.c0;
succ:=true;
with BSRules[id] do if Patt_cnt>0 then
for i:=0 to Patt_cnt-1 do if succ then
if (R.c0<>'') and (Pos(Patts[i].c0,R.c0)=1)
then begin
delete(R.c0,1,length(Patts[i].c0));
succ:=false;
end;
until cp=R.c0;
noaditive:=cp<>'';
end;
const bmaxlen=dm+2 { dm_2 };
begin
id:=GetBaseRule(R0.s,R0.md,R0.a);
if id>=0 then begin
AditiveTest;
newrule:=true;
with BSRules[id] do if Patt_cnt>0 then
for i:=0 to Patt_cnt-1 do if R0.c0=Patts[i].c0 then newrule:=false;
i:=BSRules[id].Patt_cnt;
if newrule and (i<=bmax) and (length(R0.c0)<=bmaxlen) and
(f_use or
(
(length(BSRules[id].a)=0) and (length(R0.c0)<=bmaxlen) and
(
((not BStatRep) and (length(R0.c0)=R0.c)) or
(noaditive and (length(R0.c0)<R0.c))
)
)
)
then begin
BRuleFound:=true;
with BSRules[id].Patts[i] do begin
c0:=R0.c0;
c1:=R0.c1;
c :=R0.c;
end;
inc(BSRules[id].Patt_cnt);
if BSRules[id].Patt_cnt>1 then SortBRules(id);
end;
if BSRules[id].Patt_cnt=0 then dec(BSR_cnt);
end;
end;
var j,k:word;
begin
R0.a :=a0;
R0.c0:=c0; R0.c1:=c1;
i:=SR_cnt;
AddRule0;
if not BRuleFound then begin
AddBaseRule;
{ BRuleFound:=true; }
end;
if i<SR_cnt then begin
if i>0 then for j:=0 to i-1 do for k:=i to SR_cnt-1 do begin
Follow(SRules[k],SRules[j]);
Follow(SRules[j],SRules[k]);
end;
{ SortRules; }
end;
end;
procedure TryRule(la,lc:longint; l,r,l1:string; f_use:boolean);
begin
a0:=GetF(l,1,la); a1:=GetF(l1,1,la);
if a0=a1 then begin
c0:=GetF(r ,1,lc);
c1:=GetF(l1,la+1,lc);
if length(r)<=1
then begin e_state:=m_loop; OK:=true end;
if e_state=0 then SetRule(a0,c0,c1,f_use)
end;
end;
procedure TryCenter(la,lb:longint; l,r,l1,r1:string);
begin
if (GetF(r,1,lb)=GetF(r1,1,lb)) and
(GetF(l,1,la)=GetF(l1,1,la))
then begin e_state:=c_loop; OK:=true end;
end;
var clmin,clmax,crmin,crmax:longint;
begin
if (CD.smax<250) and (SH_cnt<dm2qub) then begin
for i:=1 to dm do sst[i]:=0;
i:=SH_cnt; OK:=false; BRuleFound:=false;
p_min:=mmax+1; p_max:=-p_min;
clmin:=i; clmax:=i; crmin:=i; crmax:=i;
BStatRep:=false;
while (not OK) and (i>0) do begin
dec(i);
with SH[i] do begin
inc(sst[s]);
if sst[s]>1 then BStatRep:=true;
if p<=p_min then begin
if p<p_min then clmax:=i;
p_min:=p;
clmin:=i;
end;
if p>=p_max then begin
if p>p_max then crmax:=i;
p_max:=p;
crmin:=i;
end;
if (s=CD.s) and (md=CD.md) then begin { new rule ? }
R0.p:=CD.p-p; R0.c:=CD.c-c;
R0.s:=s; R0.md:=md;
if (R0.p>0) and (md=1) and (CD.p=p_max+1) { r_rule }
then TryRule(p-p_min,CD.p-p,l,r,CD.l,crmin<=clmax);
if (R0.p<0) and (md=0) and (CD.p=p_min-1) { l_rule }
then TryRule(p_max-p,p-CD.p,r,l,CD.r,clmin<=crmax);
if R0.p=0 then if md=1 { c_loop }
then TryCenter(p-p_min,p_max+1-CD.p,l,r,CD.l,CD.r)
else TryCenter(p-p_min+1,p_max-CD.p,l,r,CD.l,CD.r);
end;
end;
end;
end;
end;
{ -------------------------------------------------------------}
procedure info0;
var i:byte;
begin
gotoxy(3,1); write(m:10);
gotoxy(55,1);
write('V = ',m div (get_sec - old_sec + 1):4,' machines/sec ');
for i:=1 to e_max do
begin gotoxy(5,i+1); write(e_cnt[i]:8) end;
end;
{ -------------------------------------------------------------}
procedure InvSTest;
var i,j:byte;
function S(k:byte):byte;
begin if k=j then S:=i else S:=k end;
begin
for i:=1 to dm-1 do for j:=i+1 to dm do
if ((C[i]=C[j]) and (C[i]<>dum)) and
((C[i+dm]=C[j+dm]) and (C[i+dm]<>dum)) and
((B[i]=B[j]) and (B[i]<>dum)) and
((B[i+dm]=B[j+dm]) and (B[i+dm]<>dum)) and
((S(A[i])=S(A[j])) and (A[i]<>dum)) and
((S(A[i+dm])=S(A[j+dm])) and (A[i+dm]<>dum))
then e_state:=i_loop;
end;
procedure back_track;
const bt_sz=4; bt_sz2=bt_sz+bt_sz; bt_sz2s=bt_sz2+1;
bt_max=16; sp_max=08;
{
const bt_sz=8; bt_sz2=bt_sz+bt_sz; bt_sz2s=bt_sz2+1;
bt_max=32; sp_max=16;
}
type st=array[0..bt_sz2] of byte;
s_rec=record t:st; ct,j,p:byte end;
var v,w:s_rec;
Stack:array[0..sp_max] of s_rec;
sp:byte; end_bt:boolean;
procedure bt_push;
begin
if sp<=sp_max
then begin Stack[sp]:=w; inc(sp) end
else end_bt:=true
end;
procedure bt_pull;
begin dec(sp); v:=Stack[sp] end;
procedure bt_0;
var i,j,bb:byte;
procedure bt1;
var x:byte;
begin
w.j:=j; inc(w.ct);
if w.ct>=bt_max then end_bt:=true;
x:=w.t[w.p];
if (x=dum) or (x=C[i]) or (C[i]=dum)
then begin w.t[w.p]:=bb; bt_push end;
end; { bt1 }
procedure bt_l;
begin if w.p<bt_sz2 then begin inc(w.p); bt1 end else end_bt:=true end;
procedure bt_r;
begin if w.p>0 then begin dec(w.p); bt1 end else end_bt:=true end;
begin { bt_0 }
i:=0;
repeat
inc(i);
if v.j=A[i] then begin
w:=v; j:=i;
if i>dm then begin j:=j-dm; bb:=1 end else bb:=0;
if B[i]<>dum
then if B[i]=0 then bt_l else bt_r
else begin bt_l; w:=v; bt_r end;
end;
until (i=dm_2) or end_bt;
end; { bt_0 }
begin { back_track }
fillchar(w.t,bt_sz2s,chr(dum));
{ for i:=0 to bt_sz2 do w.t[i]:=dum; }
sp:=0; w.p:=bt_sz; w.ct:=0;
w.j:=0; bt_push;
w.j:=dum; bt_push; { Have i need this ??? }
end_bt:=false;
repeat bt_pull; bt_0 until end_bt or (sp=0);
if not end_bt then e_state:=b_loop;
end; { back_track }
function lDum:boolean;
var i,k:byte;
begin
k:=0;
for i:=1 to dm_2 do if A[i]=dum then inc(k);
lDum:=k<2;
end;
{ -------------------------------------------------------------}
var new_def:boolean;
procedure MakeMStep0(var D:TDescr; macro:byte);
var k,ko,s1,v1,d1,v0:byte; sstep:boolean;
procedure ch_state;
var l,n,o:byte; b:boolean;
function lnk(n:byte):boolean;
var x:array[1..dm] of boolean; l:byte; b,b1:boolean;
procedure d(n:byte);
begin
if n=dum then b:=true
else if n>0 then if not x[n] then begin
x[n]:=true; d(A[n]); d(A[n+dm]) end
end;
begin
for l:=1 to dm do x[l]:=false;
b:=false; d(n); b1:=true;
for l:=1 to dm do if not x[l] then b1:=false;
lnk:=b or b1;
end; { lnk }
begin { ch_state }
l:=dm+1; if k>dm then n:=k-dm else n:=k;
repeat dec(l); b:=(A[l]=dum) and (A[l+dm]=dum) and (l>n) until not b;
if l<dm then inc(l);
for o:=1 to l-1 do begin
A[k]:=o; if lnk(n) then push(chr(ord('0')+o)) end;
A[k]:=l; s1:=l; if not lnk(n) then e_state:=s_loop;
end; { ch_state }
begin
pr_fail:=false;
case macro of
0:sstep:=true;
1:sstep:=not SuccMStep(D,SRules,SR_cnt);
2:sstep:=not SuccBStep(D);
3:sstep:=not SuccMStep(D,SSRules,SSR_cnt);
end;
if sstep then begin
with D do if md=0 then UnpackFirst(l) else UnpackFirst(r);
v0:=GetDV(D);
D.rname:=chr(ord('@')+D.s)+V_str[v0];
if v0=0 then k :=D.s else k :=D.s+dm;
if v0=1 then ko:=D.s else ko:=D.s+dm;
v1:=C[k];
if v1=dum then if D.af
then pr_fail:=true
else if A[k]=0
then v1:=0
else begin C[k]:=0; push('_'); C[k]:=1; v1:=1; new_def:=true end;
s1:=A[k];
if s1=dum then if D.af
then pr_fail:=true
else begin ch_state; new_def:=true end;
d1:=B[k];
if d1=dum then if D.af
then pr_fail:=true
else if (A[k]=0) or (e_state>0)
then d1:=0
else begin
B[k]:=0;
if SameDir then B[ko]:=0;
push('<');
B[k]:=1;
if SameDir then B[ko]:=1;
d1:=1; new_def:=true
end;
if (not pr_fail) then MakeDStep(D,s1,v1,d1,macro);
with D do if (not af) then
if p<p_left then p_left:=p
else if p>p_right then p_right:=p;
if s1=0 then if D.af then pr_fail:=true else e_state:=nm_end;
end;
end;
procedure MakeMStep(var D:TDescr);
begin
{
if rule_min>dm_2
then repeat MakeMStep0(D,1) until D.rn>=0
else
}
MakeMStep0(D,1);
if (not D.af) then TryInfinity(D);
end;
procedure ClearDescr(var D:TDescr);
begin with D do begin
md:=0; s:=1;
l:='.'; r:='.';
c:=0; p:=0;
af:=false;
rn:=-1;
rname:='--';
smax:=0;
{
r_mark:='.<A.';
l_mark:=r_mark;
}
end end;
{ -------------------------------------------------------------}
const
ptran_max=400;
function eqDes(var D1,D2:TDescr):boolean;
begin
eqDes:=
(D1.s=D2.s) and
(D1.md=D2.md) and
(D1.l=D2.l) and
(D1.r=D2.r) and
(D1.p=D2.p)
end;
{ ---------- New Pos test: ------------- }
type
TPosString = record
mode:byte; { 0 - left 1 - center 2 - right }
md:byte; { 0/1 - rigth/left accessibility }
s:string;
end;
TPosDescr = record
mode:byte;
a,b,n:longint; { left/right end, length }
end;
TPosTran_3 = record
D,DNext:TDescr;
str_l,str_r: longint; { pointers to PStrArr }
mod_l,mod_c,mod_r: TPosDescr;
a,b:longint; { left/right end }
end;
TPosTuple = record
i,j:longint; { pointers to PStrArr }
end;
var
PStrArr: array[0..ptran_max] of TPosString;
PStr_cnt: longint;
PTupleArr: array[0..gfin_max] of TPosTuple;
PTuple_cnt: longint;
PTArr_3: array[0..gfin_max] of TPosTran_3;
PTA_cnt3:longint;
procedure wr_postran_3(var f:text; i:longint; var PT:TPosTran_3);
begin with PT do begin
write(f,
i:3,' ',
mod_l.mode,'-',mod_c.mode,'-',mod_r.mode,' ',
str_l:3,' ',str_r:3,' ',
a+1:4,b:4,D.p:6,DNext.p:6,DNext.c:6,': ');
with D do write(f,RevStr(l)+SD_str(s,md)+r:15,' --> ');
with DNext do writeln(f,RevStr(l)+SD_str(s,md)+r);
end end;
procedure wr_pproof_3(var f:text);
var i:longint;
begin
writeln(f);
writeln(f,'Position words:');
writeln(f,' id mode md string');
for i:=0 to PStr_cnt-1 do with PStrArr[i] do
writeln(f,i:3,' ',mode,' ',md,' ',s);
writeln(f);
writeln(f,'Tuples:');
writeln(f,' id i0 j0');
for i:=0 to PTuple_cnt-1 do
writeln(f,i:3,' ',PTupleArr[i].i:3,' ',PTupleArr[i].j:3);
writeln(f);
writeln(f,'Position_3 proof:');
writeln(f,' i mode s_l s_r a b p_old p_new c');
if PTA_cnt3>0 then for i:=0 to PTA_cnt3-1
do wr_postran_3(f,i,PTArr_3[i]);
end;
function EqPStr(var p1,p2:TPosString):boolean;
begin
EqPStr:=
(p1.mode=p2.mode) and (p1.md=p2.md) and (p1.s=p2.s)
end;
function EqPDescr(var p1,p2:TPosDescr):boolean;
begin
EqPDescr:=
(p1.mode=p2.mode) and (p1.a=p2.a) and (p1.b=p2.b)
end;
function PStrId(var PS:TPosString):longint;
var i,n:longint; found:boolean;
begin
found:=false; n:=-1;
if PStr_cnt>0 then for i:=0 to PStr_cnt-1 do
if EqPStr(PStrArr[i],PS)
then begin found:=true; n:=i end;
if not found then if PStr_cnt>ptran_max
then pr_fail:=true
else begin
PStrArr[PStr_cnt]:=PS;
{
writeln(ttm,'Str[',PStr_cnt,'] ==> mode=',PS.mode,' md=',PS.md,' s=',PS.s);
}
n:=PStr_cnt; inc(PStr_cnt);
end;
PStrId:=n;
end;
procedure AddPTuple(i0,j0:longint);
var k:longint; found:boolean;
begin
found:=false;
for k:=0 to PTuple_cnt-1 do with PTupleArr[k] do
if (i=i0) and (j=j0) then found:=true;
if not found then if PTuple_cnt>gfin_max
then pr_fail:=true
else begin
with PTupleArr[PTuple_cnt] do
begin i:=i0; j:=j0 end;
inc(PTuple_cnt);
end;
end;
function eqTPT_3(var D1,D2:TPosTran_3):boolean;
begin
eqTPT_3:=eqDes(D1.D,D2.D) and
(D1.a=D2.a) and
(D1.b=D2.b) and
(D1.str_l=D2.str_l) and
(D1.str_r=D2.str_r) and
EqPDescr(D1.mod_l,D2.mod_l) and
EqPDescr(D1.mod_c,D2.mod_c) and
EqPDescr(D1.mod_r,D2.mod_r)
end;
procedure TryP_3(PosAl,PosBl,PosAr,PosBr:longint);
var
PT:TPosTran_3;
old_PTA_cnt,old_scnt,old_tcnt,i:longint; closed:boolean;
modes:array[0..2] of TPosDescr;
procedure Loop0;
const rmax1=rmax;
var
DArr:array[0..rmax1] of TDescr;
D_cnt:longint;
procedure SearchD(var D:TDescr);
var i:longint; found:boolean;
begin
found:=false;
if D_cnt>0 then for i:=0 to D_cnt-1 do
if eqDes(DArr[i],D) then found:=true;
if not found then if D_cnt>rmax1
then pr_fail:=true
else begin
DArr[D_cnt]:=D;
inc(D_cnt)
end;
if found then pr_fail:=true;
end;
begin with PT do begin
D_cnt:=0; D.c:=0;
repeat
MakeMStep0(D,0);
SearchD(D);
until pr_fail or
((D.p<=a) and (D.md=0)) or
((D.p>=b+1) and (D.md=1));
end end;
function CutStr(s:string; b,l:longint):string;
var w:string;
begin
w:=s;
delete(w,1,b);
w:=copy(w,1,l);
{
if w[length(w)]<>'.' then w:=w+'.';
}
if w[length(w)]='.' then delete(w,length(w),1);
while length(w)<l do w:=w+'-';
w:=w+'.';
CutStr:=w;
end;
procedure AddTran1(var PT:TPosTran_3);
var i:longint; found:boolean; PT1:TPosTran_3;
begin
PT1:=PT;
with PT1 do begin b:=b-a; D.p:=D.p-a; a:=0 end;
found:=false;
if PTA_cnt3>0 then for i:=0 to PTA_cnt3-1 do
if eqTPT_3(PTArr_3[i],PT1) then found:=true;
if not found then if PTA_cnt3>gfin_max
then pr_fail:=true
else begin
PTArr_3[PTA_cnt3]:=PT1;
inc(PTA_cnt3)
end;
end;
procedure Shift0;
var
a0,b0,c0:TPosString;
ci,bi,k,str_old,a_old:longint;
m_old:TPosDescr;
begin with PT do begin
with c0 do begin
s:=CutStr(D.r,mod_l.n+mod_c.n,mod_r.n);
mode:=mod_r.mode; md:=0;
end;
with b0 do begin
s:='S'+CutStr(D.r,mod_l.n,mod_c.n);
mode:=mod_c.mode; md:=0;
end;
ci:=PStrId(c0); bi:=PStrId(b0);
for k:=0 to PTuple_cnt-1 do with PTupleArr[k] do
if str_r=i then AddPTuple(ci,j);
AddPTuple(bi,ci);
str_r:=bi;
D.r:=CutStr(D.r,0,mod_l.n+mod_c.n);
m_old:=mod_r; mod_r:=mod_c; mod_c:=mod_l;
inc(D.p,m_old.n); D.c:=0;
str_old:=str_l; a_old:=a;
for k:=0 to PTuple_cnt-1 do with PTupleArr[k] do
if str_old=i then begin
a0:=PStrArr[j]; str_l:=j;
mod_l:=modes[a0.mode];
D.l:=a0.s;
a:=a_old+m_old.n-mod_l.n;
if a0.s[1]<>'S' then AddTran1(PT);
end;
end end;
procedure Shift1;
var
a0,b0,c0:TPosString;
ai,bi,k,str_old,b_old:longint;
m_old:TPosDescr;
begin with PT do begin
with a0 do begin
s:=CutStr(D.l,mod_r.n+mod_c.n,mod_l.n);
mode:=mod_l.mode; md:=1;
end;
with b0 do begin
s:='S'+CutStr(D.l,mod_r.n,mod_c.n);
mode:=mod_c.mode; md:=1;
end;
ai:=PStrId(a0); bi:=PStrId(b0);
for k:=0 to PTuple_cnt-1 do with PTupleArr[k] do
if str_l=i then AddPTuple(ai,j);
AddPTuple(bi,ai);
str_l:=bi;
D.l:=CutStr(D.l,0,mod_r.n+mod_c.n);
m_old:=mod_l; mod_l:=mod_c; mod_c:=mod_r;
dec(D.p,m_old.n); D.c:=0;
str_old:=str_r; b_old:=b;
for k:=0 to PTuple_cnt-1 do with PTupleArr[k] do
if str_old=i then begin
c0:=PStrArr[j]; str_r:=j;
mod_r:=modes[c0.mode];
D.r:=c0.s;
b:=b_old-m_old.n+mod_r.n;
if c0.s[1]<>'S' then AddTran1(PT);
end;
end end;
procedure Loop;
begin with PT do begin
Loop0;
PTArr_3[i].DNext:=D;
{
wr_postran_3(ttm,i,PTArr_3[i]);
}
if not pr_fail then if ((D.p<=a) and (D.md=0))
then Shift0 else Shift1;
end end;
begin
with modes[0] do begin mode:=0; a:=-PosBl; b:=-PosAl end;
with modes[1] do begin mode:=1; a:=-PosAl; b:= PosAr end;
with modes[2] do begin mode:=2; a:= PosAr; b:= PosBr end;
for i:=0 to 2 do with modes[i] do n:=b-a;
with PStrArr[0] do begin s:='.'; mode:=0; md:=1 end;
with PStrArr[1] do begin s:='.'; mode:=2; md:=0 end;
PStr_cnt:=2;
with PTupleArr[0] do begin i:=0; j:=0 end;
with PTupleArr[1] do begin i:=1; j:=1 end;
PTuple_cnt:=2;
{
writeln(ttm,'ABlr= ',-PosBL,' ',-PosAl,' ',PosAr,' ',PosBr);
writeln(ttm,'ExLens= ',modes[0].n,' ',modes[1].n,' ',modes[2].n);
}
old_PTA_cnt:=0;
old_scnt:=0;
old_tcnt:=0;
repeat
PTA_cnt3:=1; i:=0;
pr_fail:=false;
with PTArr_3[0] do begin
ClearDescr(D);
D.af:=true;
str_l:=0; str_r:=1;
mod_l:=modes[0];
mod_c:=modes[1];
mod_r:=modes[2];
a:=-PosBl;
b:=PosBr;
end;
while (not pr_fail) and (i<PTA_cnt3) do begin
PT:=PTArr_3[i];
Loop;
inc(i);
end;
closed:=
(PTA_cnt3=old_PTA_cnt) and
(PStr_cnt=old_scnt) and
(PTuple_cnt=old_tcnt);
if not closed then begin
old_PTA_cnt:=PTA_cnt3;
old_scnt:=PStr_cnt;
old_tcnt:=PTuple_cnt;
end;
until pr_fail or closed;
if not pr_fail then begin
writeln(ttm,'M=',m,' gfin_3 PosLR= ',
PosAl,'-',PosBl,' ',PosAr,'-',PosBr);
flush(ttm);
e_state:=pfin_l;
end;
{ wr_pproof_3(ttm); }
end;
{ ---------- Old Pos parts: ------------- }
{
function eq(var R1,R2;SZ:word):boolean;
var
i:longint;
A:array[word] of char absolute R1;
B:array[word] of char absolute R2;
begin
eq:=true;
for i:=0 to SZ-1 do if A[i]<>B[i] then eq:=false;
end;
}
procedure TryPFin_2;
var dL,dR,d_l,d_r:longint;
procedure TryNext;
begin
if (e_state<>pfin_l) then begin
e_state:=0;
{ TryP(PosAl+d_l,PosBl+d_l,PosAr+d_r,PosBr+d_r); }
TryP_3(PosAl+d_l,PosBl+d_l,PosAr+d_r,PosBr+d_r);
end;
end;
begin
EvalPSCnt;
{
WrPosStat(ttm);
}
if ((PosAl>=0) or (pst_min>-16)) and
((PosAr>=0) or (pst_max<16)) then begin
if PosAl<0 then begin PosAl:=PosAr; PosBl:=PosBr end;
if PosAr<0 then begin PosAr:=PosAl; PosBr:=PosBl end;
if PosAl<0 then begin PosAl:=2; PosBl:=PosAl+2 end;
if PosAr<0 then begin PosAr:=2; PosBr:=PosAr+2 end;
while PosBl-PosAl in [1{,2}] do inc(PosBl,PosBl-PosAl);
while PosBr-PosAr in [1{,2}] do inc(PosBr,PosBr-PosAr);
dL:=PosBl-PosAl; if dL>0 then dec(dL);
dR:=PosBr-PosAr; if dR>0 then dec(dR);
{
writeln(ttm,'Bl Al = ',PosBl,' ',PosAl);
writeln(ttm,'Br Ar = ',PosBr,' ',PosAr);
}
{ dL:=dL+dL; dR:=dR+dR; }
{
for d_l:=1-PosAl to dL do for d_r:=1-PosAr to dL do TryNext;
}
while PosAl>1 do begin dec(PosAl); dec(PosBl) end;
while PosAr>1 do begin dec(PosAr); dec(PosBr) end;
for d_l:=0 to dL do for d_r:=0 to dL do TryNext;
end;
end;
procedure TryPFin_2_all(dim:word);
var dL,dR,d_l,d_r,PBl,PBr,dim_1,i0,i1:longint;
procedure TryNext;
begin
if (e_state<>pfin_l) then begin
e_state:=0;
TryP_3(PosAl+d_l,PosBl+d_l,PosAr+d_r,PosBr+d_r);
end;
end;
begin
PosAl:=1; PosAr:=1;
if dim>dm then dim_1:=dim+dm else dim_1:=dim;
{
for PBl:=PosAl+2 to PosAl+dim_1+2 do
for PBr:=PosAr+2 to PosAr+dim_1+2 do
}
for i0:=0 to dim_1 do for i1:=0 to dim_1 do
if (e_state<>pfin_l) and
((i0<dim) or (i1<dim))
then begin
PBl:=PosAl+2+i0;
PBr:=PosAr+2+i1;
PosBl:=PBl; PosBr:=PBr;
gotoxy(55,5); write('PosLR=',PosBl,'|',PosBr,' ');
dL:=PosBl-PosAl;
if dL>dm then dL:=dm; if dL>0 then dec(dL);
dR:=PosBr-PosAr;
if dR>dm then dR:=dm; if dR>0 then dec(dR);
for d_l:=0 to dL do for d_r:=0 to dL do TryNext;
end;
end;
{ -------------------------------------------------------------}
const
ESet_max = 1000 {3000} {5000} {10000};
TIntroneStrLen=60;
type
TIntronArr = array[0..bmax] of string[TIntroneStrLen];
{ TIntroneStrLen must be enough for TryBL_Proof intrones !!! }
TExoneSet = record
EA:TIntronArr;
cnt:longint
end;
var
MainRule:TBRule;
MSRule,OSRule:TRule;
BBR_id:longint;
BBG,BBGs:TGraph;
BBG_cnt,BBGs_cnt:longint;
IntronI, IntronO: TIntronArr;
InI_cnt, InO_cnt: longint;
Lexones, Rexones: TIntronArr;
Lex_cnt, Rex_cnt: longint;
Lex_id, Rex_id, LR_mod:word;
procedure AddIntron(var IntrIO:TIntronArr; var In_cnt:longint; newIntr:string);
var i:longint; found:boolean;
begin
found:=false;
if In_cnt>0 then for i:=0 to In_cnt-1 do
if IntrIO[i]=newIntr then found:=true;
if not found then
if (In_cnt<bmax) and (length(newIntr)<=TIntroneStrLen) then begin
IntrIO[In_cnt]:=newIntr;
inc(In_cnt);
end else pr_fail:=true;
end;
procedure wr_brules(
var f:text; name:string; var Rules:TBRuleArr; R_cnt:longint; all:boolean);
var i:longint;
procedure wr_intr(var IntrIO:TIntronArr; In_cnt:longint; name:string);
var i:longint;
begin if In_cnt>0 then begin
write(f,name);
for i:=0 to In_cnt-1 do write(f,IntrIO[i],' ');
writeln(f);
end end;
begin
writeln(f);
if not all then name:='used '+name;
writeln(f,'List of the '+name+' rules:');
if R_cnt>0 then for i:=0 to R_cnt-1 do wr_brule(f,Rules[i]);
if BBR_id>=0 then begin
writeln(f,'Main rule:');
wr_brule(f,MainRule);
wr_intr(IntronI,InI_cnt,'I_intrones = ');
wr_intr(IntronO,InO_cnt,'O_intrones = ');
wr_rules(f,'opposite',OSRules,OSR_cnt,true);
writeln(f);
case MainRule.nice of
1:writeln(f,'Unknown machine type !');
2:writeln(f,'Vortex at corner machine type !');
end;
end;
flush(f);
end;
procedure MakeBStep(var DF:TDescr);
var simple:boolean; rnam0,rnam1:string;
function OldVertex(var CTG:TGraph; CTG_cnt:longint):boolean;
var j:longint;
begin
OldVertex:=false;
for j:=0 to CTG_cnt-1 do if SimMacro2(DF,CTG[j].D)
then OldVertex:=true;
end;
procedure AddVertex(var CTG:TGraph; var CTG_cnt:longint);
begin
if not OldVertex(CTG,CTG_cnt) then if CTG_cnt<gfin_max then begin
CTG[CTG_cnt].D:=DF;
CTG[CTG_cnt].checked:=false;
inc(CTG_cnt);
end else e_state:=too_lng;
end;
procedure MakeBLoopStep;
function PackR(var r:string; io:boolean):boolean;
var j:longint; c0a,c0b:string; w:char;
begin
PackR:=false;
with MainRule do for j:=0 to Patt_cnt-1 do begin
if io then c0b:=Patts[j].c0 else c0b:=Patts[j].c1;
c0a:=GetF(r,1,length(c0b));
if c0a=c0b then begin
delete(r,1,length(c0a));
if r='' then r:='.';
if Pos('[',r)=1
then delete(r,1,1)
else IncS(']',r,DF.af) { r:=']'+r };
w:=chr(ord('0')+j);
r:='['+w+r;
if io then rnam1:='i' else rnam1:='o';
rnam1:=rnam1+'+'+w;
PackR:=true;
end;
end;
end;
procedure TestI(var l,r:string);
var w:char;
begin
with MainRule do if Pos('[',r)=1 then begin
if not simple then begin
w:=r[2]; delete(r,1,2);
if w='*' then begin
e_state:=mem_ov;
{
gotoxy(1,23);
writeln('Unpacking of * is disabled !');
Halt;
}
w:=chr(ord('0')+m_id);
end;
if r[1]=']' then delete(r,1,1) else r:='['+r;
IncS(Patts[ord(w)-ord('0')].c0,r,DF.af);
rnam0:='i-'+w;
end;
simple:=not simple;
end else simple:=true;
end;
procedure TestO(var l,r:string);
var
w,wc:char; orule:boolean; n,n1,k:longint; a1:string;
TR:TRule;
begin
with MainRule do if Pos('[',l)=1 then begin
orule:=false;
if not simple then begin
wc:=l[2]; delete(l,1,2);
if wc='*' then w:=chr(ord('0')+m_id) else w:=wc;
n:=ord(w)-ord('0');
n1:=Pos('[',r);
if n1>0 then a1:=copy(r,1,n1-1) else a1:=copy(r,1,length(r)-1);
if OSR_cnt>0 then for k:=0 to OSR_cnt-1 do
with OSRules[k] do if (s=DF.s) and (a=a1) and (c0=Patts[n].c1)
then begin TR:=OSRules[k]; orule:=true end;
if orule then begin
k:=1;
while l[1]=w do begin inc(k); delete(l,1,1) end;
if l[1]=']' then delete(l,1,1) else l:='['+l;
delete(r,1,length(a1));
if r='.' then r:=']'+r else delete(r,1,1);
while k>0 do begin
IncS(wc,r,DF.af);
dec(k);
DF.c:=DF.c+TR.c;
DF.p:=DF.p+TR.p;
end;
r:=a1+'['+r;
rnam0:='O-'+w; rnam1:='I+'+w;
end else begin
if wc='*' then begin
e_state:=mem_ov;
{
gotoxy(1,23);
writeln('Unpacking of * is disabled !');
Halt;
}
end;
if l[1]=']' then delete(l,1,1) else l:='['+l;
IncS(Patts[n].c1,l,DF.af);
rnam0:='o-'+w;
end;
end;
if not orule then simple:=not simple;
end else simple:=true;
end;
procedure Test(var l,r:string);
var wI:string; n:byte; pack:boolean; wc:char;
begin with MainRule do begin
if (DF.md=md)
then pack:=PackR(l,false)
else pack:=PackR(r,true);
if not pack then begin
if (DF.s=s) and (DF.md=md) and (Pos('[',r)=1)
then begin
if not simple then begin
delete(r,1,1); n:=Pos(']',r);
wI:=copy(r,1,n-1); delete(r,1,n);
if Pos('[',l)=1 then delete(l,1,1) else l:=']'+l;
while wI<>'' do begin
wc:=wI[1]; IncS(wc,l,DF.af);
if wc='*' then wc:=chr(ord('0')+m_id);
n:=ord(wc)-ord('0');
delete(wI,1,1);
DF.c:=DF.c+Patts[n].c;
if md=1
then DF.p:=DF.p+length(Patts[n].c0)
else DF.p:=DF.p-length(Patts[n].c0);
end;
l:='['+l;
rnam1:='m+*';
rnam0:='m-*';
end;
simple:=false;
end else if DF.md=md
then TestI(l,r)
else TestO(l,r);
end else simple:=false;
if simple then MakeMStep0(DF,0);
end end;
begin
if MainRule.md=1
then Test(DF.l,DF.r)
else Test(DF.r,DF.l);
end;
begin
rnam0:=' '; rnam1:=' ';
BBGs_cnt:=1; BBGs[0].D:=DF;
simple:=false;
repeat
MakeBLoopStep;
if simple then if OldVertex(BBGs,BBGs_cnt)
then e_state:=b_loop
else AddVertex(BBGs,BBGs_cnt);
until (not simple) or (e_state>0);
DF.rname0:=rnam0;
DF.rname1:=rnam1;
end;
procedure wrf_m(var f:text; hd,sc:boolean; tstr:string); forward;
procedure ClearBRCntrs;
var i,j:longint;
begin
for i:=0 to BSR_cnt-1 do with BSRules[i] do begin
ucnt:=0;
for j:=0 to Patt_cnt-1 do Patts[j].ucnt:=0;
end;
end;
procedure VortexLoop(
var CD:TDescr; var MH:THistory; var MH_cnt:longint;
mmode:byte; lim:longint);
function PackTest:boolean;
procedure Pack(var l:string);
var w:char;
begin
w:=chr(ord('0')+MainRule.m_id);
if l[1]='[' then begin
if l[2]=w then l[2]:='*';
while l[3]=w do delete(l,3,1);
end;
end;
begin with MainRule do begin
if (s=CD.s) and (md=CD.md) then begin
PackTest:=true;
case md of
0:if CD.l='.' then Pack(CD.r);
1:if CD.r='.' then Pack(CD.l);
end;
end else PackTest:=false;
end end;
begin
ClearDescr(CD);
MH_cnt:=0;
new_def:=false;
e_state:=0;
repeat
MH[MH_cnt]:=CD; inc(MH_cnt);
repeat
MakeBStep(CD);
if MH_cnt>=lim then e_state:=too_lng;
if new_def and (e_state=0) then begin
InvSTest;
if (e_state=0) and lDum then back_track;
new_def:=false;
end;
until (e_state>0) or PackTest;
until e_state>0;
end;
{ --------------- Swiming position test ------------------ }
const
PSwim_max=30;
type
TContext = record s:byte; w:string end;
WordArr = array[0..PSwim_max] of string;
ContArr = array[0..PSwim_max] of TContext;
var
Iwords, Owords: WordArr;
Iw_cnt, Ow_cnt: longint;
{ ---------------- Bin Vortex test ------------------- }
var
L1r1,L1r2,L1r3,L1r4:string;
procedure wr_bmhistory(var f:text; lmax:longint);
var i,lim:longint;
begin
write(f,'MainShift single rule: ');
wr_rule(f,MSRule,true,false);
write(f,'Opposite single rule: ');
wr_rule(f,OSRule,true,false);
writeln(f,'Macro_words near the main sequence (noted with *):');
for i:=0 to Iw_cnt-1 do write(f,chr(ord('0')+i),'=',Iwords[i],' ');
writeln(f);
writeln(f,'Macro_words opposite to the main sequence:');
for i:=0 to Ow_cnt-1 do write(f,chr(ord('0')+i),'=',Owords[i],' ');
writeln(f);
writeln(f,'Lemma1 rules:');
writeln(f,' '+L1r1);
writeln(f,' '+L1r2);
writeln(f,' '+L1r3);
writeln(f,' '+L1r4);
BMH[BMH_cnt]:=BMM;
lim:=lmax;
if lim>BMH_cnt then lim:=BMH_cnt;
writeln(f);
writeln(f,'First ',lmax,' bin_main_macro steps:');
writeln(f,' ind p c LsdR');
for i:=0 to lim do with BMH[i] do begin
write(f,i:4,' ',p:6,c:10,': ');
writeln(f,TD_str(BMH[i]));
end;
writeln(f);
end;
procedure BVortexLoop(lim:longint);
const st_max = 800;
var
CD:TDescr; i:longint; fail:boolean;
Lemma1, L1Proved:boolean; b_id:longint;
S_F,S_B:byte; L1wz,L1wv,L1w0,L1w1:char;
procedure MakeStep;
begin
MakeMStep0(CD,0); inc(i);
if i>=st_max then e_state:=too_lng;
if new_def and (e_state=0) then begin
InvSTest;
if (e_state=0) and lDum then back_track;
new_def:=false;
end;
if CD.s=0 then fail:=true;
if e_state>0 then fail:=true;
end;
function AddWord(s:string; var WArr:WordArr; var cnt:longint):char;
var j:longint; found:boolean;
begin
found:=false;
if cnt>0 then for j:=0 to cnt-1 do if s=WArr[j]
then begin found:=true; AddWord:=chr(ord('0')+j) end;
if not found then if cnt<PSwim_max then begin
WArr[cnt]:=s;
AddWord:=chr(ord('0')+cnt);
inc(cnt);
end else fail:=true;
end;
procedure PLoop(var l,r:string);
var
l1,ocont,oc0:string; n,k:byte;
j1:longint;
function TestI:boolean;
begin
TestI:=(CD.s=MSRule.s) and (CD.md=MSRule.md)
and (r='.') and (GetF(l,1,n)=oc0)
end;
function TestO:boolean;
begin TestO:=(CD.md=1-MSRule.md) and (l='*.') end;
procedure Unpck0(var s:string; var WArr:WordArr);
var w:char;
begin
w:=s[1]; delete(s,1,1);
if w in digits
then s:=WArr[ord(w)-ord('0')]+s
else fail:=true;
end;
procedure SingleLoop;
var fin:boolean; packs:string; j:longint;
function TestU:boolean;
var w:char;
begin
j:=1;
if CD.md=MSRule.md then begin
w:=r[1];
while l[j] in ['-','+'] do inc(j);
packs:=copy(l,1,j-1);
end else begin
w:=l[1];
while r[j] in ['-','+'] do inc(j);
packs:=copy(r,1,j-1);
end;
TestU:=(not (w in ['-','+','.'])) or (j>k);
end;
begin if not fail then begin
fin:=false; i:=0;
if CD.md=MSRule.md then begin
if r='*.' then begin
if CD.s=MSRule.s then begin
r:='0*.'; CD.p:=0;
CD.s:=OSRule.s;
CD.md:=1-CD.md;
fin:=true
end else fail:=true;
end else Unpck0(r,Iwords);
end else begin
if l='b.' then begin
if (CD.s=S_F) and (r[1]=L1wz) then begin
l:=L1wv+'b.'; CD.p:=0;
delete(r,1,1);
CD.s:=S_B; CD.md:=1-CD.md;
fin:=true
end else fail:=true;
end else if l<>'.' then Unpck0(l,Owords);
end;
if not (fin or fail) then begin
repeat MakeStep
until fail { (e_state>0) or (i>st_max) } or TestU;
if not fail { (e_state=0) and (i<=st_max) } then begin
if j>1 then if CD.md=MSRule.md then begin
delete(l,1,j-1);
while length(packs)<k do packs:=packs+'-';
l:=AddWord(packs,Owords,Ow_cnt)+l;
end else begin
delete(r,1,j-1);
while length(packs)<k do packs:=packs+'-';
r:=AddWord(packs,Iwords,Iw_cnt)+r;
if (pos('*',r)=2 + (n div k)) and (CD.s=OSRule.s)
then begin
packs:='';
for j:=0 to n div k do
packs:=packs+Iwords[ord(r[j+1])-ord('0')];
if packs=ocont+MSRule.c0
then delete(r,2,n div k);
end;
end;
end;
end;
{
write(ttm,'Mc=',m,' '); wr_state(ttm,CD); flush(ttm);
}
end end;
procedure TestLemma1;
var CD_save:TDescr; l_t:string; j:longint;
begin if l='.' then begin
S_F:=CD.s; L1wz:=r[1];
CD_save:=CD;
r:='*.'; j:=0;
L1r1:=TD_str(CD);
repeat SingleLoop; inc(j) until fail or (r='*.') or (j>st_max);
if (not fail) and (r='*.') then begin
S_B:=CD.s; L1wv:=l[1];
L1r1:=L1r1+' --> '+TD_str(CD);
{ gotoxy(55,7); write(L1r1,' '); }
delete(l,1,1); l_t:=l;
l:=L1wv+'*.'; r:=L1wz+'*.';
L1r4:=TD_str(CD);
repeat SingleLoop until fail or (r='*.') or (l='*.');
if (not fail) and (r='*.') and (S_B=CD.s) and (l[1]=L1wv) then begin
L1w0:=l[2]; L1r4:=L1r4+' --> '+TD_str(CD);
{ gotoxy(55,8); write(L1r4,' '); }
delete(l,1,1); r:=L1wz+'*.';
CD.s:=S_F; CD.md:=1-CD.md;
L1r2:=TD_str(CD);
repeat SingleLoop until fail or (r='*.') or (l='*.');
if (not fail) and (r='*.') and (S_B=CD.s) and (l[1]=L1wv) then begin
L1w1:=l[2]; L1r2:=L1r2+' --> '+TD_str(CD);
{ gotoxy(55,9); write(L1r2,' '); }
delete(l,1,1); r:=L1wz+'*.';
CD.s:=S_F; CD.md:=1-CD.md;
L1r3:=TD_str(CD);
repeat SingleLoop until fail or (r='*.') or (l='*.');
if (not fail) and (l='*.') and (S_F=CD.s) and (r[1]=L1wz) and (r[2]=L1wz) then begin
Lemma1:=true; L1r3:=L1r3+' --> '+TD_str(CD);
{ gotoxy(55,10); write(L1r3,' '); }
while l_t<>'.' do begin
if not ((l_t[1]=L1w0) or (l_t[1]=L1w1)) then Lemma1:=false;
delete(l_t,1,1);
end;
if Lemma1 then begin
gotoxy(55,5); write('L1 proved, m=',m);
end;
end;
end;
end;
end;
CD:=CD_save; fail:=false;
if Lemma1 then begin l:='b.'; b_id:=BMH_cnt end;
end end;
begin
ocont:=OSRule.a;
oc0 :=OSRule.c0;
k:=length(ocont); n:=length(oc0);
repeat MakeStep until (e_state>0) or (i>st_max) or TestI;
if TestI then begin
BMH[BMH_cnt]:=CD; inc(BMH_cnt);
l1:=l; l:='*.';
repeat MakeStep until (e_state>0) or (i>st_max) or TestO;
if TestO and (CD.s=OSRule.s) then begin
if (GetF(r,1,k)=ocont) and (k>0) and ((n mod k)=0) then begin
BMH[BMH_cnt]:=CD; inc(BMH_cnt);
{
gotoxy(55,10); write('m=',m,' n=',n,' k=',k,' ');
}
fail:=false;
Ow_cnt:=0; Iw_cnt:=0;
AddWord(ocont,Iwords,Iw_cnt);
r:='0*.'; l:='';
while (length(l1)>0) and (GetF(l1,1,n)=oc0) do delete(l1,1,n);
while length(l1)>1 do begin
l:=l+AddWord(GetF(copy(l1,1,k),1,k),Owords,Ow_cnt);
delete(l1,1,k);
end;
AddWord(GetF('.',1,k),Owords,Ow_cnt);
l:=l+'.';
write(ttm,'Owords = ');
for j1:=0 to Ow_cnt-1 do write(ttm,Owords[j1],' ');
writeln(ttm);
write(ttm,'Iwords = ');
for j1:=0 to Iw_cnt-1 do write(ttm,Iwords[j1],' ');
writeln(ttm);
Lemma1:=false; L1Proved:=false;
repeat
BMH[BMH_cnt]:=CD; inc(BMH_cnt);
SingleLoop;
if not fail then if Lemma1
then with BMH[b_id] do L1Proved:=
(s=CD.s) and (md=CD.md) and
(l=CD.l) and (r=CD.r)
else TestLemma1;
until fail or L1Proved or (BMH_cnt>lim {2*lim div 3});
{
for j1:=0 to Ow_cnt-1 do if j1<12 then begin
gotoxy(70,11+j1); write(Owords[j1],' ');
gotoxy(70,12+j1); write(' ');
end;
}
if L1Proved then e_state:=swpf_l;
end;
end;
end;
end;
begin
ClearDescr(CD);
new_def:=false;
e_state:=0; BMH_cnt:=0; i:=0;
if MSRule.md=1 then PLoop(CD.l,CD.r) else PLoop(CD.r,CD.l);
BMM:=CD;
if e_state<>swpf_l then e_state:=too_lng;
end;
{ --------------- Exones loop/test ---------------------- }
procedure wr_ex0(var f:text);
var i,l_b:longint;
begin
if Lex_cnt<26 then l_b:=EL_leter else l_b:=EL_base;
write(f,'Left exones: ');
for i:=0 to Lex_cnt-1 do write(f,chr(l_b+i),'=',Lexones[i],' ');
writeln(f);
if Rex_cnt<26 then l_b:=EL_leter else l_b:=EL_base;
write(f,'Right exones: ');
for i:=0 to Rex_cnt-1 do write(f,chr(l_b+i),'=',Rexones[i],' ');
writeln(f);
end;
function Ex_str(var D:TDescr):string;
function conv(s:string; cnt:longint):string;
var w:string; i:byte;
begin
w:=s;
if (cnt<26) and (w<>'') then for i:=1 to length(w) do
if ord(w[i])>=EL_base
then w[i]:=chr(EL_leter+ord(w[i])-EL_base);
conv:=w;
end;
begin
with D do
Ex_str:=RevStr(conv(l,Lex_cnt))+SD_str(s,md)+conv(r,Rex_cnt)
end;
procedure wr_ex1(var f:text);
var i:longint;
begin
writeln(f,'Left * consists of the expressions: ');
for i:=0 to Lex_cnt-1 do writeln(f,' '+chr(EL_leter+i),'=',Lexones[i],' ');
writeln(f);
writeln(f,'Right * consists of the expressions: ');
for i:=0 to Rex_cnt-1 do writeln(f,' '+chr(EL_leter+i),'=',Rexones[i],' ');
writeln(f);
end;
procedure SortExones(rolling:boolean);
procedure Sort1(var exarr:TIntronArr; cnt:longint);
var i,j,n,n0,n1:longint; s:string; w:char; succ:boolean;
begin
if cnt>1 then for i:=0 to cnt-2 do for j:=i+1 to cnt-1 do
if length(exarr[i])<length(exarr[j]) then begin
s:=exarr[i]; exarr[i]:=exarr[j]; exarr[j]:=s
end;
{ Roll exones to be similar to the last one }
if rolling then if cnt>1
then for j:=cnt-1 downto 1 do begin
i:=j-1;
s:=exarr[i]; succ:=false;
n0:=length(exarr[j]);
n1:=length(s)-n0;
n:={n1} length(s);
succ:=copy(s,n1+1,n0)=exarr[j];
if n1>0 then while (not succ) and (n>0) do begin
if not succ then begin w:=s[1]; delete(s,1,1); s:=s+w end;
succ:=copy(s,n1+1,n0)=exarr[j];
dec(n)
end;
if succ then exarr[i]:=s;
end;
end;
begin
Sort1(Lexones,Lex_cnt);
Sort1(Rexones,Rex_cnt);
end;
const
H_eps:byte=0;
HuffmanMode:boolean=false;
{
HuffCmpMode:boolean=false;
}
type
TExStat = array[0..bmax] of longint;
var
T_eps:array[0..1] of longint;
Lexstat, Rexstat:TExStat;
LexStat1, RexStat1:TExStat;
L_mask, R_mask:string;
procedure ClearExStats;
var k:longint;
begin
for k:=0 to bmax do begin
LexStat[k]:=0; RexStat[k]:=0;
LexStat1[k]:=0; RexStat1[k]:=0;
end;
end;
function HuffCmpStr(c0,l:string; md:byte):boolean;
begin
HuffCmpStr:=length(c0)+1=length(l)+T_eps[1-md]
end;
function HuffLessStr(c0,l:string; md:byte):longint;
begin
HuffLessStr:=length(l)+T_eps[1-md]-length(c0)-1
end;
function MakeEStep(var DF:TDescr):byte;
var simple:boolean;
function OldVertex(var CTG:TGraph; CTG_cnt:longint):boolean;
var j:longint;
begin
OldVertex:=false;
for j:=0 to CTG_cnt-1 do if SimMacro2(DF,CTG[j].D)
then OldVertex:=true;
end;
procedure AddVertex(var CTG:TGraph; var CTG_cnt:longint);
begin
if not OldVertex(CTG,CTG_cnt) then if CTG_cnt<gfin_max then begin
CTG[CTG_cnt].D:=DF;
CTG[CTG_cnt].checked:=false;
inc(CTG_cnt);
end else begin
e_state:=too_lng;
pr_fail:=true;
end;
end;
procedure MakeELoopStep;
procedure Test(
var l,r:string;
var Lexs, Rexs:TIntronArr;
var L_cnt,R_cnt:longint;
var ExStat,ExStat1:TExStat);
procedure Pack_l;
var
j,n:longint; c0a,c0b,l1,l2:string;
w:char; succ,repack:boolean;
begin
repack:=false; n:=Pos('[',l);
if n>1 then begin
w:=l[n+1];
for j:=0 to L_cnt-1 do begin
c0b:=Lexs[j];
if HuffmanMode and (l[n+2]=']') then begin
l2:=l; delete(l2,1,n+2);
l1:=copy(l,1,n-1)+Lexs[ord(w)-EL_base]+l2;
c0a:=GetF(l1,1,length(c0b));
if (c0a=c0b) and HuffCmpStr(c0b,l1,DF.md) then begin
repack:=true;
l:='['+chr(EL_base+j)+']'+l2;
end;
end else begin
c0a:=copy(l,1,n-1)+Lexs[ord(w)-EL_base];
if c0a=c0b then begin
repack:=true;
delete(l,1,n+1);
l:='['+chr(EL_base+j)+l;
end;
end;
end;
end;
if not repack then for j:=0 to L_cnt-1 do begin
c0b:=Lexs[j];
c0a:=GetF(l,1,length(c0b));
succ:=c0a=c0b;
if HuffmanMode then if succ
then begin
if Pos('[',l)=length(c0b)+1
then succ:=true
else if Pos('[',l)>0
then succ:=false
else succ:=HuffCmpStr(c0b,l,DF.md)
end;
if succ then begin
if DF.af then simple:=false;
delete(l,1,length(c0a));
if l='' then l:='.';
if Pos('[',l)=1
then delete(l,1,1)
else begin
if (l<>'.') and (not HuffmanMode) then Pack_l;
if Pos('[',l)=1
then delete(l,1,1)
else IncS(']',l,DF.af);
end;
w:=chr(EL_base+j);
if not DF.af then begin
if Pos(']',l)>1 then begin
inc(ExStat[ord(l[1])-EL_base]);
end;
if Pos(']',l)>2{3} then begin
inc(ExStat1[ord(l[1{2}])-EL_base]);
end;
end;
IncS('['+w,l,DF.af);
end;
{ bad attempt to resolve SemiHuffman repacking }
{
else begin
if HuffmanMode and (l[1] in ['+','-']) then begin
w:=l[1]; delete(l,1,1);
Pack_l; l:=w+l;
end;
end;
}
end;
end;
procedure TestIO;
var nw,ow:string; i:word;
function NoShorter:boolean;
var j:word;
begin
NoShorter:=true;
if i<R_cnt-1 then begin
nw:=ow; delete(nw,1,1);
for j:=i+1 to R_cnt-1 do
if Rexs[j]=nw then begin
NoShorter:=false;
r[2]:=chr(EL_base+j);
r:=ow[1]+r;
end;
end;
end;
begin
if Pos('[',r)=1 then begin
i:=ord(r[2])-EL_base;
ow:=Rexs[i];
if NoShorter then begin
delete(r,1,2);
if r[1]=']' then delete(r,1,1) else r:='['+r;
IncS(ow,r,DF.af);
simple:=false;
end;
end;
end;
procedure Pack_l_Rec;
var c0b:string; k,j:longint;
begin
for j:=0 to L_cnt-1 do if Pos('[',l)=0 then begin
c0b:=Lexs[j];
k:=HuffLessStr(c0b,l,DF.md);
if k>0 then begin
c0b:=copy(l,1,k);
delete(l,1,k);
Pack_l;
l:=c0b+l;
end;
end;
Pack_l;
end;
var l_save:string; md_o,nl:byte;
begin
nl:=Pos('[',l);
if (nl>H_eps) or ((nl=0) and (length(l)>H_eps)) then begin
l_save:=copy(l,1,H_eps); delete(l,1,H_eps);
Pack_l_Rec; l:=l_save+l;
end;
{ Pack_l; }
TestIO;
md_o:=DF.md;
if simple then MakeMStep0(DF,0);
if (r='.') and (DF.md=md_o) then begin
simple:=false;
{
with DF do if md=1
then l_mark:=RevStr(l)+SD_str(s,md)+r
else r_mark:=RevStr(l)+SD_str(s,md)+r;
}
end;
end;
begin
{
with DF do begin
writeln(ttm,'ELoopStep --> ',RevStr(l)+SD_str(s,md)+r);
flush(ttm);
end;
}
if DF.md=1
then Test(DF.l,DF.r,Lexones,Rexones,Lex_cnt,Rex_cnt,LexStat,LexStat1)
else Test(DF.r,DF.l,Rexones,Lexones,Rex_cnt,Lex_cnt,RexStat,RexStat1);
end;
begin
pr_fail:=false;
with DF do begin rname0:=' '; rname1:=' ' end;
BBGs_cnt:=1; BBGs[0].D:=DF;
simple:=true;
repeat
MakeELoopStep;
{ if not pr_fail then }
if simple then if OldVertex(BBGs,BBGs_cnt)
then begin e_state:=b_loop; pr_fail:=true end
else AddVertex(BBGs,BBGs_cnt);
until (not simple) or (e_state>0) or pr_fail;
if pr_fail and DF.af
then MakeEStep:=mem_ov
else MakeEStep:=e_state;
end;
procedure MacroLoop(
var CD:TDescr; var MH:THistory; var MH_cnt:longint;
mmode:byte; lim:longint); forward;
{ -------- Exone Grammar test: --------- }
var
MidArr:array[byte] of string;
Mid_cnt:byte;
procedure GenMidStr_0(lc:char; mid:string);
var patt,tail:string; n0:byte;
begin
Mid_cnt:=0;
n0:=Pos('}',mid);
tail:=mid; delete(tail,1,n0);
patt:=copy(mid,2,n0-2);
while length(patt)>0 do begin
if patt[1]=lc then begin
if length(patt)=2
then MidArr[Mid_cnt]:=lc+patt[2]+tail
else MidArr[Mid_cnt]:=lc+patt[2]+mid;
inc(Mid_cnt);
end;
if Pos(',',patt)>0
then delete(patt,1,3)
else patt:='';
end;
end;
procedure GenMidStr_1(mid:string);
var tail:string; n0,i:byte;
begin
Mid_cnt:=0;
n0:=Pos('}',mid);
tail:=mid; delete(tail,1,n0);
for i:=2 to n0-1 do begin
MidArr[Mid_cnt]:=mid[i]+mid;
inc(Mid_cnt);
MidArr[Mid_cnt]:=mid[i]+tail;
inc(Mid_cnt);
end;
end;
function PackG_0(mid:string; var packOK:boolean; ex_cnt:word):string;
var n0,n1:byte;
function InsPatt(tup,patt:string):string;
var p0,p1,t1,exused:string; n0:byte; found:boolean;
function ManyExones:boolean;
var i,n:byte;
begin
n:=0;
for i:=1 to ex_cnt do if exused[i]='*' then inc(n);
ManyExones:=(ex_cnt>5 {4 ?}) and (5*n>4*ex_cnt) {3/2;4/3;5/4};
end;
begin
exused:=''; for n0:=1 to ex_cnt do exused:=exused+' ';
(* Example: tup=bb patt={ab,bc,bb} *)
p0:=patt; n0:=length(p0);
p1:=copy(p0,n0-2,3); delete(p0,n0-3,4);
(* p1=bb} p0={ab,bc *)
exused[1+ord(p1[1])-EL_base]:='*';
exused[1+ord(tup[1])-EL_base]:='*';
found:=false;
while length(p0)>0 do begin
n0:=length(p0);
t1:=copy(p0,n0-1,2);
delete(p0,n0-2,3);
if (t1<=tup) and (not found) then begin
found:=true;
if t1<tup then p1:=tup+','+p1;
end;
p1:=t1+','+p1;
exused[1+ord(p1[1])-EL_base]:='*';
end;
if found
then p1:='{'+p1
else p1:='{'+tup+','+p1;
if length(p1)>220 then pr_fail:=true;
if ManyExones {(Pos(' ',exused)=0) or (ex_cnt>9)}
then pr_fail:=true;
InsPatt:=p1;
end;
begin
PackG_0:=mid;
packOK:=true;
n0:=length(mid);
n1:=Pos('{',mid);
if n1>0 then begin
packOK:=n1<=3;
if n1>=3 then PackG_0:=
copy(mid,1,n1-2)+
InsPatt(
copy(mid,n1-2,2),
copy(mid,n1,n0-n1+1));
end else begin
PackG_0:=copy(mid,1,n0-1)+'{'+copy(mid,n0-1,2)+'}';
packOK:=n0=2;
end;
end;
function PackG_1(mid:string; var packOK:boolean):string;
var n0,n1:byte;
function InsPatt(nc:char; patt:string):string;
var p0,tail:string; n0:byte; found:boolean;
begin
(* Example: nc=b patt={abd}x *)
n0:=Pos('}',patt);
tail:=patt; delete(tail,1,n0-1);
p0:=patt; delete(p0,n0,length(p0)-n0+1);
(* tail=}x p0={abd *)
found:=false;
n0:=length(p0);
while n0>1 do begin
if (p0[n0]<=nc) and (not found) then begin
found:=true;
if p0[n0]<nc then tail:=nc+tail;
end;
tail:=p0[n0]+tail;
dec(n0);
end;
if found
then tail:='{'+tail
else tail:='{'+nc+tail;
if length(tail)>220 then pr_fail:=true;
InsPatt:=tail;
end;
begin
PackG_1:=mid; packOK:=true;
n0:=length(mid); { must be >=2 !!! }
n1:=Pos('{',mid);
if n1>0 then begin
packOK:=n1<=2;
if n1>=2 then PackG_1:=
copy(mid,1,n1-2)+
InsPatt(mid[n1-1],copy(mid,n1,n0-n1+1));
end else begin
PackG_1:=copy(mid,1,n0-2)+'{'+mid[n0-1]+'}'+mid[n0];
packOK:=n0=2;
end;
end;
function PackG_2(mid:string; var packOK:boolean; ex_cnt:word):string;
var
ExCnts:array[byte] of longint;
mid_u:string;
procedure ExStat_0;
var i,k:byte; bmod:boolean;
begin
for i:=0 to ex_cnt-1 do ExCnts[i]:=0;
bmod:=false;
for i:=1 to length(mid) do if mid[i] in ['{','}']
then bmod:=not bmod
else begin
if bmod then k:=2 else k:=1;
inc(ExCnts[ord(mid[i])-EL_base],k);
end;
mid_u:=mid;
for i:=1 to length(mid) do
if mid[i] in ['{','}']
then mid_u[i]:=' '
else if ExCnts[ord(mid[i])-EL_base]=1
then mid_u[i]:='u' else mid_u[i]:=' ';
end;
function Pack(s:string):string;
var
Exones:array[byte] of boolean;
res:string; i:byte;
begin
{writeln(ttm,'Pack --> s="',s,'"'); flush(ttm);}
for i:=0 to ex_cnt-1 do Exones[i]:=false;
for i:=1 to length(s) do
if not (s[i] in ['{','}'])
then Exones[ord(s[i])-EL_base]:=true;
res:='{';
for i:=0 to ex_cnt-1 do if Exones[i]
then res:=res+chr(i+EL_base);
Pack:=res+'}';
end;
function RecPack(m_u,m_s:string):string;
var n0,n1,n2:byte;
begin
{
writeln(ttm,'RecPack --> m_u="',m_u,'" m_s=',m_s);
flush(ttm);
}
n1:=length(m_s);
if n1=0 then RecPack:='' else begin
n0:=Pos('u',m_u);
if n0>1
then RecPack:=
Pack(copy(m_s,1,n0-1))+m_s[n0]+
RecPack(copy(m_u,n0+1,n1-n0),
copy(m_s,n0+1,n1-n0))
else if n0=1 then begin
n2:=Pos(' ',m_u);
if n2>0
then RecPack:=copy(m_s,1,n2-1)+
RecPack(copy(m_u,n2,n1-n2+1),
copy(m_s,n2,n1-n2+1))
else RecPack:=m_s;
end else RecPack:=Pack(m_s);
end;
end;
var res:string;
begin
packOK:=true;
ExStat_0;
res:=RecPack(mid_u,mid);
{
write(ttm,' mid=',mid);
write(ttm,' mid_u=',mid_u);
writeln(ttm,' pack=',res);
flush(ttm);
}
if length(res)>200 then pr_fail:=true;
PackG_2:=res;
end;
function IncludeG_0(var D1,D2:TDescr):boolean;
function IncStr(l0,l1:string):boolean;
var n0,n1,k0,k1:byte; h0,h1:string;
function Include0:boolean;
var n0,n1:byte; succ:boolean; t0,t1:string;
begin
n0:=length(h0); n1:=length(h1);
if copy(h0,n0-1,2)=copy(h1,n1-1,2) then begin
delete(h0,n0-2,3);
delete(h1,n1-2,3);
succ:=true;
while succ and (length(h1)>0) do begin
n0:=length(h0); n1:=length(h1);
if n0<n1 then succ:=false else begin
t0:=copy(h0,n0-1,2); t1:=copy(h1,n1-1,2);
if t0<t1 then succ:=false else begin
delete(h0,n0-2,3);
if t0=t1 then delete(h1,n1-2,3);
end;
end;
end;
Include0:=succ;
end else Include0:=false;
end;
begin
if l0=l1 then IncStr:=true else begin
n0:=Pos('{',l0);
n1:=Pos('{',l1);
if (n0>0) and (n0=n1) then begin
k0:=Pos('}',l0);
k1:=Pos('}',l1);
h0:=copy(l0,k0,length(l0)+1-k0);
h1:=copy(l1,k1,length(l1)+1-k1);
if (copy(l0,1,n0)=copy(l1,1,n1)) and
(h0=h1) then begin
h0:=copy(l0,n0,k0-n0);
h1:=copy(l1,n1,k1-n1);
IncStr:=Include0;
end else IncStr:=false;
end else IncStr:=false;
end;
end;
begin
IncludeG_0:=
IncStr(D1.l,D2.l) and IncStr(D1.r,D2.r)
and (D1.s=D2.s) and (D1.md=D2.md);
end;
function IncludeG_1(var D1,D2:TDescr):boolean;
function IncStr(l0,l1:string):boolean;
var n0,n1,k0,k1:byte; h0,h1:string;
function Include0:boolean;
var n0,n1:byte; succ:boolean;
begin
succ:=true; n0:=length(h0); n1:=length(h1);
while succ and (n1>0) do begin
if n0<n1 then succ:=false else begin
if h0[n0]<h1[n1]
then succ:=false
else begin dec(n0); if h0[n0]=h1[n1] then dec(n1) end;
end;
end;
Include0:=succ;
end;
begin
if l0=l1 then IncStr:=true else begin
n0:=Pos('{',l0);
n1:=Pos('{',l1);
if (n0>0) and (n0=n1) then begin
k0:=Pos('}',l0);
k1:=Pos('}',l1);
h0:=copy(l0,k0,length(l0)+1-k0);
h1:=copy(l1,k1,length(l1)+1-k1);
if (copy(l0,1,n0)=copy(l1,1,n1)) and
(h0=h1) then begin
h0:=copy(l0,n0+1,k0-n0-1);
h1:=copy(l1,n1+1,k1-n1-1);
IncStr:=Include0;
end else IncStr:=false;
end else IncStr:=false;
end;
end;
begin
IncludeG_1:=
IncStr(D1.l,D2.l) and IncStr(D1.r,D2.r)
and (D1.s=D2.s) and (D1.md=D2.md);
end;
function PosL(c:char; s:string):byte;
var i,n:byte;
begin
n:=Pos(c,s);
if n>0 then begin
for i:=n to length(s) do
if s[i]=c then PosL:=i;
end else PosL:=n;
end;
function IncludeG_2(var D1,D2:TDescr):boolean;
function IncStr(l0,l1:string):boolean;
var n0,n1,k0,k1,i:byte; h0,h1,t0,t1:string;
function Include0(h0,h1:string):boolean;
var n0,n1:byte; succ:boolean;
begin
succ:=true;
n0:=length(h0); n1:=length(h1);
while succ and (n1>0) do begin
if n0<n1 then succ:=false else begin
if h0[n0]<h1[n1]
then succ:=false
else begin dec(n0); if h0[n0]=h1[n1] then dec(n1) end;
end;
end;
Include0:=succ;
end;
begin
if l0=l1 then IncStr:=true else begin
n0:=Pos('{',l0);
n1:=Pos('{',l1);
if (n0>0) and (n0=n1) then begin
k0:=PosL('}',l0);
k1:=PosL('}',l1);
h0:=copy(l0,k0,length(l0)+1-k0);
h1:=copy(l1,k1,length(l1)+1-k1);
if (copy(l0,1,n0)=copy(l1,1,n1)) and
(h0=h1) then begin
h0:=copy(l0,n0+1,k0-n0-1);
h1:=copy(l1,n1+1,k1-n1-1);
k0:=Pos('}',h0);
k1:=Pos('}',h1);
if (k0=0) and (k1=0)
then IncStr:=Include0(h0,h1)
else if (k0>0) and (k1>0) then begin
n0:=Pos('{',h0);
n1:=Pos('{',h1);
t0:=h0; delete(t0,1,n0);
t1:=h1; delete(t1,1,n1);
if (Pos('{',t0)=0) and (Pos('{',t1)=0)
then IncStr:=
Include0(t0,t1) and
Include0(copy(h0,1,k0-1),copy(h1,1,k1-1)) and
(copy(h0,k0,n0-k0)=copy(h1,k1,n1-k1))
else IncStr:=false;
end else if (k0=0) and (k1>0) then begin
IncStr:=true;
for i:=1 to length(h1) do
if not (h1[i] in ['{','}'])
then if Pos(h1[i],h0)=0
then IncStr:=false;
end else IncStr:=false;
end else IncStr:=false;
end else IncStr:=false;
end;
end;
begin
IncludeG_2:=
IncStr(D1.l,D2.l) and IncStr(D1.r,D2.r)
and (D1.s=D2.s) and (D1.md=D2.md);
end;
function IncludeG(var D1,D2:TDescr; gram_mod:byte):boolean;
begin case gram_mod of
0:IncludeG:=IncludeG_0(D1,D2);
1:IncludeG:=IncludeG_1(D1,D2);
2:IncludeG:=IncludeG_2(D1,D2) {false};
end end;
function PackG(
mid:string; var packOK:boolean; gram_mod:byte; l_cnt:word):string;
begin case gram_mod of
0:packG:=PackG_0(mid,packOK,l_cnt);
1:packG:=PackG_1(mid,packOK);
2:packG:=PackG_2(mid,packOK,l_cnt);
end end;
procedure TryExGFin(g_max:longint; gram_mod:byte);
const av_max=800;
var
old_gcnt, i_0,i_1:longint;
closed, simple:boolean;
DF:TDescr;
BBG1:TGraph;
BBG1_cnt:longint;
AvNodes:array[0..av_max] of longint;
Av_cnt:longint;
function Av_found(i0:longint):boolean;
var i:longint;
begin
Av_found:=false;
if Av_cnt>0 then for i:=0 to Av_Cnt-1 do
if i0=AvNodes[i] then Av_found:=true;
end;
procedure Add_Av(j:longint);
{var found:boolean; i:longint;}
begin if Av_cnt<av_max then begin
{
found:=false;
if Av_cnt>0 then for i:=0 to Av_Cnt-1 do
if j=AvNodes[i] then found:=true;
if not found then begin
}
if not Av_found(j) then begin
AvNodes[Av_cnt]:=j;
inc(Av_cnt);
if Av_cnt mod 10 = 0 then begin
gotoxy(55,10);
write('G/A/m=',BBG_cnt:4,'/',Av_cnt:3,'/',gram_mod);
end;
end;
end end;
function OldVertex(var CTG:TGraph; CTG_cnt:longint):boolean;
var j:longint;
begin
OldVertex:=false;
for j:=0 to CTG_cnt-1 do if SimMacro2(DF,CTG[j].D)
then OldVertex:=true;
end;
procedure AddVertex(var CTG:TGraph; var CTG_cnt:longint);
begin
if not OldVertex(CTG,CTG_cnt) then if CTG_cnt<g_max then begin
CTG[CTG_cnt].D:=DF;
CTG[CTG_cnt].checked:=false;
inc(CTG_cnt);
end else pr_fail:=true;
end;
function OldIVertex(var CTG:TGraph; CTG_cnt:longint):boolean;
var j:longint;
begin
OldIVertex:=false;
for j:=0 to CTG_cnt-1 do if SimMacro2(DF,CTG[j].D)
then OldIVertex:=true
else if IncludeG(CTG[j].D,DF,gram_mod)
then OldIVertex:=true
else if IncludeG(DF,CTG[j].D,gram_mod) then begin
CTG[j].checked:=true;
if j<>i_1 then Add_Av(j);
end;
end;
procedure AddIVertex(var CTG:TGraph; var CTG_cnt:longint);
var id{,i}:longint;
begin
if not OldIVertex(CTG,CTG_cnt) then if CTG_cnt<g_max then begin
if Av_cnt>0 then begin
dec(Av_cnt); id:=AvNodes[Av_cnt];
end else begin
id:=CTG_cnt; inc(CTG_cnt);
end;
CTG[id].D:=DF;
CTG[id].checked:=false;
if id<i_0 then i_0:=id;
end else if not pr_fail then begin
if {true} g_max>=(gfin_max*2) then begin
write(ttm,'m=',m,' g_max/i_0=',g_max,'/',i_0,' ');
write(ttm,'gram=',gram_mod,' H/T=',H_eps,'/',T_eps[0],'|',T_eps[1]);
writeln(ttm,' S/H=',LR_mod,' i/j=',Lex_id,'-',Rex_id);
{
ClearExStats;
MacroLoop(CEM,EMH,EMH_cnt,4,2*dump_max);
wr_exones(ttm);
}
{
wr_ex0(ttm);
for i:=0 to g_max-1 do if not Av_found(i) then begin
with CTG[i].D do write(ttm,RevStr(l)+SD_Str(s,md)+r);
if CTG[i].checked then write(ttm,' Checked');
writeln(ttm,' i=',i);
end;
}
flush(ttm);
end;
pr_fail:=true;
end;
end;
procedure Test(var l,r:string; l_cnt:word);
var n0,n1:byte;
procedure Pack;
var tail,mid,head:string; packOK:boolean;
begin
repeat
packOK:=true;
n0:=Pos('[',l); n1:=Pos(']',l);
if n0>0 then
if n1-n0>=4 then begin
tail:=l; delete(tail,1,n1-1);
head:=copy(l,1,n0+1);
mid :=copy(l,n0+2,n1-n0-2);
l:=head+PackG(mid,packOK,gram_mod,l_cnt)+tail;
end;
until packOK;
end;
procedure Unpack;
var n2,k:byte; tail,mid,head:string;
function NeedWord:boolean;
begin case gram_mod of
0:NeedWord:=n1=n0+2;
1,2:NeedWord:=n1=n0+1;
end end;
procedure GenMidStr;
var lc:char;
begin case gram_mod of
0:begin lc:=r[n0+1]; GenMidStr_0(lc,mid) end;
1,2:GenMidStr_1(mid);
{ 2:GenMidStr_1(mid); }
end end;
begin
n0:=Pos('[',r); n1:=Pos('{',r); n2:=Pos(']',r);
if n1>0 then begin
if NeedWord {n1-n0=2} then begin
tail:=r; delete(tail,1,n2-1);
head:=copy(r,1,n0);
mid :=copy(r,n1,n2-n1);
GenMidStr;
if Mid_cnt=0 then begin
writeln(ttm,'Error: empthy Grammar !');
flush(ttm); Halt;
end;
if Mid_cnt>1 then begin
simple:=false;
for k:=0 to Mid_cnt-1 do begin
r:=head+MidArr[k]+tail;
AddIVertex(BBG,BBG_cnt);
end;
end else r:=head+MidArr[0]+tail;
end;
end;
end;
begin
Pack;
Unpack;
end;
procedure Loop;
var state:byte;
begin
simple:=true;
BBG1_cnt:=1; BBG1[0].D:=DF;
repeat
state:=MakeEStep(DF);
{
writeln(ttm,'BBG1_cnt=',BBG1_cnt,' ',
'--> ',RevStr(DF.l),SD_str(DF.s,DF.md),DF.r);
flush(ttm);
}
if state=0 then begin
BBG[i_1].checked:=true;
BBG[i_1].DNext:=DF;
if DF.md=1
then Test(DF.l,DF.r,Lex_cnt)
else Test(DF.r,DF.l,Rex_cnt);
if simple then if OldVertex(BBG1,BBG1_cnt)
then begin
simple:=false;
AddIVertex(BBG,BBG_cnt);
end else AddVertex(BBG1,BBG1_cnt);
end else pr_fail:=true;
until (not simple) or pr_fail;
end;
begin
if g_max>2*gfin_max then begin
gotoxy(1,24);
writeln('Error: g_max must be less than ',2*gfin_max,' !');
Halt;
end;
old_gcnt:=0;
ClearExStats;
repeat
BBG_cnt:=1; i_0:=0;
Av_cnt:=0;
pr_fail:=false;
ClearExStats;
ClearDescr(DF);
pr_fail:=false;
e_state:=0;
DF.af:=true; { ??? }
with BBG[0] do begin D:=DF; checked:=false end;
while (not pr_fail) and (i_0<BBG_cnt) do begin
DF:=BBG[i_0].D;
i_1:=i_0; inc(i_0);
if not BBG[i_1].checked then Loop;
end;
closed:=BBG_cnt=old_gcnt;
if not closed then old_gcnt:=BBG_cnt;
until pr_fail or closed;
if not pr_fail then begin
ClearExStats;
MacroLoop(CEM,EMH,EMH_cnt,4,dump_max);
{
writeln(ttm,'M=',m,' TryExGFin prooof succeed !!! g_fin=',BBG_cnt);
wr_grapf(ttm,BBG,BBG_cnt);
wr_exones(ttm);
flush(ttm);
}
e_state:=exS2_l;
end else begin
{ writeln(ttm,'M=',m,' TryExGFin prooof fail !!!'); }
{
if (g_max<gfin_max) and (T_eps[0]=0) and (T_eps[1]=0) and
(Lex_cnt>2) and (Rex_cnt>2)
then begin
ClearExStats;
MacroLoop(CEM,EMH,EMH_cnt,4,2*dump_max);
wr_exones(ttm);
flush(ttm);
end;
}
e_state:=0;
end;
end;
{ ----------------------------------------------------------- }
procedure CollatzLoop(
var CD:TDescr; var MH:THistory;
var MH_cnt:longint; lim:longint);
const max_cnt=100000000;
var vc0:longint;
begin
ClearDescr(CD);
MH_cnt:=0;
new_def:=false;
e_state:=0;
repeat
vc0:=VarCount(CD);
MH[MH_cnt]:=CD; inc(MH_cnt);
{writeln(ttm);}
repeat
MakeMStep0(CD,1);
{
with CD do writeln(ttm,'c:',c,' ',RevStr(l),SD_str(s,md),r,
' e_state=',e_state,' vc=',VarCount(CD));
flush(ttm);
}
until
(VarCount(CD)<>vc0) or (CD.s=0) or
(e_state>0) or (CD.c>max_cnt);
if MH_cnt mod 10=0 then begin
gotoxy(55,2); write('Collatz_cnt=',MH_cnt,' ');
end;
if CD.c>max_cnt then begin
CM:=Cl_M;
MH:=ClMH;
MH_cnt:=ClMH_cnt;
{
writeln(ttm,'------- Collatz-like bad machine: ------');
writeln(ttm,'M# = ',m-1);
wrf_m(ttm,true,false);
wr_rules(ttm,'approved shift',SRules,SR_cnt,false);
wr_mhistory(ttm,cmax);
wr_grapf(ttm,CTG,CTG_cnt,false);
writeln(ttm,'-------------------------------------');
}
e_state:=too_lng;
end;
if CD.s=0 then e_state:=col0_e;
if MH_cnt>=lim then e_state:=too_lng;
if new_def and (e_state=0) then begin
InvSTest;
if (e_state=0) and lDum then back_track;
new_def:=false;
end;
until e_state>0;
{ If fail, continue normal interpretation }
if e_state<>col0_e then e_state:=0;
end;
procedure MacroLoop(
var CD:TDescr; var MH:THistory; var MH_cnt:longint;
mmode:byte; lim:longint);
procedure Make100Steps;
var i:longint;
begin
i:=0;
repeat
MakeMStep0(CD,0);
inc(i);
until (i=100) or new_def or (e_state>0);
end;
begin
gfin_lim:=lim;
ClearDescr(CD);
MH_cnt:=0;
new_def:=false;
e_state:=0;
repeat
MH[MH_cnt]:=CD; inc(MH_cnt);
case mmode of
1:MakeMStep(CD);
2:MakeMStep0(CD,2);
3:MakeBStep(CD);
4:MakeEStep(CD);
5:MakeMStep0(CD,3);
6:Make100Steps;
end;
if MH_cnt mod 100=0 then begin
gotoxy(55,6); write('MH_cnt=',MH_cnt,' ');
end;
if MH_cnt>=lim then e_state:=too_lng;
if new_def and (e_state=0) then begin
InvSTest;
if (e_state=0) and lDum then back_track;
new_def:=false;
end;
until e_state>0;
{ PackPatt tuning }
{
if (mmode=1) and (rule_min=5) then begin
wr_rules(ttm,'approved shift',SRules,SR_cnt,false);
wr_mhistory(ttm,lim);
flush(ttm);
end;
}
end;
(*
procedure CreateOSRules;
var i,j,k:longint; TR:TRule; succ:boolean; w:char;
begin
OSR_cnt:=0; OSR_main:=-1;
with MainRule do for i:=0 to ASR_cnt-1
do if md<>ASRules[i].md then for j:=0 to Patt_cnt-1
do if (ASRules[i].c0=Patts[j].c1) then begin
TR:=ASRules[i]; succ:=false;
for k:=0 to length(TR.c1)-1 do if not succ then begin
if TR.c1=Patts[j].c0 then begin
OSRules[OSR_cnt]:=TR;
if j=m_id then OSR_main:=OSR_cnt;
inc(OSR_cnt); succ:=true;
end else with TR do begin
w:=c1[1]; delete(c1,1,1);
c1:=c1+w; a:=a+w;
end;
end;
end;
if OSR_main>=0 then OSRule:=OSRules[OSR_main];
OSRule.p:=(OSRule.md+OSRule.md-1)*length(OSRule.c0);
end;
*)
procedure wr_exones(var f:text);
var i,lim:longint;
begin
wr_ex0(f);
EMH[EMH_cnt]:=CEM;
lim:=EMH_cnt {dump_max} ;
if lim>EMH_cnt then lim:=EMH_cnt;
writeln(f);
writeln(f,'First ',lim,' exone macro stEps:');
writeln(f,' ind p c LsdR');
for i:=0 to lim do with EMH[i] do begin
write(f,i:4,' ',p:6,c:10,': ');
writeln(f,Ex_str(EMH[i]));
end;
writeln(f);
end;
procedure DoubleExones(
var Exones:TIntronArr; var Ex_cnt:longint);
var i,l:longint;
begin
l:=Ex_cnt;
if l<=32 then for i:=0 to l-1 do begin
Exones[Ex_cnt]:='-'+Exones[i];
Exones[i] :='+'+Exones[i];
inc(Ex_cnt);
end;
end;
procedure SqrExones(
var Exones:TIntronArr; var Ex_cnt:longint);
var i,j,l:longint;
begin
l:=Ex_cnt;
if l<=8 then begin
for i:=0 to l-1 do for j:=0 to l-1 do
if i<>j then begin
Exones[Ex_cnt]:=Exones[i]+Exones[j];
inc(Ex_cnt);
end;
for i:=0 to l-1 do
Exones[i]:=Exones[i]+Exones[i];
end;
end;
const
Huff_size = 9;
HStat_max = 1000;
type
HStatEl=record
mode,eps,i,j,cnt:longint;
end;
HuffCodesArr = array[0..ESet_max] of TExoneSet;
var
HuffCodes: HuffCodesArr; Huff_cnt:longint;
SemiCodes: HuffCodesArr; Semi_cnt:longint;
H_Stats: array[0..HStat_max] of HStatEl;
H_St_cnt:longint;
function GetHStat0(amode,eps0,i0:longint):boolean;
var found:boolean; k:longint;
begin
found:=false;
if H_St_cnt>0 then for k:=0 to H_St_cnt-1 do
with H_Stats[k] do if
(mode=amode) and (eps=eps0) and ((i=i0) or (j=i0))
then found:=true;
GetHStat0:=found;
end;
function GetHStat(amode,eps,i,j:longint; proved:boolean):boolean;
var
f:text;
S0:HStatEl; found:boolean; k:longint;
begin
S0.mode:=amode;
S0.eps:=eps; S0.cnt:=1;
if i>j then begin
S0.i:=j; S0.j:=i;
end else begin
S0.i:=i; S0.j:=j;
end;
found:=false;
if H_St_cnt>0 then for k:=0 to H_St_cnt-1 do
with H_Stats[k] do if
(mode=S0.mode) and (eps=S0.eps) and (i=S0.i) and (j=S0.j)
then begin found:=true; if proved then inc(cnt) end;
if (not found) and (H_St_cnt<HStat_max) and proved then begin
H_Stats[H_St_cnt]:=S0;
inc(H_St_cnt);
if H_St_cnt>0 then begin
assign(f,'HuffStat.txt');
rewrite(f);
for k:=0 to H_St_cnt-1 do with H_Stats[k] do
writeln(f,mode,' ',eps,' ',i,' ',j,' ',cnt);
close(f);
end;
end;
GetHStat:=found;
end;
procedure InitHStat;
var f:text; w:string; mode,eps,i,j:longint;
function GetInt:longint;
var w1:string; i,n:longint;
begin
w1:=copy(w,1,Pos(' ',w)-1);
val(w1,n,i);
delete(w,1,Pos(' ',w));
GetInt:=n;
end;
begin
H_St_cnt:=0;
{$I-} assign(f,'HuffStat.dat'); reset(f); {$I+}
if IOResult=0 then while not eof(f) do begin
readln(f,w);
mode:=GetInt; eps:=GetInt;
i:=GetInt; j:=GetInt;
GetHStat(mode,eps,i,j,true);
end;
end;
procedure SortHSet(var G0:TExoneSet);
var i,j:longint; w:string;
function Less(s1,s2:string):boolean;
begin
if length(s1)<>length(s2)
then Less:=length(s1)<length(s2)
else Less:=RevStr(s1)>RevStr(s2);
end;
begin with G0 do
for i:=0 to cnt-2 do for j:=i+1 to cnt-1 do
if Less(EA[i],EA[j]) then begin w:=EA[i]; EA[i]:=EA[j]; EA[j]:=w end;
end;
procedure CreateHuffCodes(
var HuffCodes: HuffCodesArr; var Huff_cnt:longint; c_mode:byte);
var
Gen_cnt,i,j,n:longint;
G0:TExoneSet; allowed:boolean;
function CmpSet(var HS:TExoneSet):boolean;
var succ:boolean; i:longint;
begin
succ:=HS.cnt=G0.cnt;
if succ then for i:=0 to G0.cnt-1
do if HS.EA[i]<>G0.EA[i] then succ:=false;
CmpSet:=succ;
end;
procedure AddHSet;
var i:longint; succ:boolean;
begin
succ:=true;
for i:=0 to Huff_cnt-1 do
if CmpSet(HuffCodes[i]) then succ:=false;
if succ and (Huff_cnt<ESet_max) then begin
HuffCodes[Huff_cnt]:=G0;
inc(Huff_cnt);
end
end;
procedure PrintCodes;
var i,j:longint;
begin
case c_mode of
0:writeln(ttm,'------------- Huffman codes: --------------');
1:writeln(ttm,'----------- Semi_Huffman codes: -----------');
end;
for i:=0 to Huff_cnt-1 do with HuffCodes[i] do begin
write(ttm,'HuffSet[',i,'] cnt=',cnt,' ');
for j:=0 to cnt-1 do write(ttm,chr(ord('a')+j),'=',EA[j],' ');
writeln(ttm);
end;
writeln(ttm,'-------------------------------------------');
flush(ttm);
end;
procedure MakeNewSet(i,s_mode:byte);
begin
G0:=HuffCodes[Gen_cnt];
with G0 do begin
case s_mode of
0:begin EA[cnt]:='-'+EA[i]; EA[i]:='+'+EA[i] end;
1:EA[cnt]:='+'+EA[i];
2:EA[cnt]:='-'+EA[i];
end;
inc(cnt);
end;
SortHSet(G0);
AddHSet;
end;
function Test_Acc(i:byte):boolean;
var j:byte; s0,s1:string;
begin
Test_acc:=false;
s0:=HuffCodes[Gen_cnt].EA[i];
if s0[1]='-' then s0[1]:='+' else s0[1]:='-';
with HuffCodes[Gen_cnt] do for j:=0 to n do begin
s1:=EA[j];
if length(s1)>length(s0) then delete(s1,1,length(s1)-length(s0));
if s1=s0 then Test_acc:=true;
end;
end;
var mid_v:longint;
begin
InitHStat;
with HuffCodes[0] do begin EA[0]:='+'; EA[1]:='-'; cnt:=2 end;
HuffCodes[4]:=HuffCodes[0]; { 1-bit set }
with HuffCodes[0] do DoubleExones(EA,cnt); { 2-bit set }
with HuffCodes[0] do DoubleExones(EA,cnt); { 3-bit set }
HuffCodes[1]:=HuffCodes[0];
with HuffCodes[1] do DoubleExones(EA,cnt); { 4-bit set }
HuffCodes[2]:=HuffCodes[1];
with HuffCodes[2] do DoubleExones(EA,cnt); { 5-bit set }
HuffCodes[3]:=HuffCodes[2];
with HuffCodes[3] do DoubleExones(EA,cnt); { 6-bit set }
Huff_cnt:=5; Gen_cnt:=4;
while (Huff_cnt>Gen_cnt) and (Huff_cnt<ESet_max) do begin
n:=HuffCodes[Gen_cnt].cnt-1;
if n<=Huff_size then for i:=0 to n do begin
allowed:=true;
with HuffCodes[Gen_cnt] do for j:=0 to n do
if (EA[j]='-'+EA[i]) or (EA[j]='+'+EA[i])
then allowed:=false;
if allowed then case c_mode of
0:MakeNewSet(i,0);
1:begin
if Test_acc(i) then MakeNewSet(i,0);
MakeNewSet(i,1);
MakeNewSet(i,2);
end;
end;
end;
inc(Gen_cnt);
end;
case c_mode of
0:mid_v:=25;
1:mid_v:=39;
end;
for i:=0 to 3 do begin { shift special codes }
G0:=HuffCodes[0];
for j:=1 to mid_v do HuffCodes[j-1]:=HuffCodes[j];
HuffCodes[mid_v]:=G0;
end;
PrintCodes;
end;
const
SqrEx_2:boolean=false;
procedure MakeEx_2(md,id:longint);
var i:byte; G0:TExoneSet;
begin
G0:=HuffCodes[id];
if (G0.cnt<=7) and SqrEx_2 then begin
SqrExones(G0.EA,G0.cnt);
SortHSet(G0);
end;
with G0 do case md of
0:begin Lexones:=EA; Lex_cnt:=cnt end;
1:begin Rexones:=EA; Rex_cnt:=cnt end;
end;
if md=0 then begin
L_mask:=''; for i:=0 to Lex_cnt-1 do L_mask:=L_mask+'_';
end else begin
R_mask:=''; for i:=0 to Rex_cnt-1 do R_mask:=R_mask+'_';
end;
end;
procedure MakeEx_3(md,id:longint);
var i:byte; G0:TExoneSet;
begin
G0:=SemiCodes[id];
with G0 do case md of
0:begin Lexones:=EA; Lex_cnt:=cnt end;
1:begin Rexones:=EA; Rex_cnt:=cnt end;
end;
if md=0 then begin
L_mask:=''; for i:=0 to Lex_cnt-1 do L_mask:=L_mask+'_';
end else begin
R_mask:=''; for i:=0 to Rex_cnt-1 do R_mask:=R_mask+'_';
end;
end;
procedure Shoot(i,j,g_max:longint; mode,gram_mod,sh_mode:byte);
function ProperEx(i:longint):boolean;
var w:boolean;
begin
case sh_mode of
0:w:=not (i in [{37}38..39]);
1:w:=not (i in [{23}24..25]);
end;
ProperEx:=w or (EL_base=128+64);
end;
var shs:string;
begin if ProperEx(i) and ProperEx(j) then
if e_state in [0,mem_ov,too_lng] then begin
case sh_mode of
0:begin MakeEx_3(0,j); MakeEx_3(1,i); shs:='SGr_'; LR_mod:=0; end;
1:begin MakeEx_2(0,j); MakeEx_2(1,i); shs:='HGr_'; LR_mod:=1; end;
end;
Lex_id:=j; Rex_id:=i;
case gram_mod of
0:shs:='S'+shs;
1:shs:='E'+shs;
2:shs:='e'+shs;
end;
TryExGFin(g_max,gram_mod);
if e_state=exS2_l then begin
GetHStat(4+sh_mode+2*gram_mod,H_eps,i,j,true);
writeln(ttm,'M=',m,
' ',shs,mode,' H_eps=',H_eps,
' T_eps=',T_eps[0],'_',T_eps[1],
' i=',i,' j=',j,' g_cnt=',BBG_cnt);
flush(ttm);
case gram_mod of
0:case mode of
0:e_state:=ex0f_l;
1,2:e_state:=ex1f_l;
end;
1:case mode of
0:e_state:=exH0_l;
1,2:e_state:=exH1_l;
end;
2:case mode of
0:e_state:=exS0_l;
1,2:e_state:=exS1_l;
end;
end;
end else begin
{ test_5388487 }
{
if (i=39) and (j=39) then begin
wr_grapf(ttm,BBG,BBG_cnt,false);
end;
}
end;
end end;
procedure FastExones3(g_max:longint; mode,gram_mod:byte; all:boolean);
procedure Loop(sh_mode:byte);
var m_max:longint;
{ 6 for up to 3 words in SemiHuffman code }
{ 35 for up to 4 words in SemiHuffman code }
{ 39 for up to 4 words in SemiHuffman code + spec sets }
{ 173 for up to 5 words in SemiHuffman code + special sets }
{ 795 for up to 6 words in SemiHuffman code + special sets }
{ must be less than 1000 !!! }
var i,j:longint;
function i_max:longint;
begin case sh_mode of
0:case mode of
0:i_max:=35 {13};
1:i_max:=173;
2:i_max:=795;
end;
1:case mode of
0:i_max:=21 {8};
1:i_max:=67;
2:i_max:=199;
end;
end end;
function j_max:longint;
begin case sh_mode of
0:case mode of
0:j_max:=6;
1:j_max:=35;
2:j_max:=173;
end;
1:case mode of
0:j_max:=7 {2};
1:j_max:=21;
2:j_max:=67;
end;
end end;
begin if e_state in [0,mem_ov,too_lng] then begin
HuffmanMode:=true;
for i:=0 to i_max do if e_state in [0,mem_ov,too_lng]
then if all or GetHStat0(4+sh_mode+2*gram_mod,H_eps,i) then begin
gotoxy(55,7); write('SHG',sh_mode,'=',i,' eps=',H_eps,' ');
j:=i;
Shoot(i,i,g_max,mode,gram_mod,sh_mode);
if i>j_max then m_max:=j_max else m_max:=i-1;
if i>0 then for j:=0 to m_max do
if all or GetHStat(4+sh_mode+2*gram_mod,H_eps,i,j,false) then begin
Shoot(i,j,g_max,mode,gram_mod,sh_mode);
Shoot(j,i,g_max,mode,gram_mod,sh_mode)
end;
end;
HuffmanMode:=false;
end end;
begin
Loop(0);
Loop(1);
end;
procedure TryBestEx(g_max:longint; l_mode:byte);
var k:longint; gram_mod,sh_mode:byte;
function i_max(sh_mode:byte):longint;
begin case sh_mode of
0:case l_mode of
0:i_max:=35;
1:i_max:=173;
2:i_max:=Semi_cnt-1 {795};
end;
1:case l_mode of
0:i_max:=21;
1:i_max:=199 {67};
2:i_max:=Huff_cnt-1 {628} {199};
end;
end end;
function ProperEx(j:word):boolean;
begin
ProperEx:=j<=i_max(sh_mode);
if (sh_mode=0) and (l_mode<2) and (j in [38..39])
then ProperEx:=false;
end;
begin
HuffmanMode:=true;
if H_St_cnt>0 then for k:=0 to H_St_cnt-1 do
with H_Stats[k] do begin
H_eps:=eps;
sh_mode:=mode mod 2;
gram_mod:=(mode-4) div 2;
if ProperEx(j) and ProperEx(i) then begin
gotoxy(55,7); write('mod=',mode,':',i,'|',j,'/',H_eps,' ',l_mode,' ');
Shoot(i,j,g_max,l_mode,gram_mod,sh_mode);
if i<j then Shoot(j,i,g_max,l_mode,gram_mod,sh_mode);
end;
end;
HuffmanMode:=false;
end;
procedure ShowESeq(i,j:word; sh_mode:byte);
begin
{
H_eps:=0;
T_eps[0]:=0;
T_eps[1]:=0;
HuffmanMode:=true;
}
case sh_mode of
0:begin MakeEx_3(0,i); MakeEx_3(1,j) end;
1:begin MakeEx_2(0,i); MakeEx_2(1,j) end;
end;
ClearExStats;
MacroLoop(CEM,EMH,EMH_cnt,4,4*dump_max);
wr_exones(ttm);
flush(ttm);
end;
procedure EvalBestEx(mode:byte; g_max:longint; all_ex:boolean);
procedure Loop(sh_mode,vl_mode,vr_mode:byte);
var l_max,r_max,i,steps:longint; l_r,r_r:real; best:boolean;
{ 6 for up to 3 words in SemiHuffman code }
{ 35 for up to 4 words in SemiHuffman code }
{ 39 for up to 4 words in SemiHuffman code + spec sets }
{ 173 for up to 5 words in SemiHuffman code + special sets }
{ 795 for up to 6 words in SemiHuffman code + special sets }
{ must be less than 1000 !!! }
function ProperEx(i:longint):boolean;
begin
case sh_mode of
0:ProperEx:=all_ex or (not (i in [36..39]));
1:ProperEx:=not (i in [{23}22..25]);
end;
end;
procedure EvalSteps(i:longint);
begin case sh_mode of
0:begin
steps:=500;
case i of
0..6:steps:=100;
7..35:steps:=200;
36:steps:=600;
37:steps:=700;
38:steps:=800;
39:steps:=900;
40..173:steps:=300;
end;
end;
1:begin
steps:=600;
case i of
0..2:steps:=100;
3..7:steps:=200;
8..21:steps:=300;
22:steps:=600;
23:steps:=700;
24:steps:=800;
25:steps:=900;
26..67:steps:=400;
end;
end;
end end;
procedure Shoot1(i:longint);
procedure EvalBest(
Ex_cnt:word; var ExArr:TIntronArr; var ExStat:TExStat;
var id_max:longint; var r:real; v_mode:byte);
var r0:real; j,k:word;
begin
r0:=0.0; k:=0;
for j:=0 to Ex_cnt-1 do if ExStat[j]>0 then inc(k);
case v_mode of
{ OldBest: }
0:begin
if k=0 then begin
writeln(ttm,'ERROR --> k=0 ');
wr_exones(ttm);
flush(ttm);
k:=10;
end;
for j:=0 to Ex_cnt-1 do if ExStat[j]>0 then begin
r0:=r0+sqr(length(ExArr[j]){-1});
end;
r0:=sqrt(r0)/sqr(k);
end;
{ NewBest: }
1:if k=0 then r0:=0.0 else begin
r0:=99.00;
for j:=0 to Ex_cnt-1 do if ExStat[j]>0 then
if r0>length(ExArr[j]) then r0:=length(ExArr[j]);
r0:=r0/sqrt(k);
end;
{ Best_2: }
2,3:begin
if k=0 then r0:=10.0 else begin
r0:=0.0;
for j:=0 to Ex_cnt-1 do if ExStat[j]>0 then case v_mode of
2:r0:=r0+1.0/length(ExArr[j]);
3:r0:=r0+1.0/sqr(length(ExArr[j]));
end;
end;
r0:=1.0/r0;
end;
end;
if r0>=r then begin id_max:=i; r:=r0; best:=true end;
end;
{
procedure Show;
var k:word;
begin
writeln(ttm,'i= ',i,' sh_mode=',sh_mode,' steps=',steps);
write(ttm,'LexStats: addr=',longint(addr(LexStat1)),' ');
for k:=0 to Lex_cnt-1 do write(ttm,LexStat1[k]:6);
writeln(ttm);
write(ttm,'RexStats: addr=',longint(addr(RexStat1)),' ');
for k:=0 to Rex_cnt-1 do write(ttm,RexStat1[k]:6);
writeln(ttm);
flush(ttm);
end;
}
var lim:longint;
begin if ProperEx(i) then begin
gotoxy(55,7);
case sh_mode of
0:write('S_Best=',i:4,' ');
1:write('H_Best=',i:4,' ');
end;
case sh_mode of
0:begin MakeEx_3(0,i); MakeEx_3(1,i) end;
1:begin MakeEx_2(0,i); MakeEx_2(1,i) end;
end;
ClearExStats;
EvalSteps(i);
lim:=steps*(mode+1)*3 div 2;
if lim>cmax then lim:=cmax;
{ ExBug } {writeln(ttm,'B> i=',i,' e_state=',e_state); flush(ttm);}
MacroLoop(CEM,EMH,EMH_cnt,4,lim);
{ ExBug } {writeln(ttm,'C> i=',i,' e_state=',e_state); flush(ttm);}
{ ExBug }
{
if e_state=1 then begin
wr_exones(ttm); flush(ttm);
end;
}
e_state:=0;
{ Show; }
EvalBest(Lex_cnt,Lexones,LexStat1,l_max,l_r,vl_mode);
EvalBest(Rex_cnt,Rexones,RexStat1,r_max,r_r,vr_mode);
end end;
function i_max:longint;
begin case sh_mode of
0:case mode of
0:i_max:=39 {35};
1:i_max:=173;
2:i_max:=Semi_cnt-1 {795};
end;
1:case mode of
0:i_max:=21;
1:i_max:=199 {67};
2:i_max:=Huff_cnt-1 {628} {199};
end;
end end;
procedure TryProof;
var he:byte;
function lr_OK:boolean;
begin
case mode of
0:lr_OK:=l_max+r_max>5;
1:lr_OK:=l_max+r_max>50;
2:lr_OK:=l_max+r_max>500;
end;
end;
begin
for he:=0 to 4 {2} do if lr_OK then begin
H_eps:=he;
Shoot(r_max,l_max,g_max,mode,2,sh_mode);
Shoot(r_max,l_max,g_max,mode,0,sh_mode);
end;
end;
begin if e_state in [0,mem_ov,too_lng] then begin
H_eps:=2 {1};
l_r:=-1.0; r_r:=-1.0;
for i:=0 to i_max do
if e_state in [0,mem_ov,too_lng] then begin
best:=false;
Shoot1(i);
if best then begin
writeln(ttm,'Best: M=',m,' T_eps=',T_eps[0],'|',T_eps[1],
' l/r_id=',l_max,'|',r_max,
' l/r_v=',l_r:5:3,'|',r_r:5:3,
' SH:mode:vl|vr=',sh_mode,':',mode,':',vl_mode,'|',vr_mode);
flush(ttm);
if l_max+r_max>1600 then ShowESeq(l_max,r_max,sh_mode);
TryProof;
if not (e_state in [0,mem_ov,too_lng]) then writeln(ttm,
'SuccBest for M=',m,
' SH:mode:vl|vr=',sh_mode,':',mode,':',vl_mode,'|',vr_mode);
end;
end;
end end;
var vl,vr,hm:byte;
begin
{T_eps[0]:=0; T_eps[1]:=0;}
HuffmanMode:=true;
for vl:=0 to 0{1..3} do
for vr:=0 to 0{1..3} do
for hm:=0 to 1 do Loop(hm,3-vl,3-vr);
HuffmanMode:=false;
end;
{ --------- Spectrum stats: -------- }
const
SpecCnt:byte=0;
var
SpecArr:array[byte] of string;
SpecStr:string;
function SpecCheck(s:string):boolean;
var i:longint;
begin
SpecCheck:=false;
if SpecCnt>0 then for i:=0 to SpecCnt-1 do
if SpecArr[i]=s then SpecCheck:=true;
end;
procedure SpecAdd(s:string);
begin
if (SpecCnt<255) and (not SpecCheck(s)) then begin
inc(SpecCnt);
SpecArr[SpecCnt]:=s;
end;
end;
procedure ExonesSpecFast(lim:longint);
const
tsize=3 {3}; nreg0 = 0 {12};
procedure Fast2(mode:byte; all:boolean);
var i,j,g_max:longint;
function Allow:boolean;
begin
Allow:=
(mode>0) or ((T_eps[0]<=0) and (T_eps[1]<=0))
end;
function AllOK_0:boolean;
begin
AllOK_0:=
T_eps[0]+T_eps[1]<{=}0
{true}
end;
begin
for i:=0 to (tsize*tsize-1) do begin
T_eps[0]:=(i mod tsize)-(tsize div 2);
T_eps[1]:=(i div tsize)-(tsize div 2);
gotoxy(55,4);
write('T_eps=',T_eps[0],',',T_eps[1],' ');
if all then write('T') else write('F');
case mode of
0:if all
then g_max:=gfin_max
else g_max:=gfin_max div 4;
1:if all
then g_max:=gfin_max*2
else g_max:=gfin_max;
2:g_max:=gfin_max*2;
end;
if all then begin
if AllOK_0 then EvalBestEx(mode,g_max,false);
if mode>0 then for j:=0 to 3 do begin
H_eps:=j;
if AllOK_0 then FastExones3(g_max,mode-1,0,all);
if AllOK_0 then FastExones3(g_max,mode-1,2,all);
end;
end else begin
if Allow then TryBestEx(g_max,mode);
end;
end;
gotoxy(55,4); write(' ');
end;
begin if e_state in [0,mem_ov,too_lng] then begin
if lim<600 then begin
{EvalBestEx(2);}
{ShowESeq(241,241);}
{ShowESeq(241,30);}
{
Fast2(2,false);
Fast2(2,true);
}
Fast2(0,false);
end else begin
if lim<cmax
then begin
Fast2(1,false);
if slow_0 then Fast2(0,true);
end else begin
Fast2(2,false);
end;
if slow_scan and (lim=cmax) and
(not SpecCheck(SpecStr)) and
(e_cnt[too_lng]>=nreg0)
then begin
Fast2(1,true);
if slow_2 then Fast2(2,true);
end;
end;
H_eps:=0;
end end;
procedure TryBL_Pr_0(m_cnt:byte);
{ m_cnt must be >=1 }
var
DF:TDescr; simple,reps:boolean;
k,i, Lex_0,Rex_0 :longint;
stepmode:byte;
steparr:array[0..cmax] of TDescr;
stepcnt:longint;
function OldVertex(var CTG:TGraph; CTG_cnt:longint):boolean;
var j:longint;
begin
OldVertex:=false;
for j:=0 to CTG_cnt-1 do if SimMacro2(DF,CTG[j].D)
then OldVertex:=true;
end;
procedure AddVertex(var CTG:TGraph; var CTG_cnt:longint);
begin
if not OldVertex(CTG,CTG_cnt) then if CTG_cnt<gfin_max then begin
CTG[CTG_cnt].D:=DF;
CTG[CTG_cnt].checked:=false;
inc(CTG_cnt);
end else pr_fail:=true;
end;
procedure Convert(
var l,r:string;
var Lexs:TIntronArr; var L_cnt:longint;
var Rexs:TIntronArr; var R_cnt:longint);
procedure PackL;
var v1,v2:string; i0,e_cod:longint;
begin
if VarSCnt(l)>0 then begin
v1:=GetVCnt(l);
if { (v1='p') or } ((length(v1)>1) and (v1[2]='-'))
then pr_fail:=true
else begin
if v1[1]='p' then delete(v1,1,2);
val(v1,i0,e_cod);
if i0>m_cnt then i0:=m_cnt;
Str(i0,v1);
v1:='p+'+v1;
SetVCnt(l,v1);
end;
if (not pr_fail) and (VarSCnt(l)>1) then begin
i0:=Pos(')',l); v1:=copy(l,1,i0); delete(l,1,i0);
i0:=Pos('*',l);
if i0=0 then i0:=Pos(')',l) else dec(i0);
v2:=copy(l,1,i0); delete(l,1,i0);
if l[1]<>'*' then l:='*'+l;
AddIntron(Lexs,L_cnt,v2);
l:=v1+l;
end;
end;
end;
procedure UnpackR;
var j:integer; r0,r1,v1:string;
begin
if r[1]='*' then begin
simple:=false;
stepmode:=1;
stepcnt:=0;
r1:=r; r0:=r; delete(r0,1,1);
for j:=0 to R_cnt-1 do begin
r:=Rexs[j]+r1; steparr[stepcnt]:=DF; inc(stepcnt);
r:=Rexs[j]+r0; steparr[stepcnt]:=DF; inc(stepcnt);
end;
r:=r1;
end else if VarSCnt(r)>0 then begin
v1:=GetVCnt(r);
if (length(v1)>1) and (v1[2]='-') then pr_fail:=true
end;
end;
begin
PackL;
if not pr_fail then UnpackR;
end;
procedure MakeBL_Step;
begin
simple:=true;
MakeMStep0(DF,3);
if not pr_fail then if DF.md=1
then Convert(DF.l,DF.r,Lexones,Lex_cnt,Rexones,Rex_cnt)
else Convert(DF.r,DF.l,Rexones,Rex_cnt,Lexones,Lex_cnt);
end;
begin
gotoxy(55, 8); write('BL_Proof M=',m,' ');
Lex_cnt:=0; Rex_cnt:=0;
rep_min:=m_cnt-1;
repeat
Lex_0:=Lex_cnt;
Rex_0:=Rex_cnt;
ClearDescr(DF);
DF.af:=true;
pr_fail:=false;
e_state:=0;
BBG_cnt:=1; i:=0;
with BBG[0] do begin D:=DF; checked:=false end;
repeat
DF:=BBG[i].D; BBG[i].checked:=true;
BBGs_cnt:=1; BBGs[0].D:=DF;
repeat
BBG[i].DNext:=DF;
MakeBL_Step;
if simple then begin
reps:=OldVertex(BBGs,BBGs_cnt);
if not reps then AddVertex(BBGs,BBGs_cnt);
end else reps:=true;
until reps
or OldVertex(BBG,BBG_cnt)
or pr_fail;
{ if simple or (stepmode=0) then} BBG[i].DNext:=DF;
if not pr_fail then if simple
then AddVertex(BBG,BBG_cnt)
else case stepmode of
0:AddVertex(BBG,BBG_cnt);
1,2,3:for k:=0 to stepcnt-1 do begin
DF:=steparr[k];
AddVertex(BBG,BBG_cnt);
end;
end;
inc(i)
until (i=BBG_cnt) or pr_fail;
until pr_fail or ((Lex_0=Lex_cnt) and (Rex_0=Rex_cnt));
if (not pr_fail) then begin
e_state:=BLfinl;
writeln(ttm,'M=',m,' BL_Proof m_cnt=',m_cnt,' g_cnt=',BBG_cnt);
end;
end;
procedure TryBL_Proof;
var k:byte;
begin
for k:=1 to 5 do { may be 4 is enough ! }
if e_state in [0,mem_ov,too_lng]
then TryBL_Pr_0(k);
end;
const
best_rlen:byte=0;
procedure TryBL_Loop(lim:longint);
var id_r:longint; succ:boolean;
procedure FindMSRule(amd:byte);
var i,j,cnt,cnt0:longint;
begin
cnt0:=-1; id_r:=-1;
if SR_cnt>0 then for i:=0 to SR_cnt-1 do
with SRules[i] do if used and (md=amd) then begin
cnt:=0; for j:=1 to spec_max do cnt:=cnt+j*spectrum[j]*length(c0);
if cnt>cnt0 then begin cnt0:=cnt; id_r:=i; best_rlen:=length(c0) end;
end;
end;
procedure FindOSRule;
var i,k:longint; TR:TRule; w:char;
begin
succ:=false;
{ old - hint ???
with SSRules[0] do for i:=0 to ASR_cnt-1
do if md<>ASRules[i].md then
if (ASRules[i].c0=c1) and (not succ) then begin
TR:=ASRules[i];
}
with SSRules[0] do for i:=0 to SR_cnt-1
do if md<>SRules[i].md then
if (SRules[i].c0=c1) and (not succ) {and (SRules[i].used)} then begin
TR:=SRules[i];
for k:=0 to length(TR.c1)-1 do if not succ then begin
if TR.c1=c0 then begin
SSRules[1]:=TR;
succ:=true;
end else with TR do begin
w:=c1[1]; delete(c1,1,1);
c1:=c1+w; a:=a+w;
end;
end;
end;
end;
procedure TryBLmd(amd:byte);
var i:longint;
begin
SSR_cnt:=2;
FindMSRule(amd);
SSRules[0]:=SRules[id_r];
FindOSRule;
{
wr_rules(ttm,'approved shift',SRules,SR_cnt,false);
wr_rules(ttm,'Special ',SSRules,SSR_cnt,true);
flush(ttm);
}
if succ then begin
for i:=0 to SSR_cnt-1 do SSRules[i].allowed:=true;
rep_min:=0; rule_min:=0;
MacroLoop(CEM,EMH,EMH_cnt,5,lim);
TryBL_Proof;
{ this is not solution: }
{
for i:=0 to SSR_cnt-1 do with SSRules[i] do begin
c0:=c0+c0; c1:=c1+c1; p:=p+p; c:=c+c;
end;
TryBL_Proof;
}
{
wr_rules(ttm,'approved shift',SRules,SR_cnt,false);
wr_rules(ttm,'Special ',SSRules,SSR_cnt,true);
wr_macro_history(ttm,CEM,EMH,EMH_cnt,lim);
wr_ex1(ttm);
wr_grapf(ttm,BBG,BBG_cnt,false); flush(ttm);
flush(ttm);
}
end;
end;
begin
TryBLmd(0);
TryBLmd(1);
end;
procedure loop_t({show:boolean;} s_x,s_y:byte);
var
rm:array[byte] of word;
rulem,rmin0,max_rid{,k_factor}:longint;
procedure ShowRCnt(y:byte);
var i:byte;
begin
gotoxy(1,y);
for i:=1 to 25 do write(rm[i]:2,' ');
end;
function StrRCnt(y:byte):string;
var i:byte; s,w:string;
begin
Str(ASR_cnt:4,w);
s:=' |'+w+' |';
for i:=1 to y do begin
Str(rm[i]:3,w);
s:=s+w;
end;
StrRCnt:=s;
end;
procedure EvalRCnt;
var i:longint;
begin
for i:=1 to 255 do rm[i]:=0;
if SR_cnt>0 then for i:=0 to SR_cnt-1
do inc(rm[length(SRules[i].c0)]);
end;
procedure clear1;
var i:longint;
begin
EvalRCnt;
rulem:=0; rule_min:=0;
for i:=1 to 255 do if rm[i]>rulem then begin
rulem:=rm[i];
rule_min:=i;
end;
rmin0:=rule_min;
rep_min:=1;
end;
function RID_OK(i:byte):boolean;
begin
RID_OK:=
(i<>rmin0) and
((rm[i]>(rulem div 3)) or (rm[i]>=2));
end;
function AvRule:byte;
var i,n:byte;
begin
n:=0;
if max_rid>0 then for i:=1 to max_rid do
if RID_OK(i) then inc(n);
AvRule:=n;
end;
procedure clear1a;
var OK:boolean;
begin
OK:=false;
while not OK do begin
if RID_OK(max_rid)
then begin rule_min:=max_rid; OK:=true end;
dec(max_rid);
end;
if rule_min<dm then rep_min:=2
else if rule_min<dm_2 then rep_min:=1
else rep_min:=0;
end;
procedure clear2(show:boolean);
begin
{
writeln(ttm,'M_20=',m,' e_state=',e_state,' rmin0=',rmin0); flush(ttm);
writeln(ttm,'M_20=',m,' e_state=',e_state,' rmin0=',rmin0); flush(ttm);
}
if (rmin0<=dm) and (rm[rmin0*2]=0) and show then begin
rule_min:=rmin0;
rep_min:=2;
end else begin
rule_min:=0;
if show
then rep_min:=2
else rep_min:=3;
end;
if show then ShowRCnt(23);
end;
procedure clear0;
begin
rmin0:=0; rulem:=0;
SR_cnt:=0; ASR_cnt:=0; BSR_cnt:=0;
rep_min:=1; rule_min:=0;
new_def:=true;
e_state:=0;
p_left:=0; p_right:=0;
ClPosStat;
ClearDescr(CD);
SH_cnt:=0;
end;
procedure clear(enable:boolean);
var i,j,n_max:longint;
procedure EvalMaxUsed;
var i,k,n:longint;
begin
n_max:=0;
for i:=0 to SR_cnt-1 do begin
n:=0;
for k:=1 to spec_max do n:=n+SRules[i].spectrum[k]*k;
if n>n_max then n_max:=n;
end;
end;
function BadRule(var SR:TRule):boolean;
var n,k:longint;
begin
n:=0;
{ PackPatt tuning }
for k:=1 to spec_max do n:=n+SR.spectrum[k]*k;
BadRule:=n*3<n_max;
end;
begin
if enable then if SR_cnt>0 then for i:=0 to SR_cnt-1 do begin
SRules[i].used:=false;
SRules[i].allowed:=true;
for j:=1 to spec_max do SRules[i].spectrum[j]:=0;
end;
if not enable then begin
EvalMaxUsed;
for i:=0 to SR_cnt-1 do begin
if BadRule(SRules[i])
then SRules[i].allowed:=false;
for j:=1 to spec_max do SRules[i].spectrum[j]:=0;
SRules[i].used:=false;
end;
{
writeln(ttm,'rule_min=',rule_min,' rep_min=',rep_min);
}
if rule_min>0 then rep_min:=0;
end;
IP_cnt:=0;
ms_cnt:=0;
fin_att:=0;
ClearDescr(CM);
MH_cnt:=0;
end;
procedure info1;
begin
{
if show
then begin
gotoxy(1,24);writeln('info1 accesed in bad way !');
Halt;
wr_mash(s_x,s_y);
gotoxy(s_x+1,s_y+7); write('c=',CM.c:6);
gotoxy(s_x+1,s_y+8); write(MemUsed(CM),'/',sigma);
end
else begin
}
inc(e_cnt[e_state]);
inc(m);
if (m and 7)=0 then begin gotoxy(3,1); write(m:10) end;
if (m and 31)=0 then info0;
{ end }
end; { info1 }
procedure PassMacro(lim:longint);
begin
{rep_min:=2;}
clear(true);
MacroLoop(CM,MH,MH_cnt,1,lim);
{ PackPatt tuning }
if (e_state in [0,mem_ov,too_lng]) and
(rule_min>0) and (lim>1000)
then begin
{ ttm_print }
{
if rule_min in [6] then begin
writeln(ttm,'-------------------');
writeln(ttm);
wr_mhistory(ttm,4000);
writeln(ttm);
CollatzLoop(Cl_M,ClMH,ClMH_cnt,cmax div 10);
CM:=Cl_M;
MH:=ClMH;
MH_cnt:=ClMH_cnt;
writeln(ttm,'-------------------');
writeln(ttm);
wr_mhistory(ttm,4000);
writeln(ttm);
flush(ttm);
Halt;
end;
}
clear(false);
MacroLoop(CM,MH,MH_cnt,1,lim);
end;
{
if e_state in [lNct_l,modf_l] then begin
writeln(ttm,
'M=',m,' Rule_min=',rule_min,
' k=',k_factor,' rep_min=',rep_min,
' e_state=',e_state);
end;
}
end;
procedure Pass1(frst:boolean; lim:longint);
procedure Pass1a(rep:longint; k:longint);
begin if e_state in [0,mem_ov,too_lng] then begin
{ k_factor:=k; }
if frst then rule_min:=rep;
{writeln(ttm,'rule_min=',rule_min,' lim=',lim); flush(ttm); }
PassMacro(lim);
end end;
var k,k1,k2:longint;
begin
if frst then clear1 else clear1a;
{
if e_state in [0,mem_ov,too_lng] then
if rmin0>0 then Pass1a(rmin0,1);
}
{
if frst and (e_state in [0,mem_ov,too_lng]) and (lim=470) then begin
rule_min:=6;
PassMacro(cmax);
end;
}
for k1:=1 to dm+1 do if rm[k1]>0 then
for k2:=1 to dm+1 do if rm[k2]>0 then
if (k1*k2<=sr_lmax) and (rm[k1*k2]=0) and (lim>1000) and
frst and (e_state in [0,mem_ov,too_lng])
then Pass1a(k1*k2,1);
for k:=1 to dm+1 do if rm[k]>0 then begin
if frst and (e_state in [0,mem_ov,too_lng])
then Pass1a(k,1);
{
if frst and (e_state in [mem_ov,too_lng]) and
(rm[k*2]=0) then Pass1a(k*2,2);
if frst and (e_state in [mem_ov,too_lng]) and
(rm[k*3]=0) then Pass1a(k*3,3);
if frst and (e_state in [mem_ov,too_lng]) and
(rm[k*4]=0) then Pass1a(k*4,4);
}
end;
if e_state in [0,mem_ov,too_lng] then
if rmin0>0 then Pass1a(rmin0,1);
end;
procedure Pass2(lim:longint);
begin
{k_factor:=1;}
clear2(lim=cmax);
PassMacro(lim);
end;
procedure Pass0;
begin
clear0;
{
writeln(ttm,'M_c2=',m,' e_state=',e_state,' rmin0=',rmin0); flush(ttm);
}
repeat
SH[SH_cnt]:=CD; inc(SH_cnt);
MakeMStep0(CD,0);
if (e_state=0) then ShiftTest;
if new_def and (e_state=0) then begin
InvSTest;
if (e_state=0) and lDum then back_track;
new_def:=false;
end;
if e_state=0 then begin
if ((SH_cnt>10) and (SH_cnt mod 200=70) and (SH_cnt<800))
or (SH_cnt=1500)
then begin
SortRules;
if e_state in [0,mem_ov,too_lng] then Pass2(SH_cnt);
if (e_state in [0,mem_ov,too_lng]) and (SH_cnt=1500) then begin
{ Pass2(SH_cnt); }
TryBL_Loop(SH_cnt);
end;
if e_state in [0,mem_ov,too_lng] then Pass1(true,SH_cnt);
if ((SH_cnt=470) or (SH_cnt=1500)) and
(e_state in [0,mem_ov,too_lng])
then ExonesSpecFast(SH_cnt);
if (e_state in [0,mem_ov,too_lng]) and (SH_cnt>200) then TryPFin_2;
if (e_state in [0,mem_ov,too_lng]) and (SH_cnt=470) then TryPFin_2_all(2);
end;
if e_state in [mem_ov,too_lng] then e_state:=0;
end else if e_state=nm_end then Pass2(cmax - 1 {SH_cnt+1});
until (e_state>0) or (SH_cnt>dm2qub);
SortRules;
end;
procedure Pass100K(lim:longint);
begin MacroLoop(CM,MH,MH_cnt,6,lim) end;
function ShRecTest:boolean;
begin
ShRecTest:=(ASR_cnt<=20) and (dm>4);
{
(false or
((dm>=5) and (not reversal) and (not SameDir)));
}
end;
const spec_max=15;
var nrtyp:string;
begin { loop_t }
Pass0;
if e_state in [0,mem_ov,too_lng] then begin
if not ShRecTest then begin
if e_state in [0,mem_ov,too_lng] then Pass100K(cmax div 5);
if e_state in [0,mem_ov,too_lng] then TryPFin_2_all(dm);
if e_state in [0,mem_ov,too_lng] then Pass1(true,cmax);
max_rid:=sr_lmax*2;
while (e_state in [0,mem_ov,too_lng]) and (AvRule>0)
do Pass1(false,cmax);
if e_state in [0,mem_ov,too_lng] then Pass2(cmax);
if e_state in [0,mem_ov,too_lng] then TryBL_Loop(SH_cnt);
SpecStr:=StrRCnt(spec_max);
if (e_state in [0,mem_ov,too_lng]) and (not slow_scan)
then ExonesSpecFast(cmax);
if e_state in [0,mem_ov,too_lng] then Pass100K(cmax);
if e_state in [0,mem_ov,too_lng] then TryPFin_2_all(dm_2rR);
if (e_state in [0,mem_ov,too_lng]) and (slow_scan)
then ExonesSpecFast(cmax);
end;
if e_state in [0,mem_ov,too_lng] then begin {Pass2(cmax); }
clear(true);
rule_min:=best_rlen; rep_min:=1;
MacroLoop(CM,MH,MH_cnt,1,cmax);
end;
end;
info1;
if e_state in [0,mem_ov,too_lng] then begin
if ShRecTest then begin
writeln(tsrec,'M# = ',m-1);
wrf_m(tsrec,true,false,'ShRec');
wr_rules(tsrec,'all shift',ASRules,ASR_cnt,true);
wr_history(tsrec);
flush(tsrec);
nrtyp:='SRec';
end else nrtyp:='----';
SpecStr:=StrRCnt(spec_max);
SpecAdd(SpecStr);
wrf_m(tnr1,e_cnt[mem_ov]+e_cnt[too_lng]<=1,false,nrtyp+SpecStr);
flush(tnr1);
end;
end; { loop_t }
procedure info_1(s_x,s_y:byte);
begin
wr_mash(s_x,s_y);
gotoxy(s_x+1,s_y+7); write('c=',CM.c:6);
gotoxy(s_x+1,s_y+8); write(MemUsed(CM),'/',sigma);
end;
procedure wrf_m(var f:text; hd,sc:boolean; tstr:string);
var i:byte; w:char;
procedure wr(i:byte);
begin
if A[i]<>dum
then w:=chr(A[i]+ord('@'))
else w:='x';
if w='@' then w:='H';
write(f,w);
if C[i] in [0,1]
then write(f,C[i])
else write(f,'x');
if B[i] in [0,1]
then if B[i]=0
then write(f,'L ')
else write(f,'R ')
else write(f,'x ');
end;
begin
if hd then begin
for i:=1 to dm do begin
w:=chr(i+ord('@'));
write(f,w,'0 ',w,'1 ');
end;
if sc
then writeln(f,' ones steps')
else writeln(f,'| id | type |SRcnt| spectrum');
writeln(f);
end;
for i:=1 to dm do begin
wr(i); wr(i+dm); write(f,' ')
end;
if sc
then writeln(f,Sigma:7,CM.c:12)
else writeln(f,'|',m-1:9,' | ',tstr);
end;
procedure wrf_tm(var f:text; var TM:machine);
procedure wr_m0(X:t_arr; k:byte);
var i:byte;
begin
for i:=k+1 to k+dm do if X[i]=dum
then write(f,'x') else write(f,X[i]);
for i:=dm to 8 do write(f,' ');
end;
begin with TM do begin
wr_m0(A,0); wr_m0(A,dm);
wr_m0(B,0); wr_m0(B,dm);
wr_m0(C,0); wr_m0(C,dm);
writeln(f);
end end;
procedure EvalSigma(var CM:TDescr);
function Cp(l:string):longint;
var i,j:longint;
begin
j:=0;
for i:=1 to length(l) do if l[i]='+' then inc(j);
Cp:=j;
end;
procedure CountP(l:string);
var n,i:longint; w1,w2:string;
begin
n:=Pos('(',l);
if n>0 then begin
if n>1 then begin
sigma:=sigma+Cp(copy(l,1,n-1));
delete(l,1,n-1);
end;
w1:=copy(l,2,Pos('|',l)-2);
delete(l,1,Pos('|',l));
w2:=copy(l,1,Pos(')',l)-1);
delete(l,1,Pos(')',l));
val(w2,n,i);
sigma:=sigma+n*Cp(w1);
CountP(l);
end else sigma:=sigma+Cp(l);
end;
begin
sigma:=0; { why not 1 ? }
CountP(CM.l);
CountP(CM.r);
end;
var
rec_min:longint;
procedure init_r;
var dm0:byte;
begin
rec_min:=cmax;
if SameDir then dm0:=dm-1 else dm0:=dm;
case dm0 of
2:if reversal then rec_min:=1 else rec_min:=5;
3:if reversal then rec_min:=10 else rec_min:=15;
4:if reversal then rec_min:=40 else rec_min:=80;
5:if reversal then rec_min:=800 else rec_min:=10000000;
6:if reversal then rec_min:=10000000 else rec_min:=50000000;
end;
if Destructive then case dm of
3,4:rec_min:=20;
5:rec_min:=50;
6:rec_min:=200;
end;
end;
procedure OnScreen(s_x,s_y:byte);
begin
wr_mash(s_x,s_y);
gotoxy(s_x+1,s_y+7); write('c=',CM.c:6);
gotoxy(s_x+1,s_y+8); write(MemUsed(CM),'/',sigma);
end;
begin { root }
Str(dm,RevS);
if Destructive then RevS:='DTM'+RevS else
case reversal of
true: case SameDir of
true: RevS:='STM'+RevS;
false:RevS:='RTM'+RevS;
end;
false:case SameDir of
true: RevS:='UTM'+RevS;
false:RevS:='TM'+RevS;
end;
end;
assign(tnr, 'noreg_' +RevS+'.txt'); rewrite(tnr);
assign(tnr1, 'nreg_' +RevS+'.txt'); rewrite(tnr1);
assign(trc, 'recrd_' +RevS+'.txt'); rewrite(trc);
//assign(tproof,'proved_'+RevS+'.txt'); rewrite(tproof);
tproof := Output;
assign(tsrec, 'ShRec_' +RevS+'.txt'); rewrite(tsrec);
assign(ttm, 'others.txt'); rewrite(ttm);
clrscr; old_sec:=get_sec;
rec_cnt:=0;
CTG_cnt:=0;
init_0;
init_r;
{init_ExSCnt;}
CreateHuffCodes(HuffCodes,Huff_cnt,0);
CreateHuffCodes(SemiCodes,Semi_cnt,1);
for a1:=dm to dm+2 do { Full scan }
{a1:=dm+0;} {0,1,2} { Partial scan }
begin
init_t(a1);
repeat
pull;
{
if m>=915350 then begin
writeln(ttm,'M# = ',m);
wrf_m(ttm,true,false);
flush(ttm);
end;
}
loop_t({false,}1,1);
case e_state of
nm_end,col0_e:begin
if e_state=col0_e then begin
CM:=Cl_M;
MH:=ClMH;
MH_cnt:=ClMH_cnt;
end;
EvalSigma(CM);
if CM.c>rec_min then begin
wrf_m(trc,true,true,'');
inc(rec_cnt);
wr_rules(trc,'approved shift',SRules,SR_cnt,false);
wr_mhistory(trc,cmax);
flush(trc);
end;
if CM.c>=t_record-dm+1 then begin
if CM.c>=t_record then t_record:=CM.c;
if e_state=nm_end
then info_1(sh_ct1,1) {loop_t(true,sh_ct1,1)}
else OnScreen(sh_ct1,1);
inc(sh_ct1,12); if sh_ct1=50 then sh_ct1:=14;
end;
if (e_state=col0_e) and (e_cnt[e_state]<=showmax) then begin
writeln(tproof,'M# = ',m-1);
wrf_m(tproof,true,true,'');
writeln(tproof,'------- Collatz-like machine: ------');
wr_rules(tproof,'approved shift',SRules,SR_cnt,false);
wr_mhistory(tproof,cmax);
wr_grapf(tproof,CTG,CTG_cnt,false);
writeln(tproof,'-------------------------------------');
end;
if sigma>s_record then begin
s_record:=sigma;
if e_state=nm_end
then info_1(sh_ct2,12) {loop_t(true,sh_ct2,12)}
else OnScreen(sh_ct2,12);
inc(sh_ct2,12); if sh_ct2=50 then sh_ct2:=14;
end;
end;
mem_ov,too_lng:
if e_cnt[e_state]<=2*showmax then begin
writeln(tnr,'M# = ',m-1);
wrf_m(tnr,true,false,'nonregular');
wr_brules(tnr,'basic shift', BSRules,BSR_cnt,true);
writeln(tnr,'Main Rule ID = ',BBR_id);
{
wr_bhistory(tnr,dump_max);
if BBR_id>=0 then begin
wr_grapf(tnr,BBG,BBG_cnt,false);
wr_mmhistory(tnr,dump_max*2);
end;
}
{
wr_rules(tnr,'all shift', ASRules,ASR_cnt,true);
wr_rules(tnr,'approved shift',SRules,SR_cnt,true);
}
wr_rules(tnr,'approved shift',SRules,SR_cnt,false);
wr_mhistory(tnr,cmax);
wr_history(tnr);
WrPosStat(tnr);
{
wr_pproof_3(tnr);
wr_grapf(tnr,CTG,CTG_cnt,false);
}
writeln(tnr,
'====================================================');
flush(tnr);
end;
lNct_l,BLfinl,modf_l,
pfin_l,swpf_l,ex0f_l,ex1f_l,
exS0_l..exS2_l,
exH0_l..exH1_l:
if e_cnt[e_state]<=showmax then begin
writeln(tproof,'M# = ',m-1);
wrf_m(tproof,true,false,'infinite');
case e_state of
lNct_l,modf_l:begin
wr_rules(tproof,'approved shift',SRules,SR_cnt,false);
wr_mhistory(tproof,dump_max);
case e_state of
lNct_l:begin
writeln(tproof,'Incremental Formula test passed !');
end;
modf_l:begin
writeln(tproof,'Closed Transition Modulo_Graph test passed !');
end;
end;
wr_grapf(tproof,CTG,CTG_cnt,false);
end;
BLfinl:begin
wr_rules(tproof,'Special ',SSRules,SSR_cnt,true);
wr_macro_history(tproof,CEM,EMH,EMH_cnt,dump_max);
writeln(tproof,'BL_Proof succeed !');
wr_ex1(tproof);
wr_grapf(tproof,BBG,BBG_cnt,false);
end;
pfin_l:begin
wr_history(tproof);
WrPosStat(tproof);
wr_pproof_3(tproof);
writeln(tproof,'Closed Position test passed !');
end;
swpf_l:begin
wr_brules(tproof,'basic shift', BSRules,BSR_cnt,true);
writeln(tproof,'Main Rule ID = ',BBR_id);
wr_bmhistory(tproof,dump_max);
writeln(tproof,'BinVortex (Lemma1 + linear) test passed !');
end;
ex0f_l,ex1f_l,exS0_l..exS2_l,exH0_l..exH1_l:begin
{ wr_bhistory(tproof,dump_max); }
case e_state of
ex0f_l:writeln(tproof,'Single exone test proof:');
ex1f_l:writeln(tproof,'Self_tuning exone test proof:');
exS0_l:writeln(tproof,'Spec0 exone test proof:');
exS1_l:writeln(tproof,'Spec1 exone test proof:');
exS2_l:writeln(tproof,'Spec2 exone test proof:');
exH0_l:writeln(tproof,'SpecH0 exone test proof:');
exH1_l:writeln(tproof,'SpecH1 exone test proof:');
end;
{
wr_brules(tproof,'basic shift',BSRules,BSR_cnt,true);
writeln(tproof,'Basic Rule ID = ',BBR_id);
}
wr_exones(tproof);
{
if e_state in [exS0_l..exS2_l] then wr_extuples(tproof);
wr_grapf(tproof,BBG,BBG_cnt,e_state in [exS0_l..exS2_l]);
}
wr_grapf(tproof,BBG,BBG_cnt,false);
writeln(tproof,'finite exones graph test passed !');
end;
end;
writeln(tproof,
'====================================================');
flush(tproof);
end;
end;
until s_ct=0;
gotoxy(1,24);
write(a1,' loop finished ! ');
end;
info0;
writeln;
close(tsrec);
close(tnr);
close(tnr1);
close(trc);
close(ttm);
close(tproof);
gotoxy(1,24);
end. { root }
diff --git a/skelet/bbfind.pp b/skelet/bbfind.pp
index a7832fc..c1a6948 100644
--- a/skelet/bbfind.pp
+++ b/skelet/bbfind.pp
@@ -388,10 +388,13 @@ procedure pull;
procedure init_0;
var l:longint;
begin
+{
table(14, 1); table(26, 1); table(38, 1); sh_ct1:=14;
table(14,12); table(26,12); table(38,12); sh_ct2:=14;
+}
m:=0; t_record:=0; s_record:=0;
gotoxy(1,1);
+{
writeln('M=000000000');
writeln('nrm='); writeln('mov=');
writeln('tov='); writeln('b_t=');
@@ -400,16 +403,50 @@ procedure init_0;
writeln('lNc=');
writeln('gMl=');
writeln('p_l='); writeln('pSl=');
+}
{ writeln('brl='); writeln('bil='); }
+{
writeln('eH0='); writeln('eH1=');
writeln('e0l='); writeln('e1l=');
writeln('eS0='); writeln('eS1=');
writeln('eS2=');
writeln('B-L=');
writeln('cl0=');
+}
for l:=1 to e_max do e_cnt[l]:=0;
end;
+procedure SetTMStdin();
+ var i,j:byte;
+ sz:word;
+ s:string;
+ procedure SetStd0(i,j:byte);
+ begin
+ if s[j+2]='-'
+ then A[i]:=0
+ else A[i]:=ord(s[j+2])-ord('@');
+ if s[j+1]='L'
+ then B[i]:=0 else B[i]:=1;
+ if s[j]='0'
+ then C[i]:=0 else C[i]:=1;
+ end;
+ begin
+ sz := 7*dm-1;
+ while true do begin
+ if (EOF(Input)) then Halt();
+ ReadLn(Input, s);
+ if Length(s) = 0 then continue
+ else if Length(s) = sz then break
+ else WriteLn('invalid input length, skipping line');
+ end;
+ WriteLn('Read machine from stdin: ', s);
+ for i:=1 to dm do begin
+ j:=(i-1)*7;
+ SetStd0(i,j+1);
+ SetStd0(dm+i,j+4);
+ end;
+ end;
+
procedure SetTM(s:string);
var i,j:byte;
procedure Set0(i,j:byte);
@@ -461,7 +498,7 @@ procedure init_t(a1:byte);
end;
for l:=1 to dm do C[dm+l]:=1;
end;
-
+ SetTMStdin();
{ SpecalSubClasses rev0/rev1 }
{ C[1]:=1; C[2]:=1; C[3]:=1; C[4]:=1; C[5]:=1; }
@@ -784,9 +821,11 @@ procedure init_t(a1:byte);
}
s_ct:=0; push('\');
+{
table (x0,12); wr_mash(x0,12);
gotoxy(x1,19); write('c=',cmax:6);
gotoxy(x1,20); write('m=',mmax:6);
+}
end;
function HTSize(s:string):longint;
@@ -6035,7 +6074,8 @@ begin { root }
assign(tnr, 'noreg_' +RevS+'.txt'); rewrite(tnr);
assign(tnr1, 'nreg_' +RevS+'.txt'); rewrite(tnr1);
assign(trc, 'recrd_' +RevS+'.txt'); rewrite(trc);
- assign(tproof,'proved_'+RevS+'.txt'); rewrite(tproof);
+ //assign(tproof,'proved_'+RevS+'.txt'); rewrite(tproof);
+ tproof := Output;
assign(tsrec, 'ShRec_' +RevS+'.txt'); rewrite(tsrec);
assign(ttm, 'others.txt'); rewrite(ttm);
clrscr; old_sec:=get_sec;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment