170 likes | 387 Views
Larch: valodas un līdzekļi formālai specifikācijai. Specifikāciju valodu pamati. Larch sistēma: pārskats. Larch: mēģinājums ekvacionālu ADT specifikāciju saistīt ar procedūru interfeisa specifikācijām konkrētās valodās. 2 līmeņu specifikācijas: 1) LSL – Larch Shared Language
E N D
Larch: valodas un līdzekļi formālai specifikācijai Specifikāciju valodu pamati
Larch sistēma: pārskats Larch: mēģinājums ekvacionālu ADT specifikāciju saistīt ar procedūru interfeisa specifikācijām konkrētās valodās. 2 līmeņu specifikācijas: 1) LSL – Larch Shared Language 2) valodas procedūru interfeisa specifikācijai konkrētām programmēšanas valodām: LCL, LM3, Larch/C++ LSL: ADT ekvacionālā specifikācija ar vājo semantiku; LP: Larch Prover, līdzeklis specifikāciju īpašību analīzei. Interfeisa specifikācijas:requires, ensures predikāti, modifies sarakstsIzmanto specifikācijā LSL definētos jēdzienus Literatūra:J.Guttag, J.Horning – pieejama bibliotēkā un elektroniski caur kursa resursu lapu.
Larch Shared Language: piemērs Trait: specifikācijas pamatvienība, definē loģisku teoriju. Table: traitincludes Integerintroduces new: → Tab add: Tab,Ind,Val → Tab _ _: Ind,Tab → Bool isEmpty: Tab → Bool lookup: Tab,Ind → Val size: Tab → Intasserts i,i1:Ind, v:Val, t:Tab (i new); i add(t,i1,v) == i=i1 i t; lookup(add(t,i,v),i1) == if i=i1 then v else lookup(t,i1); size(new) = 0; size(add(t,i,v)) == if i t then size(t) else size(t) + 1 isEmpty(t) == size(t) = 0
LSL: semantika Traita teorija: visas formulas, kas izvedamas kā loģiskās sekas no dotajiem apgalvojumiem (Apgalvojuma neesamība nepievieno nekādas papildus zināšanas – sal. ar iniciālo semantiku). Loģiskā valoda: vairāksortu pirmās kārtas loģika ar vienādību(kvantori x, bet nevis P vai f, kur P-predikāta, f-funkcijas vārds). (Pastāv citi specifikāciju formālismi, kas balstās uz augstākas kārtas loģikām: HOL, PVS, etc.) Papildinājumi pirmās kārtas loģikai LSL valodā (‘meta-apgalvojumi’): generated by, partitioned by. Traits var būt daļēji definēts, pēc tam papildināts (teorija tiek bagātināta). Nepretrunība: nav true == false.
LSL traitu struktūra (1): Boolean, Conditional Boolean: traitSk. LSL Handbookintroduces true, false: → Bool _ : Bool → Bool __, __, __: Bool, Bool → Boolasserts Bool generated by true, false b: Bool true = false, false = true, true b = b, false b = false, etc.implies AC(,Bool), AC(,Bool), Involutive(,Bool), Transitive( for ○, Bool for T), etc. Conditional (T): traitintroduces if_then_else_: Bool,T,T → Tassertsx,y,z: T if true then x else y == x; if false then x else y == yimplies b:Bool, x:T if b then x else x == x Boolean, Conditional: iebūvētie traiti, izmanto daudzos citos
LSL traitu struktūra (2): Integer Integer(Int): traitincludesDecimalLiterals (Int for N);TotalOrder (Int)introduces 0,1: → Int succ, pred, -_, abs: Int → Int _+_, _-_, _*_, div, mod, min, max: Int,Int → Intasserts Int generated by 0, succ, predx,y: Int succ(pred(x)) = x; pred(succ(x)) = x; -0 == 0; abs(x) = max(-x,x); x+0 == x; y>0 mod(x,y) + (div(x,y) * y) = x; y>0 mod(x,y) ≥ 0;y>0 mod(x,y) < y; etc.impliesAC(+,Int), AC(*,Int), AC(min,Int),RingWithUnit(Int for T); Int generated by 1,+,-:Int→Int
LSL: augstākas kārtas konstrukcijas (1) Tab generated by new, add Iespējams lietot ģeneratoru indukciju, lai pierādītu sorta Tab objektu īpašības: t:Tab (size(t) ≥ 0) Bāze: size(new) ≥ 0 Solis: t:Tab, i:Ind, v:Val(size(t) ≥ 0 size(add(t,i,v)) ≥ 0) [“Pierādījumā” pieņemam veselo skaitļu īpašības kā zināmas] t:Tab, i:Ind (i t size(t) > 0) Bāze: i:Ind (i new size(new) > 0) Solis: t:Tab, i1:Ind, v1:Val(i:Ind (i t size(t) > 0) (i:Ind (iadd(t,i1,v1) size(add(t,i1,v1))>0))) Šādi pierādītās īpašības iekļaujas traita teorijā. Vienam sortam var būt vairāki ģeneratoru komplekti (sk. Integer).
LSL: augstākas kārtas konstrukcijas (2) Tab partitioned by , lookup Divi objekti ir vienādi, ja tie nav atšķirami, izmantojot norādītās operācijas – novērotājus. “Duālā konstrukcija” attiecībā pret generated by. i:Ind (i t1 = i t2) i:Ind (lookup(t1,i1)) = lookup(t2,i1)))-----------------------------------------t1 = t2 Operācijas addkomutativitāte (pievienojot to pašu vērtību): t:Tab, i,i1:Ind, v:Val(add(add(t,i,v),i1,v)=add(add(t,i1,v),i,v)) Jāpierāda divas lietas:i2:Ind (i2add(add(t,i,v),i1,v) = i2add(add(t,i1,v),i,v))i2:Ind (lookup(add(add(t,i,v),i1,v),i2) = lookup(add(add(t,i1,v),i,v),i2)) Īstai “dualitātei” ar generated by: rekursijas iespējaspartitioned by pielietojumā - ? Ko-indukcijas princips (sk. valodā OBJ).Cik tālu iespējams šeit? Cik tālu šeit vajadzīgs?
LSL: specifikācijas “korektība” Specifikācijās kļūdas iespējamas tāpat, kā programmās. Kā pārbaudīt, vai LSL specifikācijā nav “kļūdas”? Specifikācijas “korektība” – ar kādu standartu salīdzināt? 3 veidu īpašības, ko attiecībā uz LSL specifikācijām var pārbaudīt, izmantojot LP (Larch Prover): • Konsistence: starp teorijas formulām nav formulas true == false; • Nepieciešamās sekas (theory containment): konkrēti apgalvojumi, kas traita specifikācijā norādīti aiz implies klauzulas; • Relatīvā pilnība: traita fragmenta (operatoru kopuma) relatīvās pilnības prasību atklāti specificē ar converts klauzulu:implies converts isEmptyapgalvo, ka traita aksiomas pilnībā definē isEmpty (ja citu operatoru interpretācijas ir fiksētas, tad ir tikai viens iespējams isEmpty operators, kas apmierina aksiomas) • Traitā Tablenevar rakstīt implies converts isEmpty, lookup, jo lookup(new,i) nav definēts • Var rakstīt: implies converts isEmpty, lookupexempting i: Ind (lookup(new,i))
LSL: kas netiek pateikts? Table: trait … etc. • Kā tabulas tiek attēlotas/realizētas ar programmēšanas valodas konstrukcijām? • Algoritmi darbam ar tabulām -? • Kādas procedūras darbam ar tabulām implementējamas? • Kas notiek tad, ja tabulā meklē vērtību pēc indeksa, kas tabulai nepieder? 1.,2. – implementācijas jautājumi. 3.,4. – jautājumi, kas risināmi interfeisa specifikācijā.
Interfeisa specifikācijas - pārskats • “Otrais” specifikācijas līmenis (LSL – “pirmais”); • Definē interfeisu (signatūra, ieejas – izejas predikāti) starp programmu komponentēm noteiktā programmēšanas valodā (C, Modula3, C++, u.c.); • Rakstītas specifiskā Larch sistēmas interfeisa valodā konkrētajai progr. valodai (LCL, LM3, Larch/C++, u.c.); • Izmanto programmas stāvokļa jēdzienu (attēlojumu no atmiņas šūnām uz vērtībām); • Izteiktas programmēšanas valodas tipu un funkciju terminos; • Izmanto LSL traitu definētos sortus un operācijas (katrs interfeisa spec. tips ir balstīts uz noteiktu LSL sortu).
Procedūras specifikācija Procedūras galvene (header): nosaka argumentu un rezultāta tipus; Procedūras darbības specifikācija: requires reqP modifies modList ensures ensP reqP – nosaka ierobežojumus uz programmas stāvokli, t.sk. parametru vērtības procedūras izsaukuma brīdī modList – saraksts ar šūnām, kuru vērtības programmai ir atļauts mainīt (ja šis saraksts ir tukšs, programma nedrīkst mainīt neko) ensP – saista procedūras sākuma un beigu vērtības gadījumā, ja procedūra korekti izsaukta. Mainīgo (šūnu) vērtības noteiktos stāvokļos: x^, y^ – sākuma stāvoklī,x’, y’ – beigu stāvoklī (sal. ar i/o specifikāciju ar Hoara 3-niekiem). Ja reqPpatiess programmas izsaukuma brīdī, tad: • procedūra apstāsies; • izmaiņas stāvoklī nebūs notikušas ārpusmodList; • ieejas/izejas dati būs saistīti arensP. Klienta un programmētāja atbildības sadalījums.
LCL: interfeisa specifikācijas valodai C mutable type table; uses Table (table for Tab, char for Ind, char for Val, int for Int); constant int maxTabSize; table table_create(void) {ensures result = new fresh(result);} bool table_add(table t, char i, char c) {modifies t;ensures result = (size(t^) < maxTabSize i t^) (if result then t’=add(t^,i,c) else t’=t^);} char table_read(table t, char i) {requires i t^;ensures result = lookup(t^,i);} • Matemātiskas vērtības (i,c) un mainīgie, kas apzīmē šūnas (t); • t’ un t^ piemēri (sākuma un beigu vērtības); • specifikācija, kas saista šeit definētās konstrukcijas ar konstrukcijām no LSL līmeņa (new, add, lookup, ).
Implementācija: valodā C #include “bool.h” #define maxTabSize (10) typedef struct {char ind[maxTabSize]; char val[maxTabSize]; int next;} tableRep; typedef tableRep * table; table table_create(void) { table t;t = (table) malloc(sizeof(tableRep));if (t==0) {printf(“Malloc failed in table_create\n”); exit(1);}t->next = 0; return t;} bool table_add(table t, char i, char c) { int j;for (j=0; j < t->next; j++) if (t->ind[j] == i) {t->val[j]=c; return TRUE;}if (t->next == maxTabSize) return FALSE;t->val[t->next++] = c; return TRUE; } char table_read(table t, char i) { int j;for (j=0; TRUE; j++) if (t->ind[j] == i) return t->val[j];}
Specifikācijas un implementācijas sasaiste Specifikācija: valodā LCL, izmanto abstraktos jēdzienus no LSL (abstraktās table vērtības, new, add, lookup, …) Implementācija: valodā C, konkrēta reprezentācija tipa table vērtībām (table – norāde uz struktūru, kurā ir indeksu un vērtību masīvi ..) Kā definēt C programmas atbilstību LCL specifikācijai? Specifikācijas predikāti un implementācija dažādās valodās … A – abstraktais datu apgabals, C – konkrētais datu apgabals a: C → A, abstrakcijas funkcija R = {c C | a A: a = a(c)} – reprezentācijas invariants Vienai abstraktai vērtībai var atbilst vairākas konkrētas vērtības (jāuzmanās ar vienādības definējumu konkrētajā tipā ..)
Specifikācijas un implementācijas sasaiste (2) A – abstraktais datu apgabals, C – konkrētais datu apgabals a: C → A, datu abstrakcijas funkcija R = {c C | a A: a = a(c)} – datu reprezentācijas invariants St(C) = Fun(Var,C); St(A) = Fun(Var,A); - stāvokļu kopas a: St(C) → St(A), stāvokļu abstrakcijas funkcija R St(C) – stāvokļu reprezentācijas invariants s, s’ St(C) - konkrētie stāvokļi, a(s), a(s’) St(A) – atbilstošie abstraktie stāvokļi s R a(s) sat reqP------------------------------------------------------------------------ s’ : s →Ps’ s’ R <a(s), a(s’) > sat ensP Katra procedūra: 1) saglabā reprezentācijas invariantu; 2) ir pilnā nozīmē korekta pret datu abstraktajām vērtībām
Specifikācijas un implementācijas sasaiste (3) t = <ind,val,next> - konkrētā vērtība Abstrakcijas funkcija: toTab (<ind,val,next>) ==if next = 0 then emptyelse insert(toTab(<ind,val,next-1>), ind[next],val[next]) Reprezentācijas invariants: 0 ≤ t->next t->next ≤ maxTabSize i,j:int(0 ≤ i i < j j < t->next) (t->ind)[i] ≠ (t->ind)[j]