Eine Einführung

Entwicklung von regelbasierten Systemen

Lars Wunderlich

Innerhalb dieses Artikels wollen wir einen ersten Blick hinter die Kulissen von
Rules Engines werfen. Nach einem Streifzug durch die If/Else-Strukturen der
Java-Programmierung setzen wir uns mit den Hauptschlagworten von Expertensystemen
auseinander.

Seit Anbeginn der Entwicklung und Forschung mit und an Computern ist es ein
Traum von Nutzern und Programmierern, eine Maschine oder ein Programm zu
erstellen, das selbstständig denken, lernen und verstehen kann. Verständnis für
seine Umwelt und Interaktion mit ihr bezieht sich dabei primär auf die Kommunikation
mit Menschen.

Java Rules Engine

von Lars Wunderlich


Dieser Onlineartikel ist ein Auszug aus dem Buch „Java Rules Engine. Entwicklung von regelbasierten Systemen“ von Lars Wunderlich, das bei entwickler.press erschienen ist. Sie können das Buch im Onlineshop von entwickler.press erwerben.

entwickler-press.de

Von Evolutionsstufe zu Evolutionsstufe zeichnet sich die Menschheit dabei
durch die Fähigkeit aus, Wissen durch Erkenntnis, Erfahrung und Forschung
anzuhäufen und zu erweitern. Computer und Programme sind dazu nicht, oder
nicht so, wie wir es verstehen, in der Lage. Zwar zeigen sie virale Ansätze der
Vermehrung, besitzen rudimentäre kognitive Fähigkeiten und Erfassungsmöglichkeiten,
dennoch fehlt ihnen fast jegliches Verständnis für Emotionen, die
wiederum essentieller Bestandteil verbaler und non-verbaler Kommunikation
zwischen Individuen sind.

Vor allem weil zahlreiche Jahrzehnte der Forschung und Entwicklung an künstlicher
Intelligenz (artificial intelligence) für Laien und Beobachter noch nicht
in Bezug auf AI groß. Noch sind sie nicht in Sicht, die Roboter, die uns z.B.
Steven Spielberg 2001 mit dem kleinen Jungen David, einer menschenähnlichen
Android-Form (Android: gr. andro- von ανδρος = Mann – griechisch: menschenförmig; bezeichnet einen humanoiden/menschenähnlichen Roboter) oder Data aus den diversen Star Trek-Next Generation
vorspielen.

Der Begriff „AI“ ist also in vielen Gehirnen mit negativer Entwicklung verbunden.
Einerseits zeigen die Fortschritte im Computersektor noch immer nicht,
dass hier große Meilensteine genommen wurden, die eine gesamt-sozial-relevante Auswirkung gehabt hätten (niemand hat einen intelligenten Androiden zu
Hause, bitte um Meldung!), andererseits haben wir bewusst Angst davor, selbst
durch künstliche Wesen ersetzt zu werden. AI berührt also bei manchem auch
psychologische Grundängste.

Wissen, Sprache und Schlussfolgerungen

Sich in einer Diskussion darüber zu ergehen, was künstliche Intelligenz ausmacht,
bedingt die Auseinandersetzung und Festlegung einiger Grundbegriffe.
Da wir hier nicht anstreben, eine wissenschaftlich endgültig tragfähige Definition
all dieser Begriffe herzuleiten, sollen an dieser Stelle nur einige Grundthesen
angesprochen werden.

Intelligenz (lat.: intelligentia = „Einsicht, Erkenntnisvermögen“, intellegere = „verstehen“) bezeichnet im allgemeinsten Verständnissinne die Fähigkeit zum
Erkennen von Zusammenhängen und zum Finden von optimalen Lösungen für
anzugehende Problemfälle.

Intelligenz setzt Wissen voraus. Wissen wird beispielsweise in Wikipedia wie
folgt definiert:

„Wissen (ahd. wischan, gesehen haben) bezeichnet die Gesamtheit aller organisierten Informationen und ihrer
wechselseitigen Zusammenhänge, auf deren Grundlage ein vernunftbegabtes
System handeln kann.“

