Document

Werbung
Algorithmen und Programmierung 2
Aufgabenlösung zum
Übungsblatt 4
Aufgabe
Punkte
1
/8
2
/5
3
/7
Ø
/20
%
Tutor: Nils Barnickel - Freitag 14h-16h
Gruppe: Stephan Scheerer (3790010), Tobias Losch (3675100)
Lösung zum Aufgabenblatt 4 Aufgabe 1
(a)
sei {P} {u>=1  v>=1}
wähle I:
{ ggT(x,y) = ggT(u,v) }
1)
{ggT(x,y-x)=ggT(u,v)  x=<y} S2 {I}
=ggT(x,y)
{ggT(x-y,y)=ggT(u,v) x=y} S1 {I}
=ggT(x,y)
=> {ggT(x,y)=ggT(u,v)} Sif {I}
{I’}
also gilt {I’} Sif {I}
2)
es ist {IB}={x≠y  ggT(x,y)=ggT(u,v)}
also {IB} => {I’}
außerdem {IB} => {ggT(x,y)=gg(u,v)  x=y}
 {ggT(x,x)=ggT(u,v)}
 {x=ggT(u,v)}
also {IB}=>{Q} damit {I}w{Q}
und: {u>=1  v>=1}z{I}
{P} zw {Q}
=> {P} P {Q}
damit ist die potentielle Korrektheit bewiesen.
Beweisen der Termination
Wir zeigen: in jedem Durchlauf wird x oder y um mindestens 1 verringert, aber werden nie <1 => x ist
spätestens gleich y, wenn x=y=1
Fall 1: x>y und x>1,y>=1 nach {P}
=> x>x-y>=1 wie gefordert.
Fall 2: x<y und x>=1, y>1 nach {P}
Nicht gleich, sonst bricht die Schleife ab.
=> y>y-x>=1 wie gefordert.
Also x oder y verringern sich in jedem Durchlauf der Schleife und werden nie <1.
=> Die Schleife terminiert.
(b)
{P} = {n>1}
c=n;
S1
z=0;
SSch
while (c != 1)
SSch1 if (c%2 == 0) c=c/2;
SSch2 else c=3*c+1;
SSch3 z=z+1 ;
{Q} = {z  1  c=1}
Invariante {I} = {n  1  z  0  c  1}
Schritt 1 : {P} S1{I}
{n  1}  {0  0}  {c  c}
c=n; {c  1}  {0  0}  {n  c}
z=0; {n  1}  {z  0}  {n  c}
=> {I}
Schritt 2 : {I  BSch} SSch {I}
2a: {I  BSch  Bif} SSch1/3 {I}
{n  1  z  0  c  1}  {c ! 1}  {c%2  0}
{n  1  z  1 - 1  0  c  1}  {c%2  0}
{n  1  z  1 - 1  0  c/2  1}  {c/2%2  0}
c=c/2 ;
{n  1  z - 1  0  c/2  1}  {c/2%2  0}
z=z+1;
{n  1  z  1  c/2  1}  {c/2%2  0}
=> {I}
2b: {I  BSch   Bif} SSch2/3 {I}
{n  1  z  0  c  1}  {c ! 1}  {c%2 ! 0}
{n  1  z  1 - 1  0  c  1}  {c ! 1}  {c%2 ! 0}
c=3*c+1; {n  1  z  1 - 1  0  3 * c  1  1}  {3 * c  1! 1}  {3 * c  1%2 ! 0}
{n  1  z - 1  0  3 * c  1  1}  {3 * c  1! 1}  {3 * c  1%2 ! 0}
z=z+1;
{n  1  z  1  c  0}  {c ! 0}  {3 * c  1%2 ! 0}
=> {I}
Schritt 3: {I   BSch} nop {Q}
//nop = no Operation
{n  1  z  0  c  1}  {c  1}
{n  1  z  0  c  1}
wegen n>1 ist mindestens 1 Schleifendurchlauf nötig, daher ist z > 0
=>{Q}
=>Programm ist partiell korrekt
Die totale Korrektheit kann für dieses Programm nicht bewiesen werden, da bisher noch keine
Terminierungsfunktion für die „3-n-Funktion“ gefunden wurde.
Lösung zum Aufgabenblatt 3 Aufgabe 2
Die funktionale Programmiersprache Haskell sowie die Logikprogrammiersprache PROLOG gehören zu den
deklarativen Programmiersprachen. Sie werden z.B. durch einfache formale – meist auch mathematische Beschreibungen definiert. Bei Ausführung wird durch den Interpreter in diese Formeln Werte eingesetzt und
diese Formeln werden dann mit Hilfe von Musteranpassung ausgewertet oder durch einfaches Auswerten
ausgewertet. Da diesen einfache mathematische Regeln zu Grunde liegen, ist es einfacher diese Sprache
auszuwerten, als z.B. bei C oder anderen höheren Programmiersprachen. Die Befehle beschränken sich auch
ebenfalls auf einfache Befehle und eine einfache Werteausgabe, es gibt z.B. keine komplexe grafische
Oberfläche.
Dadurch, dass die Sprachen einer mathematischen Definition folgen, ist es nicht notwendig bzw. überflüssig ein
Compiler zu schreiben, da diese Sprache leichter eine Eingabe interpretieren kann.
Lösung zum Aufgabenblatt 3 Aufgabe 3
(a)
// Lösung zu Übungsblatt 4 - Aufgabe 3a
// Tutor: Nils Barnickel / Freitag 14-16h
// Gruppe: Stephan Scheerer, Tobias Losch
public class ALP20403a
{
public static void main(String[] args)
{
System.out.println("Die ersten 40 Fibonacci Zahlen");
int d=1; // a0
int f=1; // a1
for (int i=1; i<=20 ; i++ ) // 2*20 Berechnungen an+2=an+1+an
{
System.out.println(d+"\n"+f); // Fibonacci Zahlen ausgeben
d=d+f; // Neue Fibonacci Zahlen ausrechnen
f=d+f;
}
}
}
/* ######################################################################
Testeingabe:
>java ALP20403a
Die ersten 40 Fibonaccizahlen
1
1
2
3
5
8
13
…
63245986
102334155
###################################################################### */
(b)
// Lösung zu Übungsblatt 4 - Aufgabe 3b
// Tutor: Nils Barnickel / Freitag 14-16h
// Gruppe: Stephan Scheerer, Tobias Losch
public class ALP20403b
{
public static void main(String[] args)
{
System.out.println("Alle Primzahlen zwischen 1 und 1000");
for(int i=1; i<=1000; i++) // Schleife für alle Zahlen zwischen 1 und 1000
{
boolean isPrime=true; // Variable, ob Zahl Primzahl ist
for(int j=1; j<=i/2; j++) if(((i%j)==0)&&(j>1)) isPrime=false; // Teilt i von 1 bis i/2 und falls ein Rest nicht 0 ist, ist keine Primzahl
if(isPrime) System.out.println(i); // Primzahl ermittelt? Dann ausgeben
}
}
}
/* ######################################################################
Testeingabe:
>java ALP20403b
Alle Primzahlen zwischen 1 und 1000
1
2
3
5
7
11
13
…
991
997
###################################################################### */
Herunterladen