Skip to content
korvo edited this page Jun 7, 2020 · 27 revisions

Kelkaj konsideras Prologon mortintan lingvon, sed por kelkaj aplikoj ĝi estas tra konvena lingvo. Jen iom da rezonado pri tio.

Aplikaĵo kiel informilo

Multaj programoj kerne estas aplikaĵo por serĉi, pridemandi informojn el informstoko, t.e. datumbazo. Se multaj paralelaj uzantoj ŝanĝas tian datumbazon paralele, verŝajne vi elektas iun SQL-datumbazon kiel mySQL, MSSQL, Oracle k.a. Tiel via programo konsistas el pluraj partoj: la datumbazo kun ĉio necesa por administri ĝin, kun aparta lingvo (SQL) por ŝanĝi kaj pridemandi ĝin. Por la dialogoj vi havas apartan programon skribitan en aparta programlingvo kaj por komuniki kun la datumbazo vi bezonas specialan interfacan pelilon, kiu tradukas inter via programlingvo kaj la datumbaza lingvo.

Se via programo precipe legas el la datumbazo kaj la aktualigo ne bezonas okazi tuje, sekurigite per transagoj, sed povas esti iel seriigita, tiam la supre detaligita aranĝo aperas sufiĉe balasta. Prologo estas samtempe datumbazo kaj programlingvo kaj medio por pridemandi la datumbazon. Cetere la sintakso por pridemandi estas agrable simpla kaj permesas paŝo-post-paŝo-procedon por trovi logikajn erarojn. Kiam en SQL trioble nestita demand-frazo ofte postulis de mi tutan antaŭtagmezon ĝis mi forigis la sintaksajn kaj semantikajn erarojn, oni povas kunkonstrui ekvivalentan demandon en Prologo ofte en malpli ol horo.

Por ilustri tion, ni jen havas malgrandan liston de riveroj, virinoj kaj viroj kaj volas eltrovi, ĉu iuj estas nomoj kaj de homo kaj de rivero. En Prologo oni difinas la liston tiel:

rivero(amazono).
rivero(amudarjo).
rivero(angaro).
rivero(danubo).
rivero(dono).
rivero(elbo).
rivero(hudsono).
rivero(induso).
rivero(jenisejo).
rivero(jordano).
rivero(kamo).
rivero(karao).
rivero(leno).
rivero(luaro).
rivero(mekongo).
rivero(mozelo).
rivero(nilo).
rivero(rejno).
rivero(rodano).
rivero(saro).
rivero(tamizo).
rivero(tibero).
rivero(volgo).

ino(aneto).
ino(berto).
ino(amazono).
ino(leno).
ino(saro).
ino(sofio).

malino(antono).
malino(berto).
malino(jordano).
malino(tomaso).

En SQL oni devus skribi pli vortriĉe:

CREATE TABLE rivero(nomo VARCHAR(20));
CREATE TABLE ino(nomo VARCHAR(20));
CREATE TABLE malino(nomo VARCHAR(20));

INSERT INTO rivero(nomo) VALUES('amazono');
INSERT INTO rivero(nomo) VALUES('jordano');
-- ktp.

INSERT INTO ino(nomo) VALUES('amazono');
-- ktp.
INSERT INTO malino(nomo) VALUES('jordano');

Kaj por demandi oni skribas jenan predikaton en Prologo:

sinonimo(S) :-
  rivero(S), 
  (ino(S); malino(S)).

% aŭ alternative per du klaŭzoj:

sinonimo(S) :-
  rivero(S), 
  ino(S).

sinonimo(S) :-
  rivero(S), 
  malino(S).

Komo estas logika "kaj" kaj punktokomo logika "". Alivorte ni serĉas riverojn kiuj krome (kaj) estas nomo de ino malino. Majusklaj nomoj estas variabloj, kaj se ni uzas la saman variablonomon en pluraj predikatoj, ni tiel postulas, ke ĝi havu ĉiufoje la saman valoron. Oni nomas tion "unuigo" (komapru kun uzo de JOIN en SQL malsupre).

Nun ni povas demandi:

?- sinonimo(X).
X=amazono
X=jordano
X=leno
X=saro