Als eine Art kleinster gemeinsamer Nenner lassen sich drei Aussagen formulieren:

  • Dem Wissen liegen Informationen zugrunde.
  • Diese Informationen müssen derart aufeinander bezogen sein, dass sie in
    sich stimmig sind. (Kohärenz)
  • Neben der inneren Übereinstimmung muss sich Wissen in Übereinstimmung mit den wahrnehmbaren Bedingungen einer Umwelt befinden.

Neben dem reinen Faktenwissen benötigen wir eine Syntax, die uns Schlussfolgerungen
erlaubt, auf deren Basis Handlungen ausgeführt oder Zusammenhänge
erkannt werden können. In der Mathematik finden wir dies z.B. in Form des „Modus ponens“:

Aus den Prämissen, also Vorbedingungen

A
A -> B

folgt die Schlussfolgerung (conclusio):

B

Ein typisches Beispiel wäre: Aus dem Fakt „ich habe mein Auto gewaschen“
und der Folgerung „ein gewaschenes Auto ist sauber“ ergibt sich die Schlussfolgerung „mein Auto ist sauber“.

In Java-Syntax hätte man dies in einer if-Bedingung selbstverständlich viel einfacher
formuliert:

if (A) B;

oder

Auto meinAuto = new Auto();
meinAuto.setCleaned(true);
if (isCleaned(meinAuto)) {
System.out.println("Car is clean");
}

Diese if-Bedingung können wir – da sie zwar in einer objektorientierten Sprache
formuliert ist, aber ihre Grundlage ein prozedurales Konstrukt (if-Schlüsselwort)
ist – auch als prozedural statische bzw. fixe Regel bezeichnen.

Diese Form der Anwendung einer Regel finden wir hunderttausende von Malen
in den unterschiedlichsten Programmen. Diesen Statements ein Buch zu widmen,
wäre also äußerst müßig und wenig reizvoll. Dennoch sollten wir, bevor wir über Alternativen sprechen können, einige typische
Merkmale einer solch prozeduralen Regel hier noch mal ansprechen, die
scheinbar eigentlich selbstverständlich sind:

  • Eine solche Regel ist fix. Sie wird gemeinhin beim Compile geprüft und ist
    zur Laufzeit ggf. ein- und ausschalt- aber normalerweise nicht veränderbar.
  • Eine Regel besteht normalerweise aus einem Bedingungs- und einem Ausführungs-/Konsequenzteil. Sie werden auch als linke (auch als left-hand side action (LHS) oder antecedent clause bezeichnet) und rechte (auch als right-hand side action (RHS) oder consequent clause bezeichnet) Seite der Regel bezeichnet.
  • Eine Regel kann ggf. die Existenz oder auch Nicht-Existenz einer Bedingung
    prüfen (Negation).
  • Im Konsequenzteil der Regel kann es zu einer Manipulation der Ausgangsdaten (der so genannten Fakten oder dem Basiswissen) kommen, sodass die Fakten ggf. nicht mehr der Bedingung aus der LHS (left-hand side) entsprechen
  • Die Formulierung der Regel erfolgt in der syntaktischen und semantischen
    Ausdrucksform der Sprache – in diesem Fall Java – selbst.
Syntax und Semantik in Java

Zur Umsetzung von Regeln verwenden eine
zwei-Komponenten-Strategie.
Ein wesentlicher Faktor für unseren Erfolg ist zweifelsohne die Regelmaschine
selbst. Ihre Fähigkeiten, Ausdrucksformen der Regeln (inklusive Umgang mit
ihnen) und ihre Anwendung spielen dabei eine große Rolle. Ein zweiter, noch
wichtigerer Potenzierungsfaktor wird durch die Programmiersprache selbst
geprägt. Jene Merkmale, die sie nicht aufweist, können auch nicht zur späteren
Verarbeitung herangezogen werden, insofern kommt ihr eine noch tiefere
Bedeutung zu. Da wir es mit Java als Anwendungssprache
zu tun haben, gilt es hier genauestens hinzuschauen und ggf. den Finger
in die Wunde zu legen, wenn es darum geht, an welche semantischen Lücken
man mit Java stößt.

