Modellierungsgrundsätze


... [ Seminar "Programmierkonzepte und Programmiersprachen" ] ... [ Inhaltsverzeichnis ] ... [ zurück ] ... [ weiter ] ...

Übersicht: Modellierungsgrundsätze


Transformation einer Funktion

Im Folgenden soll anhand einer kleinen in C geschriebenen Funktion gezeigt werden, wie diese in eine äquivalente Regel der logischen Programmierung mit Einschränkungen transformiert werden kann. Hierbei handelt es sich um eine Funktion, die die Restschuld eines Kreditnehmers nach n-Jahren mit konstanter Rückzahlung berechnet.

In der Funktion werden folgende Variablen verwendet, deren Bedeutung noch kurz erläutert werden soll.
P : (Rest-)Schuld
T : Laufzeit
I : Prozentsatz der Verzinsung
P : Rate, welche pro T zurückgezahlt wird

Die Ausgangsfunktion lautet
float kredit1(float P, int T, float I, float R) {
    while ( T >= 1 ) {
        P = P + P * I – R;
        T = T - 1;
    }
    return P;
}

Zuerst wird in dieser Funktion die Iteration durch einen rekursiven Aufruf ersetzt. Die Abbruchbedingung der Schleife (T >= 1) wird in eine if-Bedingung übernommen, um zu gewährleisten, dass die Funktion terminiert.
float kredit2(float P, int T, float I, float R) {
    if ( T >= 1 ) {
        P = P + P * I – R;
        T = T - 1;
        return kredit2(P,T,I,R);
    }
    else return P;
}

Als nächstes werden zwei Hilfsvariablen, NP und NT, eingeführt, die die Ergebnisse der Zwischenrechnungen aufnehmen. Dies ist notwendig, da Problemvariablen wie auch bei der logischen Programmierung nur einen Wert annehmen können.
float kredit3(float P, int T, float I, float R) {
    if ( T >= 1 ) {
        float NP = P + P * I – R;
        int NT = T - 1;
        return kredit2(NP,NT,I,R);
    }
    else return P;
}

Da Regeln in der logischen Programmierung mit Einschränkungen keinen Rückgabewert haben, wird für das Ergebnis eine zusätzliche Variable als Parameter übergeben.
kredit4 void(float P, int T, float I, float R, float *B) {
    if ( T >= 1 ) {
        float NP = P + P * I – R;
        int NT = T - 1;
        return kredit2(NP,NT,I,R,B);
    }
    else *B = P;
}

Die Funktion lässt sich nun sehr einfach in zwei Regeln der logischen Programmierung mit Einschränkungen transformieren. Besonders wichtig hierbei ist, dass das Gegenstück zur Bedingung aus der if-Klausel in der Regel ohne rekursiven Aufruf auftaucht, um sicherzustellen, dass diese terminiert. In diesem Fall wäre es das Constraintatom "T #= 0".
kredit(P, T, I, R, B) :-
    T #>= 1,
    NP = P + P * I – R,
    NT = T – 1,
    kredit(NP,NT,I,R,B).

kredit(P, T, I, R, B) :-
    T #= 0,
    B = P.


Regelordnung

Es existieren zwei simple Vorschriften, in welcher Reihenfolge gleichnamige Regeln im Programm angeordnet werden sollen.

Die erste Vorschrift sagt aus, dass Regeln ohne Rekursion immer vor Regeln mit einem rekursivem Aufruf stehen sollen. Dies stellt sicher, dass im Falle einer unter Umständen fehlerhaften rekursiven Regel das Programm terminiert. Somit sollte im obigen Beispiel die Reihenfolge der Regeln getauscht werden.

Des Weiteren sollten Regeln mit gro฿er Wahrscheinlichkeit auf Erfolg zuerst im Programm vorkommen. Dies führt dazu, dass die Lösungen im Durchschnitt schneller im linken Teil des Baums gefunden werden. Bei der Wahrscheinlichkeit handelt es sich um einen statistischen Wert, der sich jeweils nur problemspezifisch berechnen lässt.


... [ Seminar "Programmierkonzepte und Programmiersprachen" ] ... [ Inhaltsverzeichnis ] ... [ zurück ] ... [ weiter ] ...