StartseiteSitemapDownloadsHilfeImpressumPOV-Ray-Zauberwürfel Chat


Startseite

Setty−Handbuch

Setty

Setty (Set=Menge) ist eine Sprache zur schulischen Mengenlehre und vielleicht sogar ganz brauchbar für den Mathematikunterricht. Mit einem Setty−Programm kann nämlich prägnant geprüft werden, ob eine gegebene ZAHL in einer gegebenen MENGE liegt oder nicht. Ein Setty−Programm ist kurz (sehr kurz!) und besitzt die Form eines Fragesatzes: Aber auch die Variante der Negation ist in Setty integriert: Ein Setty−Programm ist als Satzfrage zu verstehen, d. h. als Antwort erwartet man „yes” oder „no”.

Beispiele

Beim Schreiben eines Setty−Programms kann man sich weitgehend auf seine Intuition verlassen, d. h. eine ZAHL schreibt man als Zahl und eine MENGE schreibt man als Menge, so wie man es aus der Schule kennt.
Im Folgenden werden einige ausgewertete Setty−Programm−Beispiele aufgelistet: Ein Setty−Programm endet stets mit dem Fragezeichen.
Der Pfeil „−>” signalisiert die Antwort des dazugehörigen Interpreters (siehe Setty−Interpreter).

Grammatik

Für die Hartgesottenen unter Ihnen gibt es natürlich auch, die vollständige Grammatik der Setty−Sprache zu sehen:

Die Grammatik der Setty−Sprache

Setty-Grammatik SG = (NTPS) mit

N = {Program, SetU, SetI, SetD, Set, From, To},

T = {LPAREN1      := '(',     RPAREN1      := ')',
     LPAREN2      := '[',     RPAREN2      := ']',
     LPAREN3      := '{',     RPAREN3      := '}',
     PLUS         := '+',     MINUS        := '-',
     SEMICOLON    := ';',     QUESTIONMARK := '?',
     COMPLEMENT   := 'C',     UNION        := 'u'|'v',
     INTERSECTION := 'n',     DIFFERENCE   := '\',
     IS           := 'Is',    IN           := 'in',
     NOT          := 'not',
     NUMBER       := ['+'|'-']('0'-'9')+['.'('0'-'9')+],
     INFINITY     := 'inf'},

P = {Program ::= IS NUMBER [ NOT ] IN SetU QUESTIONMARK,
     SetU    ::= SetI ( UNION SetI )*,
     SetI    ::= SetD ( INTERSECTION SetD )*,
     SetD    ::= Set [ DIFFERENCE Set ],
     Set     ::= COMPLEMENT LPAREN1 SetU RPAREN1
               | LPAREN1 SetU RPAREN1
               | LPAREN3 [ NUMBER ( SEMICOLON NUMBER )* ] RPAREN3
               | From SEMICOLON To,
     From    ::= RPAREN2 ( NUMBER | MINUS INFINITY )
               | LPAREN2 NUMBER,
     To      ::= NUMBER ( LPAREN2 | RPAREN2 )
               | [ PLUS ] INFINITY LPAREN2} und

S = Program.
Die Mengen-Aliase E und R sind nicht Bestandteil der Setty−Grammatik. Um diese Aliase kümmert sich der Setty−Präprozessor.



Setty−Interpreter

Der Setty−Interpreter wertet ein gegebenes Setty−Programm aus und gibt das Ergebnis auf der Konsole aus.
Folgendes Programm, welches den Setty−Interpreter in Java implementiert, ist bemerkenswert kurz und übersichtlich. Der Grund dafür ist, dass ein Interpreter im Wesentlichen alle notwendigen Aufgaben an seine Komponenten delegiert:
  1. Präprozessor,
  2. Scanner,
  3. Parser und
  4. Syntaxbaum.
Lassen wir doch einfach mal dieses Programm für sich alleine sprechen! :−)

Der Setty−Interpreter realisiert in Java

/**
 * Die Klasse Setty interpretiert die gleichnamige Quellsprache auf viererlei
 * unterschiedliche Arten:
 *    1. Auswertung des Quellprogramms (eval)
 *    2. Ausgabe eines gleichwertigen C-Programms (c)
 *    3. Ausgabe eines gleichwertigen Pascal-Programms (pascal)
 *    4. Ausgabe eines gleichwertigen SML-Programms (sml)
 */