Se vi volas mem elprovi vi povas fari tion ĉe la retpaĝo SWI-ŝelo. Kreu tie novan programon, metu maldekstre ĉiujn faktojn kaj la predikatdifinon de sinonimo. Kaj dekstre malsupre metu la demandon (sen ?-).

En SQL denove tio estas pli vortriĉa esprimo:

CREATE VIEW sinonimo(nomo) AS
SELECT r.nomo from rivero r 
WHERE EXISTS
  (SELECT i.nomo FROM ino i WHERE i.nomo = r.nomo)
OR EXISTS
  (SELECT m.nomo FROM malino m WHERE m.nomo = r.nomo);

-- aŭ
CREATE VIEW sinonimo(nomo) AS
SELECT r.nomo FROM rivero r
JOIN ino i ON i.nomo = r.nomo
UNION
SELECT r.nomo FROM rivero r
JOIN malino m ON m.nomo = r.nomo;

SELECT nomo FROM sinonimo;

Vi povas elprovi SQL ĉe SQLFiddle.

Do resume, Prologo funkcias kiel datumbazo, kie la predikatoj estas la nomoj de tabeloj aŭ rigardoj, sed kompare kun SQL la sintakso estas multe pli ŝpara kaj intuicia.

Lingvo por malskribemuloj

Unuavide la predikatoj de Prologo aspektas kiel funkcioj, sed ili ne estas. Ni rigardu kiel ekzemplo la sekvan predikaton:

unua(Elemento,Listo1,Listo2) :- Listo1 = [Elemento|Listo2].

La diferenco estas, ke en funkcio la argumentojn oni devus doni, kaj la funkcio fine redonas unu valoron. Plie oni povas kompari tion kun proceduroj, kie parto de la argumentoj servas por redoni valorojn. Sed alie, en predikato oni kutime ne postulas, ke iuj argumentoj servas por enigi valorojn kaj aliaj por eligi, sed ili difinas rilaton inter la argumentoj, kiun oni povas legi en pluraj manieroj. (Noto: oni parte forlasas tian flekseblecon, se temas pri aritmetikaj kalkuladoj).

Do jen ni ilustras la eblecojn. (Se ni ne estas interesitaj pri unu el la argumentoj ni uzas anstataŭ variablo nur substrekon: '_').

% Ĉu *a* estas la unua elemento de la donita listo? 
?- unua(a,[a,b,c,d],_).
true.

% Aldonu la *a* en la komenco de la listo. 
?- unua(a,L,[b,c,d]).
L = [a, b, c, d].

% Elprenu la unuan elementon de la listo kaj redonu ĝin.
?- unua(E,[a,b,c,d],_).
E = a.

% Se *a* troviĝas en la komenco de listo, forigu ĝin.
?- unua(a,[a,b,c,d],L).
L = [b, c, d].

% Ĉu la dua listo egalas al la unua, krom la unua elemento?
?- unua(_,[a,b,c,d],[b,d,f]).
false.

En ordona programlingvo vi bezonas plurajn funkciojn por tio:

function chu_unua(elemento,listo) {
  return (elemento == listo[0])
}

listo = new Array('b','c','d');
console.log(chu_unua('a',listo));
// false

longeco = listo.unshift('a');
console.log(listo.join());
// "a,b,c,d"

elemento = listo.shift();
console.log(elemento);
// "a"

//...

Do en Prologo oni difinas predikaton unufoje kaj uzas multmaniere, iom kompareble al Esperanto, kie oni lernas vortradikon unufoje kaj per apliko de afiksoj uzas plurmaniere. Sekve kodo de Prologo estas pli kompakta kaj en la kapon oni devas stoki malpli da lingva balasto kaj anstataŭe povas koncentriĝi pri la logiko, pri tio, kion la programo faru. Kontraŭe en ordonaj programlingvoj por ĉiu maniero de datum-prilaboro oni bezonas apartan funkcion aŭ antaŭdifinitan aŭ memdifinitan. Tio siginfas pli da lernado, pli das konsultado de manlibroj, malpli da restanta tempo por la solvenda problemo.

La algoritmo estas la lingvo