Gentle Beispielprogramme mit besonderen Gentle-Befehlen Zwischen zwei Sternchen-Zeilen steht jeweils ein lauffaehiges Gentle-Programm. Am Ende des Programms findet man Kommentarzeilen, die die Ausgabe des Programms enthalten. *************************************************************************** // ----------------------------------------------------------------------- // File pred03\alternatives01.g // An example in which an alternatives statement is possibly // of great advantage. // // Does not contain token or phrase predicates. //------------------------------------------------------------------------ // The predicates processA and processB solve the same problem, // processA with several rules and // processB with an alternatives statement in only one rule. // processA calls the procedure expensive more often then processB. //------------------------------------------------------------------------ proc processA(N:int) rule processA(N): expensive(N -> RES) RES -> 1 "*** The result was 1!\n\n" rule processA(N): expensive(N -> RES) RES -> 2 "*** The result was 2!\n\n" rule processA(N): expensive(N -> RES) RES -> 3 "*** The result was 3!\n\n" rule processA(N): "*** The result was something else!\n" //------------------------------------------------------------------------ proc processB(N:int) rule processB(N): expensive(N -> RES) { RES -> 1 "*** The result was 1!\n\n" | RES -> 2 "*** The result was 2!\n\n" | RES -> 3 "*** The result was 3!\n\n" | "*** The result was something else!\n" } //------------------------------------------------------------------------ proc expensive(N:int -> RES:int) // Computes RES as N mod 17 // Assume that this predicate is expensive to execute rule expensive(N -> N - (N/17*17)): "expensive was called!\n" //------------------------------------------------------------------------ root "-------------------------------\n" "processA:\n\n" processA(1) processA(2) processA(3) processA(-123) "-------------------------------\n" "processB:\n\n" processB(1) processB(2) processB(3) processB(-123) "-------------------------------\n" //------------------------------------------------------------------------ // Output of this program: // ------------------------------- // processA: // // expensive was called! // *** The result was 1! // // expensive was called! // expensive was called! // *** The result was 2! // // expensive was called! // expensive was called! // expensive was called! // *** The result was 3! // // expensive was called! // expensive was called! // expensive was called! // *** The result was something else! // ------------------------------- // processB: // // expensive was called! // *** The result was 1! // // expensive was called! // *** The result was 2! // // expensive was called! // *** The result was 3! // // expensive was called! // *** The result was something else! // ------------------------------- *************************************************************************** // ----------------------------------------------------------------------- // File pred03\alternatives02.g // Demonstrates the alternatives statement. //------------------------------------------------------------------------ // The predicates evalA, evalB and evalC compute the same function // (they all evalute expressions of type Exp) // // evalA consists of 5 rules, one for each case (14 lines) // evalB consists of 2 rules, the first of which contains // an alternatives statement (14 lines) // evalC the same as evalB, only typed with a different layout (11 lines) // ----------------------------------------------------------------------- type Op2 add() sub() mul() div() type Exp exp(Op2, Exp, Exp) lit(int) // ------------------------------------------------------------------------ proc evalA(Exp -> int) rule evalA(exp(add(), E1, E2) -> N1+N2): evalA(E1 -> N1) evalA(E2 -> N2) rule evalA(exp(sub(), E1, E2) -> N1-N2): evalA(E1 -> N1) evalA(E2 -> N2) rule evalA(exp(mul(), E1, E2) -> N1*N2): evalA(E1 -> N1) evalA(E2 -> N2) rule evalA(exp(div(), E1, E2) -> N1/N2): evalA(E1 -> N1) evalA(E2 -> N2) rule evalA(lit(N) -> N): // ------------------------------------------------------------------------ proc evalB(Exp -> int) rule evalB(exp(OP, E1, E2) -> V): evalB(E1 -> V1) evalB(E2 -> V2) { OP -> add() V <- V1+V2 | OP -> sub() V <- V1-V2 | OP -> mul() V <- V1*V2 | OP -> div() V <- V1/V2 } rule evalB(lit(N) -> N): // ------------------------------------------------------------------------ proc evalC(Exp -> int) rule evalC(exp(OP, E1, E2) -> V): evalC(E1 -> V1) evalC(E2 -> V2) { OP -> add() V <- V1+V2 | OP -> sub() V <- V1-V2 | OP -> mul() V <- V1*V2 | OP -> div() V <- V1/V2 } rule evalC(lit(N) -> N): // ------------------------------------------------------------------------ proc test1(Exp) rule test1(E): evalA(E -> VA) evalB(E -> VB) evalC(E -> VC) "------\n" "VA: " $VA "\n" "VB: " $VB "\n" "VC: " $VC "\n" // ------------------------------------------------------------------------ root test1(exp(add(), lit(1), lit(1))) test1(exp(sub(), exp(mul(), lit(2), lit(3) ), exp(div(), lit(8), exp(add(), lit(1), lit(3)) ) ) ) // ------------------------------------------------------------------------ // Output of this program: // // ------ // VA: 2 // VB: 2 // VC: 2 // ------ // VA: 4 // VB: 4 // VC: 4 *************************************************************************** // ----------------------------------------------------------------------- // File pred03\alternatives03.g // Nested alternatives statements //------------------------------------------------------------------------ proc pBase3(N1:int, N2:int) // Prints a single entry of the multiplication table // for base 3 numbers, from 1x1 up to 10x10 (i.e. 3x3) rule pBase3(N1, N2): { N1 -> 1 { N2 -> 1 " 1x 1 = 1\n" | N2 -> 2 " 1x 2 = 2\n" | N2 -> 3 " 1x10 = 10\n" | "Parameter N2: " $N2 " is out of range\n" } | N1 -> 2 { N2 -> 1 " 2x 1 = 2\n" | N2 -> 2 " 2x 2 = 11\n" | N2 -> 3 " 2x10 = 20\n" | "Parameter N2: " $N2 " is out of range\n" } | N1 -> 3 { N2 -> 1 "10x 1 = 10\n" | N2 -> 2 "10x 2 = 20\n" | N2 -> 3 "10x10 = 100\n" | "Parameter N2: " $N2 " is out of range\n" } | "Parameter N1: " $N1 " is out of range\n" } //------------------------------------------------------------------------ root "-----------------------\n" "1x1 for base 3 numbers:\n" "-----------------------\n" pBase3(1, 1) pBase3(1, 2) pBase3(1, 3) "------------\n" pBase3(2, 1) pBase3(2, 2) pBase3(2, 3) "------------\n" pBase3(3, 1) pBase3(3, 2) pBase3(3, 3) "------------\n" pBase3(0, 1) pBase3(1, 4) "------------\n" (@ ------------------------------------------------------------------------ Output of this program (as a multi line comment): ----------------------- 1x1 for base 3 numbers: ----------------------- 1x 1 = 1 1x 2 = 2 1x10 = 10 ------------ 2x 1 = 2 2x 2 = 11 2x10 = 20 ------------ 10x 1 = 10 10x 2 = 20 10x10 = 100 ------------ Parameter N1: 0 is out of range Parameter N2: 4 is out of range ------------------------------------------------------------------------ @) *************************************************************************** (@ ------------------------------------------------------------------------ File pred03\qups02.g Demonstriert QUPs (query update pairs) NaechsteMatNr ist ein einfaches QUP (simple query update pair) MatNr ist ein Funktions-QUP (function query update pair) ------------------------------------------------------------------------ @) data NaechsteMatNr(-> int) // Definiert 2 Praedikate: // Set-NaechsteMatNr(int) // Get-NaechsteMatNr(-> int) // ------------------------------------------------------------------------ data Name2MatNr(string -> int) // Definiert 2 Praedikate: // Set-Name2MatNr(string, int) // Get-Name2MatNr(string -> int) // ------------------------------------------------------------------------ proc imma(Name:string -> MatNr:int) // "imma" wie "Immatrikulation" // Holt sich aus dem Qups NaechsteMatNr die naechste (noch freie) // Matrikrel-Nr NM und erhoeht den Wert von NaechsteMatNr um 1. // Traegt den Name als Schluessel mit dem Wert NM in das Qups // Name2MatNr ein. Liefert NM als Wert des out-Params MatNr. rule imma(NAM -> NM): Get-NaechsteMatNr(-> NM) Set-NaechsteMatNr(NM+1) Set-Name2MatNr(NAM, NM) // ------------------------------------------------------------------------ proc p(Name:string) // Gibt den Name und die dazugehoerige Matrikel-Nr (falls vorhanden) // aus. Fehlermeldung, wenn Name noch nicht immatrikuliert ist. rule p(NAM): { Get-Name2MatNr(NAM -> MN) "Name: " $NAM ", MatNr: " $MN "\n" | $NAM " ist noch nicht immatrikuliert!\n" } // ------------------------------------------------------------------------ root // Die NaechsteMatNr initialisieren: Set-NaechsteMatNr(100101) // Zwei StudentInnen werden imatrikuliert: imma("Anna" -> ANR) imma("Bert" -> BNR) // Immatrikulations-Daten ausgeben: p("Anna") p("Bert") p("Carl") (@ ------------------------------------------------------------------------ Ausgabe: Name: Anna, MatNr: 100101 Name: Bert, MatNr: 100102 Carl ist noch nicht immatrikuliert! ------------------------------------------------------------------------ @) *************************************************************************** // ----------------------------------------------------------------------- // File pred03\optionTypes01.g // Demonstrates option types. //------------------------------------------------------------------------ type NAME nam(LastName:string, FirstName:string?) // LastName is mandatory, FirstName is optional proc pNAME(NAME) // Pretty prints a NAME rule pNAME(nam(LN, string?())): "Last name: " $LN "\n" rule pNAME(nam(LN, string?(FN))): "First and last Name: " $FN " " $LN "\n" root Present <- int?(123) "-------------------------------- A\n" "log Present: \n" log Present Present -> int?(N) "-------------------------------- B\n" "log N:\n" log N "-------------------------------- C\n" Missing <- int?() "log Missing: \n" log Missing "-------------------------------- D\n" { Present -> int?() "Present -> int?() suceeded!\n" | "Present -> int?() failed!\n" } "-------------------------------- E\n" { Missing -> int?() "Missing -> int?() suceeded!\n" | "Missing -> int?() failed!\n" } "-------------------------------- F\n" // A Name WITH a first name (which is optional): Name1 <- nam("Meyer", string?("Otto")) "log Name1:\n" log Name1 "-------------------------------- \n" "pNAME(Name1):\n" pNAME(Name1) "-------------------------------- G\n" // A Name WITHOUT a first name (which is optional): Name2 <- nam("Schulz", string?()) "log Name2:\n" log Name2 "-------------------------------- \n" "pNAME(Name2):\n" pNAME(Name2) "-------------------------------- H\n" (@ ------------------------------------------------------------------------ Output of this program: -------------------------------- A log Present: int?( 123 ) -------------------------------- B log N: 123 -------------------------------- C log Missing: int?() -------------------------------- D Present -> int?() failed! -------------------------------- E Missing -> int?() suceeded! -------------------------------- F log Name1: nam( "Meyer", string?( "Otto" ) ) -------------------------------- pNAME(Name1): First and last Name: Otto Meyer -------------------------------- G log Name2: nam( "Schulz", string?() ) -------------------------------- pNAME(Name2): Last name: Schulz -------------------------------- H ------------------------------------------------------------------------ @) ***************************************************************************