public class Setty {

  /**
   * Der Setty-Interpreter, das Hauptprogramm.
   * @param arguments Die Aufrufparameter.
   *                  Der erste Parameter gibt den Typ der Ausgabe und
   *                  der zweite Parameter das Setty-Programm als String an.
   */

  public static void main(String[] arguments) {

    if (arguments.length == 2) {

      /* Präprozessor:
       * Der Präprozessor bereitet das gegebene Setty-Programm "arguments[1]"
       * zur weiteren Analyse vor.
       */

      Preprocessor preprocessor = new Preprocessor(arguments[1]);

      /* Scanner:
       * Der Scanner erhält das vom Präprozessor bearbeitete Setty-Programm
       * zur lexikalischen Analyse.
       */

      Scanner scanner = new Scanner(preprocessor.program());

      /* Parser:
       * Der Parser erhält diesen Scanner zur syntaktischen Analyse.
       */

      Parser parser = new Parser(scanner);

      try {

        // Der Parse-Vorgang erzeugt den Syntaxbaum (parseTree)
        // Während dem Parse-Vorgang können ParseExceptions auftreten
        ProgramNode parseTree = parser.parse();

        // Ausgabe gemäß Aufruf (eval|c|pascal|sml) "arguments[0]"
        if (arguments[0].toLowerCase().equals("eval")) {

          // Auswertung des Quellprogramms ("yes" oder "no")
          System.out.println(arguments[1] + " -> " + parseTree.getResult());

        } else if (arguments[0].toLowerCase().equals("c")) {

          // Ausgabe eines gleichwertigen C-Programms
          System.out.println(parseTree.generateCCode());

        } else if (arguments[0].toLowerCase().equals("pascal")) {

          // Ausgabe eines gleichwertigen Pascal-Programms
          System.out.println(parseTree.generatePascalCode());

        } else if (arguments[0].toLowerCase().equals("sml")) {

          // Ausgabe eines gleichwertigen SML-Programms
          System.out.println(parseTree.generateSmlCode());

        } else {

          // Ausgabe der Kurzhilfe, da unbekannter Parameter verwendet wird
          System.err.println(usage());
        }

      } catch (ParseException pe) {

        // Quellprogramm (Setty-Programm) ist fehlerhaft, da ParseException
        System.err.println(pe.getMessage());
      }

    } else {

      // Ausgabe der Kurzhilfe
      System.out.println(usage());
    }
  }

  /**
   * Erläuterung zum korrekten Aufruf des SettyInterpreters (Kurzhilfe).
   * @return Die Kurzhilfe als Zeichenkette.
   */

  public static String usage() {

    String result = "java Setty (eval|c|pascal|sml) <SettyProgramm>\r\n";

    result += "\r\nBeispiele zur Auswertung:\r\n";
    result += "    java Setty eval \"Is 1 in {}?\"\r\n";
    result += "    java Setty eval \"Is 2.0 not in C([0;+inf[)?\"\r\n";
    result += "    java Setty eval \"Is 0.5 in ]-1;4.0[ n ]-inf;+3.0]?\"\r\n";

    result += "\r\nBeispiele zur Ausgabe eines C-Programms:\r\n";
    result += "    java Setty c \"Is 1 in {-1;0;+1}?\"\r\n";
    result += "    java Setty c \"Is 1 in [-1;+1]?\"\r\n";
    result += "    java Setty c \"Is 1 in ]-1;+1[ \\ {0}?\"\r\n";

    result += "\r\nBeispiele zur Ausgabe eines Pascal-Programms:\r\n";
    result += "    java Setty pascal \"Is 7 not in ({} v {1}) n {1;2}?\"\r\n";
    result += "    java Setty pascal \"Is 11 in ]-inf;-1[ v ]1;+inf[?\"\r\n";
    result += "    java Setty pascal \"Is 2 in E \\ E v R \\ R?\"\r\n";

    result += "\r\nBeispiele zur Ausgabe eines SML-Programms:\r\n";
    result += "    java Setty sml \"Is 2 in C(]-inf;5[) \\ {2.0}?\"\r\n";
    result += "    java Setty sml \"Is 0.5 in {0.5} n ]-3.0;inf[?\"";

    return result;
  }
}

Kurzhilfe im Klartext

Wenn der Setty−Interpreter ohne Parameter gestartet wird, erhält der Benutzer folgende Kurzhilfe zum Aufruf des Setty−Interpreters.

