Invarianter, +lstander og li1 mer seman+kk INF1010 14.april 2016 Stein Gjessing April 13, 2016 1
Invariant (= Invariant +lstandspåstand) Vi har se3 flere ganger at det er svært nyjg å formulere +lstandspåstander som styrer programmet (neste side). Når du lager en løkke er det all0d en invariant eller 0lstandspåstand som sier hvor langt arbeidet i løkka er kommet Data i et objekt er all0d styrt av en (eller flere) invarianter (konsistensregler, 0lstandspåstander) Tilstandspåstand = engelsk: asser0on 2
Eksempel fra Stein Michaels forelesning 3. mars om lister Tilstandsdiagram. Engelsk: state diagram 3
WIKIPEDIA: Ins0tu3 for informa0kk Invariant (computer science) In computer science, an invariant is a condi0on that can be relied upon to be true during execu0on of a program, or during some por0on of it. It is a logical asser0on that is held to always be true during a certain phase of execu0on. For example, a loop invariant is a condi0on that is true at the beginning and end of every execu0on of a loop...... Programmers o[en use asser0ons in their code to make invariants explicit. Some object oriented programming languages have a special syntax for specifying class invariants. 4
5 Invarianter på data i løkker Eksempel: Finne minste verdi i tabell minsttilnaa Ins0tu3 for informa0kk 0 minsttilnaa inneholder minste verdi i området fra og med tabell [0] til og med tabell[indeks] = Inv(indeks): indeks Induksjons- basis Induksjons- skri3 999
Invarianter på data i løkker Eksempel: Finne minste verdi i tabell // Vi vet ingenting annet enn at tabell [0] til og med // tabell[999] inneholder tall. Vi skal finne det minste int minsttilnaa = tabell[0]; Inv(0) minsttilnaa Ins0tu3 for informa0kk 0 // minsttilnaa inneholder minste verdi i området // fra og med tabell [0] til og med tabell[0] for (indeks = 1; indeks < 1000; indeks ++) { // minsttilnaa inneholder minste verdi i området // fra og med tabell [0] til og med tabell[indeks-1] if (minsttilnaa > tabell [indeks] ) minsttilnaa = tabell[indeks] Inv(indeks) Inv(indeks-1) } // minst TilNaa inneholder minste verdi i området // fra og med tabell [0] til og med tabell[indeks] // Nå er indeks == 1000 // minsttilnaa inneholder minste verdi i området // fra og med tabell [0] til og med tabell[indeks-1] // Da følger: // minsttilnaa inneholder minste verdi i området // fra og med tabell [0] til og med tabell[999]!!!!!!! Hvis Inv(indeks) er sant og vi utfører: indeks ++ så er Inv(indeks-1) sant etterpå! Induksjons- basis Induksjons- skri3 6 999
Invarianter på data i objekter Invariant: Alle dataene vi lagrer ligger i tabell[0] til og med tabell [antall 1] og 0 <= antall <= 1000 Ins0tu3 for informa0kk 0 settinn(x) { if (antall == 1000) return ; antall ++; tabell[antall-1] = x; } antall taut ( ) { if (antall == 0) return null; antall --; return (tabell[antall]); } Overbevis deg (og andre) om at invarianten gjelder initielt og at alle metodene bevarer den!!!!!!!!!!!!!!!!!!!!! 999 Da gjelder den alltid 7
Spesifikasjon av objekters oppførsel (seman+kk) ved hjelp av sekvens av metodekall: Hvis objektet (på forrige side) har hatt følgende sekvens av kall: settinn(7), settinn(4), taut(), settinn(8), settinn(2), settinn(9), taut() Hva returnerer nå neste kall på taut()? Hva returnerer neste kall på taut() om dette var en FIFO-kø?
Invarianter og monitorer Hvordan bevare invarianter på data i objekter når vi ikke har ansvaret alene. Svar: Vi venter o*e på at andre skal gjøre objektets (monitorens) 9lsand hyggeligere. Ins0tu3 for informa0kk <Buffer-data> venter på å komme inn første gang synchronized void setinn(int verdi) If (antall == 1000) vent- 0l: Ikke- Full(); antall++; : no0fy: Ikke- Tom(); synchronized int taut() Venter på at conditions / betingelser / tilstandspåstander skal bli sanne If (antall == 0) vent- 0l: Ikke- Tom(); antall - - ; : no0fy: Ikke- Full(); En monitor (et objekt) Invariant: Alle dataene vi lagrer ligger i tabell[0] til og med tabell [antall 1] og 0 <= antall <= 1000 9
Repe0sjon: Biblioteket java.concurrent: Flere køer av ventende tråder Ins0tu3 for informa0kk Lock laas = new ReentrantLock(); Condi+on ikkefull = laas.newcondi0on(); Condi+on ikketom = laas.newcondi0on(); void se3inn ( int verdi) laas.lock(); try { while (full) ikkefull.await(); // nå er det helst sikkert ikke fult : // det er lagt inn noe, så det er // helt sikkert ikke tomt: ikketom.signal(); } finally { laas.unlock() } int taut ( )..... En kø for hver condi0on- variabel (En kø for hver be0ngelse som må holde før vi gjør en lovlig operasjon på dataene, (dvs. en operasjon som bevarer invarianten)) 10
11
12
13
14