Programmeringsmetodik. (en introduktion till formella metoder)
|
|
- Helena Jonasson
- för 8 år sedan
- Visningar:
Transkript
1 Programmeringsmetodik (en introduktion till formella metoder) J. von Wright Kurskompendium, våren Att tala om program och deras egenskaper Programmeringsmetodik handlar om hur man kan skriva program som fungerar som avsett. Vi vill uppfatta program som matematiska objekt som kan diskuteras, jämföras och manipuleras. Vi koncentrerar oss på imperativa program som arbetar genom att steg för steg göra ändringar i programvariabler, via tilldelningar som struktureras med villkorskonstruktioner, iterationer, procedurer mm. Exempel på imperativa programmeringsspråk är C, Java och Pascal. 1.1 Programsystem och programfragment Klassisk programanalys handlar i första hand om sekventiella input/output-program, dvs program som beräknar ett sluresultat (utdata) på basen av på förhand givna indata. Många av dagens programsystem kan beskrivas som bestående av samverkande interaktiva komponenter. Deras uppgift är att hålla igång en verksamhet snarare än att beräkna ett resultat. Men om man tittar på de byggstenar som sådana system är uppbyggda av så hittar man, längst in, sekventiella programfragment som kan analyseras på traditionell sätt. Sådana programfragment utgörs i olika programmeringsspråk av procedurer, funktioner, metoder mm. Här försöker vi taka om programfragment på ett så allmänt plan som möjligt, oberoende av programmeringsspråk. 1.2 Konkret och abstrakt syntax Syntax handlar om de skrivregler som bestämmer hur uttryck eller satser i ett språk får se ut. Ett språk som skall läsas (tolkas) av en dator följer i allmänhet stränga syntaxregler. En konkret syntax beskriver de teckensträngar som är acceptabla. Detta kan göras med syntaxbeskrivningar, tex enligt BNF (Backus-Naur Form). Vi är här mer intresserade av abstrakt syntax, som beskriver uttryck och programsatser som träd, där en nod motsvarar ett uttryck, med ett subträd för varje deluttryck. Till 1
2 exempel kan uttrycket x + 2 y beskrivas som en addition av två deluttryck, där det vänstra är variabeln x och det högra är en multiplikation av talet 2 och variabeln y. I trädform blir detta + x y 2 Den abstrakta syntaxen skall, som namnet säger, vara abstrakt, dvs bortse från detaljer. Samma abstrakta syntaxträd motsvarar också andra konkreta syntaxer, tex x;2;y + (enligt sk omvänd polsk notation, där semikolon motsvarar enter ). En abstrakt syntax kan beskrivas med en tudelad syntaxbeskrivning, som på många sätt liknar en konkret syntax. Den abstrakta syntaxen beskrivs genom att vi anger syntaktiska kategorier, med ett namn och en metavariabel för varje kategori, och regler: en syntaxregel för varje syntaktisk kategori. Som exempel beskriver vi (något förenklat) uttryck som kan förekomma i ett programmeringsspråk. 1. De syntaktiska kategorierna är heltal (n), variabler v, logiska uttryck b och aritmetiska uttryck e. 2. Reglerna är e ::= n v e + e e e b ::= e = e not b b and b Märk att vi inte ger regler för heltal och variabler. Det kan bero på att de är atomära (variabler) eller att vi inte bryr oss om deras inre struktur (heltal). Reglerna visar hur vi kan bygga korrekta syntaxträd för aritmetiska och logiska uttryck. I praktiken vill vi inte skriva ut syntaxträd, utan vi använder parenteser för att visa strukturen, tex (x =1)and ((x +1)=((y z) + 2)) Med hjälp av regler för precedens (tex att multiplikation går före addition ) och association (tex att en serie additioner utförs från vänster till höger) kan vi minska mängden parenteser, tex x =1and x +1=y z+2 2
3 1.3 Syntaktiska objekt De syntaxträd som den abstrakta syntaxen beskriver är syntaktiska objekt som vi kan tala om och jämföra. Vi kan tex fråga om djupet hos ett syntaktiskt objekt (dvs längden hos den längsta stigen i syntaxträdet). Vi kan fråga om ett uttryck ingår som deluttryck i ett annat (märk tex att inte är ett deluttryck i eftersom multiplikation har högre precedens än addition). Vi kan också bevisa påståenden som handlar om de syntaktiska objekten. Tex i följande syntax (där de syntaktiska kategorierna är atomer a och satser s): s ::= a s seq s kan man visa att i varje uttryck är antalet atomer större än antalet seq. Beviset sker med strukturell induktion, dvs vi visar att det är sant för varje alternativ i syntaxen och i varje delbevis antar vi att påståendet är sant för de deluttryck som ingår. 1.4 Semantik Ett programmeringsspråks semantik handlar om vad program betyder. Den som skriver program måste ha något slags intuitiv bild av vad programmeringsspråkets olika konstruktioner betyder då de exekveras av en dator. Denna intuitiva semantik kan förklaras med hjälp av hur programsatser ändrar på tillståndet, dvs på programvariablernas värden. En mer exakt, formell semantik beskriver programmeringsspråkets betydelse med hjälp av matematisk och logisk notation. Vi återkommer till detta i ett senare avsnitt. 1.5 En enkel programnotation De flesta verkliga programmeringsspråk är så mångsidiga och vildvuxna att de inte lämpar sig som underlag för denna kurs. Dessutom har de ofta syntaktiska egenheter som är omotiverade och inte allmängiltiga, och som gör det svårt att se den underliggande strukturen i en programtext. Därför väljer vi att begränsa oss till en enkel programmeringsnotation som endast innehåller de grundläggande byggstenar som vi vill tala om. Syntaxen för denna notation är S ::= abort skip V := E S ; S if B then S else S fi do B S od där S står för programsatser, V står för programvariabler, E står för uttryck och B för logiska utryck. Några kommentarer till denna syntax är på sin plats: Vi antar att varje programvariabel x har en typ och att vid en tilldelning x := E har uttrycket E samma typ som x. Vi beskriver inte syntaxen för uttryck, utan vi antar att den följer rimliga standarder, för de olika typer som kommer ifråga. Exempel på rimliga uttryck är 2 x y (kan vara av typ num, dvs heltalsuttryck) och x<y(typ bool, dvs logiskt uttryck) Intuitive kan semantiken för denna programnotation beskrivas så här: 3
4 abort är ett misslyckat program - vi vet ingenting om hurudant resultat det ger. Det används för att modellera felsituationer, oändliga loopar mm. skip leder inte till några ändringar i programvariabler (kallas ibland no-op). En tilldelning x := E exekveras så att värdet på uttrycket E beräknas i det aktuella tillståndet och variabeln x får sedan detta värde. Inga andra variabler än x ändras. En sekvens S ; S exekveras så att S exekveras först, och sedan S. En villkorssats if B then S else S fi exekveras så att värdet på uttrycket B (villkorssatsens vakt) först beräknas. Om värdet är true så exekveras S, och om det är false så exekveras S. En loop do B S od exekveras så att värdet på vakten B först beräknas. Om värdet är true så exekveras S (loopens kropp) och sedan beräknas värdet på uttrycket B på nytt, osv. Ett exempel på ett programfragment skrivet i denna notation är var x, y, r : num r := 0 ; do y>0 r:= r + x ; y := y 1 od där vi antar att x, y och r alla är naturliga tal. Variabeldeklarationen i början anger namn och typ för alla variabler som ingår i programfragmentet. Märk att det inte finns skilda in- eller utmatningssatser i vår programmeringsnotation. I stället antar vi att programvariablerna har initialiserats före exekveringen (input) och att de kan avläsas efter att exekveringen avslutats (output), dvs att programfragmentet fungerar som en procedur 1 som får indata och ger resultat via parametrar. I exemplet ovan är x och y tänkta att vara input (värdeparametrar) och r output (resultatparameter). Om vi vill beskriva ett program som ett syntaxträd skall vi notera att tex loopen är en konstruktion med två delar medan if-satsen har tre. Till exempel ger programfragmentet var x, i : num ; a : array[n] of num i := 0 ; j = n ; do i<j if a[i] <xthen i := i +1else j := j 1 fi od 1 Vi använder här konsekvent begreppet procedur för för det som i olika programmeringsspråk kallas tex metod, funktion, procedur eller subrutin. 4
5 följande träd: ; ; := 0 i := while n j i<j if := a[i] <x := i j i +1 j 1 Märk att vi har lämnat uttryck som a[i] <xoch i + 1 ouppdelade, så att trädet inte skall bli alltför stort. 1.6 Multipla tilldelningar Man stöter ofta på situationer där flere variabler skall tilldelas värden som är oberoende av varandra, i den meningen att tilldelningarna lika väl kunde utföras samtidigt. Exempel på detta är initialiseringar av typen i := 1 ; m := a[0] För att göra det enkelt att hantera sådana tilldelningar som kommer efter varandra utökar vi begreppet tilldelning till att omfatta multipel tilldelning, där flere variabler samtidigt tilldelas värden, tex i, m := 1,a[0] som ger samma resultat som de två tilldelningarna ovan. Multipla tilldelningar förekommer inte i vanliga programmeringsspråk, så de skall uppfattas som en abstraktion, något som vi introducerar för att enkelt kunna tala om något som i ett verkligt programmeringsspråk måste uttryckas på något mer komplicerat sätt. Ett exempel på uttryckskraften hos multipla tilldelningar är att vi kan uttrycka swappande enkelt: x, y := y, x 1.7 Grundläggande datatyper Olika programmeringsspråk utgår ifrån olika uppsättningar datatyper och många moderna språk ger också möjligheter att definiera nya komplicerade datatyper för att beskriva 5
6 fenomen och strukturer i verkligheten. Här antar vi en liten men användbar samling datatyper som duger både för konkreta och mer abstrakta exempel. Den booleska dadatypen bool innehåller de två logiska värdena T (sant) och F (falskt). Vi använder logikens notation för logiska operationer ( för och, för eller, för inte, för ekvivalens och för implikation). De naturliga talen num är 0,1,... Märk att vi inte antar någon övre gräns för num. Vi använder den vanliga aritmetikens symboler (med för multiplikation, div för heltalsdivision och mod för resten vid division). Om vi någon gång vill tala om heltal (dvs också negativa tal) använder vi datatypen int, men i praktiken duger num sgs hela tiden. Datatypen list står för listor av element av en och samma typ. Tex är [1, 4, 2, 5] av typen num list. Följande operationer på listor antas bekanta: hd(l) ger första elementet (head) i listan l, tl(l) ger resten då första elementet tagits bort (tail) och x :: l skapar en ny lista med huvud x och svans l. Dessutom kan vi sammanfoga (append) två listor l 1 och l 2 genom att skriva l 2. Skrivsättet [1, 4, 2, 5] är egentligen en förkortning av 1 :: (4 :: (2 :: (5 :: [ ]))) där [ ] är den tomma listan. Mängder bildas med set ochvianvänder vanliga mängdsymboler. Tex betyder x a att x ingårimängden a och a b betyder unionen av mängderna a och b. Slutligen kan vi bilda arraystrukturer (tabeller) med array. Tex betyder a : array[n] of num att a är en array med plats för n naturliga tal (där n kan vara en ospecificerad konstant). Vid behov kan arraystrukturer antas vara obegränsade, och vi skriver då bara tex array of num. Platserna i en array numreras med början från 0 och vi hänvisar till elementet på plats i i arrayn a som a[i]. Vid behov kan vi också tala om ett delområde a[i..j] av en array. 1.8 Samband med riktiga programmeringsspråk Den programmeringsnotation som vi använder här är en abstraktion; den bortser från många av de detaljer som man måste ta hänsyn till då man implementerar program i ett verkligt programmeringsspråk: in- och utmatning, begränsat talområde, minnesutrymme och arraybegränsningar, osv. Genom att arbeta med en abstraktion kan vi koncentrera oss på de uträkningar och datamanipulationer som görs i ett program. Och genom att arbeta med en minimal notation (dvs bara en enda villkorskonstruktion, en enda loopkonstruktion, osv) så behöver antalet regler för hur man drar slutsatser om program inte bli oöverskådligt många. För att kunna tillämpa kunskapen på verkliga programmeringsspråk måste vi i varje fall ha något sätt att jämföra program i de olika notationerna. En enkel översättningsregel till tex Java skulle då kunna innehålla bla följande: := motsvaras i Java av = do B S od motsvaras i Java av while (B) {S} osv. Märk att semikolon i vår notation skiljer åt en programsats från nästa (semikolon skapar sekvens) medan semikolon i Java är en avslutare. I Java finns det alltså också 6
7 ett semikolon efter den sista satsen i ett block eller ett program. I allmänhet rekommenderar man användning av långa variabelnamn som visar vad en variabel står för, men här använder vi oftast korta namn, för att undvika att formler och bevis blir svårlästa. Övningar 1. Rita de abstrakta syntaxträden som motsvarar följande aritmetiska uttryck (antag att multiplikation har högre precedens än addition och att båda associerar till höger): (a) (b) Antag följande syntax för något slags uttryck: e ::= n eope där n står för heltal och op för operatorer. Motivera att följande är sant: i varje uttryck är antalet heltal större än antalet operatorer. 3. Rita det abstrakta syntaxträd som motsvarar följande program(antag att semikolon (;) associerar till höger): x := 3 ; y := 4 ; do x>0 x:= x +1;y:= y +1od. 4. Programfragmentet do y>0 r:= r +x;y := y 1 od exekveras i ett starttillstånd där x =3,y=4ochr= 0. Vad har r för värde när loopen terminerar? 5. Översätt programfragmentet do y>0 r:= r + x ; y := y 1 od till Java. 6. Skriv om följande genom att införa multipla tilldelningar, där det är möjligt: (a) x := x +1;y:= y +1 (b) x := x +1;y:= x +1 (c) x := y +1;y:= y +1 (d) x := y +1;y:= x Denna uppgift handlar om de två enklaste datatyperna num och bool. (a) (b) Antag ett tillstånd där x har värdet 3, y har värdet 5 och f har värdet F. Vad är värdet av följande uttryck: x + y>3 x f (x>y) Antag ett tillstånd där x har värdet 5, y har värdet 3 och f har värdet F. Vilka värden har x, y och f efter att följande tilldelningar utförts: x, y := x + y, x + y f := (x >y) 8. Denna uppgift handlar om listdatatyper. 7
8 (a) (b) (c) Förenkla följande listuttryck: hd(tl([1, 3, 2, 4])) tl([1, 2, 5, 6, 7]) Vi kan definiera en ny funktion över listor genom att säga vad den gör med den tomma listan och vad den gör med en sammansatt lista. Förklara vad funktionen f gör, om f([ ]) = [ ] f(h :: t) = f(t)@[h] Tips: försök beräkna f([1, 2, 3]) steg för steg. Antag att följande regler för append är givna: []@t = t (h :: t)@t = h :: (t@t ) Hur skulle man gå tillväga för att visa att t@[ ] = t gäller för alla listor t? 9. Antag att a är av typen array[n] of num och att i och j är indexvariabler vars värden är tillåtna, dvs högst n 1. (a) Beräkna värdet av följande uttryck, om n är 6, a innehåller (1, 3, 5, 7, 9, 11), och i =2ochj=3: a[i]+a[j]+a[i+j] a[a[j]] + a[a[i]] a[a[j i]] (b) Låt a(i e) betyda den array som uppstår då man ersätter det som finns på plats i i a med e. Omaär som i (a)-uppgiften, vad är då a(2 a[3] + a[4]) (a(1 2))(3 4) 2 Programannotationer Vi skall nu se hur man kan analysera en programtext genom att införa annotationer, dvs påståenden om programmets tillstånd. Avsikten med annotationer är att förklara hur programmet arbetar (dvs varför det åstadkommer det som det är avsett att åstadkomma). 2.1 Tillstånd och programvariabler Programvariablernas värden i en given situation kallas ett tillstånd (eng. state). Exekvering av ett programfragment (tex ett proceduranrop) startar i ett starttillstånd (eng. initial state). Exekveringen kan sedan antingen misslyckas (oändlig loop eller avbrott på grund av fel) eller så terminerar (eng. terminate) den i ett sluttillstånd (eng. final state). 8
9 Ett tillstånd kan alltså beskrivas med en tabell som visar varje programvariabels värde. Antag att vi talar om ett program med programvariablerna x och y (naturliga tal) och b (av logisk typ). Då är (x = 3,y = 2,b = T) ett tillstånd. Ett annat tillstånd är (x = 0,y = 2,b = F). Mängden av alla sådana möjliga tillstånd kallas programmets tillståndsrum (eng. state space). Vi använder ofta σ (lilla sigma) som namn på ett tillstånd och Σ (stora sigma) som namn på ett tillståndsrum. Grafiskt åskådliggör vi tillstånd som punkter och tillståndsrum som mängder: σ Σ 2.2 Tillståndspredikat Ett logiskt uttryck som säger något om ett tillstånd kallas ett tillståndspredikat (eng. state predicate). Ett exempel på ett tillståndspredikat är b x =3 Detta predikat är sant (vi säger också att predikatet gäller) i tillståndet (x = 3,y = 2,b = T) men falskt i tillståndet (x = 0,y = 2,b = F). Allmänt taget beskriver ett predikat en mängd av tillstånd, nämligen de tillstånd där predikatet är sant. Att evaluera ett predikat i ett tillstånd innebär att substituera in programvariablernas värden i predikatet och därefter avgöra dess värde (som blir antingen T eller F). I ett tillståndspredikat får vi använda programvariabler och logikens symboler, men vid behov också andra matematisk-logiska begrepp, förutsatt att vi har förklarat dem tillräckligt detaljerat (tex genom exakta definitioner). I praktiken kommer man långt med klassisk logik, aritmetik och mängdlära, utökad med begrepp som behövs för att hantera tex array-strukturer. Predikat är ordnade enligt styrka. Vi säger att predikatet p är starkare än predikatet q (och q är svagare än p) ifall p q gäller för alla tillstånd, dvs för alla möjliga värden på de olika programvariablerna. Tex är predikatet x 2 starkare än predikatet x>0, eftersom man kan visa att följande är sant: ( x x 2 x>0) Predikaten x = 2 och x = 3 är ojämförbara när det gäller styrka. Ett starkare predikat begränsar tillåtna tillstånd mer än ett svagt. Det starkaste av alla predikat är F medan T är det svagaste. Ett predikat kan uppfattas som em mängd av tillstånd, så att ett predikat p motsvarar alla de tillstånd där p är sant. Att p är starkare än q kan då skrivas p q (dvs p är en delmängd av q), medan p utgör komplementet till p: 9
10 Σ p p 2.3 Att skriva tillståndspredikat Man kan skriva rätt komplicerade tillståndspredikat med exakt matematisk-logisk notation. Tex kan vi uttrycka att en array a[0..n 1] är sorterad som predikatet ( i <n 1 a[i] a[i+ 1]) Märk alltså att tillståndspredikat som talar om program kan innehålla tex kvantifierare ( och ) som inte kan användas i booleska uttryck som ingår i program. Märk också att den bundna variabeln i en kvantifiering kan begränsas som i exemplet ovan; följande är ekvivalenta: ( i <n 1 a[i] a[i+ 1]) och ( i i<n 1 a[i] a[i+ 1]) liksom följande: ( i <n 1 a[i] a[i+ 1]) och ( i i<n 1 a[i] a[i+ 1]) Om vi vill skriva tillståndspredikat som tex talar om att arrays är sorterade så blir det snabbt långt och svårläst. Då kan vi definiera ett nytt begrepp sorted för arrays (och delar av arrays) enligt sorted(a[m..n]) def = ( i m i<n a[i] a[i+ 1]) Efter detta säger sorted(b[0..n 1]) att arrayn b är sorterad (om n är antalet element i b). Definitionen ger oss alltså en möjlighet att skriva korta och klara tillståndspredikat utan att ge avkall på logisk exakthet. 2.4 Annoterad programkod En annotation är en matematisk-logisk kommentar (vanligen ett tillståndspredikat) som skrivs in i programtexten. Avsikten är att visa vad som skall gälla om programmets tillstånd på den plats där annotationen finns. Annotationer skrivs inom klamrar ({...}, eng. braces eller curly brackets), tex var x, y : num x := 1 ; {x =1} y:= x +1 {x=1 y=2} 10
11 Detta är en annoterad version av programmet var x, y : num x := 1 ; y := x +1 Tilläggen inom klamrar är annotationer eller påståenden (eng. assertion) som ger information om programvariablernas värden efter varje programsats. I detta fall är det mycket enkelt att skriva in annotationer, eftersom (a) (b) programmets struktur är mycket enkel, och variablernas startvärden inte spelar någon roll. Ofta har vi någon information om programvariablernas startvärden, dvs vi vet ett förvillkor (eng. precondition). Detta kan då utgöra en startannotation som vi sedan använder för att steg för steg beräkna nya annotationer. Också omviintevetnågot speciellt om en programvariabel kan det vara bra att introducera ett namn på startvärdet, tex x 0 eller X om variabeln heter x. Till exempel kan vi annotera programfragmentet var x, y, z : num if x y then z := x else z := y fi på följande sätt. Först därefter var x, y, z : num {x = x 0 y = y 0 } if x y then z := x else z := y fi, var x, y, z : num {x = x 0 y = y 0 } if x y then {x = x 0 y = y 0 x y} z := x 11
12 else {x = x 0 y = y 0 x<y} z:= y fi, sedan och slutligen var x, y, z : num {x = x 0 y = y 0 } if x y then {x = x 0 y = y 0 x y} z := x {x = x 0 y = y 0 x y z = x} else {x = x 0 y = y 0 x<y} z:= y {x = x 0 y = y 0 x<y z=y} fi, var x, y, z : num {x = x 0 y = y 0 } if x y then {x = x 0 y = y 0 x y} z := x {x = x 0 y = y 0 x y z = x} else {x = x 0 y = y 0 x<y} z:= y {x = x 0 y = y 0 x<y z=y} fi {x=x 0 y=y 0 z=max(x 0,y 0 )} För att programmet skall bli rätt annoterat måste varje annotation kunna motiveras klart och tydligt. I det här fallet har vi gjort ett ganska stort tankehopp i det sista steget mer om det i nästa avsnitt. Programannotering kan också användas för att visa att (och varför) ett program inte fungerar. Om någon tror att vi kan få x och y att byta värden genom att utföra x := y ; y := x så kan följande annoteringar (med lämplig muntlig förklaring) fungera som motargument: 12
13 var x, y : num {x =3 y=5} x:= y ; {x =5 y=5} y:= x {x =5 y=5} Om man vill visa att ett program inte fungerar räcker det med att ge ett motexempel. Här har vi valt startvärden godtyckligt (3 för x och5för y) och sedan fyllt i de följande annotationerna. Slutannotationen visar att x och y inte bytte värden. Annoterad programtext kan göras mer lättläst om man utnyttjar hypertextens möjligheter Automatisk annotering Givet en startannotation kan annotationer beräknas automatiskt för program som inte innehåller loopar. Följande regler är tillräckliga: (a) En regel för skip: {p} skip {p} Denna regel skall tolkas så att om vi har en annotation {p} före en skip-sats så kan vi fylla i samma annotation efter skip. (b) En regel för tilldelning: {p} x := e { x 0 p[x := x 0 ] x = e[x := x 0 ]} där p[x := x 0 ] betyder p med x 0 substituerat för x. (c) En regel för början av en if-sats: {p} if b then {b p} S else { b p} S fi (d) En regel för slutet av en if-sats: if b then S {p} else S {p } fi {p p } 2 På visas ett exempel på blädderbar annotering. 13
14 Man kan använda dessa regler mekaniskt men då måste man ofta förenkla de nya annotationerna, eftersom man annars får uttryck som blir alltför komplicerade för att kunna förstås. Följande exempel illustrerar detta: {x =1 y=z+1} x:= x + y +1 { x 0 x 0 =1 y=z+1 x=x 0 +y+1} Den senare annotationen kan här förenklas till x = y + 2 y = z + 1 (se uppgifterna). Ett annat exempel är den if-sats som vi såg på tidigare: var x, y, z : num {x = x 0 y = y 0 } if x y then z := x {x = x 0 y = y 0 x y z = x} else z := y {x = x 0 y = y 0 x<y z=y} fi {x=x 0 y=y 0 z=max(x 0,y 0 )} Den sista annotationen (efter fi) får vi enligt regeln ovan som disjunktionen av de två annotationerna i if- och else-grenarna. Den är alltså egentligen (x = x 0 y = y 0 x y z = x) (x = x 0 y = y 0 x<y z=y) men detta kan förenklas till x = x 0 y = y 0 z = max(x 0,y 0 ). 2.6 Bakåtannotering Det går bra att annotera små programsnuttar men för större programtexter blir det opraktiskt. Dels är regeln för tilldelningar komplicerad, och annotationerna blir stora och ohanterliga. Men ännu viktigare är att det svårt att veta vilken information i en annotation som är viktig. Ett program är alltid skrivet för ett visst ändamål, så det är naturligt att utgå ifrån vad som borde vara sant i slutet av programmet och sedan annotera programmet bakåt för att se vad som skall gälla i början för att målet skall nås (eller om det är omöjligt). Reglerna för bakåtannotering liknar reglerna för framåtannotering. (a) En regel för skip: {q} skip {q} 14
15 (b) En regel för tilldelning: {q[x := e]} x := e {q} (c) En regel för slutet av en if-sats: if b then S {q} else S {q} fi {q} (d) En regel för början av en if-sats: {(b q) ( b q )} if b then {q} S else {q } S fi Alla dessa regler skall tolkas så att om annotationen q (och q ) efteråt är given så kan vi lägga till de andra annotationerna. Antag som exempel att vi vill bekräfta att följande programfragment byter värden på x och y: var x, y, z : num z := x ; x := y ; y := z Vi låter x 0 och y 0 som vanligt stå för startvärdena på x och y och startar med den önskade slutannotationen {x = y 0 y = x 0 }.Dåvianvänder reglerna ovan får vi följande samling annoteringar {y = y 0 x = x 0 } z := x ; {y = y 0 z = x 0 } x := y ; {x = y 0 z = x 0 } y := z {x = y 0 y = x 0 } vilket visar att programmet fungerar som det skall. I stället för att arbeta med planlösa framåtannotationer ( nu skall vi se vad som händer i det här programmet ) så visar vi att programmet utträttar precis det som det är avsett att göra. Annotationerna blir alltså enklare (tex behöver vi inte veta något om startvärdet på z eftersom slutannotationen inte använder detta startvärde). 2.7 Kommentarer och annotationer Man kan undra om annotationer egentligen bara är ett slags formaliserade kommentarer. Är det inte lika bra att skriva tydliga kommentarer i textform i stället? En viktig skillnad är att annotationer tvingar programmeraren att göra en statisk tillståndsbeskrivning som är ett verkligt komplement till den dynamiska beskrivning som den egentliga programtexten ger. Kommentarer av typen s initialiseras eller arraysumman lagras i s är däremot egentligen bara en omskrivning (eller tolkning) av det som redan står i programtexten. 15
16 Reglerna för beräkning av bakåtannoteringar är i själva verket regler för att beräkna det svagaste förvillkoret (weakest precondition) och dessa regler kan användas som en definition på vad programsatserna egentligen betyder, dvs som en programsemantik (se överkursavsnittet 12). Övningar 1. Antag att σ är ett tillstånd där x har värdet 0, y har värdet 2, b har värdet F och a är en array med de fem värdena 5, 2, 4, 6, 9. Avgör om följande tillståndspredikat är sanna eller falska i σ: (a) x y b. (b) a[x] a[y]. (c) ( i <5 a[i] x). (c) ( i <5 a[i]=y). (d) b ( i <4 a[i]=a[i+ 1]). 2. I exemplen har följande förenklingar gjorts. Motivera dem: (a) (x y z = x) (x <y z=y) har förenklats till z = max(x, y). (b) ( x 0 x 0 =1 x=x 0 +y+ 1) har förenklats till x =1+y+1. (c) x = x 0 y = y 0 z = max(x, y) har förenklats till x = x 0 y = y 0 z = max(x 0,y 0 ). 3. Antag följande variabeldeklaration: var x, y, z : num ; b : Bool ; a : array[20] of num Skriv tillståndspredikat som motsvarar följande påståenden: (a) z är större än både x och y. (b) b y och falskt annars. (c) Alla värden i arrayn a (dvs hela a[0..19]) är nollor. (d) Arrayavsnittet a[0..9] är ett palindrom (dvs samma oberoende om det läses från vänster till höger eller från höger till vänster) (e) Värdet på x förekommer i arrayn a. (f) Alla tal i arrayn a är olika. (g) Arrayn a är strikt sorterad (dvs den är sorterad och alla tal är olika). 4. Antag följande variabeldeklaration: var x, y, z : num ; f : Bool ; a, b : array[n] of num Uttryck följande tillståndspredikat på naturligt språk (dvs på så vardaglig svenska som möjligt): 16
17 (a) x<z z<y. (b) b ( z : num 1 <z<x/xmod z 0). (c) ( i <n a[i] = 0). (d) (x y z = x) (y x z = y) (e) ( i j i<20 j<20 a[i] =b[j]. 5. Ersätt frågetecknen med ett lämpliga tillståndspredikat (så starkt som möjligt) i följande annoterade programfragment: var x, y, s : num {x =2 y=5 s=0} s:= s + x ; {? } s := s + y ; {? } 6. Annotera följande program: var x, y, z : num {x =3 y=5} z:= x ; x := y ; y := z där startannotationen är given. 7. Ersätt frågetecknet med ett lämpligt tillståndspredikat: var x, y : num {x =1 y=3} if x +2 y 1then x := y else y := x fi {? } 8. Annotera följande program: var x, y, z : num z := x ; if y x then z := y else skip fi 17
18 Använd {x = x 0 y = y 0 } som startannotation. 9. Annotera följande program: var x, y : num x := x + y ; y := x y ; x := x y Använd {x = x 0 y = y 0 } som startannotation. 10. Bakåtannotera programmet i föregående uppgift (använd resultatet från uppgiften för att avgöra vilken den önskade slutannotationen är). 11. Bakåtannotera programfragmentet som användes i exemplet som lagrar det större av talen x och y i z. 3 Annotering av loopar För enkla, rätlinjiga program (eng. straight-line programs) kan annotationer alltid beräknas automatiskt (även om detta lätt ger oläsbara uttryck som måste förenklas innan en människa kan försöka förstå dem). Så fort ett program innehåller loopar blir situationen den omvända. För att annotera loopar måste vi använda vår kunskap och kreativitet. 3.1 Loopinvarianter En speciellt viktig typ av annotation är en loopinvariant. Avsikten med en loopinvariant är att att ange ett tillståndspredikat som är sant före (och efter) varje varv i loopen. Samtidigt skall invarianten visa att när loopen exekverats till slut så har man nått det önskade slutmålet. Tag som exempel följande programfragment som skall summera talen i en array a[0..n 1]: var s, i : num ; a : array[n] of num s := 0 ; i := 0 ; do i<n s:= s + a[i];i:= i +1 od Här ändrar både i och s värde för varje varv i loopen, men de ändrar på ett sätt som bibehåller ett slags balans: s är alltid summan av de i första elementen i arrayn a. Alltså är s = sum(a[0..i 1]) 18
19 en invariant för loopen. Dessutom finns det annan information som är sann hela tiden, nämligen att i n (så vilägger till detta i invarianten). Vi kan då annotera programmet med invarianten: var s, i : num ; a : array[n] of num s := 0 ; i := 0 ; {i n s = sum(a[0..i 1])} do i<n {i n s=sum(a[0..i 1])} s := s + a[i];i:= i +1 {i n s=sum(a[0..i 1])} od men för att visa att det uttryckligen handlar om en loopinvariant (och för att inte behöva skriva den tre gånger) använder vi hellre följande skrivsätt: var s, i : num ; a : array[n] of num s := 0 ; i := 0 ; do i<n {invariant i n s = sum(a[0..i 1])} s := s + a[i];i:= i +1 od dvs vi visar invarianten genast i början av loopen genom en annotation med nyckelordet invariant. 3.2 Varianter Utöver en invariant vill man dessutom visa att loopen faktiskt terminerar. Detta görs enklast genom att man visar en variant (ibland kallad termineringsargument), dvs ett uttryck vars värde (ett naturligt tal) minskar för varje varv i loopen. I exemplet ovan växer i hela tiden och kommer närmare n, sån iär en lämplig variant. Vi kan då införa både invarianten och varianten som annotationer: var s, i : num ; a : array[n] of num {unchanged a} s := 0 ; i := 0 ; {s =0 i=0} do i<n {invariant i n s = sum(a[0..i 1])} {variant n i} s := s + a[i];i:= i +1 od 19
20 Märk att vi har lagt till en annotation i början av programmet som säger att arrayvariabeln a inte ändras. Vi skriver unchanged a ibörjan i stället för att behöva införa ett namn (tex a 0 ) och sedan i varje annotation skriva... a = a 0. Annotationen visar att vi kan uppfatta a som en konstant när vi analyserar detta program. 3.3 Annotation efter loopen En invariant och en variant är inga självändamål. Varianten visar att loopen inte är oändlig, och invarianten förklarar hur loopen arbetar. Dessutom ger invarianten oss en annotation efter loopen, genom att vi där vet att invarianten är sann men vakten (dvs i<n) är falsk. I vårt exempel blir slutannotationen (i <n) i n s=sum(a[0..i 1]) vilket lätt förenklas till i = n s = sum(a[0..n 1]). Det slutliga annoterade programfragmentet blir alltså följande: var s, i : num ; a : array[n] of num {unchanged a} s := 0 ; i := 0 ; {s =0 i=0} do i<n {invariant i n s = sum(a[0..i 1])} {variant n i} s := s + a[i];i:= i +1 od {i = n s = sum(a[0..n 1])} 3.4 Att upptäcka loopinvarianter Det finns inga enkla regler för att avgöra en invariant (eller den bästa invarianten) för en given loop. I allmänhet måste man ha en klar bild av vad loopen skall uträtta, helst i form av ett förvillkor och en slutannotation. Betrakta följande loop: var i, x : num ; a : array[n] of num i := 0 ; do i<n a[i] x i:= i +1 od För att kunna hitta en invariant måste vi dels ha klart för oss vad vi antar att gäller i början, dels måste vi veta vad loopen uträttar (söker efter värdet x i arrayn a[0..n 1] 20
21 och sätter i till n om x inte finns där). Vi kan sammanfatta detta genom att fylla i startoch slutannotationer för loopen: var i, x : num ; a : array[n] of num {unchanged a, x, n} i := 0 ; {i =0} do i<n a[i] x i:= i +1 od {(i <n a[i]=x) (i=n ( k<n a[k] x)} Slutannotationen är i det här fallet rätt komplicerad, men den är vanligen den bästa startpunkten då vi vill upptäcka en invariant: slutannotationen skall ju påstå att invarianten är sann men loopens vakt är falsk. Sålänge vakten i<n a[i] xär sann kan endast en del av slutannotationen vara sann, nämligen att x inte finns i a[0..i 1]. Då vi tillägger att i hålls mellan 0 och n får vi en invariant: i n ( k <i a[k] x) Vi skall senare se hur man kan kontrollera en invariant, här nöjer vi oss med informellt bekräfta den. Ett annat exempel är följande loop, som färdigt har start- och slutannotationer. Den beräknar x! (x fakultet) och lagrar resultatet i r, samtidigt som x räknas ned till 0. {x = x 0 r =1} while x>0do r := r x ; x := x 1 od {x =0 r=x 0!} Också i detta fall vår vi tips till en invariant från slutannotationen: då loopen inte ännu är avslutad har x inte ännu räknat ned till 0 och r innehåller inte ännu hela resultatet. Ett skrivbordstest kan bekräfta att följande gäller x x 0 r = x 0 (x 0 1)... (x+1) vilket är en invariant. Den kan också skrivas x x 0 r x! =x 0!. 3.5 Klassinvarianter En klassinvariant i ett objektorienterat system liknar på många sätt en loopinvariant. Skapande av ett objekt (med en konstruktor) motsvarar att komma till den punkt i programmet där loopen börjar medan ett metodanrop motsvarar ett varv i loopen. Klassinvarianten måste vara sann i början (dvs efter att konstruktorn utförts) och sedan måste 21
22 den bevaras av varje metod (dvs om den är sann före ett metodanrop så är den också sann efter anropet). Klassinvarianten kan alltså uppfattas som en annotation av klassen, och man kan övertyga sig om att en metod faktiskt bevarar invarianten genom att annotera metoden så som beskrivits ovan. Vi skall senare se (i avsnitt 5) att klassinvarianter kan bekräftas mera formellt (bevisas) på samma sätt som loopinvarianter. Övningar 1. Följande program beräknar en summa med användning av addition och subtraktion med 1(såkallade inc- och dec-operationer): var x, y : num {x = x 0 y = y 0 } do x>0 x:= x 1,y := y +1 od Annotera programmet, dvs bestäm invariant, variant och slutannotation. 2. Följande program beräknar x y och lagrar resultatet i r: var x, y, r : num {x >0} r:= 1 ; do y>0 y:= y 1,r := x r od Annotera programmet. 3. Följande program avgör om värdet x förekommer i arrayn a[0..n 1] eller inte. var x, i : num ; f : Bool ; a : array[n] of num f := F ; i := 0 ; do i<n if a[i] =xthen f := T ; i := n else i := i +1 fi od Bestäm invarianten och varianten. Vilken är slutannotationen? 22
23 4. Annotera följande program, som lagrar heltalskvadratroten av y i x: var x, y : Nat x := 0 ; do (x +1) (x+1) y x:= x +1 od 5. Följande program söker efter den största äkta faktorn i talet x (vi antar att värdet på x är 2 eller större). var x, z, r : num ; {x 2} r := 1 ; z := 2 do z<x if (x div z) z = x then r := z ; z := z +1 else z := z +1 fi od Bestäm invarianten och varianten. Vilken är slutannotationen? 6. Antag att arrayn a[0..n 1] (där vi antar n>0) är sorterad och vi vet att det finns ett index k sådant att a[k] =x. Vi vill nu söka efter x i a så att vi hela tiden vet att det sökta indexet k uppfyller i k<jdär i och j är indexvariabler. Eftersom arrayn är sorterad kan vi använda binär sökning, dvs vid starten är i =0 och j = n och sedan skall avståndet mellan i och j halveras för varje varv i loopen. Målet är alltså att skriva ett program med följande variabeldeklaration: var x, i, j : int ; a : array[n] of int och programmet skall inte ändra på a eller x. Märk att k inte hör till programmet, utan bara till förklaringen! (a) (b) (c) Uttryck invarianten och varianten i ord. Skriv programfragmentet och förklara varför invarianten faktiskt bevaras och varianten faktiskt minskas. Skriv programfragmentet med fullständiga annotationer. 23
24 7. Vi vill beskriva en klass Key som modellerar de skåpnycklar som delas ut i tex en simhall. Nycklarna är numrerade från 0 till n-1 och systemet håller reda på vilka nycklar som är ute (variabeln taken : set of num) men också vilken som är nästa nyckel att ges ut (variabeln next : num). Man önskar att nyckarna utdelas i en obestämd ordning (dvs enligt något system som bestäms senare). Ange en invariant för klassen, dvs ett booleskt uttryck som talar om taken och next och som alltid skall vara sant. 4 Specifikationer Annotationer är ett sätt att använda tillståndspredikat för att beskriva ett program. Ett annat sätt är att ange önskade egenskaper hos ett pogram som inte ännu skrivits. En sådan beskrivning av ett program kallas en specifikation. 4.1 För- och eftervillkor Ett förvillkor (eng. precondition) är ett tillståndspredikat som beskriver de tillåtna starttillstånden för ett programfragment. Om det handlar om en procedur kan vi uppfatta förvillkoret som det krav vi har rätt att ställa på inparametrarna när vi skriver procedurens programkod. Till exempel kan förvillkoret för en procedur som tar två inparametrar x och y (av typ num) och beräknar x y vara att x inte är noll och att y inte är negativt: x 0 y 0 Ett eftervillkor (eng. postcondition) är ett tillståndspredikat som beskriver de tillåtna sluttillstånden. I praktiken vill vi kunna tala om startvärden i eftervillkoret, och för detta finns det olika standardkonventioner: (a) (b) startvärden indexeras med en nolla (så att startvärdet för x heter x 0 medan slutvärdet heter x) slutvärden anges med primtecken (så att startvärdet för x heter x medan slutvärdet heter x ) Vi använder här regeln att eftervillkoret faktiskt är ett tillståndspredikat, och om vi vill namnge startvärden så visar vi det uttryckligt i förvillkoret (och vi använder vanligen noll-indexering). En specifikation för ett programfragment som beräknar x y och lagrar resultatet i r kan då seutsåhär: var x, y, r : num pre x = x 0 y = y 0 x 0 y 0 post r = x y 0 0 Märk att denna specifikation tillåter att värdena på x och y ändras. 24
25 4.2 Exempel på specifikationer Ett annat exempel är följande specifikation: var x, y : num pre x = x 0 x 0 0 post y 2 x 0 < (y +1) 2 Det kan krävas en stunds eftertanke för att man skall bli övertygad om att den säger att y skall bli heltalskvadratroten av x. Följande exempel säger att summan av arrayn a[0..n 1] skall beräknas och lagras i s: var s : num ; a : array[n] of num pre true post s = sum(a[0..n 1]) Här har vi inte definierat begreppet sum, utan vi antar att det har en intuitiv betydelse som är tillräckligt exakt. Ifall vi vill ange att arrayn a inte får förstöras (ändras) då summan beräknas, kan vi skriva var s : num ; a : array[n] of num pre a = a 0 post a = a 0 s = sum(a[0..n 1]) eller så kan vi införa en skild rad som anger vilka variabler som inte får ändras: var s : num ; a : array[n] of num unchanged a pre true post s = sum(a[0..n 1]) 4.3 Informella och formella specifikationer De exempel på specifikationer som getts ovan är formella, dvs de använder matematisklogisk notation för att uppnå en exakthet som gör att specifikationens betydelse är absolut klar och otvetydig. I praktiken är det ofta svårt att åstadkomma fullständigt formella specifikationer. Ofta kan det tyckas att det är mycket enklare att specificera informellt. Tag som exempel följande informella specifikation: sök efter värdet x i arrayn a[0..n 1]. En formell specifikation blir lätt komplicerad, men samtidigt visar den att problemet inte är riktigt så enkelt som vi tänkt oss, och den tvingar oss att formulera allting exakt: hur skall resultatet av sökningen lagras, vad skall vi göra om x inte hittas, får x ändra värde 25
26 under sökningen,...? Vi kan tex ha en skild variabel som säger om x hittades eller inte: var x, i : num ; f : Bool ; a : array[n] of num unchanged x, a pre true post (f ( k <n a[k]=x)) (f i n a[i] =x) men vi kan också tänka oss att vi låter i stå för all information: var x, i : num ; a : array[n] of num unchanged x, a pre true post (i <n a[i]=x) (i=n ( k<n a[k] x)) En halvformell specifikation innehåller in blandning av formella och informella delar. En informell del kan vara text i vardagsspråk, men om möjligt lönar det sig att försöka skriva också den informella delen med matematisk notation, men med begrepp som inte definierats exakt. Om vi tex vill specificera att arrayn a[0..n 1] skall sorteras kan vi beskriva det så här: var a : array[n] of num pre a = a 0 post sorted(a[0..n 1]) permutation(a[0..n 1],a 0 [0..n 1]) där begreppet sorted är definierat exakt men begreppet permutation kan beskrivas informellt så att permutation(a[0..n 1],b[0..n 1]) betyder att a[0..n 1] och b[0..n 1] innehåller samma element men de får komma i olika ordning. Då kan vi senare införa en exakt definition för permutation utan att själva specifikationen behöver ändras. 4.4 Specifikationsspråk Den notation som använts ovan för att skriva specifikationer (med var, unchanged, pre och post, och med allmänna principer för hur tillståndspredikat skall skrivas) kan ses som ett enkelt specifikationsspråk. För att kunna specificera stora program och system måste vi kunna beskriva delar (moduler) var för sig och sedan ha olika sätt att kombinera delarna till större helheter. Det finns en mängd olika formella specifikationsspråk, för olika tillämpningar (tex Z, VDM, B). Till endel språk finns dessutom verktygsstöd för verifiering, kodgenerering, mm. Övningar 1. Uttryck följande specifikationer med hjälp av för- och eftervillkor. Ge alltid variabeldeklaration och ange vid behov vilka variabler som inte får ändras. Uppfinn vid behov nya begrepp men förklara dem då exakt (gärna med en formell definition). 26
27 (a) Differensen (icke-negativ) mellan x och y skall lagras i z, så att tex om x är 7 och y är 3 skall z bli 4 men om x är2ochyär 5 skall z bli 3. (b) Variabeln z : num skall få ett värde som ligger mellan värdena på x och y. (c) Avgör om arrayn a[0..n 1] är ett palindrom eller inte och lagra svaret i den logiska variabeln f. (d) Avgör om arrayerna a[0..n 1] och b[0..n 1] innehåller samma värden i samma ordning och lagra svaret i den logiska variabeln f. (e) Avgör hur många gånger talet x förekommer i arrayn a[0..n 1] och lagra svaret i den variabeln n. 2. Tolka följande specifikationer, dvs förklara i ord vad de säger: (a) var z : num ; A : set of num unchanged A pre A post z A ( x x A x z) (b) var a : array[n] of num pre a = a 0 post a[0] = a 0 [n 1] ( i 1 i<n a[i]=a 0 [i 1]) Kom ihåg att set betyder mängd, och det är alltså tillåtet att använda vanliga mängdoperationer, som (tillhör), (delmängd), mm. 3. Skriv specifikationer med för- och eftervillkor som motsvarar följande (välj själv variabelnamn och -typer): (a) (b) Beräkna kvadratroten av ett givet reellt tal (som inte får vara negativt), med en noggrannhet på Förvandla ett givet heltal till binär form (dvs en array av nollor och ettor) 4. Vi vill beskriva en klass Key som modellerar de skåpnycklar som delas ut i tex en simhall. Nycklarna är numrerade från 0 till n-1 och systemet håller reda på vilka nycklar som är ute (variabeln taken : set of num) men också vilken som är nästa nyckel att ges ut (variabeln next : num). Man önskar att nyckarna utdelas i en obestämd ordning (dvs enligt något system som bestäms senare). Skriv specifikationer med för- och eftervillkor för (a) (b) (c) konstruktorn, som ger det starttillstånd där all nycklar är inne, metoden handout där en nyckel ges ut till en kund (och en ny nyckel väljs ut att vara nästa ), och metoden return där en nyckel (variabeln inkey) returneras. 27
28 5. Skriv specifikationer med för- och eftervillkor som motsvarar följande: (a) (b) (c) Efteråt skall x innehålla det större och y det mindre av de ursprungliga värdena på x och y. Vänd om (reverse) arrayn a[0..n 1], så att det element som var först kommer sist, osv. En kortlek modelleras med en array[52] of int (och varje spelkort kodas som ett heltal på något sätt som vi inte behöver bry oss om). Specificera en blandning, så att inget kort efter blandningen ligger bredvid samma kort som det låg bredvid före blandningen. 6. Uttryck följande specifikationer med hjälp av för- och eftervillkor. Välj själv datarepresentation, dvs de variabler som används för att representera den information som specifikationen handlar om. (a) Avgör om en given array är sorterad eller inte. (b) Förvandla ett givet naturligt tal till binär form (dvs som en följd av nollor och ettor) (c) Uppdela ett givet tal i primfaktorer (d) Sätt in ett givet värde på rätt plats i en sorterad array (så att resten skuffas högerut ). 7. I ett datasystem vill man ha en uppsättning nycklar (ID-koder), som utgörs av femsiffriga tal. (a) (b) Vi tänker oss att de redan använda nycklarna bildar en mängd A : set of num. Specificera operationen Ge en ny (oanvänd) nyckel med för- och eftervillkor. I en implementation håller vi de använda nycklarna i en array (och antalet använda nycklar i en skild variabel). Specificera operationen Ge en ny (oanvänd) nyckel i detta fall. 8. Vi modellerar en telefonbok som en mängd av par av formen (namn,nummer): var c : set of (string, num) Vi vill nu specificera ett antal procedurer som arbetar med en sådan telefonbok. (a) En procedur specificeras enligt följande: var n : string ; f : Bool ; c : set of (string, num) unchanged n, c pre true post f =( x (n, x) c) Förklara i ord vad denna specifikation betyder. 28
29 (b) (c) Skriv specifikationen för en procedur som hämtar numret för en given person. Förvillkoret skall säga att namnet faktiskt finns i telefonboken. Vi vill göra en begränsning som telefonboken måste uppfylla hela tiden: samma person får inte ha fler än ett telefonnummer. Uttryck detta som ett tillståndspredikat. 9. Vi kan implementera telefonboken i föregående uppgift med hjälp av två arrays och en variabel som säger hur många namn som finns i telefonboken: var n : num ; a : array of string ; b : array of num; med tanken att namnet a[i] hör ihop med numret b[i] (för 0 i<n). Vi vill nu implementera proceduren som hämtar numret för en given person (se b-fallet i föregående uppgift). (a) (b) (c) Specificera denna procedur med för- och eftervillkor. Skriv en implementation och annotera den. Uttryck begränsningen att samma person får inte ha fler än ett telefonnummer som ett tillståndspredikat. 5 Riktighetsbevis Om vi har en specifikation med förvillkor p och eftervillkor q och en(påstådd) implementering S inställer sig osökt frågan hur vi kan kontrollera att S faktiskt implementerar den givna specifikationen. Vi skall nu beskriva ett system för att bevisa detta. Den metod som vi beskriver kallas ibland Hoare-logik, efter C.A.R. Hoare som uppfann idén i slutet av 1960-talet. 5.1 Riktighetspåståenden Vi använder skrivsättet p { S } q för att säga att programmet S är (totalt) riktigt med avseende på förvillkor p och eftervillkor q. I vardagstermer betyder detta att om programmet S exekveras i ett starttillstånd där predikatet p är sant så kommer exekveringen att terminera i ett sluttillstånd där predikatet q är sant. Programsatsen S sägs då åstadkomma (eng. establish) eftervillkoret q. Eller annorlunda uttryckt: programmet S är en godtagbar implementering av specifikationen som anger förvillkoret till p och eftervillkoret till q. Vi talar här endast om total riktighet (eng. total correctness). Många böcker behandlar partiell riktighet, vilket innebär att man visar att om exekveringen terminerar så är eftervillkoret q sant i sluttillståndet. Vid total riktighet kräver man mera; man måste visa att exekveringen säkert terminerar och att eftervillkoret blir uppfyllt. Skillnaden mellan dessa två angreppssätt blir stor när man behandlar tex loopar och rekursiva procedurer. Läsaren skall speciellt se upp med att liknande notation (tex {p} S {q}) kan användas både för total och för partiell riktighet. 29
30 5.2 Riktighetsregler Systemet för att bevisa riktighet byggs upp så att det finns regler för att bryta ned ett riktighetspåstående som handlar om ett komplicerat program till riktighetspåståenden som handlar om programmets delar. Genom att tillämpa dessa regler upprepade gånger kommer vi ned till den mest grundläggande nivån, tex tilldelningar för vilka det sedan finns skilda regler. Som enkelt exempel kan vi ta programkonstruktionen skip. Den gör ingenting, dvs den lämnar alla programvariabler oförändrade. Det betyder att om p är ett villkor som gäller innan skip exekveras så gäller p också efter exekveringen. Detta betyder också att vad som helst som följer logiskt av p kommer att gälla efter exekveringen. Riktighetsregeln för skip är följande: p q p { skip } q Detta är en inferensregel, dvs en regel som säger hur vi kan dra slutsatser om riktighetspåståenden. Liksom de andra riktighetsregler som ges senare används den på följande sätt. Anta att vi skall visa att riktighetspåståendet y = 2{ skip } y > 1är sant. Regeln kan då användas så att p motsvarar (eng. match) uttrycket y = 2och q motsvarar uttrycket y > 1. Alltså är riktighetspåståendet sant om bara det logiska påståendet y =2 y>1är sant (och det är det, för om y är2såär y större än 1). Ett alternativt sätt att skriva riktighetsregeln för skip vore följande: OM SÅ p q p { skip } q eller baklänges : Om du vill visa Såräcker det med att visa p { skip } q p q Vi följer här det först givna formatet som stämmer överens med normalt skrivsätt för inferensregler inom logik. 5.3 Tilldelningssatsen Tilldelningssatsen är den mest grundläggande satskonstruktionen i imperativ programmering. Dess riktighetsregel är p q[x := e] p { x := e } q där q[x := e] betyder q med e substituerat för x (ibland skrivs detta q[e/x] eller q[x\e] eller q e x). Denna regel motiveras bäst med exempel. Vi kan tex visa det uppenbara riktighetspåståendet x =2{ x := x +1 } x = 3. Regeln säger att vi skall visa x =2 x+1=3(märk att 30
31 högra sidan är resultatet då man substituerar x +1 för x i x = 3). Själva beviset är en enkel härledning: x =2 x+1=3 {ekvationsaritmetik} x =2 x=2 {implikation är reflexiv} T Riktighetsregeln för tilldelningar duger utan ändringar också för multipla tilldelningar, om vi uppfattar x som en vektor av (olika) variabler och e som en vektor (av samma längd som x) av uttryck: p q[x := e] p { x := e } q Samtidigt måste vi uppfatta q[x := e] som en parallel substitution, dvs variablerna x ersätts med uttrycken e samtidigt. Till exempel förvandlas riktighetspåståendet x<y{ x, y := y +1,x 1 } x>y med hjälp av tilldelningsregeln till x<y y+1>x 1 vilket sedan lätt visas vara sant. 5.4 Sekventiell komposition Sekventiell komposition av två programsatser S 1 ; S 2 innebär att S 1 exekveras först och därefter S 2. Riktighetsregeln är följande: p { S 1 } q q { S 2 } r p { S 1 ; S 2 } r dvs om vi vill visa ett riktighetspåstående av typen p { S 1 ; S 2 } r så skall vi hitta ett sådant predikat q att både p { S 1 } q och q { S 2 } r gäller. Predikatet q kallas det mellanliggande predikatet (eng. intermediate predicate) och beskriver det mellanliggande tillståndet som exekveringen av S 1 leder till. Exempel: För att visa riktighetspåståendet x =1 y=2{ x := y ; y := x } x =2 y=2 väljer vi x = 2 y = 2 som mellanliggande predikat. Riktighetsregeln för sekventiell komposition säger då att vi skall visa de två riktighetspåståendena x =1 y=2{ x := y } x =2 y=2 x=2 y=2{ y := x } x =2 y=2 31
Introduktion till formella metoder Programmeringsmetodik 1. Inledning
Introduktion till formella metoder Programmeringsmetodik 1. Inledning Fokus på imperativa program (ex. C, Java) program betyder härefter ett imperativt program Program bestäms i en abstrakt mening av hur
Programmering i C++ En manual för kursen Datavetenskaplig introduktionskurs 5p
Programmering i C++ En manual för kursen Datavetenskaplig introduktionskurs 5p Skriven av Michael Andersson Introduktion Programmering I högnivåspråk fokuserar på själv problemet (algoritmen) istället
Klassdeklaration. Metoddeklaration. Parameteröverföring
Syntax: Class Declaration Modifier Class Body Basic Class Member Klassdeklaration class Class Member Field Declaration Constructor Declaration Method Declaration Identifier Class Associations Motsvarar
Programmering II (ID1019) :00-17:00
ID1019 Johan Montelius Programmering II (ID1019) 2014-03-10 14:00-17:00 Förnamn: Efternamn: Instruktioner Du får inte ha något materiel med dig förutom skrivmateriel. Mobiler etc, skall lämnas till tentamensvakten.
Introduktion till algoritmer - Lektion 4 Matematikgymnasiet, Läsåret 2014-2015. Lektion 4
Introduktion till algoritmer - Lektion 4 Matematikgymnasiet, Läsåret 014-015 Denna lektion ska vi studera rekursion. Lektion 4 Principen om induktion Principen om induktion är ett vanligt sätt att bevisa
Programmera i C Varför programmera i C när det finns språk som Simula och Pascal??
Programmera i C Varför programmera i C när det finns språk som Simula och Pascal?? C är ett språk på relativt låg nivå vilket gör det möjligt att konstruera effektiva kompilatorer, samt att komma nära
Föreläsning 2 Programmeringsteknik och C DD1316. Mikael Djurfeldt
Föreläsning 2 Programmeringsteknik och C DD1316 Mikael Djurfeldt Föreläsning 2 Programmeringsteknik och C Python introduktion Utskrift Inläsning Variabler Datatyp Aritmetiska operatorer Omvandling
Programkonstruktion och datastrukturer. Formell verifiering eller hur man bevisar att program gör rätt utan att testa dem
Programkonstruktion och datastrukturer Formell verifiering eller hur man bevisar att program gör rätt utan att testa dem PKD 2012/13 Formell verifiering Sida 1 Uppdaterad 2008-11-28 Formell verifiering:
Sanningsvärdet av ett sammansatt påstående (sats, utsaga) beror av bindeord och sanningsvärden för ingående påståenden.
MATEMATISK LOGIK Matematisk logik formaliserar korrekta resonemang och definierar formellt bindeord (konnektiv) mellan påståenden (utsagor, satser) I matematisk logik betraktar vi påståenden som antingen
Tentamen i. TDDC67 Funktionell programmering och Lisp
1 Linköpings tekniska högskola Institutionen för datavetenskap Anders Haraldsson Tentamen i TDDC67 Funktionell programmering och Lisp och äldre kurser TDDC57 Programmering, Lisp och funktionell programmering
Logik och kontrollstrukturer
Logik och kontrollstrukturer Flödet av instruktioner i ett programmeringsspråk bygger vi upp med hjälp av dess kontrollstrukturer. I C har vi exemplen if, if else, while, do while. Dessutom finns switch
9. Predikatlogik och mängdlära
Objektorienterad modellering och diskreta strukturer 9. Predikatlogik och mängdlära Sven Gestegård Robertz Datavetenskap, LTH 2014 Rekaputilation Vi har talat om satslogik naturlig härledning predikatlogik
DD1361 Programmeringsparadigm. Carina Edlund
DD1361 Programmeringsparadigm Carina Edlund carina@nada.kth.se Funktionell programmering Grundidéen med funktionell programmering är att härma matematiken och dess funktionsbegrepp. Matematiskt funktionsbegrepp
TDDC74 Programmering: Abstraktion och modellering Datortenta , kl 14-18
TDDC74 Programmering: Abstraktion och modellering Datortenta - 017-10-7, kl 14-18 Läs alla frågorna först och bestäm dig för i vilken ordning du vill lösa uppgifterna. Uppgifterna är inte nödvändigtvis
Datastrukturer, algoritmer och programkonstruktion (DVA104, VT 2015) Föreläsning 6
Datastrukturer, algoritmer och programkonstruktion (DVA104, VT 2015) Föreläsning 6? DAGENS AGENDA Komplexitet Ordobegreppet Komplexitetsklasser Loopar Datastrukturer Några nyttiga regler OBS! Idag jobbar
Uppsala Universitet Matematiska Institutionen Thomas Erlandsson
Uppsala Universitet Matematiska Institutionen Thomas Erlandsson LÄSANVISNINGAR VECKA 36 VERSION 1. ARITMETIK FÖR RATIONELLA OCH REELLA TAL, OLIKHETER, ABSOLUTBELOPP ADAMS P.1 Real Numbers and the Real
Formella metoder. Loop-program som statetransformers. Betrakta följande problem. specifikationen.
8Att bevisa egenskaper om program Formella metoder... 1 Loop-program som statetransformers... 1 Några exempel... 2 Partiell korrekthet och total korrekthet... 3 Programspecifikation... 3 Hoarelogik och
TATM79: Föreläsning 1 Notation, ekvationer, polynom och summor
TATM79: Föreläsning 1 Notation, ekvationer, polynom och summor Johan Thim 22 augusti 2018 1 Vanliga symboler Lite logik Implikation: P Q. Detta betyder att om P är sant så är Q sant. Utläses P medför Q
Språket Python - Del 1 Grundkurs i programmering med Python
Hösten 2009 Dagens lektion Ett programmeringsspråks byggstenar Några inbyggda datatyper Styra instruktionsflödet Modulen sys 2 Ett programmeringsspråks byggstenar 3 ETT PROGRAMMERINGSSPRÅKS BYGGSTENAR
TDIU01 - Programmering i C++, grundkurs
TDIU01 - Programmering i C++, grundkurs Sammanfattning period 1 Eric Elfving Institutionen för datavetenskap 1 oktober 2013 Översikt Ett C++-programs uppbyggnad Variabler Datatyper Satser Uttryck Funktioner
Bakgrund och motivation. Definition av algoritmer Beskrivningssätt Algoritmanalys. Algoritmer. Lars Larsson VT 2007. Lars Larsson Algoritmer 1
Algoritmer Lars Larsson VT 2007 Lars Larsson Algoritmer 1 1 2 3 4 5 Lars Larsson Algoritmer 2 Ni som går denna kurs är framtidens projektledare inom mjukvaruutveckling. Som ledare måste ni göra svåra beslut
Sats. Om t är en rätvinklig triangel så är summan av kvadraterna på kateterna i t lika med kvadraten på hypotenusan.
Lunds tekniska högskola Datavetenskap Lennart Andersson Föreläsningsanteckningar EDAF10 3 Predikatlogik 3.1 Motivering I satslogiken är de minsta beståndsdelarna satslogiska variabler som kan anta värdena
Tillämpad Programmering (ID1218) :00-13:00
ID1218 Johan Montelius Tillämpad Programmering (ID1218) 2014-03-13 09:00-13:00 Förnamn: Efternamn: Regler Du får inte ha något materiel med dig förutom skrivmateriel. Mobiler etc, skall lämnas till tentamensvakten.
Alla datorprogram har en sak gemensam; alla processerar indata för att producera något slags resultat, utdata.
Att förstå variabler Alla datorprogram har en sak gemensam; alla processerar indata för att producera något slags resultat, utdata. Vad är en variabel? En variabel är en plats att lagra information. Precis
Föreläsning 3-4 Innehåll. Diskutera. Metod. Programexempel med metod
Föreläsning 3-4 Innehåll Diskutera Vad gör programmet programmet? Föreslå vilka satser vi kan bryta ut till en egen metod. Skriva egna metoder Logiska uttryck Algoritm för att beräkna min och max Vektorer
Föreläsning 7 Innehåll. Rekursion. Rekursiv problemlösning. Rekursiv problemlösning Mönster för rekursiv algoritm. Rekursion. Rekursivt tänkande:
Föreläsning 7 Innehåll Rekursion Rekursivt tänkande: Hur många år fyller du? Ett år mer än förra året! Rekursion Rekursiv problemlösning Binärsökning Generiska metoder Rekursiv problemlösning: Dela upp
Programmeringsteknik med C och Matlab
Programmeringsteknik med C och Matlab Kapitel 2: C-programmeringens grunder Henrik Björklund Umeå universitet Björklund (UmU) Programmeringsteknik 1 / 32 Mer organisatoriskt Imorgon: Datorintro i lab Logga
Föreläsningsanteckningar, Introduktion till datavetenskap HT S4 Datastrukturer. Tobias Wrigstad
1 Datatyper Tobias Wrigstad Det finns flera olika typer av (slags) data Olika datatyper har olika egenskaper. T.ex. är ett personnummer inte ett tal. (Den sista siffran skall stämma enligt den s.k. Luhnalgoritmen
Bakgrund. Bakgrund. Bakgrund. Håkan Jonsson Institutionen för systemteknik Luleå tekniska universitet Luleå, Sverige
Är varje påstående som kan formuleras matematiskt*) alltid antingen sant eller falskt? *) Inom Institutionen för systemteknik Luleå tekniska universitet Luleå, Sverige Exempel: 12 = 13 nej, falskt n! >
Föreläsning 13. Träd
Föreläsning 13 Träd Träd Ett träd är en datastruktur som tillåter oss att modellera sådant som vi inte kan modellera med linjära datastrukturer. Ett datavetenskapligt träd består av noder med pilar emellan.
Övningshäfte 1: Logik och matematikens språk
GÖTEBORGS UNIVERSITET MATEMATIK 1, MMG200, HT2014 INLEDANDE ALGEBRA Övningshäfte 1: Logik och matematikens språk Övning A Målet är att genom att lösa och diskutera några inledande uppgifter få erfarenheter
Föreläsning 3-4 Innehåll
Föreläsning 3-4 Innehåll Skriva egna metoder Logiska uttryck Algoritm för att beräkna min och max Vektorer Datavetenskap (LTH) Föreläsning 3-4 HT 2017 1 / 36 Diskutera Vad gör programmet programmet? Föreslå
Tentamen ID1004 Objektorienterad programmering October 29, 2013
Tentamen för ID1004 Objektorienterad programmering (vilande kurs), 29 oktober 2013, 9-13 Denna tentamen examinerar 3.5 högskolepoäng av kursen. Inga hjälpmedel är tillåtna. Tentamen består av tre sektioner.
Programmering II (ID1019) :00-11:00
ID1019 Johan Montelius Programmering II (ID1019) 2015-06-11 08:00-11:00 Instruktioner Du får inte ha något materiel med dig förutom skrivmateriel. Mobiler etc, skall lämnas till tentamensvakten. Svaren
Multipel tilldelning. Introduktion till programmering D0009E. Föreläsning 6: Iteration. while-satsen. Kom ihåg. Snurror kontra rekursion
Introduktion till programmering D0009E Föreläsning 6: Iteration Multipel tilldelning Helt ok att tilldela en variabel flera gånger: bruce = bruce, bruce = 7 bruce Output: 7 Som tillståndsdiagram: bruce
Introduktion till programmering SMD180. Föreläsning 4: Villkor och rekursion
Introduktion till programmering Föreläsning 4: Villkor och rekursion 1 1 Några inbyggda funktioner (med resultat!) Konverterar mellan de grundläggande typerna: >>> int("32") 32 >>> int(3.999) 3 >>> float(32)
Läsanvisning till Discrete matematics av Norman Biggs - 5B1118 Diskret matematik
Läsanvisning till Discrete matematics av Norman Biggs - 5B1118 Diskret matematik Mats Boij 28 oktober 2001 1 Heltalen Det första kapitlet handlar om heltalen och deras aritmetik, dvs deras egenskaper som
Filosofisk logik Kapitel 15. Robin Stenwall Lunds universitet
Filosofisk logik Kapitel 15 Robin Stenwall Lunds universitet Dagens upplägg Första ordningens mängdlära Naiv mängdlära Abstraktionsaxiomet (eg. comprehension) Extensionalitetsaxiomet Små mängder Ordnade
Dagens föreläsning. Repetition. Repetition - Programmering i C. Repetition - Vad C består av. Repetition Ett första C-program
Dagens föreläsning Programmeringsteknik för Ingenjörer VT05 Föreläsning 3-4 Repetition Datatyper Uttryck Operatorer Satser Algoritmer Programmeringsteknik VT05 2 Repetition Repetition - Programmering i
Beräkningsvetenskap föreläsning 2
Beräkningsvetenskap föreläsning 2 19/01 2010 - Per Wahlund if-satser if x > 0 y = 2 + log(x); else y = -1 If-satsen skall alltid ha ett villkor, samt en då det som skall hända är skrivet. Mellan dessa
Grundläggande logik och modellteori
Grundläggande logik och modellteori Kapitel 6: Binära beslutsdiagram (BDD) Henrik Björklund Umeå universitet 22. september, 2014 Binära beslutsdiagram Binära beslutsdiagram (Binary decision diagrams, BDDs)
TDDI16 Datastrukturer och algoritmer. Algoritmanalys
TDDI16 Datastrukturer och algoritmer Algoritmanalys 2017-08-28 2 Översikt Skäl för att analysera algoritmer Olika fall att tänka på Medelfall Bästa Värsta Metoder för analys 2017-08-28 3 Skäl till att
Programmering A. Johan Eliasson johane@cs.umu.se
Programmering A Johan Eliasson johane@cs.umu.se 1 Jag Undervisar mest grundläggande programmering på Institutionen för datavetensakap Applikationsutveckling för iphone Applikationsutveckling i Java Datastrukturer
DD1350 Logik för dataloger. Fö 7 Predikatlogikens semantik
DD1350 Logik för dataloger Fö 7 Predikatlogikens semantik 1 Kryssprodukt av mängder Om A och B är två mängder så är deras kryssprodukt A B mängden av alla par (a,b), där a A och b B. Ex: A={1,2}, B={3,4},
Användarhandledning Version 1.2
Användarhandledning Version 1.2 Innehåll Bakgrund... 2 Börja programmera i Xtat... 3 Allmänna tips... 3 Grunderna... 3 Kommentarer i språket... 4 Variabler... 4 Matematik... 5 Arrayer... 5 på skärmen...
i LabVIEW. Några programmeringstekniska grundbegrepp
Institutionen för elektroteknik Några programmeringstekniska grundbegrepp 1999-02-16 Inledning Inom datorprogrammering förekommer ett antal grundbegrepp som är i stort sett likadana oberoende om vi talar
LMA033/LMA515. Fredrik Lindgren. 4 september 2013
LMA033/LMA515 Fredrik Lindgren Matematiska vetenskaper Chalmers tekniska högskola och Göteborgs universitet 4 september 2013 F. Lindgren (Chalmers&GU) Matematik 4 september 2013 1 / 25 Outline 1 Föreläsning
I kursen i endimensionell analys är mängden av reella tal (eng. real number), R, fundamental.
Lunds tekniska högskola Datavetenskap Lennart ndersson Föreläsningsanteckningar EDF10 4 Mängder 4.1 Motivering Mängden är den mest grundläggande diskreta strukturen. Nästan alla matematiska begrepp går
Övningshäfte 2: Induktion och rekursion
GÖTEBORGS UNIVERSITET MATEMATIK 1, MMG200, HT2017 INLEDANDE ALGEBRA Övningshäfte 2: Induktion och rekursion Övning D Syftet är att öva förmågan att utgående från enkla samband, aritmetiska och geometriska,
Parameteröverföring. Exempel. Exempel. Metodkropp
Exempel atriangle.changesize (100, 50); // OK atriangle.changesize (100); // fel antal atriangle.changesize ( 1, 50); // fel datatyp char c = atriangle.getarea (); // fel datatyp Parameteröverföring I
TATM79: Föreläsning 1 Notation, ekvationer, polynom och olikheter
TATM79: Föreläsning 1 Notation, ekvationer, polynom och olikheter Johan Thim 15 augusti 2015 1 Vanliga symboler Lite logik Implikation: P Q. Detta betyder att om P är sant så är Q sant. Utläses P medför
Inlämningsuppgift MiniPlotter
LUNDS TEKNISKA HÖGSKOLA Institutionen för datavetenskap EDAA01 Programmeringsteknik fördjupningskurs Inlämningsuppgift MiniPlotter I den här uppgiften ska ett program som ritar grafer av matematiska funktioner
Tentamen i Introduktion till programmering
Tentamen i Introduktion till programmering Kurskod: Skrivtid: D0009E 09:00-13:00 (4 timmar) Totalt antal uppgifter: 7 Totalt antal poäng: 38 Tentamensdatum: 2014-05-17 Jourhavande lärare: Tillåtna hjälpmedel:
Några inbyggda funktioner (med resultat!) Introduktion till programmering D0009E. Föreläsning 4: Villkor och rekursion. Modulus-operatorn.
Några inbyggda funktioner (med resultat!) Introduktion till programmering D0009E Föreläsning 4: Villkor och rekursion Konverterar mellan de grundläggande typerna: >>> int("") >>> int(.999) >>> float().0
String [] argv. Dagens Agenda. Mer om arrayer. Mer om arrayer forts. String [] argv. argv är variabelnamnet. Arrayer och Strängar fortsättning
Dagens Agenda String [] argv String [] argv Arrayer och Strängar fortsättning Booleska operatorer if, for, while satser Introduktion till algoritmer public static void main(string [] argv) argv är variabelnamnet
Objektorienterad modellering och diskreta strukturer. 13. Problem. Sven Gestegård Robertz. Datavetenskap, LTH
Objektorienterad modellering och diskreta strukturer 13. Problem Sven Gestegård Robertz Datavetenskap, LTH 2014 Rekaputilation Vi har talat om satslogik och härledning predikatlogik och substitution mängder
Logik och Jämförelser. Styrsatser: Villkorssatsen if och repetitonssatsen for. Scriptfiler. Kommentarer. Tillämpningar: Ett enkelt filter.
TAIU07 Föreläsning 3 Logik och Jämförelser. Styrsatser: Villkorssatsen if och repetitonssatsen for. Scriptfiler. Kommentarer. Tillämpningar: Ett enkelt filter. 27 januari 2016 Sida 1 / 21 Logiska variabler
Föreläsning 2 Programmeringsteknik och C DD1316
Föreläsning 2 Programmeringsteknik och C DD1316 Föreläsning 2 Programmeringsteknik och C Datatyp Aritmetiska operatorer Omvandling av typer Reserverade ord Mikael Djurfeldt Logiska operatorer
Induktion, mängder och bevis för Introduktionskursen på I
Induktion, mängder och bevis för Introduktionskursen på I J A S, ht 04 1 Induktion Detta avsnitt handlar om en speciell teknik för att försöka bevisa riktigheten av påståenden eller formler, för alla heltalsvärden
MMA132: Laboration 2 Matriser i MATLAB
MMA132: Laboration 2 Matriser i MATLAB Introduktion I den här labben skall vi lära oss hur man använder matriser och vektorer i MATLAB. Det är rekommerad att du ser till att ha laborationshandledningen
(N) och mängden av heltal (Z); objekten i en mängd behöver dock inte vara tal. De objekt som ingår i en mängd kallas för mängdens element.
Grunder i matematik och logik (2017) Mängdlära Marco Kuhlmann 1 Grundläggande begrepp Mängder och element 2.01 En mängd är en samling objekt. Två standardexempel är mängden av naturliga tal (N) och mängden
SMD 134 Objektorienterad programmering
SMD 134 Objektorienterad programmering Dagens agenda: Typer i Java: primitiva datatyperna, referenstyper Variabler och variabeltilldelningar med primitiva typer Konstanter av de olika typerna. Heltalsräkning
MATEMATIKENS SPRÅK. Avsnitt 1
Avsnitt 1 MATEMATIKENS SPRÅK Varje vetenskap, liksom varje yrke, har sitt eget språk som ofta är en blandning av vardagliga ord och speciella termer. En instruktionshandbok för ett kylskåp eller för en
Filosofisk Logik (FTEA21:4) föreläsningsanteckningar/kompendium. v. 2.0, den 29/ III. Metalogik 17-19
Filosofisk Logik (FTEA21:4) föreläsningsanteckningar/kompendium IV v. 2.0, den 29/4 2013 III. Metalogik 17-19 Modeller för satslogiken 18.1 Vi har tidigare sagt att en modell är en tolkning av en teori
Programmering för språkteknologer I, VT2012. Rum
Programmering för språkteknologer I, VT2012 evelina.andersson@lingfil.uu.se Rum 9-2035 http://stp.lingfil.uu.se/~evelina/uv/uv12/pst1/ Idag - Kursplan - Börja programmera - Lokala variabler - aritmetiska
Tentamen ID1004 Objektorienterad programmering May 29, 2012
Omtentamen för ID1004 Objektorienterad programmering HT11, 29 maj 2012, 09-13 Denna tentamen examinerar 3 högskolepoäng av kursen. Inga hjälpmedel är tillåtna. Tentamen består av 12 frågor. Varje fråga
TAIU07 Matematiska beräkningar med Matlab
TAIU07 Matematiska beräkningar med Matlab Datorlektion 2. Villkor och Repetition 1 Logiska uttryck Uppgift 1.1 Låt a=3 och b=6 Vad blir resultatet av testerna ab? Uppgift 1.2 Låt a, b,
F5 Selektion och iteration. ID1004 Objektorienterad programmering Fredrik Kilander
F5 Selektion och iteration ID1004 Objektorienterad programmering Fredrik Kilander fki@kth.se Boolska uttryck Boolska uttryck använder sig av jämförelseoperatorer < > = ==!= Resultatets datatyp är boolean
Programmeringsmetodik DV1 Programkonstruktion 1. Moment 4 Om rekursion. PK1&PM1 HT-06 moment 4 Sida 1 Uppdaterad
Programmeringsmetodik DV1 Programkonstruktion 1 Moment 4 Om rekursion PK1&PM1 HT-06 moment 4 Sida 1 Uppdaterad 2006-10-17 Summera godtyckligt antal tal (* sumupto n Type: int->int Pre: n >= 0, n
Tommy Färnqvist, IDA, Linköpings universitet. 2 Strukturer 2 2.1 Domäner... 2 2.2 Tolkningar... 3
Föreläsning 2 Semantik 729G06 Logikdelen Föreläsningsanteckningar i Programmering och logik 27 januari 2014 Tommy Färnqvist, IDA, Linköpings universitet 2.1 Innehåll Innehåll 1 Lite mer syntax 1 2 Strukturer
System.out.println("Jaså du har "+ antalhusdjur+ " husdjur"); if ( antalhusdjur > 5 ) System.out.println("Oj det var många);
1 Villkor och styrsatser I de program vi sett tidigare har programkörning inneburit att sats efter sats utförts i den ordning de skrivits i källkoden. Vi har inte kunna ändra programmets uppförande beroende
TANA17 Matematiska beräkningar med Matlab
TANA17 Matematiska beräkningar med Matlab Datorlektion 3. Repetitionssatser och Programmering 1 Introduktion Denna övning syftar till att träna programmering med repetitionssatser och villkorssatser. Undvik
Komponentvisa operationer,.-notation Multiplikation (*), division (/) och upphöj till (ˆ) av vektorer följer vanliga vektoralgebraiska
Matlab-föreläsning 3 (4), 17 september, 2015 Innehåll Sekvenser (från förra föreläsningen) Upprepning med for-slingor och while-slingor Villkorssatser med if - then -else - Logik Sekvenser - repetion från
Föreläsning 9: Turingmaskiner och oavgörbarhet. Turingmaskinen. Den maximalt förenklade modell för beräkning vi kommer använda är turingmaskinen.
Föreläsning 9: Turingmaskiner och oavgörbarhet Turingmaskinen Den maximalt förenklade modell för beräkning vi kommer använda är turingmaskinen. Data är ett oändligt långt band där nollor och ettor står
Föreläsning 3: Booleans, if, switch
TDA 545: Objektorienterad programmering Föreläsning 3: Booleans, if, switch Magnus Myréen Chalmers, läsperiod 1, 2015-2016 Påminnelse om klasser och objekt Boll boll1 = new Boll(5,12); skapar ett nytt
Tentamen TEN1 HI
Tentamen TEN1 HI1029 2014-03-14 Skrivtid: 8.15-13.00 Hjälpmedel: Referensblad (utdelas), papper (tomma), penna Logga in med tentamenskontot ni får av skrivvakten. Det kommer att ta tid att logga in ha
10. Mängder och språk
Objektorienterad modellering och diskreta strukturer 10. Mängder och språk Sven Gestegård Robertz Institutionen för datavetenskap, LTH 2013 Rekaputilation Vi har talat om satslogik, predikatlogik och härledning
Kompilering och exekvering. Föreläsning 1 Objektorienterad programmering DD1332. En kompilerbar och körbar java-kod. Kompilering och exekvering
Föreläsning 1 Objektorienterad programmering DD1332 Introduktion till Java Kompilering, exekvering, variabler, styrstrukturer Kompilering och exekvering Ett program måste översättas till datorns språk
Ekvivalensrelationer
Abstrakt datatyp för disjunkta mängder Vi skall presentera en abstrakt datatyp för att representera disjunkta mängder Kan bl.a. användas för att lösa ekvivalensproblemet avgör om två godtyckliga element
2D1342 Programkonstruktion för F1, ht 2006
2D1342 Programkonstruktion för F1, ht 2006 Lappskrivning 1 Tisdag 7/11 2006 kl 11.15 12.00 Endast ett svar är rätt på varje fråga! Om mer än ett svar givits blir det noll poäng på frågan. Alla skriftliga
Föreläsning 2 Programmeringsteknik och C DD1316. Programmering. Programspråk
Föreläsning 2 steknik och C DD1316 python introduktion Variabler Datatyp Aritmetiska operatorer av typer Reserverade ord logiska operatorer If-sats kommentarer betyder att instruera en dator Ett program
TENTAMEN TDDB53. Programmering i Ada för MI (provkod TEN2) den 7 april 2010 kl Institutionen för datavetenskap, IDA Olle Willén mars 2010
Linköpings universitet Institutionen för datavetenskap, IDA Olle Willén mars 2010 Tentamen TDDB53 TENTAMEN TDDB53 (provkod TEN2) den 7 april 2010 kl 8 12 Jour: Emil Nielsen, tel 070 499 89 88 Hjälpmedel:
Programmering med Java. Grunderna. Programspråket Java. Programmering med Java. Källkodsexempel. Java API-exempel In- och utmatning.
Programmering med Java Programmering med Java Programspråket Java Källkodsexempel Källkod Java API-exempel In- och utmatning Grunderna Ann Pan panda@nada.kth.se Rum 1445, plan 4 på Nada 08-7909690 Game.java
D. x 2 + y 2 ; E. Stockholm ligger i Sverige; F. Månen är en gul ost; G. 3 2 = 6; H. x 2 + y 2 = r 2.
Logik Vid alla matematiskt resonemang måste man vara säker på att man verkligen menar det man skriver ner på sitt papper. Därför måste man besinna hur man egentligen tänker. Den vetenskap, som sysslar
Föreläsning 10 Datalogi 1 DA2001. Utskrift på skärmen. Syntax. print( Hej ) Hur är det? Hej. print( Hej,end= ) print( Hur är det? ) HejHur är det?
Föreläsning 10 Datalogi 1 DA2001 python introduktion Variabler Datatyp Aritmetiska operatorer av typer Reserverade ord logiska operatorer If-sats kommentarer på skärmen print( Hej ) print( Hur är det?
Tentamen. Datalogi I, grundkurs med Java 10p, 2D4112, Lördagen den 30 november 2002 kl , salar E33, E34
Tentamen Datalogi I, grundkurs med Java 10p, 2D4112, 2002-2003 Lördagen den 30 november 2002 kl 9.00 14.00, salar E33, E34 Inga hjälpmedel 30 poäng ger säkert godkänt, 40 poäng ger betyg 4 50 poäng ger
Tentamen i Algoritmer & Datastrukturer i Java
Tentamen i Algoritmer & Datastrukturer i Java Hjälpmedel: Skrivhjälpmedel, miniräknare. Ort / Datum: Halmstad / 2008-05-27 Skrivtid: 4 timmar Kontakt person: Nicolina Månsson, tel. 035-167487 Poäng / Betyg:
Objektorienterad programmering Föreläsning 4
Objektorienterad programmering Föreläsning 4 Copyright Mahmud Al Hakim mahmud@dynamicos.se www.webbacademy.se Agenda Introduktion till objektorientering Klasser och Objekt Instansvariabler Metoder Introduktion
Booleska variabler och översättning mellan programuttryck och booleska variabler
Vad är Boolesk algebra Lite förenklat kan man säga att Boolesk algebra är räkneregler konstruerade av den engelske matematikern Gerge Boole för att kunna räkna med logiska uttryck. I den booleska algebran
TDDC74 Programmering: Abstraktion och modellering Tentamen, onsdag 9 juni 2016, kl 14 18
TDDC74 Programmering: Abstraktion och modellering Tentamen, onsdag 9 juni 2016, kl 14 18 Läs alla frågorna först, och bestäm dig för i vilken ordning du vill lösa uppgifterna. Skriv tydligt och läsligt.
Datatyper och kontrollstrukturer. Skansholm: Kapitel 2) De åtta primitiva typerna. Typ Innehåll Defaultvärde Storlek
De åtta primitiva typerna Java, datatyper, kontrollstrukturer Skansholm: Kapitel 2) Uppsala Universitet 11 mars 2005 Typ Innehåll Defaultvärde Storlek boolean true, false false 1 bit char Tecken \u000
Omgivningar. Omgivningar är viktiga eftersom de avgör vilka namn som är synliga och därmed dessas innebörd och de värden som är förknippade med dem.
Omgivningar Omgivningar är viktiga eftersom de avgör vilka namn som är synliga och därmed dessas innebörd och de värden som är förknippade med dem. (define (sqrroot c) (define (fixpoint guess c eps) (define
Algoritmanalys. Inledning. Informationsteknologi Malin Källén, Tom Smedsaas 1 september 2016
Informationsteknologi Malin Källén, Tom Smedsaas 1 september 2016 Algoritmanalys Inledning Exempel 1: x n När vi talade om rekursion presenterade vi två olika sätt att beräkna x n, ett iterativt: x n =
Programmering I Tobias Wrigstad fredag, 2009 augusti 28
Programmering I Tobias Wrigstad tobias@dsv.su.se Vad är programmering? Lågnivåspråk och högnivåspråk Kompilering och interpretering Variabler Notation för flödesschema (flow chart) Kontrollstrukturer (conditionals,
Översikt över Visual Basic
Översikt över Visual Basic Om denna översikt Denna översikt ger en kort introduktion till de viktigaste delarna i programspråket Visual Basic 6.0. På alla ställen där det beskrivs hur man skriver kod gäller
Pascal... Pascal. Pascal... Pascal...
... Programspråk uppkallat efter Blaise. Skapat av Nicolaus Wirt. Avsett för undervisning för att lära ut typbegreppet och styrstrukturer. Har fått stor spridning p.g.a. enkelhet och att kompilatorn varken
Översikt. Varför lära sig detta? Motivering Syntax och semantik Imperativa språkets byggstenar och Python. PL-boken Kap 1 (repetition):
Översikt Motivering Syntax och semantik Imperativa språkets byggstenar och Python Datatyper Tilldelning och uttryck Kontrollstrukturer (på satsnivå) Subprogram Relaterade avsnitt: PL 3.1-3.2, 5.1-5.3,
Block 1 - Mängder och tal
Block 1 - Mängder och tal Mängder Mängder och element Venndiagram Delmängder och äkta delmängder Union och snittmängd Talmängder Heltalen Z Rationella talen Q Reella talen R Räkning med tal. Ordning av
Block 2 Algebra och Diskret Matematik A. Följder, strängar och tal. Referenser. Inledning. 1. Följder
Block 2 Algebra och Diskret Matematik A BLOCK INNEHÅLL Referenser Inledning 1. Följder 2. Rekursiva definitioner 3. Sigmanotation för summor 4. Strängar 5. Tal 6. Övningsuppgifter Referenser Följder, strängar
Pascal. reserverade ord fördefinierade funktioner och procedurer egendefinierade funktioner, procedurer och objekt
Programspråk uppkallat efter Blaise. Skapat av Nicolaus Wirt. Avsett för undervisning för att lära ut typbegreppet och styrstrukturer. Har fått stor spridning p.g.a. enkelhet och att kompilatorn varken