java Setty

java Setty (eval|c|pascal|sml) <SettyProgramm>

Beispiele zur Auswertung:
    java Setty eval "Is 1 in {}?"
    java Setty eval "Is 2.0 not in C([0;+inf[)?"
    java Setty eval "Is 0.5 in ]-1;4.0[ n ]-inf;+3.0]?"

Beispiele zur Ausgabe eines C-Programms:
    java Setty c "Is 1 in {-1;0;+1}?"
    java Setty c "Is 1 in [-1;+1]?"
    java Setty c "Is 1 in ]-1;+1[ \ {0}?"

Beispiele zur Ausgabe eines Pascal-Programms:
    java Setty pascal "Is 7 not in ({} v {1}) n {1;2}?"
    java Setty pascal "Is 11 in ]-inf;-1[ v ]1;+inf[?"
    java Setty pascal "Is 2 in E \ E v R \ R?"

Beispiele zur Ausgabe eines SML-Programms:
    java Setty sml "Is 2 in C(]-inf;5[) \ {2.0}?"
    java Setty sml "Is 0.5 in {0.5} n ]-3.0;inf[?"
Auch wenn der Setty−Interpreter in andere Sprachen übersetzen kann, wäre die Bezeichnung eines Compilers zu hoch gegriffen, da strenggenommen wichtige Phasen des Compilers fehlen, die da wären: Hierzu mehr unter Compiler.
Im Folgenden werden alle Beispiele der Kurzhilfe mit dem Setty−Interpreter ausgeführt.

Setty −> Auswertung

Der Setty−Interpreter versteht hier das Setty−Programm als Satzfrage und beantwortet diese Frage mit „yes” bzw. mit „no”.

java Setty eval "Is 1 in {}?"

Is 1 in {}? -> no

java Setty eval "Is 2.0 not in C([0;+inf[)?"

Is 2.0 not in C([0;+inf[)? -> yes

java Setty eval "Is 0.5 in ]−1;4.0[ n ]−inf;+3.0]?"

Is 0.5 in ]-1;4.0[ n ]-inf;+3.0]? -> yes

Setty −> C

Die Übersetzung eines Setty−Programms in ein C−Programm. Die Hauptarbeit besteht darin, das Setty−Programm in eine If−Anweisung umzuformulieren.

java Setty c "Is 1 in {−1;0;+1}?"

#include <stdio.h>

int main(void) {

  double element = 1.0;

  if ((element == -1.0) || (element == 0.0) || (element == 1.0)) {
    printf("yes\n");
  } else {
    printf("no\n");
  }

  return 0;
}

java Setty c "Is 1 in [−1;+1]?"

#include <stdio.h>

int main(void) {

  double element = 1.0;

  if ((element >= -1.0) && (element <= 1.0)) {
    printf("yes\n");
  } else {
    printf("no\n");
  }

  return 0;
}

java Setty c "Is 1 in ]−1;+1[ \ {0}?"

#include <stdio.h>

int main(void) {

  double element = 1.0;

  if ((!(element == 0.0)) && ((element > -1.0) && (element < 1.0))) {
    printf("yes\n");
  } else {
    printf("no\n");
  }

  return 0;
}

Setty −> Pascal

Die Übersetzung eines Setty−Programms in ein Pascal−Programm. Auch hier besteht die Hauptarbeit darin, das Setty−Programm in eine If−Anweisung umzuformulieren.

java Setty pascal "Is 7 not in ({} v {1}) n {1;2}?"

program a_setty;

var Element: Extended;

begin

  Element := 7.0;

  if not(((false) or (Element = 1.0)) and ((Element = 1.0) or (Element = 2.0)))
    then writeln('yes')
    else writeln('no');

end.

java Setty pascal "Is 11 in ]−inf;−1[ v ]1;+inf[?"

program a_setty;

var Element: Extended;

begin

  Element := 11.0;

  if (Element < -1.0) or (Element > 1.0)
    then writeln('yes')
    else writeln('no');

end.

java Setty pascal "Is 2 in E \ E v R \ R?"

program a_setty;

var Element: Extended;

begin

  Element := 2.0;

  if ((not(false)) and (false)) or ((not(not(false))) and (not(false)))
    then writeln('yes')
    else writeln('no');

end.

Setty −> SML

