Metateorija programskih jezikov#
Vsak programski jezik ima svojo teorijo, torej pravila, ki formalno opisujejo, kako se programi izvajajo ali določajo, katere programe smatramo za veljavne. Od teorije so odvisne lastnosti programskega jezika, na primer to, da se veljavni programi lahko vedno uspešno izvedejo, ali pa to, da je rezultat enolično določen. Lastnostim programskega jezika, ki sledijo iz dane teorije, pravimo metateorija. Za primer si oglejmo že znani programski jezik IMP.
Teorija#
Sintaksa#
Del teorije IMPa smo že srečali, in sicer njegovo abstraktno sintakso, ki jo tu le ponovimo:
Operacijska semantika#
V sintaksi uporabljamo besede in simbole, ki nakazujejo na pomen posameznih izrazov in ukazov, ampak to pomena formalno ne podaja. Najprej podajmo dinamično oziroma operacijsko semantiko, ki določa, kako se programi izvajajo. To smo enkrat že storili prek programa v OCamlu, zdaj pa to storimo še v jeziku matematike.
Začnimo z aritmetičnimi izrazi, ki naj bi predstavljali cela števila. Ker v aritmetičnih izrazih lahko dostopamo do lokacij
Na primer, za stanje
Če aritmetični izraz
Podobno podamo relacijo
Pri ukazih so pravila malo drugačna, saj za razliko od izrazov ne predstavljajo nobenih vrednosti, temveč je njihov končni rezultat spremenjeno stanje. Poleg tega se zaradi morebitnih neskončnih zank izvajanje ukazov ne konča vedno. Zaradi slednjega bomo pomen ukazov podali prek semantike malih korakov
Vidimo, da takrat, kadar pogoj v logičnem ukazu predstavlja resnico, v naslednjem računskem koraku začnemo izvajati prvo, sicer pa drugo vejo, obe v nespremenjenem stanju. Podobno ločimo dva primera pri zankah. Če je pogoj resničen, izvedemo telo, ki mu sledi še ena ponovitev zanke, sicer pa zaključimo izvajanje. Pri zaporednem izvajanju korak naredimo v prvem ukazu in ustrezno spremenimo stanje. Če je prvi ukaz končal z izvajanjem, začnemo izvajati drugi ukaz. Pri prirejanju spremenimo stanje in zaključimo izvajanje. Ukaz
S tako podanimi pravili lahko pokažemo, da je semantika ukazov deterministična. Če velja tako
Določanje veljavnih programov#
Želeli bi pokazati, da vsak program lahko vedno naredi korak, vendar to ni res, saj lahko nekateri programi dostopajo do lokacij, ki v stanju niso nastavljene. Da bi se tem primerom izognili, smo v implementaciji napisali funkcijo check
, ki je program preverila, preden ga je začela izvajati. Matematično pa bomo to zopet podali z induktivnimi relacijami. Relacijo
Podobno to storimo za logične izraze:
Pri ukazih je situacija malenkostno drugačna, saj spreminjajo stanje in s tem tudi množico veljavnih lokacij. Tako podamo relacijo
Izrek o varnosti#
Eden glavnih izrekov, ki jih običajno dokažemo, ko obravnavamo metateorijo programskega jezika, je izrek o varnosti. Ta govori o tem, da se veljavni programi lahko uspešno izvedejo. Razdeljen je na dva dela:
napredek, ki pove, da veljaven program bodisi lahko naredi še en računski korak bodisi je uspešno zaključil izvajanje,
ohranitev, ki pove, da veljaven program po enem računskem koraku ostane veljaven.
Oba skupaj povesta, da vsak veljaven program izvaja računske korake do točke, ko zaključi izvajanje, ali pa teče v neskončnost. Oglejmo si vsakega posebej.
Napredek#
Naj bo
Za vsak aritmetični izraz
, za katerega velja , obstaja , da velja .Za vsak logični izraz
, za katerega velja , obstaja , da velja .Za vsak ukaz
in množico lokacij , za katera velja :bodisi obstajata ukaz
in stanje , da velja ,bodisi velja
.
Dokaz#
Vsak del dokažemo z indukcijo.
Obravnavajmo vsa pravila, po katerih smo lahko prišli do zaključka
.Če smo uporabili pravilo
, potem je , torej po predpostavki obstaja , da velja , zato velja tudi .Če smo uporabili pravilo
, potem velja .Če smo uporabili pravilo
, potem po indukcijski predpostavki obstajata in , da velja in . Tedaj velja tudi . Podoben dokaz uporabimo še v primerih in .
Obravnavajmo vsa pravila, po katerih smo lahko prišli do zaključka
.Če smo uporabili pravilo
, potem velja . Podoben dokaz uporabimo še v primeru .Če smo uporabili pravilo
, potem po poprej dokazani trditvi obstajata in , da velja in . Ker velja bodisi bodisi , vedno obstaja , da velja . Podoben dokaz uporabimo še v primerih in .
Obravnavajmo vsa pravila, po katerih smo lahko prišli do zaključka
.Če smo uporabili pravilo
, potem po prejšnji trditvi obstaja , da velja . Če je , potem velja , če pa je , pa velja . V obeh primerih torej lahko naredimo korak.Podoben dokaz lahko naredimo v primeru
.Če smo uporabili pravilo
, po indukcijski predpostavki za velja:bodisi obstajata ukaz
in stanje , da velja , zaradi česar velja tudi ,bodisi je
, zaradi česar velja .
V obeh primerih torej lahko naredimo korak.
Če smo uporabili pravilo
, potem po prejšnji trditvi obstaja , da velja , zato velja tudi .Če smo uporabili pravilo
, potem velja .
Opazimo lahko, da v dokazu napredka za ukaze ne uporabimo druge množice lokacij
Varnost#
Vzemimo ukaza
je stanje
definirano na vseh lokacijah iz množice ,velja
, tervelja
.
Tedaj obstaja množica lokacij
Pozorni bodimo na dejstvo, da množica lokacij