Autor |
Beitrag |
Petroglyph
Hält's aus hier
Beiträge: 7
Windows Vista, Ubuntu 12.03
Delphi 7 Personal, Edition Free Pascal, Lazarus, Lua(Scite)
|
Verfasst: So 02.09.12 18:36
Hallo Mitglieder des Delphiforums,
bevor ich das Problem schildere, möchte ich kurz etwas zu mir und meinen Erfahrungen mit Pascal beziehungsweise Delphi sagen.
Ich bin Schüler und habe ein Jahr lang Informatikunterricht gehabt, in dem ich mit Delphi 6 gearbeitet habe. Da der Kurs nicht genügend Schüler hatte, habe ich mir mit Hans-Georg Schumanns "Delphi for Kids" Delphi selber beigebracht. Nach Abschluss des Buches erfuhr ich vom Free Pascal Compiler.
Mit genau diesem habe ich nun eine Turingmaschine programmiert. Es ist ein Konsolenprojekt ohne grafische Benutzeroberfläche mit Lazarus. Ich entwickele es auf meinem Windows Vista Laptop.
Nun habe ich, nachdem die Maschine lief, mit der Unit "heaptrc" einen Bericht über die Speicherbenutzung erstellt und 8 nicht freigegebene Speicherblöcke entdeckt. Daraufhin fügte ich einen try-finally Block hinzu und setzte alle Arrays manuell auf die Größe 0, was allerdings nicht half. Was ich auch entdeckte ist, dass der normale "Free"-Destruktor eine Access Violation beim Schlüsselwort "inherited" produziert, während der "FreeAndNil"-Destruktor nicht dieses Verhalten aufweist.
Ich habe den Quelltext in drei Units aufgeteilt: "turing.pas" ist die Hauptunit, in der die Maschine läuft; "turinghead.pas" beinhaltet die Anweisungen für den Lese- und Schreibkopf der Maschine und "turingtable.pas" liest die Datei "turingtable.txt" aus, um so das Verhalten der Maschine zu bestimmen. In "turingtable.txt" sind nicht genutzte Zeilen mit "/" auskommentiert. Der Bericht von heaptrc ist in der Datei "memory.txt" Bei den Tests benutze ich den 4-State Busy Beaver.
Da ich Programmieren durch Versuch und Irrtum lerne, bin ich dankbar für jegliche Kritik. Ich möchte auch verstehen, was ich falsch gemacht habe und nicht einfach nur eine Lösung.
Falls der Beitrag in der falschen Abteilung ist, entschuldige ich mich.
turing.pas
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118: 119: 120: 121: 122: 123: 124: 125: 126: 127: 128: 129: 130: 131: 132: 133: 134: 135: 136: 137: 138: 139: 140: 141: 142: 143: 144: 145: 146: 147: 148: 149: 150: 151: 152: 153: 154: 155: 156: 157: 158: 159: 160: 161: 162: 163: 164: 165: 166: 167: 168: 169: 170: 171: 172: 173: 174: 175: 176: 177: 178: 179: 180: 181: 182: 183: 184: 185: 186: 187: 188: 189: 190: 191: 192: 193: 194: 195: 196: 197: 198: 199: 200: 201: 202: 203: 204: 205: 206: 207: 208: 209: 210: 211: 212: 213: 214: 215: 216: 217: 218:
|
program Turing;
{$mode objfpc}{$H+}
uses sysutils, TuringHead, TuringTable;
type
TField = Array of Char;
TMachine = class(TObject) private Tape: TField; TapeSize: Integer; Head: THead; InstructionTable: TInstructionTable; ConstantOutput: Boolean; procedure GetSettings(); procedure GetInput(); procedure TapeResize(OldSize: Integer; Direction: Char); procedure TapeCopy(); procedure Display(State: Char; ReadData: Char; WriteData: Char; MoveInstruction: Char; HeadPosition: Integer); public constructor Create(); procedure Run(); destructor FreeAndNil(); protected published end; var Machine: TMachine; procedure TMachine.GetSettings(); var OutputType: Char; begin WriteLn('If you want constant output, please type "y", if not, please type "n"!'); ReadLn(OutputType); case OutputType of 'n': ConstantOutput := False; 'y': ConstantOutput := True end; WriteLn('Please input the start tape length! It will expand automatically, if it overflows.'); ReadLn(TapeSize); if TapeSize > 0 then SetLength(Tape, TapeSize) else begin WriteLn('Please input a length greater than zero!'); GetSettings() end end;
procedure TMachine.GetInput(); var UserInput: String; Data: Char; HeadPosition: Integer; begin WriteLn('Please input the data for the tape!'); SetLength(UserInput, TapeSize); ReadLn(UserInput); if UserInput[TapeSize] <> '' then begin HeadPosition := 0; while HeadPosition < TapeSize do begin Data := UserInput[HeadPosition + 1]; Head.WriteData(Tape, HeadPosition, Data); HeadPosition := Head.Move(HeadPosition, 'R') end; WriteLn('Thank you, these are the steps of the machine:') end else begin WriteLn('Please fill the whole tape with data!'); GetInput() end end;
procedure TMachine.TapeResize(OldSize: Integer; Direction: Char); var NewSize: Integer; begin case Direction of 'L': begin NewSize := OldSize + 1; SetLength(Tape, NewSize); TapeCopy(); Head.WriteData(Tape, Low(Tape), '0') end; 'R': begin NewSize := OldSize + 1; SetLength(Tape, NewSize); Head.WriteData(Tape, High(Tape), '0') end end end;
procedure TMachine.TapeCopy(); var Counter: Integer; begin Counter := High(Tape); while Counter > 0 do begin Tape[Counter] := Tape[Counter - 1]; Dec(Counter, 1) end end; procedure TMachine.Display(State: Char; ReadData: Char; WriteData: Char; MoveInstruction: Char; HeadPosition: Integer); var DispHead: Integer; begin DispHead := 0; while DispHead < Length(Tape) do begin Write(Tape[DispHead]); DispHead := Head.Move(DispHead, 'R'); end; Write(' State: ' + State + ' Read: ' + ReadData + ' Write: ' + WriteData + ' Move: ' + MoveInstruction + ' Head: ' + IntToStr(HeadPosition + 1)); WriteLn('') end;
constructor TMachine.Create(); begin inherited; Head := THead.Create(); InstructionTable := TInstructionTable.Create(); GetSettings(); GetInput() end;
procedure TMachine.Run(); var TapeData: Char; WriteData: Char; StateRegister: Char; MoveInstruction: Char; HeadPosition: Integer; Running: Boolean; begin if TapeSize > 1 then HeadPosition := (Length(Tape) div 2) - 1 else HeadPosition := 0; StateRegister := 'A'; Running := True;
while Running do begin TapeData := Head.ReadData(Tape, HeadPosition); WriteData := InstructionTable.GetData(StateRegister, TapeData, 'W'); MoveInstruction := InstructionTable.GetData(StateRegister, TapeData, 'M'); if ConstantOutput then Display(StateRegister, TapeData, WriteData, MoveInstruction, HeadPosition);
Head.WriteData(Tape, HeadPosition, WriteData);
case MoveInstruction of 'S': HeadPosition := Head.Move(HeadPosition, 'S'); 'L': HeadPosition := Head.Move(HeadPosition, 'L'); 'R': HeadPosition := Head.Move(HeadPosition, 'R') end; if HeadPosition > High(Tape) then TapeResize(Length(Tape), 'R'); if HeadPosition < Low(Tape) then begin TapeResize(Length(Tape), 'L'); HeadPosition := 0 end; StateRegister := InstructionTable.GetData(StateRegister, TapeData, 'N');
if StateRegister = 'H' then begin Display(StateRegister, TapeData, WriteData, MoveInstruction, HeadPosition); Running := Head.Halt() end end end;
destructor TMachine.FreeAndNil(); begin Head.Free(); InstructionTable.FreeAndNil(); SetLength(Tape, 0); WriteLn('The turing machine stopped. You can end the program by pressing enter.'); inherited end;
begin Machine := TMachine.Create(); try Machine.Run() finally Machine.FreeAndNil() end; ReadLn() end. |
turinghead.pas
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82:
|
unit TuringHead;
{$mode objfpc}{$H+}
interface
type THead = class(TObject) private function Stay(HeadPos: Integer): Integer; function MoveLeft(HeadPos: Integer): Integer; function MoveRight(HeadPos: Integer): Integer; public function Move(HeadPos: Integer; Direction: Char): Integer; function ReadData(Tape: Array of Char; HeadPos: Integer): Char; procedure WriteData(var Tape: Array of Char; HeadPos: Integer; Data: Char); function Halt(): Boolean; protected published end;
implementation
function THead.Move(HeadPos: Integer; Direction: Char): Integer; var NextPos: Integer; begin case Direction of 'S': NextPos := Stay(HeadPos); 'L': NextPos := MoveLeft(HeadPos); 'R': NextPos := MoveRight(HeadPos) end; Move := NextPos end;
function THead.ReadData(Tape: Array of Char; HeadPos: Integer): Char; var Data: Char; begin Data := Tape[HeadPos]; ReadData := Data end;
procedure THead.WriteData(var Tape: Array of Char; HeadPos: Integer; Data: Char); begin Tape[HeadPos] := Data end;
function THead.Stay(HeadPos: Integer): Integer; var NextPosition: Integer; begin NextPosition := HeadPos; Stay := NextPosition end;
function THead.MoveLeft(HeadPos: Integer): Integer; var NextPosition: Integer; begin NextPosition := HeadPos - 1; MoveLeft := NextPosition end;
function THead.MoveRight(HeadPos: Integer): Integer; var NextPosition: Integer; begin NextPosition := HeadPos + 1; MoveRight := NextPosition end;
function THead.Halt(): Boolean; begin Halt := False end;
begin end. |
turingtable.pas
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118: 119: 120: 121: 122: 123: 124: 125: 126: 127: 128: 129: 130: 131: 132: 133: 134: 135: 136: 137: 138: 139: 140: 141: 142: 143: 144: 145: 146: 147: 148: 149: 150: 151: 152: 153: 154: 155: 156: 157: 158: 159: 160: 161: 162: 163: 164: 165: 166: 167: 168: 169: 170: 171: 172: 173: 174: 175: 176: 177: 178: 179: 180: 181: 182: 183: 184: 185:
|
unit TuringTable;
{$mode objfpc}{$H+}
interface
const TupelLength = 5;
type
TTextFile = TextFile; TDataString = Array of String[TupelLength]; TDataTable = record State: Array of Char; Read: Array of Char; Write: Array of Char; Move: Array of Char; Next: Array of Char end;
TInstructionTable = class(TObject) private TupelNumber: Word; DataString: TDataString; DataTable: TDataTable; procedure FileRead(); procedure ArrayResize(Size: Word); procedure TableFill(); function GetWrite(CurrentState: Char; ReadData: Char): Char; function GetMove(CurrentState: Char; ReadData: Char): Char; function GetNext(CurrentState: Char; ReadData: Char): Char; public constructor Create(); function GetData(CurrentState: Char; ReadData: Char; DataType: Char): Char; destructor FreeAndNil(); protected published end;
implementation
procedure TInstructionTable.FileRead(); const FileName = 'turingtable.txt'; var Text: String[TupelLength]; CurrentTupel: Word; DataFile: TTextFile; begin SetLength(DataString, 256); CurrentTupel := 0; Assign(DataFile, FileName); Reset(DataFile); while not eof(DataFile) do begin ReadLn(DataFile, Text); if Text[1] <> '/' then begin DataString[CurrentTupel] := Text; inc(CurrentTupel, 1) end end; ArrayResize(CurrentTupel); TupelNumber := CurrentTupel; Close(DataFile) end;
procedure TInstructionTable.ArrayResize(Size: Word); begin SetLength(DataString, Size); SetLength(DataTable.State, Size); SetLength(DataTable.Read, Size); SetLength(DataTable.Write, Size); SetLength(DataTable.Move, Size); SetLength(DataTable.Next, Size) end;
procedure TInstructionTable.TableFill(); var Position: Word; CurrentTupel: Word; begin Position := 1; CurrentTupel := 0; while CurrentTupel <= TupelNumber do begin while Position <= TupelLength do begin case Position of 1: DataTable.State[CurrentTupel] := DataString[CurrentTupel][Position]; 2: DataTable.Read[CurrentTupel] := DataString[CurrentTupel][Position]; 3: DataTable.Write[CurrentTupel] := DataString[CurrentTupel][Position]; 4: DataTable.Move[CurrentTupel] := DataString[CurrentTupel][Position]; 5: DataTable.Next[CurrentTupel] := DataString[CurrentTupel][Position] end; inc(Position, 1) end; Position := 1; inc(CurrentTupel, 1) end end;
function TInstructionTable.GetWrite(CurrentState: Char; ReadData: Char): Char; var Write: Char; EntryFound: Boolean; CurrentTupel: Integer; begin EntryFound := false; CurrentTupel := 0; while not EntryFound do if (DataTable.State[CurrentTupel] = CurrentState) and (DataTable.Read[CurrentTupel] = ReadData) then EntryFound := True else inc(CurrentTupel, 1); Write := DataTable.Write[CurrentTupel]; GetWrite := Write end;
function TInstructionTable.GetMove(CurrentState: Char; ReadData: Char): Char; var Move: Char; EntryFound: Boolean; CurrentTupel: Integer; begin EntryFound := false; CurrentTupel := 0; while not EntryFound do if (DataTable.State[CurrentTupel] = CurrentState) and (DataTable.Read[CurrentTupel] = ReadData) then EntryFound := True else inc(CurrentTupel, 1); Move := DataTable.Move[CurrentTupel]; GetMove := Move end;
function TInstructionTable.GetNext(CurrentState: Char; ReadData: Char): Char; var Next: Char; EntryFound: Boolean; CurrentTupel: Integer; begin EntryFound := false; CurrentTupel := 0; while not EntryFound do if (DataTable.State[CurrentTupel] = CurrentState) and (DataTable.Read[CurrentTupel] = ReadData) then EntryFound := True else inc(CurrentTupel, 1); Next := DataTable.Next[CurrentTupel]; GetNext := Next end;
constructor TInstructionTable.Create(); begin inherited; FileRead(); TableFill() end;
function TInstructionTable.GetData(CurrentState: Char; ReadData: Char; DataType: Char): Char; var Data: Char; begin case DataType of 'W': Data := GetWrite(CurrentState, ReadData); 'M': Data := GetMove(CurrentState, ReadData); 'N': Data := GetNext(CurrentState, ReadData) end; GetData := Data end;
destructor TInstructionTable.FreeAndNil(); begin ArrayResize(0); inherited end;
begin end. |
turingtable.txt
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62:
| /This is the table for the turing machine. /Here you can define the instructions for the machine. /Please use the given format. /The start state is 'A'. /Use 'S' for staying, 'L' for moving the head leftwards and 'R' for moving the head rightwards. /'H' is used to stop the machine. /The head starts in the middle of the tape. /If the array is expanded, it is filled with '0'. /Lines are commented out when they begin with '/'. /State Read Write Move Next
/Busy beavers taken from en.wikipedia.org
/2-state, 2-symbol busy beaver /A01LB /A11RB /B01RA /B11LH
/3-state, 2-symbol busy beaver /A01LB /A11RC /B01RA /B11LB /C01RB /C11SH
/4-state, 2-symbol busy beaver A01LB A11RB B01RA B10RC C01LH C11RD D01LD D10LA
/5-state, 2-symbol best contender busy beaver /A01LB /A11RC /B01LC /B11LB /C01LD /C10RE /D01RA /D11RD /E01LH /E10RA
/6-state, 2-symbol best contender busy beaver /A01LB /A11RE /B01LC /B11LF /C01RD /C10LB /D01LE /D10RC /E01RA /E10LD /F01RH /F11LC |
memory.txt
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85:
| C:\Programming_Software\FreePascal\2.6.0\projects\Turing_Machine\memory\turing.exe Marked memory at $00075200 invalid Wrong signature $D410291C instead of A7A141DB $0040F84B $0040F907 $004154FD $004159ED $00401F3F TMACHINE__FREEANDNIL, line 203 of turing.pas $00402014 main, line 217 of turing.pas $0040C7A1 Heap dump by heaptrc unit 714 memory blocks allocated : 14207/18256 706 memory blocks freed : 14061/18080 8 unfreed memory blocks : 146 True heap size : 458752 (144 used in System startup) True free heap : 457824 Should be : 457920 Call trace for block $000753E0 size 22 $004018CF TMACHINE__TAPERESIZE, line 104 of turing.pas $00401E81 TMACHINE__RUN, line 181 of turing.pas $00402000 main, line 215 of turing.pas $0040C7A1 Marked memory at $00075380 invalid Wrong signature $7C413530 instead of F25D645E $004106B7 $0040F84B $0040F907 $004154FD $004159ED $00401F3F TMACHINE__FREEANDNIL, line 203 of turing.pas $00402014 main, line 217 of turing.pas $0040C7A1 Marked memory at $00075320 invalid Wrong signature $65B2F7C9 instead of 4D5F691D $004106B7 $0040F84B $0040F907 $004154FD $004159ED $00401F3F TMACHINE__FREEANDNIL, line 203 of turing.pas $00402014 main, line 217 of turing.pas $0040C7A1 Marked memory at $000752C0 invalid Wrong signature $4FA6B0C2 instead of 07312F06 $004106B7 $0040F84B $0040F907 $004154FD $004159ED $00401F3F TMACHINE__FREEANDNIL, line 203 of turing.pas $00402014 main, line 217 of turing.pas $0040C7A1 Marked memory at $00075260 invalid Wrong signature $5655723B instead of 6748E28D $004106B7 $0040F84B $0040F907 $004154FD $004159ED $00401F3F TMACHINE__FREEANDNIL, line 203 of turing.pas $00402014 main, line 217 of turing.pas $0040C7A1 Marked memory at $00075200 invalid Wrong signature $D410291C instead of A7A141DB $004106B7 $0040F84B $0040F907 $004154FD $004159ED $00401F3F TMACHINE__FREEANDNIL, line 203 of turing.pas $00402014 main, line 217 of turing.pas $0040C7A1 Call trace for block $0007C3C8 size 32 $00401C59 TMACHINE__CREATE, line 141 of turing.pas $00401FD7 main, line 213 of turing.pas $0040C7A1 $00610068 $00650072 $005C0064 $00690057 $0064006E Call trace for block $000751A0 size 24 $00401FD7 $0040C7A1 $0040C7A1 |
|
|
haentschman
      
