Komponen pemodelan dimaksudkan untuk deskripsi deklaratif model domain dalam bentuk ontologi - jaringan contoh data (fakta) dan konsep abstrak yang saling berhubungan melalui hubungan. Ini didasarkan pada logika bingkai - hibrida dari pendekatan berorientasi objek untuk representasi pengetahuan dan logika orde pertama. Elemen utamanya adalah konsep yang mendeskripsikan objek yang dimodelkan menggunakan sekumpulan atribut. Konsep dibangun atas dasar konsep atau fakta lain, konsep awal akan disebut parental , turunan - anak... Hubungan mengikat nilai atribut anak dan konsep induk atau membatasi kemungkinan nilainya. Saya memutuskan untuk memasukkan hubungan dalam definisi konsep, sehingga semua informasi tentang itu, jika memungkinkan, ada di satu tempat. Gaya sintaks untuk definisi konsep akan mirip dengan SQL - atribut, konsep induk, dan hubungan di antara keduanya harus dipisahkan menjadi beberapa bagian.
Dalam posting ini, saya ingin menyajikan cara-cara utama mendefinisikan konsep.
Pertama, konsep yang dibangun dengan mentransformasikan konsep orang tua .
Kedua, gaya berorientasi objek menyiratkan pewarisan , yang berarti Anda memerlukan mekanisme yang memungkinkan Anda membuat konsep dengan mewarisi atribut dan hubungan konsep induk, memperluas atau mempersempitnya.
Ketiga, saya percaya bahwa suatu mekanisme akan berguna untuk mendefinisikan hubungan antara konsep teman - tanpa membagi konsep anak dan orang tua.
Sekarang mari kita turun ke pertimbangan mendetail dari tipe dasar komponen pemodelan.
Mari kita mulai dengan fakta
Fakta mewakili deskripsi pengetahuan khusus tentang domain dalam bentuk sekumpulan key-value pair:
fact < > {
< > : < >
...
}
Contohnya:
fact product {
name: “Cabernet Sauvignon”,
type: “red wine”,
country: “Chile”
}
Nama faktanya mungkin tidak unik, misalnya mungkin ada banyak produk dengan nama, tipe dan negara asal yang berbeda. Kami akan menganggap fakta identik jika nama dan nama serta nilai atribut mereka sama.
Sebuah analogi dapat ditarik antara fakta-fakta komponen pemodelan dan fakta-fakta bahasa Prolog. Mereka hanya berbeda dalam sintaksis. Dalam Prolog, argumen fakta diidentifikasi dengan posisinya, dan atribut fakta komponen pemodelan diidentifikasi dengan nama.
Konsep
Konsep adalah struktur yang menggambarkan entitas abstrak dan didasarkan pada konsep dan fakta lain. Definisi konsep mencakup nama, daftar atribut, dan konsep anak. Dan juga ekspresi logis yang menjelaskan ketergantungan antara atribut (konsep anak) dan atribut konsep induknya, memungkinkan Anda untuk menampilkan nilai atribut konsep anak:
concept < > < > (
< > = <>,
...
)
from
< > < > (
< > = <>
...
),
…
where < >
Contoh mendefinisikan laba berdasarkan pendapatan dan biaya :
concept profit p (
value = r.value – c.value,
date
) from revenue r, cost c
where p.date = r.date = c.date
Definisi konsep mirip dalam bentuk kueri SQL, tetapi alih-alih nama tabel, Anda perlu menentukan nama konsep induk, dan sebagai ganti kolom yang dikembalikan - atribut konsep anak. Selain itu, sebuah konsep memiliki nama yang dapat digunakan untuk merujuk pada definisi konsep lain atau dalam kueri model. Konsep induk dapat berupa konsep itu sendiri atau fakta. Ekspresi hubungan dalam klausa where adalah ekspresi boolean yang dapat menyertakan operator logika, kondisi kesetaraan, operator aritmatika, pemanggilan fungsi, dll. Argumennya dapat berupa variabel, konstanta, dan referensi ke atribut konsep induk dan anak. Referensi atribut memiliki format sebagai berikut:
< >.< >
Dibandingkan dengan logika bingkai, dalam definisi sebuah konsep, strukturnya (atribut) digabungkan dengan hubungan dengan konsep lain (konsep induk dan ekspresi hubungan). Dari sudut pandang saya, ini memungkinkan Anda membuat kode lebih mudah dipahami, karena semua informasi tentang konsep dikumpulkan di satu tempat. Ini juga sesuai dengan prinsip enkapsulasi dalam arti bahwa detail implementasi suatu konsep tersembunyi di dalam definisinya. Sebagai perbandingan, contoh kecil dalam bahasa logika bingkai dapat ditemukan di publikasi sebelumnya .
Ekspresi relasi memiliki bentuk konjungtif (terdiri dari ekspresi yang dihubungkan dengan operasi logika "AND") dan harus menyertakan kondisi kesetaraan untuk semua atribut konsep turunan, cukup untuk menentukan nilainya. Selain itu, dapat mencakup kondisi yang membatasi makna konsep induk atau menghubungkannya. Jika tidak semua konsep induk terkait di klausa where , mesin inferensi akan mengembalikan semua kemungkinan kombinasi nilainya sebagai hasilnya (mirip dengan operasi FULL JOIN di SQL).
Untuk memudahkan, beberapa kondisi untuk persamaan atribut dapat ditempatkan di bagian atribut pada konsep anak dan induk. Misalnya, dalam definisi profit, kondisi atributnilai dipindahkan ke bagian atribut, dan untuk atribut tanggal itu ditinggalkan di bagian mana . Anda juga dapat mentransfernya ke bagian dari :
concept profit p (
value = r.value – c.value,
date = r.date
) from revenue r, cost c (date = r.date)
Gula sintaksis ini memungkinkan Anda membuat dependensi antar atribut lebih eksplisit dan membedakannya dari kondisi lain.
Konsep mengikuti aturan di Prolog tetapi memiliki semantik yang sedikit berbeda. Prolog berfokus pada konstruksi pernyataan dan pertanyaan yang terkait secara logis dengan mereka. Konsep terutama ditujukan untuk menyusun data masukan dan mengekstraksi informasi darinya. Atribut konsep sesuai dengan argumen istilah Prolog. Tetapi jika dalam Prolog istilah argumen terikat menggunakan variabel, maka dalam kasus kami atribut dapat langsung diakses dengan namanya.
Karena daftar konsep induk dan istilah hubungan dipisahkan menjadi beberapa bagian terpisah, inferensi akan sedikit berbeda dari yang ada di Prolog. Saya akan menjelaskan secara umum algoritmanya. Konsep induk akan menjadi keluaran dalam urutan yang ditentukan di bagian from . Pencarian solusi untuk konsep selanjutnya dilakukan untuk setiap solusi parsial dari konsep sebelumnya dengan cara yang sama seperti pada resolusi SLD. Tetapi untuk setiap solusi parsial, validitas ekspresi relasi dari klausa where diperiksa.... Karena ekspresi ini dalam bentuk konjungsi, setiap subekspresi diuji secara terpisah. Jika subekspresi salah, maka solusi parsial ini ditolak dan pencarian dilanjutkan ke yang berikutnya. Jika beberapa argumen subekspresi belum ditentukan (tidak terkait dengan nilai), maka validasinya ditunda. Jika subekspresi adalah operator persamaan dan hanya satu argumennya yang ditentukan, maka sistem inferensi akan menemukan nilainya dan mencoba mengaitkannya dengan argumen yang tersisa. Ini dimungkinkan jika argumen bebas adalah atribut atau variabel.
Misalnya, ketika menampilkan entitas konsep laba , entitas konsep pendapatan dan, karenanya, nilai atributnya akan ditemukan terlebih dahulu . Maka persamaan p.date = r.date = c.datedi bagian where akan memungkinkan Anda untuk mengaitkan atribut tanggal dan konsep lain dengan nilai . Ketika pencarian logis sampai pada konsep biaya , nilai atribut tanggalnya akan diketahui dan akan menjadi argumen input untuk cabang pohon pencarian ini. Saya berencana untuk berbicara secara rinci tentang algoritma inferensi di salah satu publikasi berikutnya.
Perbedaan dari Prolog adalah bahwa dalam aturan Prolog semuanya adalah predikat - panggilan ke aturan lain dan predikat bawaan dari persamaan, perbandingan, dll. Dan urutan pemeriksaannya harus ditentukan secara eksplisit, misalnya, dua aturan pertama harus pergi dan kemudian persamaan variabel:
profit(value,date) :- revenue(rValue, date), cost(cValue, date), value = rValue – cValue
Dalam urutan ini, mereka akan dieksekusi. Dalam komponen pemodelan, diasumsikan bahwa semua evaluasi kondisi pada klausa where bersifat deterministik, yaitu tidak memerlukan penyelaman rekursif ke cabang pencarian berikutnya. Karena penghitungannya hanya bergantung pada argumennya, mereka dapat dihitung dalam urutan sewenang-wenang karena argumen tersebut terikat pada nilai.
Sebagai hasil dari inferensi, semua atribut konsep anak harus dikaitkan dengan nilai. Dan juga ekspresi relasi harus benar dan tidak mengandung subekspresi yang tidak terdefinisi. Perlu dicatat bahwa derivasi konsep parenting tidak harus berhasil. Ada beberapa kasus ketika diperlukan untuk memeriksa kegagalan penurunan konsep induk dari data sumber, misalnya, dalam operasi negasi. Urutan konsep induk dalam klausa from menentukan urutan di mana pohon keputusan dilintasi. Hal ini memungkinkan untuk mengoptimalkan pencarian solusi, dimulai dengan konsep-konsep yang lebih membatasi ruang pencarian.
Tugas dari inferensi logis adalah menemukan semua kemungkinan substitusi dari atribut konsep anak dan merepresentasikannya masing-masing sebagai objek. Objek semacam itu dianggap identik jika nama konsep, nama, dan nilai atributnya cocok.
Dianggap dapat diterima untuk membuat beberapa konsep dengan nama yang sama, tetapi dengan implementasi yang berbeda, termasuk sekumpulan atribut yang berbeda. Ini dapat berupa versi berbeda dari konsep yang sama, konsep terkait yang dapat digabungkan dengan mudah di bawah satu nama, konsep identik dari sumber berbeda, dll. Dalam kesimpulan logis, semua definisi konsep yang ada akan dipertimbangkan, dan hasil pencariannya akan digabungkan. Beberapa konsep dengan nama yang sama dapat dianalogikan dengan aturan dalam Prolog, di mana daftar istilah memiliki bentuk terpisah (istilah adalah ORed).
Pewarisan konsep
Salah satu hubungan paling umum antar konsep adalah hubungan hierarki seperti genus-spesies. Keunikan mereka adalah bahwa struktur konsep anak dan orang tua akan sangat mirip. Oleh karena itu, dukungan mekanisme inheritance pada tingkat sintaksis sangat penting, tanpanya, program akan penuh dengan kode berulang. Saat membangun jaringan konsep, akan lebih mudah untuk menggunakan kembali atribut dan hubungannya. Meskipun daftar atribut mudah untuk diperluas, dipersingkat, atau didefinisikan ulang beberapa di antaranya, situasi dengan memodifikasi relasi lebih rumit. Karena mereka adalah ekspresi logis dalam bentuk konjungtif, mudah untuk menambahkan subekspresi tambahan padanya. Namun, menghapus atau mengubah dapat memerlukan komplikasi sintaks yang signifikan. Manfaatnya tidak begitu jelasoleh karena itu, kami akan menunda tugas ini untuk masa mendatang.
Anda dapat mendeklarasikan konsep berdasarkan pewarisan menggunakan konstruksi berikut:
concept < > < > is
< > < > (
< > = <>,
...
),
...
with < > = <>, ...
without < >, ...
where < >
Bagian is berisi daftar konsep yang diwariskan. Nama mereka dapat ditentukan langsung di bagian ini. Atau, tentukan daftar lengkap konsep induk di bagian from , dan di is - alias hanya yang akan diwarisi:
concept < > < > is
< >,
…
from
< > < > (
< > = <>
...
),
…
with < > = <>, ...
without < >, ...
where < >
Bagian dengan memungkinkan Anda untuk memperluas daftar atribut konsep yang diwariskan atau menimpa beberapa di antaranya, bagian tanpa - untuk mempersingkat.
Algoritma inferensi dari konsep berdasarkan pewarisan sama dengan konsep yang dibahas di atas. Satu-satunya perbedaan adalah bahwa daftar atribut secara otomatis dibuat berdasarkan daftar atribut dari konsep induk, dan ekspresi relasi dilengkapi dengan operasi persamaan atribut dari konsep anak dan induk.
Mari pertimbangkan beberapa contoh penggunaan mekanisme pewarisan. Pewarisan memungkinkan Anda membuat konsep berdasarkan konsep yang sudah ada, menyingkirkan atribut yang hanya bermakna untuk orang tua, tetapi tidak untuk konsep anak. Misalnya, jika data sumber disajikan dalam bentuk tabel, maka sel kolom tertentu dapat diberi nama sendiri (menghilangkan atribut dengan nomor kolom):
concept revenue is tableCell without columnNum where columnNum = 2
Juga dimungkinkan untuk mengubah beberapa konsep terkait menjadi satu bentuk umum. Bagian with diperlukan untuk mengubah beberapa atribut ke format umum dan menambahkan atribut yang hilang. Misalnya, data sumber dapat berupa dokumen dengan versi berbeda, yang daftar bidangnya telah berubah seiring waktu:
concept resume is resumeV1 with skills = 'N/A'
concept resume is resumeV2 r with skills = r.coreSkills
Katakanlah versi pertama dari konsep "Lanjutkan" tidak memiliki atribut dengan keahlian, dan versi kedua memiliki nama yang berbeda.
Memperluas daftar atribut mungkin diperlukan dalam banyak kasus. Tugas umum adalah mengubah format atribut, menambahkan atribut yang secara fungsional bergantung pada atribut yang ada atau data eksternal, dll. Contohnya:
concept price is basicPrice with valueUSD = valueEUR * getCurrentRate('USD', 'EUR')
Dimungkinkan juga untuk menggabungkan beberapa konsep dalam satu nama tanpa mengubah strukturnya. Misalnya, untuk menunjukkan bahwa mereka dari genus yang sama:
concept webPageElement is webPageLink
concept webPageElement is webPageInput
Atau buat subset konsep dengan memfilter beberapa entitasnya:
concept exceptionalPerformer is employee where performanceEvaluationScore > 0.95
Warisan berganda juga dimungkinkan, di mana konsep anak mewarisi atribut dari semua konsep induk. Jika ada nama atribut yang identik, prioritas akan diberikan ke konsep induk di sebelah kiri daftar. Anda juga dapat menyelesaikan konflik ini secara manual dengan secara eksplisit mengganti atribut yang diinginkan di bagian
with. Misalnya, jenis warisan ini akan berguna jika Anda perlu mengumpulkan beberapa konsep terkait dalam satu struktur "datar":
concept employeeInfo is employee e, department d where e.departmentId = d.id
Pewarisan tanpa mengubah struktur konsep mempersulit verifikasi identitas objek. Sebagai contoh, perhatikan definisi performa luar biasa . Kueri tentang konsep induk ( karyawan ) dan anak ( luar biasaPerformer) akan mengembalikan entitas karyawan yang sama. Objek yang merepresentasikannya akan identik artinya. Mereka akan memiliki sumber data yang sama, daftar yang sama dan nilai atribut, untuk nama konsep yang berbeda, bergantung pada konsep mana kueri dibuat. Oleh karena itu, operasi persamaan objek harus mempertimbangkan fitur ini. Nama konsep dianggap sama jika bertepatan atau dihubungkan oleh hubungan warisan transitif tanpa mengubah strukturnya.
Inheritance adalah mekanisme berguna yang memungkinkan Anda mengekspresikan hubungan secara eksplisit antara konsep seperti class-subclass, private-common, dan set-subset. Dan juga singkirkan duplikasi kode dalam definisi konsep dan buat kode lebih mudah dipahami. Mekanisme pewarisan didasarkan pada penambahan / penghapusan atribut, menggabungkan beberapa konsep dengan satu nama dan menambahkan kondisi pemfilteran. Tidak ada semantik khusus yang tertanam di dalamnya, setiap orang dapat melihat dan menerapkannya sesuai keinginan mereka. Misalnya, bangun hierarki dari khusus ke umum, seperti pada contoh dengan konsep resume , price , dan webPageElement . Atau sebaliknya, dari umum ke khusus, seperti pada contoh dengan konsep pendapatan dan performa luar biasa... Ini akan memungkinkan Anda menyesuaikan secara fleksibel dengan spesifikasi sumber data.
Konsep untuk menggambarkan hubungan
Diputuskan bahwa untuk kenyamanan memahami kode dan memfasilitasi integrasi komponen pemodelan dengan model OOP, hubungan konsep anak dengan induk harus dibangun ke dalam definisinya. Jadi, relasi ini menentukan cara memperoleh konsep anak dari konsep induk. Jika model domain dibangun dalam beberapa lapisan, dan setiap lapisan baru didasarkan pada yang sebelumnya, ini dibenarkan. Namun dalam beberapa kasus, hubungan antar konsep harus dinyatakan secara terpisah, dan tidak termasuk dalam definisi salah satu konsep. Ini bisa menjadi hubungan universal yang ingin Anda definisikan secara umum dan diterapkan pada konsep yang berbeda, misalnya, hubungan Induk-Anak. Hubungan yang menghubungkan dua konsep harus dimasukkan ke dalam definisi kedua konsep, sehingga memungkinkan untuk menemukan baik esensi konsep pertama dengan atribut yang diketahui dari konsep kedua, dan sebaliknya.Kemudian, untuk menghindari duplikasi kode, akan lebih mudah untuk mengatur relasi secara terpisah.
Dalam definisi hubungan, perlu untuk membuat daftar konsep yang termasuk di dalamnya dan mengatur ekspresi logis yang menghubungkannya satu sama lain:
relation < >
between < > < > (
< > = <>,
...
),
...
where < >
Misalnya, hubungan yang mendeskripsikan persegi panjang bersarang dapat didefinisikan sebagai berikut:
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
Hubungan seperti itu, pada kenyataannya, adalah konsep umum, yang atributnya merupakan esensi dari konsep bertingkat:
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
Hubungan dapat digunakan dalam definisi konsep bersama dengan konsep induk lainnya. Konsep yang termasuk dalam hubungan akan dapat diakses dari luar dan akan memainkan peran atributnya. Nama atribut akan cocok dengan alias konsep bertingkat. Contoh berikut menyatakan bahwa formulir HTML menyertakan elemen HTML yang terletak di dalamnya pada halaman HTML:
oncept htmlFormElement is e
from htmlForm f, insideSquareRelation(inner = e, outer = f), htmlElement e
Mencari solusi pertama-tama akan menemukan semua nilai konsep htmlForm , kemudian akan dikaitkan dengan konsep bersarang di luar relasi insideSquare dan nilai atribut dalamnya ditemukan . Pada akhirnya, nilai - nilai dalam yang terkait dengan konsep htmlElement akan difilter .
Hubungan juga dapat diberikan semantik fungsional - dapat digunakan sebagai fungsi dari tipe Boolean untuk memeriksa apakah hubungan terpenuhi untuk entitas konsep bertingkat yang diberikan:
oncept htmlFormElement is e
from htmlElement e, htmlForm f
where insideSquareRelation(e, f)
Berbeda dengan kasus sebelumnya, di sini relasi diperlakukan sebagai fungsi yang akan mempengaruhi urutan inferensi. Evaluasi fungsi akan ditunda hingga saat semua argumennya dikaitkan dengan nilai. Yaitu, pertama-tama semua kombinasi nilai konsep htmlElement dan htmlForm akan ditemukan , dan kemudian kombinasi yang tidak sesuai dengan relasi insideSquareRelation akan disaring . Saya berencana untuk berbicara lebih detail tentang integrasi paradigma pemrograman logis dan fungsional di salah satu publikasi berikutnya.
Sekarang saatnya untuk melihat contoh kecil.
Definisi fakta dan jenis konsep dasar sudah cukup untuk menerapkan contoh dengan debitur dari publikasi pertama. Misalkan kita memiliki dua file CSV yang menyimpan informasi tentang pelanggan (ID pelanggan, nama dan email) dan faktur (ID akun, ID pelanggan, tanggal, jumlah jatuh tempo, jumlah yang dibayarkan).
Dan juga ada prosedur tertentu yang membaca konten file-file ini dan mengubahnya menjadi sekumpulan fakta:
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
};
Pertama, mari beri nama yang berarti pada sel tabel:
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;
Sekarang Anda dapat menggabungkan sel dari satu baris menjadi satu objek:
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;
Mari perkenalkan konsep "Faktur belum dibayar" dan "Debitur":
concept unpaidBill is bill where amountToPay > amountPaid;
concept debtor is client c where exist(unpaidBill {clientId: c.id});
Kedua definisi tersebut menggunakan pewarisan, konsep unpaidBill adalah bagian dari konsep tagihan , debitur - konsep klien . Definisi debitur berisi subquery untuk konsep unpaidBill . Kami akan mempertimbangkan secara rinci mekanisme kueri bersarang nanti di salah satu publikasi berikut.
Sebagai contoh konsep "flat", kami juga akan mendefinisikan konsep "Utang pelanggan", di mana kami menggabungkan beberapa bidang dari konsep "Pelanggan" dan "Akun":
concept clientDebt (
clientName = c.name,
billDate = b.date,
debt = b. amountToPay – b.amountPaid
) from unpaidBill b, client c(id = b.client);
Ketergantungan antara atribut konsep klien dan tagihan dipindahkan ke bagian from , dan ketergantungan konsep anak clientDebt - ke bagian atributnya. Jika diinginkan, semuanya dapat ditempatkan di bagian di mana - hasilnya akan sama. Tetapi dari sudut pandang saya, versi saat ini lebih ringkas dan lebih menekankan tujuan ketergantungan ini - untuk menentukan hubungan antar konsep.
Sekarang, mari kita coba mendefinisikan konsep orang yang mangkir yang memiliki setidaknya 3 faktur yang belum dibayar berturut-turut. Untuk melakukan ini, Anda memerlukan hubungan yang memungkinkan Anda memesan faktur dari satu pelanggan berdasarkan tanggal mereka. Definisi umum akan terlihat seperti ini:
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
);
Ini menyatakan bahwa dua faktur berurutan jika mereka milik klien yang sama, tanggal salah satu lebih besar dari tanggal yang lain, dan tidak ada faktur lain yang terletak di antara mereka. Pada tahap ini, saya tidak ingin memikirkan kompleksitas komputasi dari definisi seperti itu. Tetapi jika, misalnya, kita mengetahui bahwa semua invoice dikeluarkan dengan interval 1 bulan, maka ini dapat sangat disederhanakan:
relation billsOrder between bill next, bill prev
where next.date = prev.date + 1 month and next.clientId = prev.clientId;
Urutan 3 faktur yang belum dibayar akan terlihat seperti ini:
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;
Dalam konsep ini, pertama-tama akan ditemukan semua faktur yang belum dibayar, kemudian untuk masing-masing faktur berikutnya akan ditemukan menggunakan relasi next1 . Gagasan b2 akan memungkinkan Anda memverifikasi bahwa faktur ini belum dibayar. Dengan prinsip yang sama, dengan menggunakan next2 dan b3 , faktur ketiga yang belum dibayar akan ditemukan berturut-turut. Pengidentifikasi pelanggan telah ditambahkan ke daftar atribut secara terpisah, untuk lebih memudahkan hubungan konsep ini dengan konsep pelanggan:
concept hardCoreDefaulter is client c where exist(unpaidBillsSequence{clientId: c.id});
Contoh debitur mendemonstrasikan bagaimana model domain dapat sepenuhnya dijelaskan dalam gaya deklaratif. Dibandingkan dengan implementasi contoh ini dalam OOP atau gaya fungsional, kode yang dihasilkan sangat ringkas, mudah dipahami, dan mendekati mendeskripsikan masalah dalam bahasa alami.
Kesimpulan singkat.
Jadi, saya mengusulkan tiga jenis konsep utama dari komponen pemodelan bahasa hybrid:
- konsep yang dibuat atas dasar transformasi konsep lain;
- konsep yang mewarisi struktur dan hubungan konsep lain;
- konsep yang mendefinisikan hubungan antara konsep lain.
Ketiga jenis konsep ini memiliki bentuk dan tujuan yang berbeda, tetapi logika internal untuk menemukan solusi sama untuk mereka, hanya metode pembentukan daftar atribut yang berbeda.
Definisi konsep menyerupai kueri SQL, baik dalam bentuk maupun dalam logika eksekusi internal. Oleh karena itu, saya berharap bahasa yang diusulkan dapat dimengerti oleh pengembang dan memiliki ambang masuk yang relatif rendah. Dan fitur tambahan seperti penggunaan konsep dalam definisi konsep lain, pewarisan, hubungan turunan, dan definisi rekursif akan memungkinkan Anda melampaui SQL dan membuatnya lebih mudah untuk menyusun dan menggunakan kembali kode.
Tidak seperti RDF dan OWL, komponen pemodelan tidak membedakan antara konsep dan hubungan - semuanya adalah konsep. Berbeda dengan bahasa logika bingkai, bingkai yang mendeskripsikan struktur sebuah konsep, dan aturan yang menentukan hubungan di antara keduanya, digabungkan bersama. Berbeda dengan bahasa pemrograman logika tradisional seperti Prolog, elemen utama model adalah konsep yang memiliki struktur berorientasi objek, dan bukan aturan yang memiliki struktur datar. Desain bahasa ini mungkin tidak nyaman untuk membuat ontologi skala besar atau seperangkat aturan, tetapi jauh lebih baik untuk bekerja dengan data semi-terstruktur dan untuk mengintegrasikan sumber data yang berbeda. Konsep komponen pemodelan dekat dengan kelas model OOP, yang seharusnya memfasilitasi tugas termasuk deskripsi deklaratif model dalam kode aplikasi.
Deskripsi komponen pemodelan belum lengkap. Pada artikel berikutnya saya berencana untuk membahas masalah-masalah dari dunia logika komputer seperti variabel boolean, negasi dan elemen logika tingkat tinggi. Dan kemudian ada definisi konsep bersarang, agregasi, dan konsep yang menghasilkan entitas mereka menggunakan fungsi yang diberikan.
Teks lengkap dalam gaya ilmiah dalam bahasa Inggris tersedia di: paper.ssrn.com/sol3/papers.cfm?abstract_id=3555711
Link ke publikasi sebelumnya:
Mendesain bahasa pemrograman multi-paradigma. Bagian 1 - Untuk apa ini?
Kami merancang bahasa pemrograman multi-paradigma. Bagian 2 - Perbandingan Pembuatan Model di PL / SQL, LINQ dan GraphQL
Kami merancang bahasa pemrograman multi-paradigma. Bagian 3 - Gambaran Umum Bahasa Representasi Pengetahuan