Die Modellierungskomponente dient zur deklarativen Beschreibung eines Domänenmodells in Form einer Ontologie - eines Netzwerks von Dateninstanzen (Fakten) und abstrakten Konzepten, die durch Beziehungen verbunden sind. Es basiert auf der Rahmenlogik - eine Mischung aus einem objektorientierten Ansatz zur Wissensrepräsentation und einer Logik erster Ordnung. Sein Hauptelement ist ein Konzept, das ein modelliertes Objekt unter Verwendung einer Reihe von Attributen beschreibt. Das Konzept basiert auf anderen Konzepten oder Fakten, die anfänglichen Konzepte werden Eltern , das Derivat - Kind genannt... Beziehungen binden die Werte von Attributen der untergeordneten und übergeordneten Konzepte oder beschränken deren mögliche Werte. Ich habe beschlossen, Beziehungen in die Definition des Konzepts aufzunehmen, damit alle Informationen darüber, wenn möglich, an einem Ort gespeichert werden. Der Syntaxstil für Konzeptdefinitionen ähnelt SQL - Attribute, übergeordnete Konzepte und Beziehungen zwischen ihnen sollten in verschiedene Abschnitte unterteilt werden.
In diesem Beitrag möchte ich die wichtigsten Möglichkeiten zur Definition von Konzepten vorstellen.
Erstens ein Konzept, das durch die Transformation elterlicher Konzepte aufgebaut wird .
Zweitens impliziert der objektorientierte Stil Vererbung . Dies bedeutet, dass Sie einen Mechanismus benötigen, mit dem Sie ein Konzept erstellen können, indem Sie die Attribute und Beziehungen übergeordneter Konzepte erben, erweitern oder eingrenzen.
Drittens glaube ich, dass ein Mechanismus nützlich wäre, um die Beziehung zwischen Peer-Konzepten zu definieren - ohne sich in Kinder- und Elternkonzepte zu unterteilen.
Kommen wir nun zu einer detaillierten Betrachtung der Haupttypen von Modellierungskomponenten.
Beginnen wir mit den Fakten
Fakten stellen eine Beschreibung des spezifischen Wissens über eine Domäne in Form eines benannten Satzes von Schlüssel-Wert-Paaren dar:
fact < > {
< > : < >
...
}
Zum Beispiel:
fact product {
name: “Cabernet Sauvignon”,
type: “red wine”,
country: “Chile”
}
Der Faktenname ist möglicherweise nicht eindeutig. Beispielsweise gibt es möglicherweise viele Produkte mit unterschiedlichen Namen, Typen und Herkunftsländern. Wir werden Fakten als identisch betrachten, wenn ihre Namen und die Namen und Werte ihrer Attribute übereinstimmen.
Es kann eine Analogie zwischen den Fakten der Modellierungskomponente und den Fakten der Prolog-Sprache gezogen werden. Sie unterscheiden sich nur in der Syntax. In Prolog werden die Argumente von Fakten durch ihre Position identifiziert, und die Attribute der Fakten der Modellierungskomponente werden durch ihren Namen identifiziert.
Konzepte
Ein Konzept ist eine Struktur, die eine abstrakte Entität beschreibt und auf anderen Konzepten und Fakten basiert. Die Definition eines Konzepts umfasst einen Namen, Listen von Attributen und untergeordnete Konzepte. Außerdem ein logischer Ausdruck, der die Abhängigkeiten zwischen seinen Attributen (untergeordnetes Konzept) und den Attributen übergeordneter Konzepte beschreibt und es Ihnen ermöglicht, den Wert der Attribute des untergeordneten Konzepts abzuleiten:
concept < > < > (
< > = <>,
...
)
from
< > < > (
< > = <>
...
),
…
where < >
Ein Beispiel für die Definition des Gewinns basierend auf Umsatz und Kosten :
concept profit p (
value = r.value – c.value,
date
) from revenue r, cost c
where p.date = r.date = c.date
Die Definition eines Konzepts ähnelt in ihrer Form einer SQL-Abfrage, aber anstelle des Tabellennamens müssen Sie die Namen der übergeordneten Konzepte und anstelle der zurückgegebenen Spalten die Attribute des untergeordneten Konzepts angeben. Darüber hinaus hat ein Konzept einen Namen, unter dem es in Definitionen anderer Konzepte oder in Modellabfragen referenziert werden kann. Das übergeordnete Konzept kann entweder das Konzept selbst oder die Fakten sein. Der Beziehungsausdruck in der where-Klausel ist ein boolescher Ausdruck, der logische Operatoren, Gleichheitsbedingungen, arithmetische Operatoren, Funktionsaufrufe usw. enthalten kann. Ihre Argumente können Variablen, Konstanten und Verweise auf Attribute von übergeordneten und untergeordneten Konzepten sein. Attributreferenzen haben das folgende Format:
< >.< >
Im Vergleich zur Rahmenlogik wird bei der Definition eines Konzepts seine Struktur (Attribute) mit Beziehungen zu anderen Konzepten (übergeordnete Konzepte und Ausdruck von Beziehungen) kombiniert. Aus meiner Sicht können Sie so den Code verständlicher machen, da alle Informationen über das Konzept an einem Ort gesammelt werden. Es entspricht auch dem Prinzip der Kapselung in dem Sinne, dass Implementierungsdetails eines Konzepts in seiner Definition verborgen sind. Zum Vergleich finden Sie in der vorherigen Veröffentlichung ein kleines Beispiel in der Sprache der Rahmenlogik .
Der Ausdruck von Beziehungen hat eine konjunktive Form (besteht aus Ausdrücken, die durch logische Operationen "UND" verbunden sind) und muss Gleichheitsbedingungen für alle Attribute des untergeordneten Konzepts enthalten, die ausreichen, um ihre Werte zu bestimmen. Darüber hinaus kann es Bedingungen enthalten, die die Bedeutung übergeordneter Konzepte einschränken oder miteinander verbinden. Wenn nicht alle übergeordneten Konzepte in der where-Klausel verknüpft sind, gibt die Inferenz-Engine als Ergebnis alle möglichen Kombinationen ihrer Werte zurück (ähnlich der FULL JOIN- Operation in SQL).
Der Einfachheit halber können einige der Bedingungen für die Gleichheit von Attributen im Attributabschnitt des untergeordneten und des übergeordneten Konzepts platziert werden. Zum Beispiel in der Definition des Gewinns die Bedingung für das AttributDer Wert wird in den Attributabschnitt verschoben, und für das Datumsattribut wird er im Where- Abschnitt belassen . Sie können sie auch auf die Übertragung von Abschnitt :
concept profit p (
value = r.value – c.value,
date = r.date
) from revenue r, cost c (date = r.date)
Mit diesem syntaktischen Zucker können Sie die Abhängigkeiten zwischen Attributen expliziter gestalten und von anderen Bedingungen trennen.
Die Konzepte folgen den Regeln in Prolog, haben jedoch eine leicht unterschiedliche Semantik. Prolog betont die Konstruktion logisch verwandter Aussagen und Fragen an sie. Konzepte dienen in erster Linie dazu, Eingabedaten zu strukturieren und Informationen daraus zu extrahieren. Konzeptattribute entsprechen den Argumenten von Prolog-Begriffen. Wenn in Prolog die Begriffsargumente jedoch mithilfe von Variablen gebunden sind, können in unserem Fall die Namen direkt über ihre Namen aufgerufen werden.
Da die Liste der übergeordneten Konzepte und die Begriffe der Beziehung in separate Abschnitte unterteilt sind, unterscheidet sich die Schlussfolgerung geringfügig von der in Prolog. Ich werde allgemein seinen Algorithmus beschreiben. Übergeordnete Konzepte werden in der Reihenfolge ausgegeben, in der sie in dem angegeben werden , aus Abschnitt . Die Suche nach einer Lösung für das nächste Konzept wird für jede Teillösung der vorherigen Konzepte auf dieselbe Weise wie in der SLD-Auflösung durchgeführt. Für jede Teillösung wird jedoch die Gültigkeit des Beziehungsausdrucks aus der where-Klausel überprüft... Da dieser Ausdruck die Form einer Konjunktion hat, wird jeder Unterausdruck separat getestet. Wenn der Unterausdruck falsch ist, wird diese Teillösung verworfen und die Suche wird mit der nächsten fortgesetzt. Wenn einige der Unterausdrucksargumente noch nicht definiert sind (nicht mit Werten verknüpft sind), wird ihre Validierung verschoben. Wenn der Unterausdruck ein Gleichheitsoperator ist und nur eines seiner Argumente definiert ist, findet das Inferenzsystem seinen Wert und versucht, ihn dem verbleibenden Argument zuzuordnen. Dies ist möglich, wenn das freie Argument ein Attribut oder eine Variable ist.
Wenn beispielsweise die Entitäten des Gewinnkonzepts angezeigt werden , werden zuerst die Entitäten des Ertragskonzepts und dementsprechend die Werte seiner Attribute gefunden . Dann ist die Gleichheit p.date = r.date = c.datein der in dem Abschnitt werden Sie zu assoziieren lassen Datum Attribute und andere Konzepte mit Werten . Wenn die logische Suche auf den Begriff der bekommt Kosten , der Wert seines Datum Attribut bereits bekannt sein und wird das Eingabeargument für diesen Zweig des Suchbaums sein. Ich habe vor, in einer der nächsten Veröffentlichungen ausführlich über Inferenzalgorithmen zu sprechen.
Der Unterschied zu Prolog besteht darin, dass in Prolog-Regeln alles Prädikate sind - und Verweise auf andere Regeln und integrierte Prädikate für Gleichheit, Vergleich usw. Die Reihenfolge ihrer Überprüfung muss explizit angegeben werden. Beispielsweise müssen zuerst zwei Regeln und dann die Gleichheit der Variablen vorhanden sein:
profit(value,date) :- revenue(rValue, date), cost(cValue, date), value = rValue – cValue
In dieser Reihenfolge werden sie ausgeführt. In der Modellierungskomponente wird angenommen, dass alle Berechnungen der Bedingungen in der where-Klausel deterministisch sind, dh kein rekursives Eintauchen in den nächsten Suchzweig erfordern. Da ihre Berechnung nur von ihren Argumenten abhängt, können sie in beliebiger Reihenfolge berechnet werden, da die Argumente an Werte gebunden sind.
Aufgrund von Schlussfolgerungen müssen alle Attribute des untergeordneten Konzepts mit Werten verknüpft werden. Und auch der Ausdruck von Beziehungen muss wahr sein und darf keine undefinierten Unterausdrücke enthalten. Es ist erwähnenswert, dass die Ableitung von elterlichen Konzepten nicht erfolgreich sein muss. Es gibt Fälle, in denen es erforderlich ist, den Fehler bei der Ableitung des übergeordneten Konzepts aus den Quelldaten zu überprüfen, z. B. bei Negationsoperationen. Die Reihenfolge der übergeordneten Konzepte in dem von Abschnitt bestimmt die Reihenfolge , in der der Entscheidungsbaum durchlaufen wird. Dies ermöglicht es, die Suche nach einer Lösung zu optimieren, beginnend mit den Konzepten, die den Suchraum stärker einschränken.
Die Aufgabe der logischen Folgerung besteht darin, alle möglichen Substitutionen von Attributen des untergeordneten Konzepts zu finden und jedes von ihnen als Objekt darzustellen. Solche Objekte gelten als identisch, wenn die Namen ihrer Konzepte, Namen und Attributwerte übereinstimmen.
Es wird als akzeptabel angesehen, mehrere Konzepte mit demselben Namen, jedoch mit unterschiedlichen Implementierungen, einschließlich unterschiedlicher Attribute, zu erstellen. Dies können verschiedene Versionen eines Konzepts sein, verwandte Konzepte, die bequem unter einem Namen kombiniert werden können, identische Konzepte aus verschiedenen Quellen usw. In der logischen Schlussfolgerung werden alle vorhandenen Definitionen des Konzepts berücksichtigt und die Ergebnisse ihrer Suche kombiniert. Mehrere Konzepte mit demselben Namen sind analog zu der Regel in Prolog, in der eine Liste von Begriffen eine disjunktive Form hat (Begriffe sind ODER-verknüpft).
Konzeptvererbung
Eine der häufigsten Beziehungen zwischen Konzepten sind hierarchische Beziehungen wie Gattungsarten. Ihre Besonderheit ist, dass die Strukturen der Kinder- und Elternkonzepte sehr ähnlich sein werden. Daher ist die Unterstützung des Vererbungsmechanismus auf Syntaxebene sehr wichtig. Ohne diesen Mechanismus sind die Programme voll von sich wiederholendem Code. Beim Aufbau eines Netzwerks von Konzepten wäre es zweckmäßig, sowohl ihre Attribute als auch ihre Beziehungen wiederzuverwenden. Während die Liste der Attribute leicht erweitert, gekürzt oder neu definiert werden kann, ist die Situation beim Ändern von Beziehungen komplizierter. Da sie ein logischer Ausdruck in konjunktiver Form sind, ist es einfach, zusätzliche Unterausdrücke hinzuzufügen. Das Löschen oder Ändern kann jedoch erhebliche Syntaxkomplikationen erfordern. Die Vorteile sind nicht so offensichtlichDaher werden wir diese Aufgabe für die Zukunft verschieben.
Sie können ein auf Vererbung basierendes Konzept mit der folgenden Konstruktion deklarieren:
concept < > < > is
< > < > (
< > = <>,
...
),
...
with < > = <>, ...
without < >, ...
where < >
Der Abschnitt is enthält eine Liste geerbter Konzepte. Ihre Namen können direkt in diesem Abschnitt angegeben werden. Oder geben Sie die vollständige Liste der übergeordneten Konzepte in der aus Abschnitt und in ist - Aliase jener von ihnen nur , die vererbt werden:
concept < > < > is
< >,
…
from
< > < > (
< > = <>
...
),
…
with < > = <>, ...
without < >, ...
where < >
Mit dem Abschnitt with können Sie die Liste der Attribute geerbter Konzepte erweitern oder einige davon überschreiben, den Abschnitt without - verkürzen.
Der Inferenzalgorithmus eines auf Vererbung basierenden Konzepts ist der gleiche wie der des oben diskutierten Konzepts. Der einzige Unterschied besteht darin, dass die Liste der Attribute automatisch basierend auf der Liste der Attribute des übergeordneten Konzepts generiert wird und der Ausdruck von Beziehungen durch Operationen zur Gleichheit der Attribute des untergeordneten und des übergeordneten Konzepts ergänzt wird.
Betrachten wir einige Beispiele für die Verwendung des Vererbungsmechanismus. Mit der Vererbung können Sie ein Konzept erstellen, das auf einem vorhandenen Konzept basiert, und die Attribute entfernen, die nur für das übergeordnete, nicht aber für das untergeordnete Konzept von Bedeutung sind. Wenn die Quelldaten beispielsweise in Form einer Tabelle dargestellt werden, können die Zellen bestimmter Spalten ihre eigenen Namen erhalten (wobei das Attribut mit der Spaltennummer entfernt wird):
concept revenue is tableCell without columnNum where columnNum = 2
Sie können auch mehrere verwandte Konzepte in eine generische Form konvertieren. Der Abschnitt with wird benötigt, um einige der Attribute in das allgemeine Format zu konvertieren und die fehlenden hinzuzufügen. Beispielsweise können die Quelldaten Dokumente verschiedener Versionen sein, deren Liste sich im Laufe der Zeit geändert hat:
concept resume is resumeV1 with skills = 'N/A'
concept resume is resumeV2 r with skills = r.coreSkills
Angenommen, die erste Version des Resume-Konzepts hatte kein Skill-Attribut und die zweite Version hatte einen anderen Namen.
In vielen Fällen kann es erforderlich sein, die Liste der Attribute zu erweitern. Häufige Aufgaben sind das Ändern des Attributformats, das Hinzufügen von Attributen, die funktional von vorhandenen Attributen oder externen Daten usw. abhängen. Zum Beispiel:
concept price is basicPrice with valueUSD = valueEUR * getCurrentRate('USD', 'EUR')
Es ist auch möglich, einfach mehrere Konzepte unter einem Namen zu kombinieren, ohne deren Struktur zu ändern. Um beispielsweise anzuzeigen, dass sie derselben Gattung angehören:
concept webPageElement is webPageLink
concept webPageElement is webPageInput
Oder erstellen Sie eine Teilmenge eines Konzepts, indem Sie einige seiner Entitäten herausfiltern:
concept exceptionalPerformer is employee where performanceEvaluationScore > 0.95
Es ist auch eine Mehrfachvererbung möglich, bei der ein untergeordnetes Konzept die Attribute aller übergeordneten Konzepte erbt. Wenn identische Attributnamen vorhanden sind, wird dem übergeordneten Konzept links in der Liste Vorrang eingeräumt. Sie können diesen Konflikt auch manuell lösen, indem Sie das gewünschte Attribut im Abschnitt explizit überschreiben
with. Diese Art der Vererbung wäre beispielsweise praktisch, wenn Sie mehrere verwandte Konzepte in einer "flachen" Struktur sammeln müssen:
concept employeeInfo is employee e, department d where e.departmentId = d.id
Vererbung ohne Änderung der Konzeptstruktur erschwert die Überprüfung der Identität von Objekten. Betrachten Sie als Beispiel die Definition von ExceptionalPerformer . Abfragen zu den Konzepten Eltern ( Mitarbeiter ) und Kind ( ExceptionalPerformer ) geben dieselbe Mitarbeiterentität zurück. Die Objekte, die es darstellen, haben eine identische Bedeutung. Sie haben eine gemeinsame Datenquelle, dieselbe Liste und dieselben Attributwerte für einen anderen Konzeptnamen, je nachdem, für welches Konzept die Abfrage durchgeführt wurde. Daher muss die Objektgleichheitsoperation diese Funktion berücksichtigen. Konzeptnamen gelten als gleich, wenn sie übereinstimmen oder durch eine transitive Vererbungsbeziehung verbunden sind, ohne die Struktur zu ändern.
Vererbung ist ein nützlicher Mechanismus, mit dem Sie Beziehungen zwischen Konzepten wie Klassenunterklasse, Privatgemeinschaft und Mengenuntermenge explizit ausdrücken können. Entfernen Sie außerdem doppelten Code in Konzeptdefinitionen und machen Sie den Code verständlicher. Der Vererbungsmechanismus basiert auf dem Hinzufügen / Entfernen von Attributen, dem Kombinieren mehrerer Konzepte unter einem Namen und dem Hinzufügen von Filterbedingungen. Es ist keine spezielle Semantik eingebettet, jeder kann sie wahrnehmen und anwenden, wie er will. Erstellen Sie beispielsweise eine Hierarchie vom Besonderen zum Allgemeinen wie in den Beispielen mit den Konzepten resume , price und webPageElement . Oder umgekehrt von allgemein zu spezifisch, wie in den Beispielen mit den Konzepten Umsatz und außergewöhnlicher Leistung... Auf diese Weise können Sie sich flexibel an die Besonderheiten der Datenquellen anpassen.
Konzept zur Beschreibung von Beziehungen
Es wurde beschlossen, dass zum besseren Verständnis des Codes und zur Erleichterung der Integration der Modellierungskomponente in das OOP-Modell die Beziehung des untergeordneten Konzepts zum übergeordneten Element in seine Definition integriert werden sollte. Somit definieren diese Beziehungen die Art und Weise, wie ein untergeordnetes Konzept von den übergeordneten erhalten wird. Wenn das Domänenmodell in Ebenen erstellt ist und jede neue Ebene auf der vorherigen basiert, ist dies gerechtfertigt. In einigen Fällen muss die Beziehung zwischen Konzepten jedoch separat deklariert werden und darf nicht in die Definition eines der Konzepte einbezogen werden. Es kann sich um eine universelle Beziehung handeln, die Sie allgemein definieren und auf verschiedene Konzepte anwenden möchten, z. B. die Eltern-Kind-Beziehung. Entweder muss eine Beziehung, die zwei Konzepte verbindet, in die Definition beider Konzepte einbezogen werden, damit es möglich wäre, sowohl die Essenz des ersten Konzepts mit den bekannten Attributen des zweiten zu finden, als auch umgekehrt.Um eine Codeduplizierung zu vermeiden, ist es dann zweckmäßig, die Beziehung separat festzulegen.
Bei der Definition einer Beziehung müssen die darin enthaltenen Konzepte aufgelistet und ein logischer Ausdruck festgelegt werden, der sie miteinander verbindet:
relation < >
between < > < > (
< > = <>,
...
),
...
where < >
Beispielsweise kann eine Beziehung, die verschachtelte Rechtecke beschreibt, wie folgt definiert werden:
relation insideSquareRelation between square inner, square outer
where inner.xLeft > outer.xLeft and inner.xRight < outer.xRight
and inner.yBottom > outer.yBottom and inner.yUp < outer.yUp
Eine solche Beziehung ist in der Tat ein allgemeines Konzept, dessen Attribute die Essenzen verschachtelter Konzepte sind:
concept insideSquare (
inner = i
outer = o
) from square i, square o
where i.xLeft > o.xLeft and i.xRight < o.xRight
and i.yBottom > o.yBottom and i.yUp < o.yUp
Eine Beziehung kann in Konzeptdefinitionen zusammen mit anderen übergeordneten Konzepten verwendet werden. Die in der Beziehung enthaltenen Konzepte sind von außen zugänglich und spielen die Rolle ihrer Attribute. Die Attributnamen stimmen mit den Aliasnamen für verschachtelte Konzepte überein. Im folgenden Beispiel wird angegeben, dass ein HTML-Formular die HTML-Elemente enthält, die sich auf einer HTML-Seite darin befinden:
oncept htmlFormElement is e
from htmlForm f, insideSquareRelation(inner = e, outer = f), htmlElement e
Bei der Suche nach einer Lösung werden zuerst alle Werte des htmlForm- Konzepts gefunden , dann werden sie dem verschachtelten Konzept außerhalb der Beziehung insideSquare zugeordnet und die Werte seines inneren Attributs werden gefunden . Am Ende werden die inneren Werte gefiltert , die sich auf das Konzept von htmlElement beziehen .
Der Beziehung kann auch eine funktionale Semantik zugewiesen werden. Sie kann als Funktion eines booleschen Typs verwendet werden, um zu überprüfen, ob die Beziehung für die angegebenen Entitäten verschachtelter Konzepte erfüllt ist:
oncept htmlFormElement is e
from htmlElement e, htmlForm f
where insideSquareRelation(e, f)
Im Gegensatz zum vorherigen Fall wird hier die Beziehung als eine Funktion behandelt, die die Reihenfolge der Inferenz beeinflusst. Die Auswertung der Funktion wird bis zu dem Zeitpunkt verschoben, an dem alle ihre Argumente mit Werten verknüpft sind. Das heißt, zuerst werden alle Wertekombinationen der Konzepte htmlElement und htmlForm gefunden , und dann werden diejenigen herausgefiltert, die nicht der Beziehung insideSquareRelation entsprechen . Ich habe vor, in einer der nächsten Veröffentlichungen ausführlicher über die Integration logischer und funktionaler Programmierparadigmen zu sprechen.
Jetzt ist es Zeit, sich ein kleines Beispiel anzusehen.
Definitionen von Fakten und Grundtypen von Konzepten reichen aus, um das Beispiel mit Schuldnern aus der ersten Veröffentlichung umzusetzen. Angenommen, wir haben zwei CSV-Dateien, in denen Kundeninformationen (Kunden-ID, Name und E-Mail-Adresse) und Rechnungen (Konto-ID, Kunden-ID, Datum, fälliger Betrag, bezahlter Betrag) gespeichert sind.
Außerdem gibt es eine bestimmte Prozedur, die den Inhalt dieser Dateien liest und in eine Reihe von Fakten konvertiert:
fact cell {
table: “TableClients”,
value: 1,
rowNum: 1,
columnNum: 1
};
fact cell {
table: “TableClients”,
value: “John”,
rowNum: 1,
columnNum: 2
};
fact cell {
table: “TableClients”,
value: “john@somewhere.net”,
rowNum: 1,
columnNum: 3
};
…
fact cell {
table: “TableBills”,
value: 1,
rowNum: 1,
columnNum: 1
};
fact cell {
table: “TableBills”,
value: 1,
rowNum: 1,
columnNum: 2
};
fact cell {
table: “TableBills”,
value: 2020-01-01,
rowNum: 1,
columnNum: 3
};
fact cell {
table: “TableBills”,
value: 100,
rowNum: 1,
columnNum: 4
};
fact cell {
table: “TableBills”,
value: 50,
rowNum: 1,
columnNum: 5
};
Geben wir den Tabellenzellen zunächst aussagekräftige Namen:
concept clientId is cell where table = “TableClients” and columnNum = 1;
concept clientName is cell where table = “TableClients” and columnNum = 2;
concept clientEmail is cell where table = “TableClients” and columnNum = 3;
concept billId is cell where table = “TableBills” and columnNum = 1;
concept billClientId is cell where table = “TableBills” and columnNum = 2;
concept billDate is cell where table = “TableBills” and columnNum = 3;
concept billAmountToPay is cell where table = “TableBills” and columnNum = 4;
concept billAmountPaid is cell where table = “TableBills” and columnNum = 5;
Jetzt können Sie Zellen einer Zeile zu einem einzigen Objekt kombinieren:
concept client (
id = id.value,
name = name.value,
email = email.value
) from clientId id, clientName name, clientEmail email
where id.rowNum = name.rowNum = email.rowNum;
concept bill (
id = id.value,
clientId = clientId.value,
date = date.value,
amountToPay = toPay.value,
amountPaid = paid.value
) from billId id, billClientId clientId, billDate date, billAmountToPay toPay, billAmountPaid paid
where id.rowNum = clientId.rowNum = date.rowNum = toPay.rowNum = paid.rowNum;
Lassen Sie uns die Konzepte "Unbezahlte Rechnung" und "Schuldner" vorstellen:
concept unpaidBill is bill where amountToPay > amountPaid;
concept debtor is client c where exist(unpaidBill {clientId: c.id});
Beide Definitionen verwenden Vererbung, das Konzept unpaidBill ist eine Teilmenge der Konzepte Rechnung , Schuldner - das Konzept des Kunden . Die Definition des Schuldners enthält eine Unterabfrage für das Konzept der unbezahlten Rechnung . Wir werden den Mechanismus verschachtelter Abfragen später in einer der folgenden Veröffentlichungen im Detail betrachten.
Als Beispiel für ein "flaches" Konzept definieren wir auch das Konzept der "Kundenverschuldung", in dem wir einige Felder aus den Konzepten "Kunde" und "Konto" kombinieren:
concept clientDebt (
clientName = c.name,
billDate = b.date,
debt = b. amountToPay – b.amountPaid
) from unpaidBill b, client c(id = b.client);
Die Abhängigkeit zwischen den Attributen des Konzepts client und bill wird in den Abschnitt from und die Abhängigkeiten des untergeordneten Konzepts clientDebt in den Abschnitt seiner Attribute verschoben . Falls gewünscht, können sie alle in einem Where- Bereich platziert werden - das Ergebnis ist das gleiche. Aus meiner Sicht ist die aktuelle Version jedoch prägnanter und betont den Zweck dieser Abhängigkeiten besser - die Definition von Beziehungen zwischen Konzepten.
Versuchen wir nun, das Konzept eines böswilligen Schuldners zu definieren, der mindestens drei unbezahlte Rechnungen hintereinander hat. Dazu benötigen Sie eine Beziehung, mit der Sie die Rechnungen eines Kunden nach dessen Datum bestellen können. Eine generische Definition würde folgendermaßen aussehen:
relation billsOrder between bill next, bill prev
where next.date > prev.date and next.clientId = prev.clientId and not exist(
bill inBetween
where next.clientId = inBetween.clientId
and next.date > inBetween.date > prev.date
);
Es heißt, dass zwei Rechnungen hintereinander abgelegt werden, wenn sie demselben Kunden gehören, das Datum der einen größer ist als das Datum des anderen, und keine andere Rechnung zwischen ihnen liegt. An dieser Stelle möchte ich nicht auf die rechnerische Komplexität einer solchen Definition eingehen. Wenn wir zum Beispiel wissen, dass alle Rechnungen im Abstand von einem Monat ausgestellt werden, kann dies erheblich vereinfacht werden:
relation billsOrder between bill next, bill prev
where next.date = prev.date + 1 month and next.clientId = prev.clientId;
Die Reihenfolge von 3 unbezahlten Rechnungen sieht folgendermaßen aus:
concept unpaidBillsSequence (clientId = b1.clientId, bill1 = b1, bill2 = b2, bill3 = b3)
from
unpaidBill b1,
billsOrder next1 (next = b1, prev = b2)
unpaidBill b2
billsOrder next2 (next = b2, prev = b3)
unpaidBill b3;
In diesem Konzept werden zuerst alle nicht bezahlten Rechnungen gefunden, dann wird für jede von ihnen die nächste Rechnung unter Verwendung der Beziehung next1 gefunden . Mit dem Begriff b2 können Sie überprüfen, ob diese Rechnung nicht bezahlt wurde. Nach dem gleichen Prinzip wird unter Verwendung von next2 und b3 die dritte unbezahlte Rechnung in Folge gefunden. Die Kundenkennung wurde der Liste der Attribute separat hinzugefügt, um die Verbindung dieses Konzepts mit dem Kundenkonzept weiter zu erleichtern:
concept hardCoreDefaulter is client c where exist(unpaidBillsSequence{clientId: c.id});
Das Schuldnerbeispiel zeigt, wie ein Domain-Modell deklarativ vollständig beschrieben werden kann. Verglichen mit der Implementierung dieses Beispiels in OOP oder Funktionsstil ist der resultierende Code sehr präzise, verständlich und nahe an der Beschreibung des Problems in natürlicher Sprache.
Kurze Schlussfolgerungen.
Daher schlug ich drei Hauptkonzepte für die Hybrid-Sprachmodellierungskomponente vor:
- Konzepte, die auf der Grundlage der Transformation anderer Konzepte erstellt wurden;
- Konzepte, die die Struktur und Beziehungen anderer Konzepte erben;
- Konzepte, die Beziehungen zwischen anderen Konzepten definieren.
Diese drei Arten von Konzepten haben unterschiedliche Formen und Zwecke, aber die interne Logik zum Finden von Lösungen ist für sie dieselbe, nur die Methode zum Erstellen der Liste der Attribute unterscheidet sich.
Konzeptdefinitionen ähneln SQL-Abfragen - sowohl in der Form als auch in der internen Ausführungslogik. Daher hoffe ich, dass die vorgeschlagene Sprache für Entwickler verständlich ist und eine relativ niedrige Einstiegsschwelle aufweist. Zusätzliche Funktionen wie die Verwendung von Konzepten in anderen Konzeptdefinitionen, Vererbung, abgeleiteten Beziehungen und rekursiven Definitionen ermöglichen es Ihnen, über SQL hinauszugehen und die Strukturierung und Wiederverwendung Ihres Codes zu vereinfachen.
Im Gegensatz zu RDF und OWL unterscheidet die Modellierungskomponente nicht zwischen Konzepten und Beziehungen - alles sind Konzepte. Im Gegensatz zu den Sprachen der Rahmenlogik werden Rahmen, die die Struktur eines Konzepts beschreiben, und die Regeln, die Verbindungen zwischen ihnen definieren, miteinander kombiniert. Im Gegensatz zu herkömmlichen logischen Programmiersprachen wie Prolog sind Konzepte mit objektorientierter Struktur das Hauptelement des Modells und keine Regeln mit flacher Struktur. Dieses Sprachdesign ist möglicherweise nicht so praktisch, um umfangreiche Ontologien oder eine Reihe von Regeln zu erstellen, aber es ist viel besser für die Arbeit mit halbstrukturierten Daten und für die Integration unterschiedlicher Datenquellen. Die Konzepte der Modellierungskomponente liegen nahe an den Klassen des OOP-Modells, was die Aufnahme einer deklarativen Beschreibung des Modells in den Anwendungscode erleichtern sollte.
Die Beschreibung der Modellierungskomponente ist noch nicht vollständig. Im nächsten Artikel möchte ich Themen aus der Welt der Computerlogik wie boolesche Variablen, Negation und Elemente der Logik höherer Ordnung diskutieren. Und dann gibt es verschachtelte Konzeptdefinitionen, Aggregationen und Konzepte, die ihre Entitäten mithilfe einer bestimmten Funktion generieren.
Der vollständige Text in einem wissenschaftlichen Stil in Englisch ist verfügbar unter: papers.ssrn.com/sol3/papers.cfm?abstract_id=3555711
Links zu früheren Veröffentlichungen:
Entwerfen einer Programmiersprache mit mehreren Paradigmen. Teil 1 - Wofür ist es?
Wir entwerfen eine Multi-Paradigma-Programmiersprache. Teil 2 - Vergleich der Modellbildung in PL / SQL, LINQ und GraphQL
Wir entwerfen eine Multi-Paradigma-Programmiersprache. Teil 3 - Überblick über Wissensrepräsentationssprachen