{ Проверочные функции для отладки сжатия Лемпеля-Зива } {--------------------------------------------------------------------------- (c) Copyright Aleksandrov O.E., 2000 Molecular Physics department, USTU, Ekaterinsburg, K-2, 620002, RUSSIA phone 75-47-15 E-mail: aleks@dpt.ustu.ru (c) Copyright Александров О.Е., 2000 620002, Екатеринбург, К-2, УГТУ, Кафедра молекулярной физики тел. 75-47-15 E-mail: aleks@dpt.ustu.ru ----------------------------------------------------------------------------} Unit LZTests; INTERFACE USES {xCrt,} LZTypes; function SeqCheck(const Dic:tDictionary; RootIndex:tIndex):tIndex; procedure PrintLine(const Dic:tDictionary; RootIndex:tIndex); {procedure PrintTree(const Dic:tDictionary; RootIndex:tIndex);} procedure PrintTree(const Msg:string; const Dic:tDictionary; RootIndex:tIndex); function ValidSeq(const Dic:tDictionary; Index:tIndex):boolean; function CheckNodeBalance(const Dic:tDictionary; RootIndex:tNodeIndex):boolean; IMPLEMENTATION function CheckNodeBalance(const Dic:tDictionary; RootIndex:tNodeIndex):boolean; var Vbal:boolean; begin If RootIndex=cNilIndex then begin CheckNodeBalance:=TRUE; end else begin { Vbal:=(nfRight in Dic.Nodes^[RootIndex].Flags);} Vbal:=(nfRight in Dic.Flags^[RootIndex]); if (Dic.Nodes^[RootIndex].LeftRight[Vbal]<>cNilIndex) and (Dic.Nodes^[RootIndex].LeftRight[not Vbal]=cNilIndex) then begin { if (Dic.Nodes^[RootIndex].LeftRight[Vbal]<>cNilIndex) and (Dic.Nodes^[RootIndex].LeftRight[not Vbal]=cNilIndex) then begin} CheckNodeBalance:=FALSE; end else begin CheckNodeBalance:= CheckNodeBalance(Dic, Dic.Nodes^[RootIndex].LeftRight[Vbal]) and CheckNodeBalance(Dic, Dic.Nodes^[RootIndex].LeftRight[not Vbal]); { CheckNodeBalance:= CheckNodeBalance(Dic, Dic.Nodes^[RootIndex].LeftRight[Vbal]) and CheckNodeBalance(Dic, Dic.Nodes^[RootIndex].LeftRight[not Vbal]);} end; end; end; type tStrIndex=1..512; tString=array[tStrIndex] of Char; var cSpace:string; cFill:string; TreeFile:File; Str0:tString; Strs:array[0..7] of tString; Shifts:array[0..8] of integer; const FileOpened:boolean=FALSE; cEOL=#$0D#$0A; cBTb='Binary Tree:'+cEOL; cBTe='tree end.'+cEOL; procedure PrintTree(const Msg:string; const Dic:tDictionary; RootIndex:tIndex); var Level,MaxLevel:tIndex; {BaseLine:word;} procedure xPrintSubTree(Index:tIndex; CentPos:word); var s:string; ns:string[3]; begin if Index=cNilIndex then Exit; if Level>7 then Exit; if Level>MaxLevel then MaxLevel:=Level; { Str(Dic.Nodes^[Index].Byte:3,ns);} Str(Dic.Bytes^[Index]:3,ns); Inc(Level); { if nfRight in Dic.Nodes^[Index].Flags then} if nfRight in Dic.Flags^[Index] then s:='┌'+Copy(cFill,1,Shifts[Level])+ns+'>'+Copy(cFill,1,Shifts[Level])+'┐' else s:='┌'+Copy(cFill,1,Shifts[Level])+'<'+ns+Copy(cFill,1,Shifts[Level])+'┐'; Move(s[1],Strs[Pred(Level)][(CentPos-Shifts[Level])],Ord(s[0])); xPrintSubTree(Dic.Nodes^[Index].Left,CentPos-Shifts[Level]); xPrintSubTree(Dic.Nodes^[Index].Right,CentPos+Shifts[Level]); { xPrintSubTree(Dic.Nodes^[Index].Left,CentPos-Shifts[Level]); xPrintSubTree(Dic.Nodes^[Index].Right,CentPos+Shifts[Level]);} Dec(Level); end; var i:word; s:string[20]; begin if not FileOpened then begin Assign(TreeFile,'Tree.txt'); Rewrite(TreeFile,1); for i:=1 to 255 do begin cFill[i]:='─'; cSpace[i]:=' '; end; cFill[0]:=#255; cSpace[0]:=#255; Shifts[0]:=250; for i:=1 to 8 do begin Shifts[i]:=Shifts[i-1] div 2; end; Shifts[0]:=Shifts[0]+10; for i:=Low(tStrIndex) to High(tStrIndex) do begin Str0[i]:=' '; end; FileOpened:=TRUE; end; for i:=0 to 7 do begin Strs[i]:=Str0; end; Level:=0; MaxLevel:=0; { xPrintSubTree(Dic.Nodes^[RootIndex].Succ,Shifts[0]);} xPrintSubTree(Dic.Successors^[RootIndex],Shifts[0]); s:=cBTb; BlockWrite(TreeFile,s[1],Length(s)); s:=cEOL; for i:=0 to MaxLevel do begin BlockWrite(TreeFile,Strs[i],SizeOf(Strs[i])); BlockWrite(TreeFile,s[1],Length(s)); end; s:=cBTe; BlockWrite(TreeFile,s[1],Length(s)); end; procedure PrintLine(const Dic:tDictionary; RootIndex:tIndex); var Index:tIndex; begin (* Index:=Dic.Nodes[RootIndex].Fragment.Succ; while Dic.Nodes[Index].LineSeq.Lo<>cNilIndex do begin Index:=Dic.Nodes[Index].LineSeq.Lo; end; writeln('Line Tree: ->'); while Index<>cNilIndex do begin write(Dic.Nodes[Index].byte:3,', '); Index:=Dic.Nodes[Index].LineSeq.Hi; end; writeln; Index:=Dic.Nodes[RootIndex].Fragment.Succ; while Dic.Nodes[Index].LineSeq.Hi<>cNilIndex do begin Index:=Dic.Nodes[Index].LineSeq.Hi; end; writeln('Line Tree: <-'); while Index<>cNilIndex do begin write(Dic.Nodes[Index].Fragment.byte:3,', '); Index:=Dic.Nodes[Index].LineSeq.Lo; end; writeln;*) end; function SeqCheck(const Dic:tDictionary; RootIndex:tIndex):tIndex; var Index,Index0:tIndex; b,bb:byte; begin (* Index:=Dic.Nodes[RootIndex].Fragment.Succ; if Index=cNilIndex then begin SeqCheck:=RootIndex; Exit; end; Index0:=Index; b:=Dic.Nodes[Index].Fragment.byte; { write(b:3,'>');} while Dic.Nodes[Index].LineSeq.Lo<>cNilIndex do begin Index:=Dic.Nodes[Index].LineSeq.Lo; bb:=Dic.Nodes[Index].Fragment.byte; { write(', ',bb:3);} if bb>=b then begin SeqCheck:=Index; end; end; { writeln;} Index:=Index0; b:=Dic.Nodes[Index].Fragment.byte; { write(b:3,'<');} while Dic.Nodes[Index].LineSeq.Hi<>cNilIndex do begin { write(Dic.Nodes[Index].Fragment.byte:3,', ');} Index:=Dic.Nodes[Index].LineSeq.Hi; bb:=Dic.Nodes[Index].Fragment.byte; { write(', ',bb:3);} if bb<=b then begin SeqCheck:=Index; end; end; { writeln;} SeqCheck:=cNilIndex;*) end; function ValidSeq(const Dic:tDictionary; Index:tIndex):boolean; begin ValidSeq:=true; (* if Dic.Nodes[Index].LineSeq.Lo<>cNilIndex then begin if Dic.Nodes[Dic.Nodes[Index].LineSeq.Lo].LineSeq.Hi<>Index then ValidSeq:=false; end; if Dic.Nodes[Index].LineSeq.Hi<>cNilIndex then begin if Dic.Nodes[Dic.Nodes[Index].LineSeq.Hi].LineSeq.Lo<>Index then ValidSeq:=false; end;*) end; END.