Beiträge: 285
Erhaltene Danke: 33
DX10 Berlin Professional
|
Verfasst: So 02.09.12 19:26
Hallo...
ohne jetzt tiefgründiger einzusteigen. Nenne deine Destruktoren nicht FreeAndNil sondern Destroy. Eventuell biegt der Compiler falsch ab wegen der gleichnamigen Objekt Procedur.
|
|
Delphi-Laie
      
Beiträge: 1600
Erhaltene Danke: 232
Delphi 2 - RAD-Studio 10.1 Berlin
|
Verfasst: So 02.09.12 21:46
Petroglyph, herzlich willkommen in diesem Forum! So sieht eine aufrichtige Neuanmeldung aus und nicht diese Trollheimsuchungen, die wir in letzter Zeit mehrmals hatten.
Hattest Du es schon mal mit dem Debuggen versucht? Davon las ich in Deinem Text nichts. Könntest Du evtl. auch mal das gesamte Projekt hier veröffentlichen ("hochladen"), wobei die compilierten Units und die Exe-Datei nicht unbedingt dazugehören?
Für diesen Beitrag haben gedankt: Petroglyph
|
|
Tankard
      

Beiträge: 217
Erhaltene Danke: 96
|
Verfasst: So 02.09.12 22:19
du leitest von tobject ab. da heist der destructor destroy. benenne deinen destructor mal um in destroy, dann sollte es klappen. hab aber nur mal so grob drueber geschaut.
gruss
tankard
Für diesen Beitrag haben gedankt: Petroglyph
|
|
Petroglyph 
Hält's aus hier
Beiträge: 7
Windows Vista, Ubuntu 12.03
Delphi 7 Personal, Edition Free Pascal, Lazarus, Lua(Scite)
|
Verfasst: So 02.09.12 22:45
Schon einmal vielen Dank für die Hilfen,
ich habe den Rat von Tankard und haentschman befolgt und die Destruktoren in "Destroy" umbenannt. Leider stehen im Speicherbericht immer noch 8 nicht freigegebene Blöcke. Jetzt sind aber von ein paar mehr Informationen über die Aufrufe Unit "turingtable.pas" dabei. Das hängt aber glaube ich damit zusammen, dass ich das Programm vollständig neu kompilierte. Eine Frage habe ich aber dennoch: Als ich den Destruktor deklarierte, warnte mich der Compiler, dass "Destroy" eine versteckte Methode sei. Deshalb habe ich ihn mit dem Schlüsselwort "Override" überschrieben. War das so richtig?
Danke Delphi-Laie, ich bin schon etwas länger angemeldet, habe aber bisher nur gelesen(unter anderem auch diese "Vorstellungsthemen"). Ich habe vorher noch nicht mit FPCs Debugger gearbeitet und deshalb nur wenige Informationen bekommen. Was ich allerdings hearusfand ist, dass das Programm nicht mit dem Exitcode 00 beendet wird, sondern mit 01. Dieser steht nach der Dokumentation für "Invalid function number An invalid operating system call was attempted.". Allerdings weiß ich nicht, wie mir das weiterhilft.
Ich hänge diesmal auch die Quelltextdateien und Anweisungen an. Die Textdatei muss im gleichen Ordner, wie die Exe sein. Als Eingabe verwende ich zum Testen immer "y", "1" und "0"(für Ausgabeart, Startlänge und Startdaten).
Edit: Ich vergaß den Speicherbericht anzuhängen. Die Quelltextdateien sind ohne die "heaptrc"-Unit.
Einloggen, um Attachments anzusehen!
|
|
Delphi-Laie
      
