uzdevuma nostādne - web viewpēc tam secīgi ir faktu, likumu un deducēto faktu...
TRANSCRIPT
RĪGAS TEHNISKĀ UNIVERSITĀTE
DATORZINĀTNES UN INFORMĀCIJAS TEHNOLOĢIJAS FAKULTĀTE
Deduktīvā datu bāze
Izstrādāja:Henrihs Gorskis
2012. /2013. m. g.
Saturs
1. Uzdevuma nostādne............................................................................................................3
2. Programmas struktūra.........................................................................................................4
2.1. DDB.............................................................................................................................4
2.2. DDBIO........................................................................................................................5
2.3. DDBLog......................................................................................................................6
2.4. DDBInterface..............................................................................................................6
2.6. DDBDeduction............................................................................................................7
2.7. DDBMain....................................................................................................................8
2.8. DDBfrMain..................................................................................................................8
2.9. DDBfrSettings...........................................................................................................10
2.10. DDBfrLog..............................................................................................................11
3. Darbības princips..............................................................................................................12
3.1. Likumu nepilnības.....................................................................................................14
4. Labojumi...........................................................................................................................16
5. Nepilnības.........................................................................................................................19
6. Secinājumi........................................................................................................................22
2
1. Uzdevuma nostādne
Dotajā darbā tiek apskatīts programmas līdzeklis, kas bija izstrādāts Sergejam
Boļšedvorskim bakalaura darba ietveros. Programma izpilda datalog programmas kodu un
realizē deduktīvas datubāzes iespējas. Tajā ir vairākas iespējas kurus lietotājs var izmantot.
Tā ir spējīga izveidot savienojumu ar datubāzi. Sagatavot datubāzi, izveidojot nepieciešamas
tabulas. Tajā var apskatīties ievadītus faktus, likumus un iegūtus deducētus faktus.
Programmā ir arī dotas parauga datalog programmas teksti. To izpildot var pārliecināties par
programmas iespējam.
Dotā darba uzdevums ir izpētīt, aprakstīt un uzlabot dotu programmas līdzekli. Darbā
tika aprakstīti uzlabotas programmas moduļu uzdevumi, to saistības ar citiem moduļiem un
programmas darbības pamati. Ir dota dokumentācija par lielākām izmaiņām programmā un kā
tā atšķīrās no programmas sākotnējās darbības. Ir doti turpmākās papildināšanas un
uzlabošanas ieteikumi, pamatojoties uz atklātām nepilnībām.
3
2. Programmas struktūra
Programmas pirmkods ir sadalīts uz 9 atsevišķiem moduļiem, kas ir aprakstīti Java
klasēs. Sākotnējais modulis ir DDB, kas satur programmas main metodi, kas tiek izsaukta
programmai palaižoties. Pastāv trīs klases kas apraksta programmas vizuālos logus. Piecas
klases kas pilda dedukcijas un datubāzes savienojuma un piekļuvēs uzdevumus. Šīs piecas
klases ir savstarpēji saistīti ar mantošanu un tiek lietotas tikai kopīgi (attēls 2.1).
2.1. Att. Programmas moduļu struktūra
DDDBLog manto no DDBIO. DDBInterface manto no DDDBLog utt. Programmā tiek
izveidota tikai viena DDBMain instance, kas satur visu mantotu klašu metožu un mainīgo
apvienojumu.
2.1. DDBDDB ir galvenā programmas klase, jo tā tiek palaista programmas izpildes sākumā, bet
saistībā ar programmas ilglaicīgo darbību, tai nav īpaša nozīme. Darba uzsākšanas laikā tajā
4
tiek izveidotas visas klašu instances. Ievadītas vizuālas vērtības (logu izmēri un pozīcijas).
Tiek veidoti savienojumi starp instancēm, nododot instanču virtuālas atmiņas adreses starp
moduļiem, kā tas bija redzams attēlā 2.1.
Ir jāpiebilst, ka tas satur statisko un publisko atsauci un moduli DDBmain. Tas nozīmē,
ka katrs modulis var izpildes laikā izmantot šo atsauci, lai piekļūtu pie izveidotas DDBmain
moduļa instances un izsaukt tās metodes.
2.2. DDBIOŠīs modulis veido pamatu galvenajam saliktajam modulim, kas izpilda ar deduktīvas
datubāzes saistītos uzdevumus. Tā ir pirmā klase klašu ķēdē un tā nemanto nekādas īpašības
no citām klasēm. Šī moduļa galvenais uzdevums ir glabāt informāciju par datubāzes
savienojumu. Tajā ietilpst simbolisko ķēžu vērtības datubāzes nosaukumam, savienojuma
nosaukumam (adrese), paroli, lietotāja vārdu un citu informāciju, kas ir nepieciešama, lai
izveidotu savienojumu. Šīs modulis glabā arī pašu savienojuma (OracleDataSource) objektu,
kas tiek ņemts no arējās bibliotēkas (ojdbc14.jar). Klasē ir aprakstītas „get” un „set” metodes
simbolisko vērtību saņemšanai un izdošanai, kas tiek izmantoti iestatījumu loga darbībā, lai
nomainītu un parādītu esošas savienojuma vērtības. Pastāv savienojuma atvēršanas un
aizslēgšanas metodes. Tās tiek izsauktas galvenā logā un iestatījumu logā (piekļuve caur
galvenā loga metodi), kad tiek izsauktas savienošanas metodes, nospiežot pogas. Mēģinājums
izveidot savienojumu tiek automātiski izpildīts programmai palaižoties. Tajā brīdī tiek
lietotas vērtības, kas ir dotas pēc noklusējuma.
Šim modulim piemīt sistēmas kļūdu glabāšanas un izgūšanas funkcijas. Šī iespēja tiek
lietota daudzās vietās visā sistēmā, lai piefiksētu un pēc tam parādītu radušās kļūdas. Tas tiek
darīts ar vienkāršu simbolu virkni, kura tiek papildināta ar sistēmas kļūdu ziņojumiem. Katru
reizi izvēloties vienu no galvenā loga iespējām, attiecīgo metožu izpildes beigās tiek iegūta
sistēmas kļūdu ziņojumu virkne un parādīta.
Izpildes metode SysExecute, dod iespēju izpildīt norādīto SQL vaicājumu. Šī metode ir
domāta vienvirziena vaicājumiem, kas neatgriež vērtības (INSERT, DELETE). Šo metodi
izmanto faktu, likumu un deducēto likumu datubāzes ievadīšanas metodes no DDBMain un
BBBDeducted moduļiem un datubāzes inicializācijas metode SysInitDDB.
5
Datubāzes inicializācijas metode SysInitDDB sagatavo datubāzi. Tā nodzēš un izveido
visus nepieciešamus datubāzes tipus, tabulas un funkcijas paketi. Šī metode tiek izsaukta no
galvenā loga izvēlnes.
Pastāv datubāzes attīrīšanas funkcijas, kas izdzēš faktus, likumus un/vai deducētos
faktus. Šīs metodes tiek izsauktas no galvenā loga pogām un izvēlnes.
2.3. DDBLogDDBLog ir nākošā klases mantošanas ķēdē. Tās galvenais uzdevums ir sistēmas darbības
protokola, jeb uzskaites izveidošana un iegūšana. Tajā ir tikai šīs divas metodes. Tas tiek
darīts caur datubāzes paketes funkcijām. Tiek izmantots iepriekšējā modulī izveidotais
savienojums. Daudzas metodes mantinieku moduļos lietot uzskaites ierakstīšanas iespējas,
bet iegūšana tiek izmantota tikai protokola logā.
2.4. DDBInterfaceŠīs modulis ir domāts, ka vispārēja saskarne starp programmas iespējām un datubāzes
iespējam. Visas metodes dotajā modulī ir domāti informācijas iegūšanai no datubāzes.
Lielāka daļa metožu aprakstīti dotajā klasē ir domātas, lai iegūtu faktus, likumus un
deducētos likumus vizuālai atrādīšanai un nav citādāk lietojamas. Tās ir parādītas tabulā 2.1.
2.5. Tabula. Teksta iegūšanas metodesMetode Funkcija Tiek izmantots Izmanto metodes
String[]GetFactList
Atgriež simbolisko virkņu masīvu, kura ir ierakstīti fakti pilnā veidā ar argumentiem:Fakts(Arg0, Arg1).…
Main logs, nospiežot pogu, lai parādītu faktus.
GetFactArgs
StringGetFactArgs
Atgriež norādīta fakta argumentu simbolisko virkni:(Arg0, Arg1)
GetFactList
String[]GetRuleList
Atgriež tekstu masīva veidā visus datubāzē ievadītus likumus:Likums(Arg0, Arg1) :- LĶerm0(Arg0, Arg1), LĶerm1(Arg0, Arg1).…
Galvenais logs, nospiežot likuma atrādīšanas pogu.
GetRuleArgsGetPredicate
StringGetRuleArgs
Atgriež norādīta likuma argumentu simbolisko virkni, dotajā veidā:(Arg0, Arg1) : -
GetRuleList
StringGetPredicate
Atgriež norādīta likuma ķermeņa predikātu un argumentu teksta veidā:LĶerm0(Arg0, Arg1)
GetRuleList GetPredicateArgs
StringGetPredicateArgs
Atgriež teksta veidā norādīta likuma ķermeņa argumentus:(Arg0, Arg1)
GetPredicate
String[] Izveido un atgriež deducēto faktu Galvenajā logā GetDeductedArgs
6
GetDeductedList masīvu kurā teksta veidā ir ierakstīti fakti:DedFakts(Arg0, Arg1).…
nospiežot uz deducēto faktu atrādīšanas pogu, vai pēc izpildes.
StringGetDeductedArgs
Atgriež deducēta fakta argumentus:(Arg0, Arg1).
GetDeductedList
Tālāk dotajā modulī ir pieejamas metodes GetDeductedCount, GetFactCount un
GetRuleCount, kas saskaita datubāzē esošus faktus un likumus.
Metode GetStats izmanto iepriekš minētas saskaitīšanas metodes lai izveidotu
informatīvo testu, kas tiek rādīts galvenā loga apakšējā daļā.
Metodes GetSampleFamilyDatalog un GetSampleTreeDatalog ieraksta parauga
programmas ievades laukā, nospiežot attiecīgas pogas galvenajā logā.
2.6. DDBDeductionIzpilda visas tieši ar dedukciju saistītos uzdevumus. Funkcija ExecuteGoal saņem
izpildāma vaicājuma predikāta nosaukumu un katra argumentā ierakstīto tekstu. Pamatojoties
uz to vai saņemtais predikāts ir fakta nosaukums, to nodod tālāk ExecuteFakt metodei, kas
pārbauda vai eksistē tāds fakts un ieraksta atrasto faktu deducētajos datos. Pretējā gadījumā
(kad saņemtais predikāts nav fakts) tiek izpildīta metode ExecuteRule. Tā secīgi izpilda
visus atrastos likumus, kuru nosaukums sakrīt ar vaicājumā norādīto predikātu. Izmantojot
metodi PreparePredicates tiek iegūts ar likumu saistītais predikātu skaits un vienlaicīgi tiek
atrasti visi ar predikātu saistītie fakti (tos ierakstīta deducētos faktos). Tālāk tiek atrasti visi ar
pašreizēji apskatāmo likumu saistīti predikāti (likuma ķermenis). Visa iegūta informācija
(predikātu skaits, predikātu nosaukumi, katra predikāta argumentu skaits, argumentu vērtības,
mērķa likuma identifikācijas numurs, mērķa likuma nosaukums, mērķa likuma argumentu
skaits un argumentu vērtības) tiek nodota metodei ExecuteDeductedFact. Šī metode sākumā
izsauc metodi GetRuleArgList, lai iegūtu mērķa likuma argumentus, kā tie ir ierakstīti
datubāzē. Izmantojot funkcijas getUniqueFactArgCount, lai iegūtu visu unikālo termu
skaitu un metodi getUniqueFactArgs, kas atgriež visus unikālos termus kā simbolu virkņu
masīvu, ir iespējams tos ievietot visu palikušo brīvo mainīgo vietā. Sīkāk dedukcijas process
ir paskaidrots nodaļā 3.
Funkcija isExistingFact pārbauda vai dotais fakts ir atrodams deducētos datos un
atgriež patiesības vērtību atrašanas gadījumā. Metode CheckForNewDeductedFact
pārbauda vai dotais fakts jau ir atrodams deducētos faktos. Metode InsertDeductedFact
ievieto norādīto faktu deducētajos faktos. Metodes isFact un isRule pārbauda vai norādītais
7
predikāts ir atrodams faktos vai likumos. Metode isGroundRule dara to pašu ko isFact, bet
pašlaik netiek nekur lietota (iespējams tas ir pārpalikums no iepriekšēja izstrādes procesa).
2.7. DDBMainPēdējais modulis mantošanas ķēdē. Tas pilda vispārīgos vaicājuma sagatavošanas
uzdevumus. Tas sadala ievadīto tekstu uz ierakstiem. Katru ierakstu pārbauda uz atļautiem
simboliem. Atklāj ieraksta veidu un izsauc attiecīgo metodi. Metode Datalog saņem pilno
ievadīto tekstu no ievades lauka galvenā logā, pēc pogas nospiešanas. Programma var saņemt
maksimāli 100 komandas vienā izpildes piegājienā. Katra ieraksta tips tiek pārbaudīts ar
metodēm isQuery (vai ir vaicājums?) un isRule (vai ir likums?). Ja ieraksts nav vaicājums un
arī nav likums tad tiek izpildīta metode DatalogFact, kas sagatavo datubāzē ievietojamās
vērtības un pēc tam izsauc metodi InsertDatalogFact, lai to ievietotu datubāzē.
Gadījumā, kad ieraksts ir likums, tiek izsaukta metode DatalogRule, kas apstrādā visas
likuma daļas, lai iegūtu nepieciešamo informāciju datubāzes laukiem un pēc tam izsauc
metodi InsertDatalogRuleHead un InsertDatalogRulePredicate, lai ievietotu datubāzē
likuma galvu un ķermeņi.
Gadījumā, kad apstrādājamā tekstā ir atklāts vaicājums, tas tiek piefiksēts uz izpildes
beigām. Tādā veidā tiek nodrošināts, ka visa informācija ir ievadīta datubāzē pirms notiek
vaicājuma izpilda. Sakarā ar to, kā tas tiek realizēts ir iespējams izpildīts tikai vienu
vaicājumu vienā izpildes piegājienā, turklāt tikai pēdējo atklāto vaicājumu. Metode
DatalogQuery, sagatavo vaicājumu izpildei, pēc tam izpildot metodi ExecuteGoal
iepriekšējā modulī (DDBDeduction).
2.8. DDBfrMainŠīs modulis veido galveno programmas logu un apraksta tikai tādas metodes un
mainīgos, kas nodrošina vizuālo elementu darbību. Galvenais logs ir redzams attēlā 2.2. Kā
var redzēt logs ir sadalīts vairākās daļās. Pašā augšā ir izvēlnes josta, kurā var atrast visas
programmas iespējas (attēls 2.3). „Savienojuma uzstādījumi” izsauc metodi, kas atvērs
savienojuma iestatījumu logu (aprakstīts klasē DDBfrSettings). Savienošanas funkcija atslēdz
pašreizējo savienojumu ar datubāzi (CloseConnection metode no DDBIO) un izveido jaunu
savienojumu (OpenConnection metode no DDBIO), izmantojot pašreizēji iestatītas vērtības
datubāzes savienojumam. Datubāzes sagatavošanas funkcija izsauc SysInitDDB metodi no
DDBIO moduļa. Sistēmas protokola iespējas atvērs protokola logu, kas ir aprakstīts klasē
8
DDBfrLog. Līdz šim uzskaitītas funkcijas no izvēlnes ir atrodamas tikai izvēlnē. Visas
pārejas iespējas ir dublicētās un ir dotas kā pogas galvenajā logā.
2.2. Att. Galvenais programmas logs
9
2.3. Att. Izvēlnes jostas „Datu Baze” iespējas.
Pirmā poga ar baltās lapas simbolu izdzēš visus faktus, likumus un deducētos faktus no
datubāzes. Pēc tam secīgi ir faktu, likumu un deducēto faktu parādīšanas funkcijas. Zobrats
simbolizē vaicājuma izpilde funkciju. Dzeltenās un baltas lapas ir datalog parauga
programmu tekstu izsaukšanas funkcijas. Baltās lapas ar „D” burtu simbolizē deducēto faktu
izdzēšanas funkciju. Sarkana poga izslēdz programmu.
Divi lielākie objekti, kas ir redzami galvenajā logā ir ievades un izvades lauki. Ievades
lauks ir teksta lauks un tajā var brīvi rakstīt datalog programmas komandas. Izvades lauks arī
ir tekstuāls lauks, bet tas ir saraksts. Tas ir īpašais saraksta objekts kurā ir tekstuāli ieraksti. Ir
iespējams izvēlēties vienu vai vairākus no šiem ierakstiem, bet nav iespējams tos mainīt. Pašā
apakšā ir redzama vispārīga informācija par datubāzi, kas ir saņemta no metodes GetStats,
no DDBInterface.
Lielākā daļa metožu šajā klasē, izpildes laikā veic izsaukumus metodei GetStats un lieto
saņemtas vērtības gan informācijas atjaunošanai, gan izvades lauka apstrādē (nosakot cik
daudz ieraksti būs izvads laukā).
10
2.9. DDBfrSettingsDotajā klasē tiek aprakstīts iestatījumu logs, kurā tiek ierakstītas savienojuma vērtības.
2.4. Att. Iestatījumu logs
Dotajā logā tiek ierakstīts:
servera adrese, kas pēc noklusējuma ir „localhost”;
porta numurs (pēc noklusējuma 1521), teksta veidā. Gadījumā, kad ierakstīta
vērtība nav vesels skaitlis radīsies kļūda;
datubāzes nosaukums, jeb SID. Pēc noklusējuma „XE”;
lietotāja vārs („sql_user”);
lietotāja parole („sql_user”).
Loga apakšā ir trīs pogas. Savienošanas poga saglabā visas ievadītas vērtības un veiks
mēģinājumu savienoties. Poga „Labi” saglabā ierakstītas vērtības, bet nemēģina savienoties
(var izpildīt savienojuma mēģinājumu no galvenā loga izvēlnes, nospiežot „Savienoties”).
Poga „Atcelt” un sarkanais X loga augšējā daļā paslēp logu un atcel visas izmaiņas. Vērtības
tiek saņemtas un nodotas ar „get” un „set” metodēm no moduļa DDBIO. Savienošanas poga
izsauc galvenā loga publisko savienošanas metodi connect.
2.10. DDBfrLogSistēmas protokola logs (attēls 2.5). Uz Doto brīdi tas atbalsta tikai piedejo 150 ierakstu
parādīšanu.
11
2.5. Att. Sistēmas protokola logs.
Līdzīgi galvenā loga izvades lauka, protokola lauks arī ir saraksta objekts. Atrādāmās
vērtības tiek saņemtas no moduļa DDBLog GetSysLog metodes. Mākslīgi ieviestais
ierobežojums 150 ierakstiem iespaido abus moduļus.
12
3. Darbības princips
Dotā sadaļa mēģina paskaidro kādā veidā notiek vaicājuma izpilde un kas to iespaido.
Kad DDBMain modulis ir piefiksējis vaicājumu, atklājot jautājuma zīmi ieraksta
sākumā, tas to sadala sastāvdaļās (predikāta nosaukums, argumentu skaits un masīvs kurā ir
sagatavoti argumenti [argumenta tips un argumenta vērtība]) un nodot šo informāciju
DDBDeduction moduļa ExecuteGoal metodei. Šī metode pārbauda vai vaicājums attiecās un
faktu vai likumu. Tas tiek realizēta ar metodes isFact palīdzību, kas izmanto funkciju is_fact
no datubāzes funkciju paketes. Tā atgriež patiesību, kad vaicājuma predikāta nosaukums ir
atrodams datubāzes faktu sarakstā. Gadījumā, kad ir konstatēts fakts tiek izsaukta metode
ExecuteFact. Tai nodot visu informāciju par vaicājumu.
ExecuteFact veic izsaukumu datubāzei (get_fact_id no DDB paketes) kuru rezultātā
saņem kursoru uz rezultātu. Tas ir nepieciešams, jo pastāv iespēja saņemt vairākus faktus ar
vienādu nosaukumu un argumentu skaitu. Ciklā tiek iegūts fakta identifikācijas numurs un ar
līdzīgu pieeju tiek iegūti visi fakta argumenti (get_fact_args no DDB paketes). Cikla izpildes
laikā tiek veikts salīdzinājums starp argumentu vērtībām, kas ir iegūti no datubāzes un
vaicājumā norādītiem argumentu vērtībām. Gadījumā, kad ir atklāta sakrišana, tiek veikts
mēģinājums doto faktu pievienot deducētiem faktiem.
Faktu ievietošana arī citās metodēs notiek vienādā veidā. Sākumā tie izsaukta metode
CheckForNewDeductedFact, kas apskata visus ievietotus deducētos faktus un meklē vai
ievietojamais fakts jau ir atrodams tajos. Gadījumā, ja tāda fakta vēl nav, tiek izsaukta
metode InsertDeductedFact, kas to ievieto datubāzē.
Tajā gadījumā, kad pirmā metode atklāja, ka apskatāmais predikāts nav fakts, tā pieņem,
ka to ir jāapstrādā kā likums. Metode ExecuteRule saņem visu uz doto brīdi esošu
informāciju par likumu. Ļoti līdzīgā veidā, kā to darīja faktu apstrādes metode, tiek meklēti
visi likuma nosaukumam atbilstoši datubāzē esošie likumi, kuriem arī ir norādītais argumentu
skaits.
Lielā ciklā tiek sagatavota visa informācija par atrasto likumu. Tiek iegūts dota likuma
ķermenis no datubāzes. Katra cikla iterācijā (viena iterācija katram likumam) tiek izsaukta
metode ExecuteDeductedFact. Jāņem vērā, ka likums kuram ir divas daļas, tiek izpildīts
13
tieši šādā veidā. Sākumā izpildot vienu daļu, pēc tam otru. Piemēram likums „pēctecis” no
piemēra ir definēts šādā veidā:
pectecis(A, B) :- vecaks(A, B). pectecis(A, B) :- vecaks(Z, B), pectecis(A, Z).
Pirmā daļa tiek izpildīta vispirms un atsevišķi no otras daļas. Uz doto brīdi nav definētas
apvienojošās darbības. Vienīgi katra likuma izpildes rezultāts tiek ierakstīts deducētajos datos
un jebkurš nākošais likums var piekļūt rezultātiem deducētajos datos un tādā veidā turpināt
informācijas ieguves procesu. To ir jāņem vērā rakstot likumu. Var rasties situācijas kurā ir
nepieciešams paralēli izmanot abas likuma daļas (piemērs ir dots nodaļā 3.2). Tas var novest
pie situācijas, kad ir nepieciešams atkārtoti izsaukt vaicājuma izpildi lai iegūtu pilnīgo
rezultātu, vai arī var gadīties, ka rezultāts netiks atrasts.
Izsaukta izpildes metode saņem visu līdz šim savāktu informāciju par likumu. Šajā
informācijā ietilpst: likuma ķermenī esošo predikātu skaits, šo predikātu nosaukumi, katra
predikāta argumentu skaiti, katra predikāta saliktie argumenti (tips un vērtība), likuma
identifikācijas numurs, likuma galvas predikāta nosaukums, likuma galvas argumentu skaits,
un likuma galvas saliktie argumenti, tā kā tie bija ierakstīti vaicājumā.
Gadījumā, kad vaicājumā argumentos likuma vietā bija dota cita vērtība, pastāv
nepieciešamība veikt attiecīgos aizstāvēšanas darbības. Lai to īstenotu ir nepieciešams iegūt
likuma argumentus, tā kā tie ir rakstīti datubāzē. Šo uzdevumu veic metode GetRuleArgList
(izmanto get_fact_args no DDB paketes), kas iegūst mainīgo nosaukumu sarakstu. Tālāk
notiek pārbaude uz to, kādi mainīgie tika aizstāti vaicājumā, lai nomainītu visus mainīgos
likuma ķermenī (uz izpildes laiku) ar ievadīto vērtību.
Nākošais solis paredz visu palikušo unikālo mainīgo saskaitīšanu. Mainīgo skaits tiek
piefiksēts, jo tiem būs nepieciešams piemeklēt iespējamos termus (predikātu argumentu
vērtības), lai veidotu faktu kombinācijas.
Lai iegūtu visus unikālos termus no datubāzes tiek izsauktas metodes
getUniqueFactArgCount un getUniqueFactArgs (lieto parastus SQL vaicājumus). Abas
metodes izpilda vienu un to pašu vaicājumu datubāzei, bet pirmā saskaita iegūtos ierakstus,
otrā veido sarakstu ar termiem. Tas ir nepieciešam, lai dināmiski piešķirtu pietiekamo
atmiņas apjomu sarakstam.
14
Iegūtie unikālie termi tiek secīgi ievietoti visos palikušajos brīvos mainīgos. Tādā veidā
tiek veidotas visas iespējamas likuma kombinācijas. Katra likuma ķermenī esoša predikāta
kombinācija ar izveidotajiem argumentiem tiek pārbaudīta un esamību deducētos datos. Tam
tiek lietota metode isExistingFact (lieto vienkāršu SQL vaicājumu, lai iegūtu deducētos
datus).
Ir svarīgi piefiksēt, ka vaicājuma izpildei tiek tieši lietoti deducētie fakti, nevis pamata
fakti. Tas ir iespējams, jo katrs ar likumu saistīts fakts tiek ievadīts deducētajos faktos
vaicājuma sagatavošanas stadijā. Pateicoties šādai pieejai ir iespējams piekļūt iepriekšējās
iterācijās iegūtajiem faktiem. Tomēr ir jāpiebilst, ka dotajā brīdī ir paredzēta darbība tikai ar
deducētiem faktiem, kas daļēji nodrošina rekursiju, bet nenodrošina pilnu un sarežģītu
rekursiju.
Šādā veidā secīgi tiek pārbaudīts, katrs likuma ķermenī esošais fakts. Gadījumā, ja visi
fakti likuma ķermenī izpildījās, likuma galva ar pašreizējiem mainīgo vērtībām tiek ievietos
deducētajos datos. Tas tiek darīts iepriekš aprakstītā veidā.
Ir paredzēta atkārtota vaicājuma izpilde. Gadījumā, ja vaicājuma izpildes laikā bija
pievienoti fakti, izpildes beigās process sākās no jauna. Tas tiek darīts tik ilgi, kamēr vairs
netiek pievienoti jauni fakti.
3.1. Likumu nepilnības
Ir nepieciešams pievērst uzmanību noteikto likumu definīcijai un ar šādu definīciju
saistītām izpildes grūtībām. Ir doti divi gandrīz vienādi likumi:
1) pectecis(A, B) :- vecaks(A, B).pectecis(A, B) :- vecaks(A, Z), pectecis(Z, B).
2)pectecis(A, B) :- vecaks(A, B).pectecis(A, B) :- vecaks(Z, B), pectecis(A, Z).
Ir doti divi likumi „pēctecis”. Likums abos gadījumos sastāv no divām daļām. Pirmais
likuma variants ir ņemts no programmas oriģināla piemēra. Otrais likums ir pirmā likuma
modifikācija. Abiem likumiem ir vienāds mērķis – atklāt pēctecības saiti starp A un B.
15
Sakarā ar programmas dedukcijas uzdevuma izpildes mehānismu uz doto brīdi (likumu
izpildes secība, rezultātu glabāšana, likumu atbilstības konstatēšana), pirmais likums izpildās
nepilnīgi.
Pārtulkojot likumus uz cilvēkam saprotamo tekstu sanāk:
B ir pēctecis no A, tad kad A ir vecāks B. Tas ir loģiski, jo šādā radniecības gadījumā,
nav šaubu par pēctecību. Šī daļa abos gadījumos ir vienāda un kļūdas nerada. Otra likuma
daļa ir sekojoša pirmajā gadījumā:
B ir pēctecis no A, kad A ir vecāks kaut kādam Z un vienlaicīgi ir B kuram ir pēctecības
saite ar šo Z.
Var likties, ka tas ir loģiski pareizi un likums izpildīsies, tomēr rodas kļūdas. Problēma ir
tajā, ka ir nepieciešams konstatē radniecisko saiti starp Z un B pirms tika izpildīts vaicājums
ar norādīto A. Sakarā ar to, ka vaicājuma izpildē tiek apskatīti tikai jau esošie deducētie fakti,
gadījumā, kad tiek norādīta A manīga vērtība (piemēram ‘Jānis’), tiek atrasti tikai tieši Jāņa
bērni. Gadījumā, kad netiek norādītas vērtības un tiek meklētas visas radnieciskas saites tiek
atklātas tikai tās radnieciskas saites, kas nav tālāk par divām paaudzēm.
Šāds rezultāts ir paskaidrojams šādi:
Programma atrod abas likuma daļas. Tie tiek izpildīti secīgi. Pirmā daļa meklē
radniecības faktu. Tiek atrasti visi Jāņa bērni. Tie tiek pierakstīti deducētos faktos, kā
„Pēctecis (‘Jānis’,’Kārlis’)” un „Pēctecis (‘Jānis’,’Māris’)”. Līdz šim viss ir pareizi. Tālāk
tiek apskatīta likuma otrā daļa. Tagad tiek meklētas radnieciskas saites starp Jāni un jebkuru,
kam būtu pēctecības saite ar B. Te rodas grūtības, jo uz doto brīdi nav nekādas informācijas
par citiem pēctečiem deducētos datos. Ja vien pēctecība starp Z un B nebija deducētos datos
no iepriekšēja vaicājuma, dota vaicājuma izpilde šādu saiti neatrādīs. Tas ir saistīts ar to, ka
vaicājuma izpildē tiek meklēti tikai fakti. Rekursija ar paralēla vaicājuma izpildi uz doto brīdi
nav iespējama (skat. nodaļa 5).
Savukārt otra vaicājuma varianta otra daļā skan sekojošā veidā:
Jāņa pēctecis ir tas, kas ir bērns (vecāks(Z, B)) Jāņa pēctecim (pēctecis(‘Jānis’, Z)).
16
Šis vaicājuma variants meklē tieši to pašu saiti ar visiem Jāņa pēctečiem un atrod tos
atsaucoties tikai uz jau iepriekš iegūtiem datiem, bez nepieciešamības veikt paralēlu
vaicājumu izpildi. To panāca aizstāvot pēctecības meklēšanu ar secīgu izpildi. Katrai jaunai
paaudzei ir garantēta pēctecības atklāšana ar vecākiem un ir nepieciešams tikai pievienot
viņus, kā pēcteču bērnus.
4. Labojumi
Šajā nodaļa ir uzskaitītas visas lielas izmaiņas programmas pirmkodā.
DDB.java
Pievienota publiska statiska atsauce uz galveno logu, lai iestatījuma logs varētu
izsaukt galvenā loga savienojuma metodei connect.
Nomainīta aizvēršanas uzvedība iestatījuma un sistēmas protokola logiem no
EXIT_ON_CLOSE uz HIDE_ON_CLOSE. Tas tika darīts, lai logu aizvēršana ar
X loga augšējā stūrī nepārtrauktu visas programmas izpildi.
DDBDeduction.java
Pievienots mainīgais insrtDed ar tipu boolean. Šīs mainīgais tiek lietots, lai
piefiksētu fakta pievienošanu datubāzē, lai noteiktu nepieciešamību atkārtot
vaicājuma izpildi.
Labota metode ExecuteRule. Predikātu atklāšana un pierakstīšana tagad notiek
dināmiskā veidā, kas ļauj iegūt jebkuru skaitu predikātu no likuma ķermeņa.
Pilnībā pārtaisīta metode ExecuteDeductedFact. Informācija par likumu tiek
saņemta masīvos, kas apraksta likuma ķermeni.
Metodē ExecuteDeductedFact ieviesta funkcionalitāte, kas aprakstīta 2. un 3.
nodaļā.
Pievienota jauna metode GetRuleArgList, likuma argumentu iegūšanai no
datubāzes.
Pievienota metode getUniqueFactArgCount, unikālo termu skaita iegūšanai.
Pievienota metode getUniqueFactArgs, unikālo termu iegūšanai.
Pievienota metode isExistingFact, kas pārbauda vai norādītais fakts ir atrodams
datubāzē deducētos faktos.
17
Mainīta metode isExistingFact, lai tā veiktu ierakstu mainīgā insrtDed.
Labota metode CheckForNewDeductedFact, lai tā spētu dināmiski apstrādāt
jebkādu argumentu skaitu.
Pievienota metode isRule, likuma atklāšanai (pašlaik netiek lietota).
DDBInterface.java
Labota metode GetFactList, lai tā dināmiski izveidotu jebkādā garuma faktu
sarakstu.
Mainīta metode GetRuleList, kas tagad piešķir 4 ierakstus sarakstā katram
likumam.
Labota metode GetDeductedList, lai tā dinamiski piešķirtu saraksta garumu.
Veiktas izmaiņas datalog piemēru programmu tekstos.
DDBLog.java
Pārveidota metode GetSysLog, lai tā atgrieztu pēdējos 150 ierakstus no
datubāzes.
DDBIO.java
Pievienotas get un set metodes datubāzes nosaukumam un porta numuram.
Pievienota attīrīšanas metode SysClearDeduced, kas izdzēš deducēto faktu
ierakstus no datubāzes tabulas.
Papildināta metode SysInitDDB, lai tā datubāzes sagatavošanas laikā arī
izveidotu DDB procedūru paketi.
DDBfrMain.java
Pievienota ikona imageClearDed, kura sevī glabā attēlu no faila iclearDed.png.
Pievienota poga buttonClearDed un izvēlnes ieraksts mmClearDeduced
o Piešķirtas nepieciešamas īpašības
o Izveidotas saites ar attiecīgām notikuma metodēm
o Pievienoti apkopojošiem objektiem (toolbar un mmDatabase)
18
Pievienotas metodes mmClearDeduced_actionPerformed un
buttonClearDed_actionPerformed pogu un izvēlnes notikumu apstrādei, kad
tiek izvēlētas deducēto datu iztīrīšanas darbība. Metodes izsauc
SysClearDeduced metodi no DDBIO.
Pievienots „komponentes klausītājs” logam, kas izsauc attiecīgo metodi saistībā
ar loga izmēra izmaiņām.
Pievienota metode onResize, kas nomaina visu vizuālo komponentu izmērus
atkarībā no loga pašreizēja izmēra.
DDBfrSettings
Pievienoti vizuālie objektu datubāzes nosaukuma ievadei
Pievienoti vizuālie objekti porta numura ievadei
Pievienota savienojuma izveides poga
Pievienota metode btConnect_actionPerformed, kas apstrādā pogas
nospiešanas notikumu.
19
5. Nepilnības
Kaut arī programmas darbība tika labota uz papildināta pēc iespējām, dotajā laikā,
joprojām tajā paliek nepilnības un iespējas tālākai uzlabošanai. Šajā nodaļa ir uzskaitītas
lielākas atklātas nepilnības.
Par lielāko nepilnību varētu minēt vaicājuma izpildes procesu. Uz doto brīdi pārbaude uz
to vai likums piepildās tiek realizēta meklējot vai likuma ķermeņa daļā esošie fakti ir
atrodami deducētos faktos. Vēra tiek ņemti tikai jau atrastie un datubāzē esošie fakti. Tas
nozīmē, ka likumi, kas tiek definēti nepareizi (ar domu, ka likuma izpildes laikā tiek izsaukta
cita likuma izpilde) netiks pareizi realizēti. Tika veikts mēģinājums šādu funkciju ieviest, bet
tas cieta neveiksmi. Modulī DDBDeduction tika ieviesta metode isRule. Ar tās palīdzību ir
iespējams noteikt, vai apskatāmā likuma ķermeņa predikāts ir pats par sevi likums. Likuma
atrašanas gadījumā būtu iespējams realizēt likuma apstrādes, nevis fakta meklēšanas
darbības. Šādas piegājiens ciet neveiksmi, jo gadījumā, kad likumā ķermenī ir norādīts tāds
pats likuma nosaukums, kā izpildāmai likums, var veidoties bezgalīgs cikls. Tā tas notiek ar
pēctecības likumu no oriģināla datalog programmas piemēra. Viens no iespējamiem
risinājumiem ir mehānisma ieviešana, kas regulē ciklisko izpildi, ierobežojot to uz noteiktu
dziļumu. Šāds piegājiens arī negarantē vispilnīgāko rezultātu visos gadījumos.
Viens no iemesliem, kas neļauj atrast labu risinājumu iepriekšējai nepilnībai ir
programmas vispārīga struktūra un veids kurā pašlaik notiek izpilde. Vēl viena nepilnība ir
fakta pārbaude ExecuteGoal metodē. Tajā notiek pārbaude uz to vai apskatāmais predikāts ir
likums, bet apstrādē netika ņemts vērā gadījums, kad dotais predikāts pieder gan likumam,
gan faktam. Dotajā brīdī arī tiek atšķirts starp pamata faktu un deducēto faktu tajos
gadījumos, kad vajadzētu iedziļināties, kāpēc jālieto vienu vai otru. Šādas nepilnības ir
vaicājuma izpildes pamatā un iespaido visu procesu.
Vēl viens faktors, kas ļoti spēcīgi iespaido programmas izpildi, ir lēmums veikt ļoti lielu
daļu uzdevuma programmā. Programma izmanto DDB paketes procedūras un SQL
vaicājumus tikai lai iegūtu vai ierakstītu informāciju datubāzē. Turklāt, sakarā ar mēģinājumu
ierobežot informācijas daudzumu, kuru programma apstrādā vienlaicīgi, informācijas
iegūšanas vaicājumi tiek ļoti bieži atkārtoti. Tas noved pie īpatnējās situācijas. Programmā
tiek izmantoti īpaši datubāzes kursoru objekti. Šie kursori glabā sevī atsauci uz vaicājuma
20
rezultātu kopu. Kaut arī šādiem objektiem ir īpašs aizvēršanas mehānisms (komanda close),
patiesībā savienojums ar datubāzi netiek pārtraukts. Tas nozīmē, ka pēc noteikta laika atvērti
kursoru savienojumi ar datubāzi sakrājās. Pie noteikta atvērto kursoru skaita vaicājumi
atgriež tikai kļūdu ziņojumus par šo faktu iestāšanos. Tādā stāvoklī programma ir
neizmantojama un ir nepieciešams pārtraukt un atjaunot pamata savienojumu ar datubāzi.
Programmas pirmtekstā netika atklāti kursori kuriem kļūdu pēc netika izsaukti aizvēršanas
metodes. Pastāv aizdomas, ka pilnīga savienojuma pārtraukšana ir vienīgais risinājums dotai
problēmai, bet to nav iespējams pamatot bez dziļākas sapratnes par Java Oracle datubāzes
savienojumu. Šī nebūtu pārāk liela problēma, ja vien tā nerastos tieši vaicājuma izpildes
laikā. Rekursijas ieviešanas mēģinājumā radās kursoru problēmas, pat pie samēra neliela
datalog parauga programmas izpildes. Šo problēmu pastiprina fakts, ka vaicājumu daudzums
gandrīz katrai darbībai daudzkārt palielinās, kad palielinās faktu, likumu un deducēto faktu
skaits.
Kaut arī programmas struktūra cenšas ierobežot informācijas apjomu ar kuru programma
strādā jebkurā laika brīdī, tik un tā tiek bieži iegūts ļoti liels informācijas apjoms. Veiksmīgai
vaicājuma izpildei programmai ir jābūt spējīgai glabāt visus no datubāzes iegūtos unikālos
termus.
Dotajā brīdī ir iespējam iespaidot vaicājuma izpildi norādot citu mainīgo meklējama
likuma galvā, nekā bija dots likuma definīcijā. Šāda darbība ir atļauta, bet var novest tie
neparedzamas uzvedības, jo automātiski tiks aizstāti visi likumā esošie mainīgie uz norādīto.
Jāņem vērā, ka pašreizēja programmas darbība pieņem, ka likuma deklarācijā vienmēr
tiek izmantoti tikai mainīgie argumentos. Gadījumā kad likuma deklarācija bija uzrakstīts ar
fiksētiem termiem, programmas izpilde var būt ar neparedzamo rezultātu.
Mazāk svarīgas nepilnības ir iestatījuma loga vērtību aizmiršana programmai
izslēdzoties. Ieviešot funkciju, kas glabātu pēdējās iestatījuma vērtības failā, varētu atvieglot
programmas lietošanu.
Pirms izsaukt metodes kas iegūst likumu, faktu vai deducēto faktu sarakstus ir
nepieciešams izsaukt metodi GetStats no DDBInterface. Pretējā gadījumā var nesakrist
vērtības pēc kuram tiek veidoti sarakstu garumi un ierakstiem varētu nepietikt vietas, kas
novestu pie adresācijas kļūdas. Metode GetRuleList ir nepilnīga, jo tā vienkārši pieņem, ka
katram likumam pietiks ar vidēji 4 ierakstiem. Tas nozīmē, ka gadījumos kad likumiem būs
21
mazāk par 3 predikātiem ķermeņa daļā, būs piešķirts pārāk daudz atmiņas. Savukārt tajos
gadījumos, kad likumam būs vairāk par 3 predikātiem un pārpalikušas atmiņas no pērējiem
likumiem nepietiks lai kompensētu šādu daudzumu, var rasties saraksta adresācijas kļūdas.
Procesi kas aizņem ļoti ilgu laiku (visi procesi, kas iegūst vai ieraksta informāciju
datubāzē) bloķē pārējo programmas izpildi. Tā skaitā tiek bloķētas loga pārzīmēšanas
funkcijas. Tas ir ļoti pamanāmi vaicājuma izpildes laikā. Kamēr notiek vaicājums logs
nereaģē un var rasties nepareizs priekšstats par programmas stāvokli. Lai uzlabotu šo
nepilnību būtu jāievieš paralēlie procesa pavedieni programmas izpildē.
Sistēmas protokolēšana ir nepilnīga. Protokolā ierakstītie ziņojumi nesatur lielu
informācijas daudzumu un tiek veikti ļoti bieži. Pēc noteikta laika (~3000 ziņojumi), rodas
iespaids, ka datubāzē vairs netiek piefiksēti jaunie ziņojumi. To ir nepieciešams sīkāk
pārbaudīt. Šo problēmu varētu risināt periodiski dzēšot ieraktus no protokola tabulas.
Pagaidām tas ir iespējams tikai pieslēdzoties datubāzei ar citu rīku.
22
6. Secinājumi
Dotās programmas funkcionalitāte tika labota un papildināta pēc iespējām. Programma ir
spējīga izpildīt ar datalog uzrakstītas programmas, ja vien tās ir uzrakstītas ņemot vērā visas
izpildes īpatnības. Programma ir lietojama, bet uz doto brīdi nav viennozīmīgi noteikts, ar
kādu informācijas apjomu tā var bez kļūdām darboties. Parauga programmas tiek izpildītas
bez sarežģījumiem.
Kaut arī programma ir funkcionējoša, tā neizcilās ar resursu ekonomisku pārvaldījumu
vai ātrdarbību. Var pastāvēt nepieciešamība pārdomāt programmas struktūru, lai ulabotu
dažas nepilnības. Ja pastāvēs nepieciešamība turpināt labot programmu, ir jāatrisina
rekursijas pieejas jautājumi. Iespējams cita programmas struktūra būtu labāk piemērota
paralēlai uzdevumu risināšanai.
Projektējos programmu Sergejam Boļšedvorskim izvēlējās programmas arhitektūru, kas
pilda visus dedukcijas uzdevumus programmas rīkā. Visas darbības ar datubāzi ir tikai
informācijas iegūšanai vai ierakstīšanai. Labāka alternatīva varēja būt, ka programma tikai
parāda informāciju no datubāzes, bet lielāka daļa darba, tā skaitā arī dedukcijas uzdevumi,
tiktu izpildīti datubāzē ar PL/SQL programmas paketes palīdzību.
Varētu arī domāt par vaicājumu izpildes optimizāciju. Tā vietā lai meklētu visu faktu
kombinācijas, piemeklējot termus mainīgajiem, varētu mēģināt tiešā veidā apskatīt esošus
faktus. Šāda pieeja prasītu atsevišķi izprojektēt procesu.
Neskatoties uz dažām nepilnībām, programma uz doto brīdi ir izmantojama deduktīvas
datubāzes uzdevumu pildīšanai un tā ir pietiekami ērta lietošanā.
23