BuK/IIm10/BuK-Kreativaufgabe10 G2
Aus ProgrammingWiki
Wiki-Quelltext dieser Seite.
<language>Scheme</language>
<code id="4e0073febe720" hidden>
(define add1 (lambda (n)
(+ n 1)))
(define sub1 (lambda (n)
(- n 1)))
(define P (lambda (n)
(if (= n 0)
0
(sub1 n))))
</code>
== Aufgabenstellung ==
Entwickeln Sie einen Werkzeugkasten für primitiv rekursive Funktionen.
Es wird erwartet, dass aus primitiv rekursiven (Basis-)Funktionen unter Verwendung der
Kompositionstechniken (Substitution und primitive Rekursion) neue primitiv rekursive
Funktionen generiert werden. Diese sollen verwendbar sein.
Es wird nicht erwartet, dass ein universelles Beweisprogramm, das für eine gegebene
Funktion konstruktiv nachweist, dass sie primitiv rekursiv ist, entwickelt wird.
== Basisfunktionen ==
Zuerst definieren wir die Basisfunktionen.
<code id="4e0073febe788">
(define S
(lambda (n)
(add1 n)))
(define C0
(lambda n 0))
(define U
(lambda (i . n)
(letrec
([helper
(λ (counter args)
(if (= counter i)
(car args)
(helper (+ counter 1) (cdr args))))])
(helper 1 n))))
</code>
Die Nullfunktion kann mit beliebig vielen Parametern aufgerufen werden.
<run id="4e00745e40e2d">
(C0)
</run>
<run id="4e0076eb7301d">
(C0 1 2 3 4)
</run>
Die Projektionsfunktion erwartet als ersten Parameter den Inde des zu ermittelnden Arguments und anschließend eine variable Anzahl von Argumenten.
<run id="4e0076eb7309e">
(U 1 1 2 3)
</run>
<run id="4e0076eb73122">
(U 3 1 2 3)
</run>
Als nächstes definieren wir die Substitution und die primitive Rekursion:
<code>
(define my-apply
(lambda (ls)
(apply (car ls) (cdr ls))))
(define substitute
(lambda (f . g)
(lambda n ; h
(apply f
(map my-apply
(map
(lambda (currentG)
(cons currentG n))
g))))))
(define prim-rec
(lambda (f g)
(lambda ni
(letrec
([h
(lambda (n1 rest)
(if (= 0 n1)
(f rest)
(g n1 (h (P n1) rest) rest)
))])
(h (car ni) (cdr ni))))))
</code>
An Hand einiger Beispiele kann die Funktionsweise der beiden Prozeduren nachvollzogen werden.
Als erstes betrachten wir die Potenzierung. Die beiden benötigten
Prozeduren <math>f</math> und <math>g</math> werden wie folgt definiert:
<code>
(define pot-f
(lambda (a)
(C 1 a)))
(define pot-g
(lambda (n h . args)
(let ((x n) (a (caar args)))
(mult (U 3 (P x) h a)
(U 2 (P x) h a)))))
</code>
Um nun aus diesen beiden Prozeduren die Potenzfunktion zu generieren wird die primitive Rekursion angewandt:
<code>
(define pot-x-a (prim-rec pot-f pot-g))
</code>
<run>
(pot-x-a 2 5)
</run>