Beiträge: 1600
Erhaltene Danke: 232
Delphi 2 - RAD-Studio 10.1 Berlin
|
Verfasst: So 02.09.12 22:51
Für ein vollständiges Projekt fehlen aber leider noch ein paar Dateien. Die Units sind ja oben schon als Quelltexte aufgeführt.
Wollte gerade mit dem Einladen des Projektes, Compilieren und weiteren glückshormonausstoßenden Freudentätigkeiten beginnen, doch so wird das leider nichts.
Edit: Das nehme ich zurück. Für ein Nicht-Formularprogramm reicht doch schon die Pascaldatei aus.
Zuletzt bearbeitet von Delphi-Laie am Mo 03.09.12 17:38, insgesamt 1-mal bearbeitet
|
|
Petroglyph 
Hält's aus hier
Beiträge: 7
Windows Vista, Ubuntu 12.03
Delphi 7 Personal, Edition Free Pascal, Lazarus, Lua(Scite)
|
Verfasst: So 02.09.12 23:03
Ich habe gerade den Pc heruntergefahren(schreibe auf dem Smartphone) und kann es deshalb leider nicht sofort liefern, aber was fehlt denn? Ausser dieser Dateien sind nur noch die .o, .exe und .ppu Datei/en in dem Ordner, was ja die compilierten Units bzw. die Exe sind, oder? Ich würde sie natürlich so schnell wie möglich nachliefern, was wahrscheinlich morgen Mittag wäre.
|
|
Tankard
      

