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. |
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.