Versuchen wir es dafür mit einem einfachen Beispiel wie einem „Bleistift“.
Konzentrieren Sie sich einmal kurz auf den Begriff und überlegen Sie, welche
Assoziationen Ihnen dabei kommen. Darunter könnten z.B. sein „Schreiben“, „Hand“, „Papier“, „Buch“, „Anmerkung“,„Radiergummi“ und „Anspitzer“. Vielleicht hatten Sie dabei auch eine genaue Vorstellung, wie ein solches Gerät aussieht oder wie Sie es vor sich liegen
oder in der Hand halten sehen.

Versuchen Sie diese Assoziationen auf Javaklassen zu mappen, so fällt dies
schon nicht mehr ganz so leicht. Es mag in einem Idealmodell Klassen wie Bleistift,
Papier oder Hand geben. Schreiben könnte eine Methode von Hand sein,
aber auch selbst in einer Klasse modelliert worden sein. Es gibt Beziehungen
(eben Assoziationen) zwischen diesen Entitäten, sie gelten aber nur in bestimmten
Fällen oder Kontexten.

Grundsätzlich hat eine Hand nichts mit einem Bleistift zu tun und ein Buch oder
eine Anmerkung ebenso wenig. Versuchen wir der Bleistift-Klasse Attribute zu
verpassen, so wird es ebenfalls kompliziert. Der Bleistift hat eine Länge, verfügt
ggf. über eine farbliche Lackierung, ist angespitzt oder stumpf, besitzt möglicherweise
ein integriertes Radiergummi. Es gibt Spezialisierungen von Bleistiften
z.B. in Form eines Druckbleistiftes. Ist der Druckbleistift nun eine Unterklasse
eines normalen Bleistiftes oder sind beide wiederum aus Komponenten
zusammen gesetzt? Sind Bleistifte in sich komplexe Kompositionen aus Graphit,
Holz, Metall oder Plastik, die eine sachbezogene Bedeutung erst durch ihre
Kombinationen untereinander erlangen?

Sie sehen, wir können problemlos aus jeder Modellierung von Klassen in Java
eine philosophische Diskussion entfachen, die durch das recht starre Konzept
der Javasprache an sich, ihre Strukturierung und Einteilung verlangt wird.
Abhängig vom Anwendungsfall entstehen dadurch komplett unterschiedliche
Lösungen.

Vielleicht sind Sie sogar mit den zu beschreibenden Begriffen/Entitäten nicht
gut genug vertraut. Was bei Bleistiften weniger ein Problem sein dürfte, könnte
sich mit Stichworten wie „Benzolmolekül“, „Dextrose“ oder abstrakteren Sachverhalten
wie „Phantasie“, „Vergnügen“ oder „Illusion“ als ein solches herausstellen.

Ihre Regeln, die Sie später in Anwendungen verwenden werden, werden auf den
Grundbausteinen der menschlichen Sprache und Vorstellungskraft aufbauen.
Insofern ist dieser Artikel sicherlich ein Sinnbild für genau diesen, an sich trivialen
Sachverhalt. Dennoch ergibt sich dafür eine relativ dramatische Konsequenz für die Erstellung
von Regeln.

Regeln verwenden eine Sprache, Entitäten bauen auf einem Modell auf.
Modelle sind wiederum Abstraktionen von Realität. Was bedeutet das? Die entstehenden
Regeln sind auf die Entitätsmodellierung beschränkt. Wenn es aber keine endgültigen Modelle gibt, kann es dann Regeln geben, die
auf diesen unvollständigen Modellen sinnvolle Aussagen ermöglichen?

Wenn Sie keinen Bleistift als Klasse modelliert haben, können Sie keine vernünftige
fachliche Regel formulieren, die die Eigenschaften und das Verhalten
der Klasse Bleistift beschreibt oder darauf Bezug nimmt. In zahlreichen Texten und in Literatur zum Thema Regeln finden Sie oft sinngemäße
Formulierungsbeispiele für Regeln wie:

Wenn die Sonne scheint, können wir in den Garten gehen.
Wenn es regnet, müssen wir in der Wohnung bleiben.