Beiträge: 217
Erhaltene Danke: 96
|
Verfasst: Mo 03.09.12 06:40
Für diesen Beitrag haben gedankt: Petroglyph
|
|
Petroglyph 
Hält's aus hier
Beiträge: 7
Windows Vista, Ubuntu 12.03
Delphi 7 Personal, Edition Free Pascal, Lazarus, Lua(Scite)
|
Verfasst: Mo 03.09.12 17:29
Tankard hat folgendes geschrieben : | einen destructor ruft man nie selber auf. |
Ich bedanke mich für den Hinweis, habe das jetzt korrigiert. Leider ergab auch das keine Verbesserung. Mir fiel inzwischen auf, dass wenn ich das Programm mit Speicherbericht laufenlasse, die letzte Zeile "The turing machine stopped. You can end the program by pressing enter." nicht angezeigt wird. Auch meine Eingabe zum Beenden des Programms durch "ReadLn()" scheint ignoriert zu werden, da ich nach der Ausgabe der Zustände sofort in die Befehlszeile der Konsole weitergeleitet werde.
Diesesmal hänge ich zwei Varianten sämtlicher im Programmordner enthaltenen Dateien an. Die erste ist die normale, während die zweite den Speicherbericht beinhaltet und die Unit "turing.pas" die "heaptrc"-Unit beinhaltet.
Edit: Grammatikfehler korrigiert.
Einloggen, um Attachments anzusehen!
|
|
Delphi-Laie
      