Die Übersetzung eines Setty−Programms in ein SML−Programm. SML können Sie unter www.smlnj.org herunterladen.
Auch hier wäre es leicht möglich, das Setty−Programm als kurze If−Anweisung auszudrücken. Doch aufgrund der besonderen Ausdruckstärke von SML, kann eine Menge extrem prägnant als charakteristische Funktion dargestellt werden.
Vergleichbares bräuchte unter C und Pascal ein aufwendigeres Konzept.

java Setty sml "Is 6 in C(]−inf;5[) \ {7.5}?"

abstype 'a SET = Set of '-> bool
 with
  fun set b = Set b

  val EmptySet = Set (fn x => false)
  val RealSet = Set (fn x => true)

  fun union (Set s) (Set t) = Set (fn x => s x orelse t x)
  fun unionN [] = EmptySet
    | unionN (s::sl) = union s (unionN sl)

  fun inter (Set s) (Set t) = Set (fn x => s x andalso t x)
  fun interN [] = RealSet
    | interN (s::sl) = inter s (interN sl)

  fun elem e = Set (fn x => Real.==(x, e))
  fun elemN [] = EmptySet
    | elemN (e::el) = union (elem e) (elemN el)

  fun compl (Set s) = Set (not o s)

  fun minus S T = inter (compl T) S

  fun isin e (Set s) = s e
  fun isnotin e (Set s) = (not o s) e
 end;

fun yesorno true = print("yes\n")
  | yesorno false = print("no\n");

yesorno (isin 6.0 (minus (compl (set (fn x => x < 5.0))) (elemN [7.5])));

java Setty sml "Is 1.5 in {0.5} n ]−3.0;inf[?"

abstype 'a SET = Set of '-> bool
 with
  fun set b = Set b

  val EmptySet = Set (fn x => false)
  val RealSet = Set (fn x => true)

  fun union (Set s) (Set t) = Set (fn x => s x orelse t x)
  fun unionN [] = EmptySet
    | unionN (s::sl) = union s (unionN sl)

  fun inter (Set s) (Set t) = Set (fn x => s x andalso t x)
  fun interN [] = RealSet
    | interN (s::sl) = inter s (interN sl)

  fun elem e = Set (fn x => Real.==(x, e))
  fun elemN [] = EmptySet
    | elemN (e::el) = union (elem e) (elemN el)

  fun compl (Set s) = Set (not o s)

  fun minus S T = inter (compl T) S

  fun isin e (Set s) = s e
  fun isnotin e (Set s) = (not o s) e
 end;

fun yesorno true = print("yes\n")
  | yesorno false = print("no\n");

yesorno (isin 1.5 (interN [(elemN [0.5]), (set (fn x => x > ~3.0))]));



Gründe

Warum eigentlich Setty?

Eigentlich gibt es schon einige einfache Sprachen, die gerne zur Erklärung der Funktionsweise einzelner Komponenten eines Interpreters verwendet werden, wie beispielsweise die Sprache der arithmetischen Ausdrücke (z. B.: „3 + 4 * 5”) oder die Sprache der richtigen Klammersetzung (z. B.: „((()())())”), doch diese erschienen mir zu abgedroschen. Meines Erachtens musste mal wieder eine neue, aber dennoch einfache Sprache her, nämlich Setty!
Setty wird zwar nicht die Welt verändern, vielleicht aber Ihr Leben! :−)



Download

Die Sourcen

Die Java−Sourcen des SettyInterpreters sind auch zum Test auf Ihrem Rechner verfügbar:
  1. SettyInterpreter.zip (13.440 Bytes)
Ich wünsche Ihnen viel Vergnügen mit dem SettyInterpreter!
Mit freundlichen Grüßen
Stefan Karl Baur



Applet

Setty in Action

Wer sich aber weniger für den Aufbau des Setty−Interpreters, sondern eher für die Anwendung von Setty interessieren sollte, der kann sich über folgendes Applet freuen:
Ein Projekt in Java kann besonders schnell und einfach zu einem Applet werden. Mehr zu diesem Applet finden Sie unter Setty−Applet.



Info

stefan−baur.de / Setty
  • besucht am Freitag, den 12. März 2010 um 15:49 Uhr
  • geändert am Sonntag, den 15. März 2009 von Stefan K. Baur






Startseite

Copyright © 2004-2009 Stefan K. Baur − Druck20042005200620072008200920102011