Beide Sätze sind Regeln, bestehend aus einem Bedingungs- und einem Konsequenzabschnitt.
Insofern repräsentieren sie, natürlich beispielhaft, die Ausdrucksformen von Regeln. Was Regelmaschinen nun mit derlei Konsekutivsätzen
tun, ist, sie wiederum auf Entitäten, Eigenschaften und Verhalten herunterzubrechen
und zu mappen. Es muss also eine Klasse Sonne existieren oder eine wie auch immer geartete
Methodik, um zu prüfen, welchen Wahrheitsgehalt der Bedingungsteil (lefthand
side
) hat. Die sich daraus ergebende Schlussfolgerung (wir können in den
Garten gehen
) muss nun durch eine Aktion oder einen Endzustand auf Basis
von Objekten ausdrückbar sein. Also auf Objektmodellebene könnte dies zu folgendem
Sourcecode führen:

if (wheather.isState(SUN_SHINING)) {
we.addAbility(ENTER_GARDEN);
}
if (wheather.isState(RAINING)) {
we.removeAbility(ENTER_GARDEN);
we.setPlace(INDOORS);
}

Sie sehen, dass wir zwischen der natürlich-sprachlichen “Geschäftslogik” aus
unserem obigen Beispiel und der Formulierung der Regel in Form typischer
Java-Syntax eine semantische Lücke durch Integration der zur Verfügung stehenden
Geschäftsentitäten (wheather und we im Beispiel) zu füllen haben. Damit wäre letztendlich auch die Aufgabe einer Regelmaschine (Rules Engine)
abstrakt beschrieben, auch wenn es in Implementierung und Ausführung deutliche
Unterschiede zu verzeichnen gibt.

Definition einer Rules Engine

Eine Rules Engine ist also ein Tool, das es uns erlaubt:

  • Regeln in einer Regelsprache zu formulieren
  • Regeln im Kontext von konkreten Entitäten und zur Verfügung gestellten
    Methoden zu prüfen und anzuwenden

Abhängig vom konkreten Softwareprodukt können Sie die Liste dieser Fertigkeiten
beliebig erweitern. Viele Werkzeuge bieten z.B. typische weitere Eigenschaften
an wie:

  • Organisation von Regeln (z.B. automatische Anordnung von Regeln nach
    bestimmten Algorithmen, fachliche Strukturierbarkeit durch Namen, Kategorien
    oder Prioritäten)
  • Berechtigungsvergabe, Authentifizierung und Autorisation für Regelersteller
    und Nutzer
  • Versionierung von Regeln zwecks Revisionssicherheit (in entsprechenden
    Systemen z.B. CVS/Subversion/Perforce)
  • Austausch von Regeln zur Laufzeit des Programmes, das die Regeln verwendet
  • Im- und Export fremder Regeldefinitionen
  • Reporting und Benchmarking von erstellten Regeln (Menge, Ausführungshäufigkeit,
    Bedeutung, Metadaten, …)
  • Erfassung von Regeln in technischer Sprachsyntax (z.B. in regelnahen Sprachen
    wie LISP, PROLOG aber auch Java)
  • Erfassung von Regeln in Business-Sprache (business action language) (ggf.
    in natürlichsprachigen Formulierungen und Sätzen)
  • Erfassung von Regeln mit Hilfe von Entscheidungstabellen oder Entscheidungsbäumen
  • Visualisierung von Regeln (z.B. über UML-Diagramme, Programm-Ablauf-Pläne) etc. durch Integration in entsprechende Tools
  • Angebot diverser technischer und architektonischer Lösungen und APIs
    (z.B. EJBs, Webservices, agentenbasierte Systeme, Remote Server, In-Process-
    Integration, javax.rules-API etc.)
  • Fähigkeiten zur Visualisierung, Einbindung und Erweiterung bestehender
    Objektmodelle
  • Definition von Regeln über Basistechnologien künstlicher Intelligenz (worunter ich in meiner Definition hier Techniken wie neuronale Netzwerke in Kombination mit
    statischen oder deklarativen Regeln in ihren verschiedenen Formen verstehen möchte. Wir kommen
    später darauf zurück.)
Geschrieben von
Lars Wunderlich
Kommentare

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.