Beiträge: 1600
Erhaltene Danke: 232
Delphi 2 - RAD-Studio 10.1 Berlin
|
Verfasst: Mo 03.09.12 17:46
Wie ich nunmehr mitbekam, reicht doch bei einem solchen Nichtformularprogramm eine zentrale Pascaldatei aus. Das kannte ich von Delphi so nicht: Dort muß man auch bei Konsolenprogrammen die dpr-Datei als zentrale benutzen.
Ich hülfe Dir gern weiter, doch ist mir schleierhaft, was ich eingeben muß, damit die Turingmaschine irgendetwas sinnvolles tut oder sich wenigstens nicht in einer Endlosschleife verfängt (das ist, wie einen beliebigen Binärcode ausführen zu wollen - die Wahrscheinlichkeit, daß das Programm überhaupt nur irgendwann endet, ist praktisch so gut wie null). Und ohne Minimalablaufsinn des Programmes ist jeder Hilfeversuch wahrscheinlich vergebens.
Zuletzt bearbeitet von Delphi-Laie am Mo 03.09.12 18:33, insgesamt 1-mal bearbeitet
|
|
Petroglyph 
Hält's aus hier
Beiträge: 7
Windows Vista, Ubuntu 12.03
Delphi 7 Personal, Edition Free Pascal, Lazarus, Lua(Scite)
|
Verfasst: Mo 03.09.12 18:12
Ich werde versuchen zu erklären, wie das Programm bedient werden soll. Eine Dokumentation schreibe ich auch noch, wenn das Programm ganz fertig ist. Allgemein kann ich zum weiteren Verständnis die Wikipediaartikel "Turingmaschine" und "Busy Beaver" empfehlen.
Der erste wichtige Teil ist die Datei "turingtable.txt". In ihr sind in Fünfertupeln die Anweisungen der Maschine gespeichert. Zeilen, die mit einem "/" beginnen sind auskommentiert. Es sollte auch nur ein Programm nicht auskommentiert sein, da das ansonsten zu Fehlern führt. Als Beispiel nehme ich mal die erste Zeile des 4-State Busy Beavers.
Diese lautet "A01LB". Das "A" steht für den Zustand, in dem sich die Maschine im Moment befindet. Das kann in diesem Beispiel ein Wert von "A" bis "D" sein. Die Maschine startet immer im Zustand "A".
Die "0"(muss nicht unbedingt eine Zahl sein) steht für das Zeichen, welches die Maschine im jetzigen Schritt gelesen hat. In Kombination mit dem Zustand erhält man so die weiteren Anweisungen der Maschine.
Die "1" gibt das Zeichen an, das auf das Feld, auf dem sich der Kopf gerade befindet, geschrieben wird. Das "L" bestimmt die Bewegungsrichtung des Kopfes, was entweder links, rechts oder gar nicht sein kann.
Das letzte Zeichen "B" gibt den Zustand an, in dem sich die Maschine im nächsten Arbeitsschritt befindet.
Wenn das Programm gestartet wird, fragt es erst einmal, ob eine ständige Ausgabe gewünscht ist. Das ist eingebaut, da diese Ausgabe das Programm stark verlangsamt und zum Beispiel den 5-State Busy Beaver viel zu lange dauern lässt.
Danach wird die Startlänge des Bandes, auf dem die Daten stehen abgefragt. Dort wähle ich meistens "1", da die Tests einfach nur möglich viele Einsen schreiben sollen. Wenn die Maschine aber zum Beispiel zwei Zahlen addieren soll, dann braucht man natürlich Startwerte, die am Anfang auf das Band geschrieben werden müssen.
Danach werden diese Startwerte abgefragt. Hier wähle ich meistens eine einzelne "0". Leider konnte ich noch nicht abfangen, dass die Eingabe möglicherweise nicht auf die Bandlänge passt.
Nach der Eingabe läuft die Maschine. Je nach Ausgabeart sieht man entweder alle Ergebnisse oder nur das Endergebnis. Übrigens sind die Ergebnisse im Vergleich zu den Ergebnissen auf Wikipedia gespiegelt, da ich den Kopf und nicht das Band bewege.
|
|
Petroglyph 
Hält's aus hier
Beiträge: 7
Windows Vista, Ubuntu 12.03
Delphi 7 Personal, Edition Free Pascal, Lazarus, Lua(Scite)
|
Verfasst: So 14.10.12 14:44
Ich habe gerade eben die Frage auf stackoverflow gepostet (Crosspost: stackoverflow.com/qu...al/12881958#12881958 ).
Dank der Hilfe dort fand ich heraus, dass meine dynamischen Arrays zu klein waren, und so Speicher korrumpiert wurde. Herausgefunden hat das der Helfer indem er den Quelltext mit der Option '-Cr' kompilierte. Die folgende Änderung in Linie 68 des Quelltextes von turingtable.pas hatte das Ergebnis, dass keine Speicherlecks mehr festgestellt wurden.
Delphi-Quelltext 1: 2:
| ArrayResize(CurrentTupel); ArrayResize(CurrentTupel + 1); |
Obwohl ich hier nicht die Antwort erhielt, möchte ich mich doch für die Hilfe hier herzlich bedanken, da ich auf ein paar andere Fehler in meinem Quelltext hingewiesen wurde. Ich vermute auch, dass meine Beschreibung des Programms nicht gerade die Beste war, was natürlich nicht bei der Lösung des Problems half.
Einen schönen Sonntag noch,
Petroglyph
|
|
Fiete
      
Beiträge: 617
Erhaltene Danke: 364
W7
Delphi 6 pro
|
Verfasst: Mo 15.10.12 12:53
Moin Petroglyph,
da Du dich für die Turingmaschine interessierst, hier zwei Links die Dich weiterbringen könnten:
Simulator für eine TM
www.entwickler-ecke....light=turingmaschine
Bibersuchprogramm
www.entwickler-ecke....ighlight=busy+beaver
Gruß Fiete
_________________ Fietes Gesetz: use your brain (THINK)
|
|
|