MAJA PASARIĆ SIMULATOR TURINGOVOG STROJA ZAVRŠNI

VISOKA ŠKOLA ZA MENADŢMENT
U TURIZMU I INFORMATICI U VIROVITICI
MAJA PASARIĆ
SIMULATOR TURINGOVOG STROJA
ZAVRŠNI RAD
VIROVITICA, GODINA 2014
VISOKA ŠKOLA ZA MENADŢMENT
U TURIZMU I INFORMATICI U VIROVITICI
SIMULATOR TURINGOVOG STROJA
ZAVRŠNI RAD
Predmet: Osnove programiranja
Mentor:
Student:
dr.sc. Oliver Jukić, prof.v.š.
VIROVITICA, GODINA 2014.
Maja Pasarić
SADRŽAJ
1. UVOD ................................................................................................................................... 1
2. TEORIJSKE POSTAVKE .................................................................................................... 2
3. IZVEDBA SIMULATORA TURINGOVOG STROJA ....................................................... 3
3.1. Metodologija ...................................................................................................................... 3
3.2. Klase .................................................................................................................................. 4
3.3. Izvedba funkcionalne sheme .............................................................................................. 4
3.3.1. Unos i aţuriranje funkcionalne sheme ............................................................................ 6
3.3.2. Pohrana i naknadno uĉitavanje ..................................................................................... 10
3.4. Izvedba vanjske memorije ............................................................................................... 12
3.4.1. Unos i aţuriranje ........................................................................................................... 13
3.4.2. Pohrana i naknadno uĉitavanje ..................................................................................... 14
3.5. Izvedba simuliranja .......................................................................................................... 15
3.4. Prikaz k-te konfiguracije .................................................................................................. 21
4. RASPRAVA ....................................................................................................................... 22
5. ZAKLJUĈAK ..................................................................................................................... 24
6. POPIS LITERATURE ........................................................................................................ 25
7. POPIS ILUSTRACIJA ....................................................................................................... 26
1. UVOD
Turingov stroj je koncept univerzalnog izvršitelja algoritama. Njegova definicija je
jednostavna, ali se dotiĉe kompleksnih pitanja matematiĉke apstrakcije razmišljanja, granica
automatiziranog rješavanja problema, naĉina stvaranja, pojednostavljenja i izvoĊenja
algoritama kojima se jednostavnim operacijama pokušavaju riješiti sloţeniji problemi.
Stvaranje algoritama kojima Turingov stroj moţe poĉetnu informaciju preobraziti u
zadovoljavajuću konaĉnu je ĉesto izazovan problem, no sam rad stroja je jednostavan.
Iako je neke probleme kojih se koncept Turingovog stroja dotiĉe teško objasniti, sam
rad Turingovog stroja je jednostavan i lagan za simulirati. Sve što je potrebno jest oblik unosa
i ispisa simbola u vanjsku memoriju, mogućnost pomicanja ureĊaja za uĉitavanje i ispisivanje
simbola te nekakav spremnik za izraze logiĉke funkcije stroja. To se sve moţe izvesti
programski, i to na nekoliko naĉina, a ovaj rad prezentira jedno moguće rješenje.
Ovaj rad će se prvo osvrnuti na sam koncept Turingovog stroja i objasniti osnovne
pojmove koji se nastoje izvesti predstavljenim programskim rješenjem. Zatim će biti rijeĉi o
samoj metodologiji izvedbe rješenja problematike simuliranja Turingovog stroja. Ostatak rada
predstavlja samo rješenje problema; prezentirajući implementaciju osnovnih funkcionalnosti
simulatora Turingovog stroja. Prvo će se predstaviti funkcionalnosti vezane uz funkcionalnu
shemu: unošenje i aţuriranje funkcionalne sheme, te pohranu i naknadno uĉitavanje
funkcijske sheme. Zatim će se predstaviti izvedbe unošenja i aţuriranja vanjske memorije, te
njezine pohrane i naknadnog uĉitavanja. Nakon toga slijedi opis izvedbe simulacije
Turingovog stroja te prikaza k-te konfiguracije. Rad će zaokruţiti rasprava prikladnosti
rješenja problemu, nakon ĉega slijedi par zakljuĉnih rijeĉi.
1
2. TEORIJSKE POSTAVKE
Turingov stroj je model osmišljen da oponaša proces ljudskog razmišljanja. Prvi ga je
opisao Alan Turing u svrhu promišljanja i istraţivanja granica raĉunanja. Koncept je
usredotoĉen na razlaganje sloţenih algoritama na jednostavne korake koji se mogu
matematiĉki izraziti i uspješno izvršiti jednostavnim automatom. Raĉunanje Turingovim
strojem se svodi na uĉitavanje ulaznog znaka, mijenjanje internog stanja svijesti s obzirom na
trenutno stanje i ulazni znak, te produciranje i ispisivanje izlaznog znaka na traku1.
Turingov stroj se sastoji od glave za ĉitanje i pisanje, logiĉkog polja, polja za pohranu
untarnjeg stanja i polja za pomak. Vanjska memorija je predstavljena beskonaĉnom trakom s
poljima s koje stroj glavom za ĉitanje uĉitava ulazni znak. Ulazni znak pripada konaĉnoj
abecedi, a svako polje moţe sadrţavati najviše jedan znak. Abeceda stroja uvijek sadrţi prazni
znak (b). Ĉitanje tog znaka znaĉi da je polje trake prazno, a ispisivanje tog znaka prazni polje.
Logiĉka funkcija svakom paru ulaznog simbola i trenutnog stanja pridruţuje trojku idućeg
stanja, izlaznog simbola i pomakom glave za ĉitanje i pisanje. Internih stanja ima konaĉno
mnogo, i to najmanje dva: poĉetno stanje (q0) i konaĉno stanje (qf). Glava je pomiĉna i za
svaki Turingov stroj su definirana toĉno tri pomaka: pomak za jedno polje ulijevo (L), pomak
za jedno polje udesno (D), i ostanak glave na mjestu (N) (Jukić, Špoljarić, 2010).
Svaki Turingov stroj je definiran svojom abecedom, skupom mogućih stanja, skupom
mogućih pomaka i logiĉkom funkcijom koja opisuje njegov algoritam. Logiĉka funkcija stroja
je sadrţana u njegovom logiĉkom bloku, a moţe ju se prikazati funkcionalnom shemom.
Funkcionalna shema je tabliĉni zapis svih trojki izlaznog simbola, idućeg stanja i pomaka
pridruţenih svakom paru ulaznog simbola i trenutnog stanja (Turing, 1936).
Obrada informacije zapisane u vanjskoj memoriji se odraĊuje u taktovima. Zapis na
traci na poĉetku svakog takta predstavlja meĊuinformaciju ĉijom obradom stroj mora doći do
konaĉne informacije tj. doći u konaĉno stanje u kojem emitira stop signal i prestaje sa
daljnjim ĉitanjem vanjske memorije. Svaku meĊuinformaciju nazivamo konfiguracijom
Turingovog stroja. K-ta konfiguracija Turingovog stroja je zapis na traci na poĉetku k-tog
takta. Ako stroj moţe kroz konaĉni broj konfiguracija doći do konaĉnog rezultata, stroj je
primjenjiv za poĉetnu informaciju (Jukić, Špoljarić, 2010).
1
http://plato.stanford.edu/entries/turing-machine/ (18.11.2014.)
2
3. IZVEDBA SIMULATORA TURINGOVOG STROJA
3.1. Metodologija
Programsko rješenje problema simulacije beskonaĉnog broja razliĉitih Turingovih
strojeva napisano je jezikom C++ i izvedeno uz pomoć razvojne okoline2 Qt Creator 3.2.0. Qt
Creator je IDE osmišljen za programiranje multiplatformskih rješenja uz olakšani dizajn
korisniĉkog suĉelja3. Osim standardnih konstrukata C++ jezika, Qt nudi i vlastite klase
stvorene da budu ne samo kompatibilne sa C++ standardima, već i optimizirane izvedbe te
podrške odreĊenim konceptima programiranja.
Jedan od koncepata svojstvenih Qt Creatoru je sustav povezivanja signala i slotova
(signals and slots). Sustav omogućuje komunikaciju izmeĊu objekata kojom funkcija jednog
objekta signalom poziva funkciju drugog objekta – slot. To se razlikuje od uobiĉajene izvedbe
takve komunikacije koja je pohrana pokazivaĉa na funkcije. Objektu koji poziva funkciju
proslijeĊuje se pokazivaĉ na funkciju drugog objekta kojeg on pohranjuje i koristi za poziv
funkcije drugog objekta kad zatreba. Mane takve izvedbe su te da nije uvijek zajamĉeno da će
objekt pozvati funkciju sa ispravnim argumentima i da je izvedba ovisna o pozivajućoj
funkciji. Ako funkcija ne zna koju funkciju mora zvati, osmišljena veza izmeĊu dvaju
objekata se neće ostvariti kako je zamišljeno. Qt-ov sustav signala i slotova osigurava
pozivanje ispravnih funkcija sa ispravnim argumentima neovisno o samom objektu. Objekt ne
pohranjuje dodatne podatke niti sam poziva funkciju; za uspostavljene konekcije brine se Qtov meta-objektni prevoditelj. Konekcije su jedino ograniĉene popisom argumenata koji se
signalom šalju. Pozivajuća funkcija ne moţe pozvanoj funkciji poslati manje argumenata
nego što pozvanoj funkciji treba za izvedbu4.
Stvaranje aplikacije u Qt-u olakšano je raznim posebnim klasama i widgetima
ukljuĉenima u Qt-ove biblioteke. Qt za mnoge elemente grafiĉkih korisniĉkih suĉelja poput
gumba, prozora, dijaloga i alatnih traka nudi i po nekoliko klasa iz kojih se izvoĊenjem novih
klasa postiţe olakšana izvedba aplikacija sa grafiĉkim suĉeljima. Jedna od tih klasa je i
QWidgetTable koja je u programskom rješenju predstavljenom ovim radom korištena kao
izvedba funkcionalne sheme i vanjske memorije Turingovog stroja. Qt podrţava i tzv. MVC
(model/view/controller) oblikovni uzorak koji manipuliranje podacima i njihovo prezentiranje
korisniku odvaja u tri komponente: model, koji sluţi kao spona izmeĊu podataka i
2
U daljnjem nastavku: IDE (Integrated development environment)
https://qt-project.org/doc/qtcreator-2.5/creator-overview.html (18.11.2014.)
4
http://qt-project.org/doc/qt-4.8/signalsandslots.html (18.11.2014.)
3
3
prezentacije, pregled (view) koji je zaduţen samo za prezentaciju podataka, i kontroler
(controller) koji upravlja naĉinom interakcije suĉelja i podataka. Pojam kontrolera u Qt-u je
izveden delegatima (delegates). MVC obrasci dizajniranja softverskih rješenja su vrlo korisni.
Programsko rješenje koje je temelj ovog rada izvodi vanjsku memoriju posebno definiranim
delegatom za zadavanje poĉetne konfiguracije Turingovog stroja kojim se osigurava da
korisnik na traku zapisuje samo one simbole koji se nalaze u vanjskoj abecedi stroja.
3.2. Klase
Programsko rješenje je izvedeno uz pomoć šest klasa: AddDialog, Dialog,
RemoveDialog, TapeDelegate, TableEditor i MainWindow. Klase AddDialog, Dialog i
RemoveDialog su dijaloške klase ĉijim objektima se aplikacija sluţi pri odreĊivanju vanjske
abecede i skupa unutarnjih stanja Turingovog stroja te izvoĊenju k-te konfiguracije stroja.
Objekti klase AddDialog koriste se za dodavanje stanja i simbola u pripadajuće skupove, a
objekti klase RemoveDialog se koristi za njihovo uklanjanje. Objekt klase Dialog od
korisnika traţi unos broja k kojim se aplikacija sluţi za odreĊivanje k-te konfiguracije
Turingovog stroja. Klasa TapeDelegate je klasa već spomenutog delegata korištenog pri
unošenju i preinakama vanjske memorije, a klasa TableEditor je klasa objekta korištenog za
unos i aţuriranje funkcionalne sheme.
Klasa
MainWindow
predstavlja
centralni
widget
aplikacije.
Velika
većina
funkcionalnosti aplikacije proizlazi upravo iz MainWindow klase koja nasljeĊuje
QMainWindow, Qt-ovu klasu specijaliziranu za aplikacije sa grafiĉkim suĉeljem. Najviše
ĉlanova ove klase su funkcije od kojih su skoro sve definirane kao slotovi, funkcije koje druga
funkcija moţe pozvati. Budući da su za internu upotrebu, tj. pozivaju ih funkcije koje su
ĉlanovi istog objekta, nema potrebe da ih se deklarira javnima.
3.3. Izvedba funkcionalne sheme
Kao što je već reĉeno, funkcionalna shema izvedena je objektom klase QTableWidget.
QTableWidget je widget za tabliĉni prikaz kojem je pridruţen standardni podatkovni model.
Budući da su zahtjevi izvedbe funkcionalne sheme jednostavni i svode se na unos i aţuriranje
tablice, nema potrebe za izvoĊenjem klasa ili MVC programiranjem.
4
Osnovica funkcionalne sheme su vanjska abeceda i skup unutarnjih stanja. Svaka ćelija
sadrţi trojku odreĊenu ulaznim simbolom (redak tablice) i trenutnim stanjem (stupac tablice).
Skup pomaka je strogo definiran. Skup unutarnjih stanja predstavlja states ĉlan klase
MainWindow koji je tipa QStringList, što ga oznaĉava kao listu u koju se spremaju podaci
tipa QString. Vanjsku abecedu predstavlja symbols, isto deklariran kao varijabla tipa
QStringList, a shifts je QStringList koji pohranjuje skup pomaka. Sva tri ĉlana se
inicijaliziraju u konstruktoru klase MainWindow, kao što je prikazano u idućem odsjeĉku
koda.
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
states.append("q0");
symbols.append("b");
shifts.append("L");
shifts.append("N");
shifts.append("D");
...
}
Funkcija append() listi dodaje ĉlanove tako da svaki novi ĉlan pozicionira u poloţaju odmah
nakon zadnjeg elementa liste5. Dodavanjem novih stanja i simbola na kraj liste osiguravamo
poredane podatke. To je posebno vaţno ostvariti za listu u kojoj ĉuvamo stanja budući da
indeksi stanja direktno koreliraju sa indeksima stringova njihovih oznaka u listi u kojoj ih
ĉuvamo. Simboli ne moraju biti poredani (npr., prema abecedi), ali zato pomaci moraju uvijek
biti inicijalizirani ovako budući da se prevoĊenje oznake pomaka u stvarni pomak glave za
ĉitanje i pisanje prevodi uprav na temelju indeksa oznake u listi. Liste koje pohranjuju
simbole i stanja moraju na poĉetku dobiti nekoliko zadanih podataka. Ti podaci predstavljaju
dva bitna elementa koja su spomenuta u izlaganju teorijske osnove ovog rada, a to su prazni
simbol b i poĉetno stanje q0. Prazni simbol i poĉetno stanje su obvezni ĉlanovi svojih
skupova, stoga u ovom dijelu koda abecedi dodajemo prazni simbol, a skupu stanja dodajemo
poĉetno stanje. Konaĉno stanje qf je isto obvezni element skupa stanja, no zbog odreĊenih
5
http://www.cplusplus.com/reference/string/string/append/ (18.11.2014.)
5
aspekata izvedbe dodavanja novih stanja, uklanjanja stanja te korištenja stanja za potrebe
simulacije, izravno ukljuĉivanje konaĉnog stanja u skup nije prikladno. Zbog toga konaĉno
stanje nije ukljuĉeno u listu, ali se koristi pri simulaciji rada stroja i ureĊivanju funkcionalne
sheme.
QTableWidget je u aplikaciju dodan preko Qt Designera, Qt-ovog alata za dizajn
grafiĉkih korisniĉkih suĉelja, stoga u kodu klase MainWindow nije zapisana deklaracija tog
objekta. Ona se nalazi u skrivenoj zaglavnoj datoteci koju generira Qt u svrhu odvajanja koda
generiranog Qt Designerom od koda napisanog od strane programera. Generirani kod postaje
dijelom ui klase koju generira Qt Designer prilikom ureĊivanja grafiĉkog suĉelja, stoga
funkcionalnoj shemi pristupamo preko pokazivaĉa na objekt klase ui. Qt tijekom dodavanja
grafiĉkih elemenata kroz Qt Designer generira i imena objekata. Tako je QTableWidget koji
se koristi kao prikaz funkcionalne sheme od strane Qt Designera nazvan tableWidget.
Naredni odsjeĉak koda inicijalizira tableWidget i tako ga priprema za daljnju
korisnikovu upotrebu. Postavljaju se dimenzije tablice te poĉetna trojka.
void MainWindow::initShema()
{
ui->tableWidget->setRowCount(1);
ui->tableWidget->setColumnCount(1);
QTableWidgetItem *item = new QTableWidgetItem(QString("q0, b, N"));
ui->tableWidget->setItem(0,0,item);
ui->tableWidget->setHorizontalHeaderItem(0, new QTableWidgetItem("q0"));
ui->tableWidget->setVerticalHeaderItem(0, new QTableWidgetItem("b"));
}
Inicijalno, dimenzije funkcionalne sheme su postavljene na 1x1, što odgovara trojci
odreĊenoj parom poĉetnog stanja i praznog simbola, a tekst zaglavnih ćelija se postavlja
shodno tome. Zadana trojka na koju se postavlja prva ćelija oznaĉava da je rezultantno stanje
uĉitavanja praznog simbola tijekom bivanja u poĉetnom stanju ponovno poĉetno stanje, i da
pomaka glave za ĉitanje i pisanje nema.
6
3.3.1. Unos i ažuriranje funkcionalne sheme
UreĊivanje funkcionalne sheme ima dvije komponente: dodavanje i brisanje elemenata
skupa unutarnjih stanja i vanjske abecede, i unošenje trojki u shemu. Objekti klasa AddDialog
i RemoveDialog se stvaraju klikom na odreĊene gumbe na suĉelju, a TableEditor se instancira
dvostrukim klikom na ćeliju sheme. To instanciranje je izvedeno niţe navedenom
konekcijom.
connect(ui->tableWidget, SIGNAL(cellClicked(int,int)),
this, SLOT(editDialog(int,int)));
Signal cellClicked(int,int) šalje oznaku retka i stupca kojima ćelija pripada. Slot prima te
argumente i koristi ih za ureĊivanje sheme.
void MainWindow::editDialog(int r, int c)
{
int a = r;
int b = c;
QTableWidget *table = dynamic_cast<QTableWidget*>(sender());
TableEditor *t = new TableEditor(this); //...
}
Osim indeksa ćelije, pribavlja i pokazivaĉ na QTableWidget posebnom naredbom koja
vraća pokazivaĉ na objekt koji je poslao signal slotu. Dijalog direktno ureĊuje tablicu, a za to
mu trebaju upravo indeks ćelije i pokazivaĉ na objekt.
7
Korisnik
tableWidget
TableEditor
"Uredi ovu ćeliju"
<indeks ćelije>
"Unesite postavke ćelije"
<sadržaj ćelije>
"Napravi string"
<nova vrijednost ćelije>
Slika 1.: MSC dijagram procesa uređivanja ćelije funkcionalne sheme
Na Slici 1. prikazana je razmjena poruka izmeĊu korisnika, funkcionalne sheme i
ureĊivaĉa ćelije. TableEditor je instanca klase ureĊivaĉa funkcionalne sheme. Nakon što
korisnik unese sadrţaj ćelije koji ţeli postaviti, ureĊivaĉ sam sebi pošalje signal da unesene
vrijednosti pretvori u string koji onda pošalje funkcionalnoj shemi, postavljajući tekstualnu
vrijednost ćelije na formirani string.
Općenito, pri unosu ili novih stanja, ili novih simbola, stvaraju se novi stupci, odnosno
redci i postavljaju se njihove zaglavne ćelije. Ovo je demonstrirano narednim odsjeĉkom koda
koji pripada funkciji addState, funkciji odgovornoj za dodavanje stanja.
void MainWindow::addState(){
int cCount = states.size();
states.append(QString("q%1").arg(cCount));
populateCombo();
cCount++;
ui->tableWidget->setColumnCount(cCount);
cCount--;
ui->tableWidget->setHorizontalHeaderItem(cCount, new
QTableWidgetItem(QString("q%1").arg(cCount)));
for(int i=0; i<ui->tableWidget->columnCount(); i++)
{
8
QTableWidgetItem *item = new QTableWidgetItem();
item->setText(" ");
ui->tableWidget->setItem(i, cCount, item);
}
}
Prvo se funkcijom size() pribavlja broj elemenata u listi da bi se mogao izvesti indeks
novog stanja. Budući da indeksiranje liste poĉinje od nule, što znaĉi da k-ti element ima
indeks k-1, broj elemenata u nekoj listi odgovara indeksu elementa koji bi se dodao na kraj
liste. Kad aplikacija pribavi broj elemenata u listi, stvori QString spajanjem znaka q i indeksa
tog novog stanja u listi. Indeksi stanja se isto poĉinju brojati od nule, što znaĉi da je indeks
svakog stanja u listi jednak njegovom indeksu kao ĉlana skupa internih stanja. Funkcija
updateCombo nakon pohrane novog stanja u listu aţurira popise opcija padajućih izbornika
koji se koriste u ureĊivaĉu ćelija.
Poslije unosa novog stanja u listu, aţuriraju se dimenzije i sadrţaj tablice. Dodaje se
novi stupac uz desni rub tablice. Tekst zaglavne ćelije se postavlja tako da odraţava novo
dodano stanje i oznaĉi taj stupac kao zonu presjeka tog stanja i pojedinih znakova vanjske
abecede. Iteriranjem kroz for petlju aplikacija prolazi kroz svaku ćeliju novododanog stupca i
postavlja nihove tekstualne vrijednosti na " ".
Uklanjanje stanja i simbola se odvija preko instance klase RemoveDialog putem koje
korisnik odabire stanje ili simbol koji ţeli ukloniti. Nakon što korisnik unese svoj odabir,
aplikacija traţi stupac ili redak koji odgovara uklonjenom elementu, uklanja ga iz tablice te
iterira kroz cijelu tablicu aţurirajući pohranjene trojke. Trojke ne smiju pokazivati na
nepostojeća stanja ili nepostojeće simbole, stoga je nuţno svaku trojku provjeriti i izmijeniti
prema potrebi. To je pokazano idućim kodnim odsjeĉkom koji je dio funkcije removeState
kojom aplikacija uklanja stanja iz skupa te shodno tome aţurira tablicu.
for(int i=0; i<=states.size(); i++)
{
for(int j=0; j<symbols.size(); j++)
{
if(ui->tableWidget->item(j,i)!=0)
{
item= ui->tableWidget->item(j, i)->text();
triplet= item.split(", ");
9
if(triplet.size()==3)
{
QString number = triplet.at(0);
if(number!="qF")
{
number.remove(0,1);
int newIndex = number.toInt();
if(newIndex>0) newIndex--;
triplet.replace(0,QString("q%1").arg(newIndex));
QString set= QString();
set=triplet.join(", ");
ui->tableWidget->item(j, i)->setText(set);
}
}
else
{
QTableWidgetItem *it = new QTableWidgetItem();
ui->tableWidget->setItem(j, i, it);
}
Aplikacija uĉitava trojku pohranjenu u ćeliji te tako dobivenim QStringom manipulira
tako da moţe razluĉiti koje stanje je u trojci zabiljeţeno kao iduće. Oznaci uĉitanog stanja
oduzima znak q i konverzijom tako dobivenog stringa u broj dobiva indeks tog stanja u
QString listi. Ako taj indeks odgovara indeksu onog stanja kojeg aplikacija uklanja, aplikacija
postavlja indekse stanja tako da pokazuju na neko postojeće stanje.
3.3.2. Pohrana i naknadno učitavanje
Spremanje funkcionalne sheme u datoteku se odvija kroz objekt klase QFileDialog,
dijaloški okvir definiran za upravljanje datototekama. Korisnik unosi ime datoteke koje se
zatim koristi za instanciranje objekta klase QFile. QFile pruţa suĉelje za ĉitanje i pisanje
datoteka6. Tom objektu se pridruţuje instanca klase QDataStream koja predstavlja tok
podataka. Da bi se funkcionalna shema uspješno pohranila, treba spremiti vanjsku abecedu i
skup unutarnjih stanja, izvući podatke iz QTableWidget objekta i pretvoriti ih u oblik koji se
6
http://qt-project.org/doc/qt-5/qfile.html (18.11.2014.)
10
moţe proslijediti otvorenom toku podataka. QTableWidget se ne moţe pohraniti stavljanjem
u QDataStream tok podataka budući da objekti navedene klase sluţe za serijalizaciju binarnih
tipova podataka. U suštini, svi podaci su binarni, ali samo neki tipovi podataka se mogu tako
spremati i ĉitati neovisno o platformi7. Takvi podaci ukljuĉuju jednostavne standardne
podatkovne tipove poput integer, double, i float, te objekte pojedinih Qt-ovih klasa.
QTableWidget nije tip podatka, već sloţeni objekt, widget, stoga jednostavno stavljanje
njegovih podataka u podatkovni tok nije moguće.
Podaci se izvlaĉe iz funkcionalne sheme iteriranjem ugnijeţĊenim for petljama. U
svakoj iteraciji, tekst spremljen u ćeliji widgeta se pohranjuje u za tu svrhu deklariran
QStringList saveData.
QStringList saveData;
for(int row=0; row<symbols.size(); row++)
{
for(int column=0; column<states.size(); column++)
{
if(!ui->tableWidget->item(row, column)||ui->tableWidget->item(row, column)>text().isEmpty())
{
saveData.append(" ");
} else
{
saveData.append(ui->tableWidget->item(row, column)->text());
}
}
}
Nakon uspješnog izvlaĉenja teksta svih ćelija sheme, podaci se pohranjuju.
out<<states<<symbols<<saveData;
file.close();
Otvaranje datoteke se odvija vrlo sliĉno. Otvara se dijaloški okvir putem kojeg korisnik
odabire datoteku koju ţeli otvoriti. Otvara se novi tok podataka iz kojeg uĉitavamo podatke u
7
http://qt-project.org/doc/qt-4.8/datastreamformat.html (18.11.2014.)
11
datoteci. Prilikom otvaranja, vrlo je bitno uĉitavati podatke onim redoslijedom kojim smo ih
zapisali8. Uĉitavamo podatke iz podatkovnog toka i spremamo ih u states, symbols i
QStringList loadData.
for(int row = 0; row<symbols.size();row++)
{
ui->tableWidget->setVerticalHeaderItem(row, new
QTableWidgetItem(symbols.at(row)));
for (int column=0; column<states.size(); column++)
{
ui->tableWidget->setHorizontalHeaderItem(column, new
QTableWidgetItem(states.at(column)));
QTableWidgetItem *item=new QTableWidgetItem;
ui->tableWidget->setItem(row, column, item);
ui->tableWidget->item(row, column)->setText("###");
}}
Aplikacija pripremi QTableWidget objekt za postavljanje podataka tako da mu broj
stupaca i redaka postavi na broj podataka spremljenih u odgovarajućim QStringList
spremnicima. Broj stupaca mora biti jednak broju unutarnjih stanja, a broj redaka mora biti
jednak broju simbola vanjske abecede. Naslovi stupaca i redaka se isto postavljaju prema
skupu unutarnjih stanja i vanjske abecede. Zatim aplikacija doda ćelije QTableWidget objektu
i pstavlja njihovu tekstualnu vrijednost na " ###".
Podaci koje je aplikacija preuzela iz podatkovnog toka i pohranila u loadData se
iteracijom kroz listu postavljaju u svaku ćeliju.
for(int i=0; i<loadData.size();i++)
{
int row=i/symbols.size();
int column= i%symbols.size();
ui->tableWidget->item(row, column)->setText(loadData.at(i));
}
Aplikacija zatim zatvara podatkovni tok i datoteku iz koje je uĉitala podatke.
8
http://qt-project.org/doc/qt-4.8/qdatastream.html (18.11.2014.)
12
3.4. Izvedba vanjske memorije
Vanjska memorija je takoĊer izvedena korištenjem QTableWidgeta. QTableWidget
kojim ju aplikacija izvodi ima skrivene zaglavne ćelije, stupce i retke fiksnih dimenzija i
posebno postavljen font. Na widget je postavljen i poseban delegat. QTableWidget nije dio
Qt-ove izvedbe MVC programiranja budući da ne odvaja podatke od modela, ali moguće je
postavljati delegate na objekte te klase9. Vanjska memorija je inicijalizirana kao tablica sa
jednim retkom i 10 stupaca, dakle 10 ćelija, i bez okvira. Budući da je i ovaj objekt dodan
aplikaciji u Qt Designeru, i njemu se pristupa preko ui pokazivaĉa.
ui->tableWidget_2->setRowCount(1);
ui->tableWidget_2->setColumnCount(10);
ui->tableWidget_2->setFrameStyle(QFrame::NoFrame);
QFont *font = new QFont();
font->setPointSize(30);
3.4.1. Unos i ažuriranje
Već spomenuta klasa TapeDelegate je klasa izvedena iz QStyledItemDelegate klase.
Implementacija izvedenog delegata mora reiplementirati barem tri funkcije: createEditor(),
setEditorData() i setModelData(). Funkcija createEditor() stvara ureĊivaĉ modela, widget
putem kojeg će korisnik modificirati podatke. TapeDelegate kao ureĊivaĉ koristi padajući
izbornik koji je objekt clase QComboBox.
QWidget* TapeDelegate::createEditor( QWidget *parent, const QStyleOptionViewItem
&option, const QModelIndex &index ) const
{
if(index.row() != 0)
return QStyledItemDelegate::createEditor(parent, option, index);
QComboBox *cb = new QComboBox(parent);
//stvara ureĊivaĉ ćelije vanjske memorije
cb->addItems(MainWindow::getSymbols());
return cb;
}
9
http://qt-project.org/doc/qt-4.8/qtablewidget.html (18.11.2014.)
13
Funkcija setEditorData() predaje ureĊivaĉu podatke koji se trenutno nalaze u ćeliji, a
funkcija setModelData preuzima unesene podatke iz ureĊivaĉa te ih proslijeĊuje tabliĉnom
podatkovnom modelu. Ako korisnik unese prazni simbol, tekstualna vrijednost odabrane
ćelije se postavlja na " ".
Od nekoliko podvrsti Turingovog stroja10, aplikacija implementira onu ĉija traka se
proteţe u beskonaĉnost na oba kraja. Upravljanje duljinom trake se izvan simulacije obavlja
dvama funkcijama: lengthenTape() koja traku produljuje za jednu ćeliju, tj. umetne prazni
stupac u QTableWidget na samom rubu tablice, i shortenTape() koja traku skrati za jednu
ćeliju uklanjanjem krajnjeg stupca. Tijekom simulacije, produljivanje trake se vrši prema
potrebi unutar funkcije goForth() o kojoj će kasnije biti rijeĉi.
3.4.2. Pohrana i naknadno učitavanje
Vanjska memorija se pohranjuje u datoteke sa ekstenzijom .tst. Funkcija spremanja
vanjske memorije saveTape() se od funkcije spremanja funkcionalne sheme saveShema()
razlikuje samo po ekstenziji datoteke i naĉinu izvlaĉenja podataka iz widgeta. Za razliku od
funkcionalne sheme za ĉiju definiciju je nuţno imati definiranu vanjsku abecedu i skup
unutarnjih stanja, vanjsku memoriju ne odreĊuje ništa drugo osim nje same. Njezina struktura
je jednostavnija od strukture funkcionalne sheme te je naĉin izvlaĉenja podataka iz nje
jednostavniji. Iteriranjem kroz jedini redak pripadajućeg QTableWidgeta i pohranjivanjem
tekstualne vrijednosti svake ćelije u QStringList saveData dobiva se lista QStringova koju se
jednostavno proslijedi u podatkovni tok. Ako je tekstualna vrijednost neke ćelije prazna, kao
simbol se pohranjuje string " ".
for(int column =0; column < ui->tableWidget_2->columnCount(); column++)
{
if(!ui->tableWidget_2->item(0, column)||ui->tableWidget_2->item(0, column)>text().isEmpty())
{
saveData.append(" ");
}else
{
saveData.append(ui->tableWidget_2->item(0, column)->text());
10
http://plato.stanford.edu/entries/turing-machine/ (18.11.2014.)
14
}
Uĉitavanje vanjske memorije iz datoteke se odvija po istom procesu kao i otvaranje
funkcionalne sheme. Prvo se dijaloškim okvirom od korisnika zatraţi odabir datoteke.
Instancira se datoteĉni objekt klase QFile kojem se pridruţi objekt podatkovnog toka klase
QDataStream.
QString fileName = QFileDialog::getOpenFileName(this,
QString("Otvaranje..."),
QString(""),QString("Vanjska memorija (*.tst);;Sve datoteke (*.*)"));
if (fileName.isEmpty())
{
return; //izlazi iz funkcije ako korisnik ne zada ime datoteke
}
else {
QFile file(fileName);
if (!file.open(QIODevice::ReadOnly)) {
QMessageBox::information(this, QString("Greška!"), QString("Datoteka se ne moţe
otvoriti"), QMessageBox::Ok);
return;
}
QDataStream in(&file);
in.setVersion(QDataStream::Qt_4_5);
Svaka verzija Qt-a izaĊe sa malo drukĉijom specifikacijom odreĊenih klasa i koncepata.
Binarni formati Qt-a su se isto mijenjali kroz razvoj okruţenja i vrlo je vaţno datoteku
spremiti prema onoj verziji binarnog formata koja će se koristiti prilikom uĉitavanja datoteke.
Naredba setVersion() izriĉito biljeţi prema kojoj verziji Qt-a se definira binarni format
datoteke11.
3.5. Izvedba simuliranja
Već spomenuta funkcija goForth() je ta koja vrši simuliranje rada stroja po taktovima.
Na Slici 7. je prikazana aplikacija usred simuliranja rada Turingovog stroja. Aplikacija vrši
pomake na traci, uĉitavanje simbola, mijenjanje stanja te ispis simbola, i ispisuje zapise
11
http://qt-project.org/doc/qt-4.8/qdatastream.html (18.11.2014.)
15
taktova u obliku (trenutno stanje, ulazni simbol) --> (iduće stanje, izlazni simbol, pomak).
Kontrole koje su korisniku na raspolaganju su kontrole potrebne za simulaciju koje su aktivne
kad je naĉin davanja takta ruĉan. U bilokojem trenutku, korisnik moţe promijeniti naĉin
davanja takta.
Osim funkcije goForth(), u simulaciji sudjeluju i neki podatkovni ĉlanovi klase
MainWindow. StepCount je podatkovni ĉlan tipa integer koji pohranjuje broj odraĊenih
taktova, napoĉetku postavljen na vrijednost 0. CurrentConfiguration je isto cjelobrojni
podatkovni ĉlan koji pohranjuje broj konfiguracija koje je stroj prošao. Na poĉetku programa
je jednak 1 jer je prva konfiguracija ona na poĉetku prvog takta. AutoStep je logiĉkog tipa i
mijenja se s obzirom na to da li je davanje takta ruĉno ili automatski. Ako je njegova
vrijednost false, davanje takta je postavljeno kao ruĉno. Budući da neki elementi suĉelja poput
gumbova za davanje takta i traţenje k-te konfiguracije ne smiju biti aktivni dok je davanje
takta automatsko, bitno je negdje u aplikaciji nekako pratiti postavke naĉina davanja takta.
Gumbom takt:auto u alatnoj traci korisnik moţe prebacivati s jednog naĉina davanja takta na
drugi. Da bi gumb ispravno mijenjao naĉine davanja takta na korisnikov klik, mora nekako
znati koji naĉin davanja takta je trenutno postavljen. Sliĉnu funkciju ima i podatkovni ĉlan
simActive koji je isto logiĉkog tipa. SimActive prati da li je korisnik poĉeo simulaciju ili ne.
void MainWindow::goForth()
{
int row, column, move, tapeCell;
QString cSymbol, cState, next;
QStringList triplet;
QModelIndex index;
QString quintuplet;
U funkciji deklariramo pomoćne varijable. Row i column sluţe za odreĊivanje ćelije
funkcionalne sheme iz koje aplikacija uzima trojku. Move sluţi za matematiĉko odreĊivanje
pomaka, a tapeCell pohranjuje oznaku stupca u kojem se nalazi glava za ĉitanje i pisanje.
CSymbol, i cState pohranjuju trenutni par, a next pohranjuje QString dobavljen iz odreĊene
ćelije koji predstavlja trojku. Next nakon dobavljanja iz funkcionalne sheme razlamamo u
triplet radi razluĉivanja pomaka od idućeg stanja i izlaznog simbola. Index se koristi pri
odreĊivanju indeksa iduće ćelije, a quintuplet predstavlja zapis takta.
16
Korisnik prije poĉetka simulacije bira poĉetnu ćeliju trake. Ima i mogućnost biranja
trenutnog stanja putem padajućeg izbornika. Ako je uĉitan QString " ", ulazni simbol se
pohranjuje kao "b". Tijekom traţenja trojke, aplikacija traţi ulazni simbol u QStringListu
symbols u kojem je prazni znak zabiljeţen kao "b".
cSymbol=ui->tableWidget_2->currentItem()->text();
if(cSymbol==" ")
{
cSymbol="b";
}
cState=ui->comboBox->currentText();
column=states.indexOf(cState);
row=symbols.indexOf(cSymbol);
next=ui->tableWidget->item(row, column)->text();
ui->tableWidget->setCurrentCell(row, column);
Nakon uĉitavanja para, aplikacija izvlaĉi trojku iz odreĊene ćelije funkcionalne sheme i
postavlja ju kao trenutno odabranu ćeliju. To omogućava korisniku da tijekom simulacije
prati koja trojka se toĉno izvršava što moţe pomoći pri osmišljavanju logiĉke funkcije
Turingovog stroja.
Ako je uĉitana trojka prazna, aplikacija javlja korisniku da odreĊenom paru nije
pridruţena trojka. Ako trojka nije prazna, next se funkcijom triplet = next.split(", ") razdvaja
na tri QStringa koja se spreme u triplet. Aplikacija zatim ĉitanjem svakog QStringa odreĊuje
odvijanje trenutnog takta. Budući da je trojka spremljena u uniformiranom formatu "qn, s, m",
gdje je qn trenutno stanje, s ulazni simbol, a m pomak, aplikacija moţe bez problema odrediti
koji QString znaĉi što. Tako je prvi QString u tripletu (triplet.at(0)) uvijek iduće stanje, drugi
je izlazni simbol, a treći je pomak.
if(triplet.at(0)=="qF")
{
QMessageBox message;
message.setText("Stroj je došao u konaĉno stanje!");
message.setWindowTitle("SiTuS");
message.exec();
simActive=false;
17
autoStep=false;
timer->stop();
}else
{
ui->comboBox->setCurrentText(triplet.at(0));
Aplikacija svaki put provjeri da li je ušla u konaĉno stanje usporeĊivanjem prvog
QStringa tripleta sa QStringom "qF". Ako je iduće stanje zaista konaĉno, aplikacija obustavlja
simulaciju i obavještava korisnika o ulasku u konaĉno stanje. Inaĉe, aplikacija kao trenutnu
vrijednost padajućeg izbornika postavlja iduće stanje. Padajući izbornik ne sluţisamo koa
mogućnost ruĉnog postavljanja trenutnog stanja, već i kao indikator tog istog.
Pomak se raĉuna izrazom move=shifts.indexOf(triplet.at(2)) - 1; kojim se dobiva
cjelobrojna vrijednost iskoristiva za odreĊivanje indeksa iduće ćelije trake. Oznake pomaka
su u QStringListi poredane ovako: "L", "N", "D". Njihovi indeksi su, redom: 0, 1, 2. Ako od
svakog oduzmemo 1, dobivamo -1, 0, 1, što odgovara pomaku ulijevo, izostanku pomaka i
pomaku udesno kretanjem po indeksima stupaca QTableWidgeta koji predstavlja traku.
index=ui->tableWidget_2->currentIndex();
tapeCell=index.column();
if(tapeCell==ui->tableWidget_2->columnCount()-2) //ako je blizu desnog ruba
{
ui->tableWidget_2->insertColumn(ui->tableWidget_2->columnCount());
ui->tableWidget_2->setItem(0, ui->tableWidget_2->columnCount()-1, item);
ui->tableWidget_2->setCurrentCell(0, tapeCell+move);
//dodaj ćeliju desno
}else
if((tapeCell+move)<0) //ako je u prvoj ćeliji i miĉe se ulijevo
{
ui->tableWidget_2->insertColumn(0);
QTableWidgetItem *item = new QTableWidgetItem();
item->setTextAlignment(Qt::AlignCenter);
QFont *font = new QFont();
font->setPointSize(30);
//dodaj ćeliju slijeva
item->setFont(*font);
18
item->setText(" ");
ui->tableWidget_2->setItem(0, 0, item);
ui->tableWidget_2->setCurrentCell(0,0);
}else
{
ui->tableWidget_2->setCurrentCell(0, tapeCell+move);
}
Budući da aplikacija simulira Turingove strojeve sa trakama koje su beskonaĉne duljine
s obje strane, nuţno je da aplikacija provjerava bliţi li se rubu trake te da ju produlji ako je to
potrebno.
stepCount++;
currentConfiguration++;
quintuplet=
QString("%1.takt:(%2,%3)-->(%4)").
arg(stepCount).arg(cState).arg(cSymbol).arg(triplet.join(", "));
Budući da je takt završen u ovom trenutku, aplikacija povećava vrijednosti stepCount i
currentConfiguration te formira zapis takta koji zatim sprema u QListWidget koji sluţi kao
zapisnik taktova.
19
tableWidget_2
Korisnik
tableWidget
MainWindow
listWidget
"Ovo je početna pozicija"
"Simuliraj!"
"Koji je ulazni simbol?"
<ulazni simbol>
"Koje je trenutno stanje?"
"Koja trojka odgovara ovom paru?"
<qn, s, m>
<iduće stanje>
<pomak>
<izlazni simbol>
<zapis takta>
Slika 2.: MSC dijagram razmjene poruka tijekom ručno danog takta
Na Slici 2. je opisana cijela razmjena poruka tijekom jednog ruĉno danog takta.
TableWidget_2 je ime objekta koji predstavlja vanjsku memoriju, a listWidget je ime objekta
koji predstavlja zapisnik taktova.
if(ui->radioButton_2->isChecked())
{
timer=new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(goForth()));
timer->start(1500);
ui->comboBox->setEnabled(false); //<--onemogućuje padajući izbornik
this->autoStep=true;
//koji sluţi kao indikator i biraĉ trenutnog stanja
RadioButton_2 je gumb kojim korisnik na poĉetku odabire automatsko davanje takta.
Ako je gumb stisnut, stvara se objekt klase QTimer koji u zadanim intervalima emitira signal
timeout(). Jedan takt ovdje zadanog tajmera traje 1500 milisekundi i njegov timeout() signal
povezan je sa funkcijom goForth() koja je definirana kao slot.
20
3.4. Prikaz k-te konfiguracije
Za prikaz k-te konfiguracije Turingovog stroja, stroj mora odraditi k-1 taktova. Korisnik
u bilokojem trenutku dok je davanje takta ruĉno moţe zatraţiti od aplikacije prikaz k-te
konfiguracije. Moţe zatraţiti prikaz konfiguracije nakon trenutne, a moţe i zatraţiti
konfiguraciju prije trenutne. Za sluĉaj kada aplikacija mora ići unazad, osmišljena je funkcija
goBack() koja je ujedno i slot.
QString step= ui->listWidget->item(stepCount)->text();
int remove=step.indexOf("(");
step.remove(0, remove+1);
remove=step.indexOf(")");
step.replace(remove,7,", ");
step.remove(")");
Funkcija iz zapisnika taktova izvuĉe zapis takta koji mora obrnuti. Zatim ga sa nekoliko
operacija oblikuje u format "qn, s, m, qm, z" gdje je qn trenutno stanje, s ulazni simbol, m
pomak, qm iduće stanje, a z je izlazni simbol. Nakon oblikovanja, aplikacija naredbom
quintuplet = step.split(", "); razlomi zapis takta u QStringListu quintuplet iz koje zatim izvlaĉi
informacije potrebne za preokretanje takta. Ulazni simbol uĉitan u ovom taktu postaje izlazni
simbol, trenutno stanje postaje iduće, a pomak se mnoţi sa -1. Aplikacija takav takt izvrši kao
i inaĉe, s time da smanji umjesto da poveća stepCount i currentConfiguration tako da
aplikacija moţe toĉno pratiti u kojem je taktu.
Prikaz k-te konfiguracije Turingovog stroja generira funkcija getConfiguration(); koja
dijaloškim okvirom zatraţi korisnika da unese broj konfiguracije koju ţeli vidjeti. Odabrani
broj se sprema u varijablu a. Ovisno o odnosu varijable a i vrijednosti currentConfgurationa,
funkcija odabire da li će pozvati funkciju goBack() ili goForth(). Ako korisnik ţeli ići naprijed
kroz simulaciju, tj. ţeli vidjeti konfiguraciju koja dolazi nakon trenutne, aplikacija mora ići
naprijed, stoga u tom sluĉaju poziva funkciju goForth(). U suprotnom sluĉaju, aplikacija zove
funkciju goBack. Ako korisnik zatraţi pregled konfiguracije koja u tom trenu već jest
prikazana, aplikacija izlazi iz tog bloka naredbi.
if(a>currentConfiguration)
{
for(int i = currentConfiguration; i<a; i++ )
{
21
goForth();
}
}else
if(a<currentConfiguration)
{
for(int i =currentConfiguration; i>a;i--)
{
goBack();
}
currentConfiguration=a;
Kada završi sa iteriranjem, aplikacija broj traţene konfiguracije postavi kao broj
trenutne konfiguracije. Simulator u svakom trenutku mora znati u kojem je taktu i koju
konfiguraciju trenutno prikazuje.
4. RASPRAVA
Programsko rješenje problema simuliranja rada Turingovog stroja predstavljeno ovim
radom nije jedino moguće rješenje. Jednom problemu se moţe pristupiti na nekoliko naĉina, a
ovaj problem nije izlika. Pristup korišten pri osmišljavanju ovog rješenja vodi se
proceduralnom paradigmom programiranja. Proceduralno programiranje odvaja podatke od
operacija nad njima i svodi se na slanje podataka odreĊenim funkcijama12. Iako ovo rješenje
koristi klase i objekte, u suštini je proceduralno programirano. Od šest izvedenih klasa
korištenih u ovom rješenju, samo MainWindow se moţe iole gledati kao objedinjenje
podataka i procedura nad njima budući da su ostale klase pomoćne i sluţe samo kao produţeci
procedura definiranih u klasi MainWindow. Rješenje se svodi na procedure kojima se pristupa
i manipulira podacima bez pokušaja dizanja koncepta na višu razinu.
Objektno orijentirano programiranje se ĉesto spominje kao bolji pristup od
proceduralnog zbog svoje fleksibilnosti, nelinearnosti i općeg pogleda na probleme. Dok
proceduralno programiranje za svaki tip podataka nalazi drukĉije rješenje, objektno
orijentirano programiranje pokušava objediniti podatke i metode nad njima u klase koje se
onda proširuju nasljeĊivanjem i polimorfizmom13. Ovo rješenje kombinira dinamiĉno
12
13
http://ocw.utm.my/file.php/42/01PPvsOOP-edit15Feb13.pdf (18.11.2014.)
http://www.virtuosimedia.com/dev/php/procedural-vs-object-oriented-programming-oop
22
korištenje objekata sa proceduralnim pristupom problemu i ne moţe se nazvati niti ĉisto
proceduralnim, niti ĉisto objektno orijentiranim rješenjem, ali oĉito je koji pristup je
dominantan.
Objektno orijentirano rješenje bi se moglo izvesti tako da se trojke i parovi
implementiraju kao objekti koji nadograĊuju jedan drugog, ili da se ĉak spoje u jedan objekt
koji bi predstavljao cijelu petorku. U tom sluĉaju, funkcionalna shema bi se mogla izvesti
MVC programiranjem. Osmislio bi se podatkovni model prilagoĊen spremanju objekata i
slanju
relevantnih
atributa
drugim
pogledima
koji
bi
se
izveo
kao
podklasa
QAbstractTableModel. Ako bismo kao osnovni objekt uzeli petorku, mogli bismo
funkcionalnu shemu i zapisnik taktova izvoditi iz istih podataka razliĉitim pogledima. Bilo bi
nuţno implementirati i specifiĉne delegate, barem za funkcionalnu shemu.
Iako se objektno orijentirani pristup ĉesto promovira kao najbolji pristup programiranju,
on nije uvijek primjeren pristup problemu. Objektno orijentirano programiranje je korisno
kada se problem sastoji od koncepata koji su apstrakcija stvarnih objekata. Osobe, vozila,
poduzeća i sliĉno se ne mogu svesti na jedan string kojim se jednostavnim manipulacijama
moţe doći do rješenja problema. Iako bi se rješenje problema simuliranja Turingovog stroja
itekako elegantno moglo riješiti objektno orijentiranim programiranjem, pristup predstavljen u
ovom radu je jednostavniji. Problematika simuliranja Turingovog stroja nije toliko
kompleksna da bi bila znatno bolje riješena objektno orijentiranim programiranjem, stoga ovo
rješenje nije pristupalo problemu na taj naĉin.
23
5. ZAKLJUČAK
Problematka simuliranja Turingovog stroja je zanimljiva budući da je Turingov stroj
jedan od bitnih koncepata raĉunalnih znanosti. Kao koncept izvršitelja algoritama, predstavlja
matematiĉku apstrakciju ljudskog razmišljanja te je kao takva neizostavan dio svakog iole
informatiĉko usmjerenog obrazovanja. Turing je svojim definiranjem takvih strojeva
dotaknuo vrlo bitno pitanje: pitanje izraĉunljivosti. Postoji beskonaĉno mnogo problema koji
bi se mogli riješiti prikladnim Turingovim strojem, kao što postoji i beskonaĉno mnogo
problema na koje sam koncept Turingovog stroja nije uopće primijenjiv.
Iako je koncept Turingovog stroja vaţan za shvaćanje stvaranja algoritama i razlaganja
tog istog na jednostavne operacije, sam rad stroja je u suštini jednostavan i lagan za
programsku izvedbu, što se i pokazalo rješenjem prezentiranim u ovom radu. Rješenje se
svodi na skup operacija nad jednostavnim podacima ĉiji rezultati su vizualizirani objektnoorijentirano stvaranim grafiĉkim elementima. Iako se moglo izvesti ĉisto objektnoorijentiranim pristupom, za time nije bilo potrebe. Rad Turingovog stroja se svodi na
automatizirano ĉitanje i pisanje što je programski vrlo jednostavno izvesti.
Rješenje predstavljeno ovim radom nije jedino rješenje problematike simuliranja rada
Turingovog stroja uz programibilnost logiĉkog polja i mogućnost unošenja razliĉitih
informacija za obradu razliĉitim Turingovim strojevima, ali je dovoljno jednostavno i stabilno
da bi se moglo smatrati prikladnim. Rješenje sadrţi sve osnovne funkcionalnosti definirane
zahtjevima problematike, što ga ĉini dobro izvedenim simulatorom Turingovog stroja.
24
6. POPIS LITERATURE
Knjige:
Jukić, O., Špoljarić, M. (2010): Uvod u graĊu raĉunala. Virovitica, VŠMTI
Članci:
Turing, A. M. (1936): On Computable Numbers, With An Application To The
Entscheidungsproblem. Proceedings of the London Mathematical Society, Series 2,
vol.42:230-265
Online izvori:
1. http://www.cplusplus.com/reference/string/string/append/ (18.11.2014.)
1. http://ocw.utm.my/file.php/42/01PPvsOOP-edit15Feb13.pdf (18.11.2014.)
2. http://plato.stanford.edu/entries/turing-machine (18.11.2014.)
3. http://qt-project.org/doc/qt-4.8/qdatastream.html (18.11.2014.)
4. http://qt-project.org/doc/qt-4.8/datastreamformat.html (18.11.2014.)
5. http://qt-project.org/doc/qt-4.8/signalsandslots.html (18.11.2014.)
6. http://qt-project.org/doc/qt-5/qfile.html (18.11.2014.)
7. https://qt-project.org/doc/qtcreator-2.5/creator-overview.html (18.11.2014.)
8. http://www.virtuosimedia.com/dev/php/procedural-vs-object-oriented-programming-oop
(18.11.2014.)
25
7. POPIS ILUSTRACIJA
Slika 1.: MSC dijagram procesa ureĊivanja ćelije funkcionalne sheme
Slika 2.: MSC dijagram razmjene poruka tijekom ruĉno danog takta
26