Üks sageli kasutatav programmeerimiskeelte liigitus põhineb andmetüüpide kasutamise rangusel. Nn. "rangete tüüpidega" keeltes (strongly typed languages) nõutakse, et muutujate andmetüüp oleks muutuja deklaratsioonis määratud ja muutujatele väärtuste omistamisel kontrollib translaator, et omistatavate väärtuste tüüp vastaks muutuja deklaratsioonis määratud tüübile. See väldib palju programmeerimisvigu, kuid teeb teisalt programmeerijale lisatööd - näiteks reaalarvu (float, real) tüüpi muutujale väärtuse 3 omistamisel võib tulla veateade - 3 on täisarv (integer) ja see tuleb enne omistamist muuta reaalarvuks. Range tüübikontroll on tavaline kompileeritavates keeltes; interpreteeritavates keeltes on enamasti olulisem programeerimismugavus ja siin muutujate tüüp ei ole fikseeritud - samale muutujale võib omistada nii täisarvulise väärtuse kui ka näiteks tekstikonstandi (stringi), interpretaator püüab omistatud väärtust ise sobitada, s.t. teeb tüübiteisendusi, kui need vajalikud on.
Ka Prologis (enamuses realisatsioonidest) ei ole ranget tüübikontrolli ja muutujate tüüpi ei
deklareerita. See on kooskõlas Prologi üldise filosoofiaga - Prolog on vahend maailma kirjeldamiseks ja tavaliselt me
ei piiritle rangelt reaalsete väärtuste tüüpe (kas kuupäev on arv, tekst või mingi kolmandat tüüpi suurus?);
väärtuste tüübid muutuvad olulisteks arvutis, kus need väärtused tuleb sobitada arvuti fikseeritud mälustruktuuriga.
Kuid Prologist ja tema töö peensustest paremaks arusaamiseks on siiski vajalik teada, kuidas Prolog väärtusi liigitab,
s.t. millised on Prologi (sisemised) andmetüübid - kuigi Prolog ei nõua muutujatele tüüpide määramist, on sageli oluline,
milliseid suurusi ja kuidas Prolog kasutab.
Prologi ja nn. käsukeelte (imperatiivsete keelte - C, C++, Pascal jne) erinevuse mõistmiseks on tarvis meeles pidada, et Prolog käsitleb kõike sümbolite jadadena - termidena; term on Prologi kõige üldisem andmetüüp.
Termi süntaks on sama, mida järgitakse programmis faktide kirjeldamisel, reegli parem ja vasaku poole osad (komadega eraldatud) on termid jne.
Kogu Prologi töö põhineb termide samastamisel (unification), s.t. termides esinevate muutujate asendamisel teiste termide või konstantidega nii et termid muutuvad võrdseteks (samastuvad). Samastamise õnnestumiseks on sageli tarvis enne analüüsida termide struktuuri - kas term on konstant (mis tüüpi - arv, tekst?) või muutuja, või on tegemist struktuurse termiga, millel on funktor (milline?) ja argumendid (kui palju?) jne. Termide (s.t. kogu Prologi programmi, andmete jne) kirjutamisel võib Swi-Prolog-is kasutada ka nn. täpitähti (ä,ö,õ jne), kuid nende kasutamisest faili- ja moodulinimedes peaks hoiduma.
Termide analüüsiks ja teisendamiseks on Prologis palju süsteemipredikaate.
Termid liigitatakse nende süntaksi (kirjaviisi) põhjal: atom, number, var (muutuja), string, list (nimistu), compound (struktuur). Kõigi nende jaoks on olemas spetsiaalpredikaadid, mis kontrollivad kas argument on seda tüüpi.
Kõige sagedamini esineb Prologi programmides aatom - väiketähega algav tekstikonstant (tühikuteta; aatomid on näiteks kõik predikaatide nimed); suvalise märgijada aatomiks tegemiseks (esineb tühik, algab arvuga jne) peab selle võtma ülakomade vahele; atomi tüüpi kontrollib predikaat atom(X), näiteks:
Aatomid on (väikesed) sümbolite jadad (sarnanevad veidi stringidega, vt. allpool)
ja nende käsitlemiseks
on palju sisseehitatud predikaate:
- atom_concat(Atom1, Atom2, Atom1Atom2) - ühendab
(konkateneerib) aatomid Atom1, Atom2 aatomiks
Atom1Atom2; kui kolmandal argumendil Atom1Atom2 väärtus
(s.t. see on aatom) ja
Atom1, Atom2 on
muutujad , siis annab tagurdamise käigus
muutujatele Atom1, Atom2 kõikvõimalikud
väärtused, mis ühendamisel annavad antud aatomi Atom1Atom2;
- concat_atom(List,Atom) - ühendab aatomitest
koosneva nimistu
List elemendid üheks aatomiks Atom;
atom_length(Atom, Pikkus) - leiab aatomi
pikkuse;
- sub_atom(Atom, Index, Pikkus, SubAtom) -
leiab aatomi
Atom alamlõigu (alamaatomi), mis algab kohalt
Index ja mille pikkus on Pikkus;
näiteks päringu
sub_atom(programmeerimine,4,5,S) vastuseks
saadakse S = gramm jne.
Integer on täisarv vahemikus -2147483648..2147483647 (s.t. 32-bitine); tüüpi kontrollib predikaat integer(X) :
Predikaat atomic(X) on tõene, kui argument X on atom või täisarv:
Reaalarvus reaalosa eraldaja on punkt (koma on nimistu liikmete eraldaja); reaalarv ei või alata ega lõppeda punktiga; reaalarvus võib kasutada ka järku ja selle tüüpi kontrollib predikaat float(X):
Predikaat number(X) on tõene, kui X väärtuseks on täis-või reaalarv:
Arvutamiseks on olemas kõik tavalised aritmeetikafunktsioonid: +,-,*,/ , ** (astendamine), max, min, mod, exp, abs, ln, log10, sqrt (ruutjuur) jne, trigonomeetrilised funktsioonid: sin, cos, tan, asin (arcsin), acos, atan jne.
Matemaatiliste valemite kirjutamisel peab meeles pidama, et Prolog käsitleb valemit nagu termi, s.t. näiteks = kasutamisel püüab samastada võrduse paremal ja vasakul pool olevaid terme:
Kahe muutujateta arimeetilise avaldise võrdlemiset kiirendab predikaat =:= :
?- 2+7 =:= 10-1.
Yes
X+3 =:= 10.
ERROR: Arguments are not sufficiently instantiated
String on sümbolite jada, mis on võetud kas dollarimärkide (erineb LPA-st!) või tagurpidi appostroofide ` ` vahele (tavalised jutumärgid ei ole stringieraldajad!); stringe kontrollib predikaat string(X):
Stringide töötlemiseks on palju sisseehitatud predikaate: string_atom(String, Atom) (teisendab stringi aatomiks ja vastupidi), strcat(StringA, StringB, StringAB) (ühendab stringid StringA, StringB stringiks StringAB), string_length(String, Pikkus) (leiab stringi String pikkuse), sub_string(String, Index, Length, SubString) (leiab stringi String alamstringi SubString, mis algab kohalt Index ja on pikkusega Length, analoogiline vastava aatomite käsitlemise predikaadiga), string_integer(String, Integer) (muudab täisarvu selle numbrite stringiks ja vastupidi, näit tõene on string_integer(`123`, 123) jne; kõigi süsteemipredikaatide kohta lisainfot vt. Help.
Kuigi stringid ja aatomid näivad üsna sarnaste tüüpidena, on nende käsitlemises oluline erinevus: aatomid kannab interpretaator nn. nimede tabelisse ja programmis kasutatakse vaid viita sellesse tabelisse (s.t. aatomit esindab programmis mingi täisarv), stringe aga käsitletakse "nagu nad on", s.t. märkide jadadena. See teeb aatomite käsitlemise oluliselt kiiremaks kui stringide käsitlemise.
Nimistute (list) süntaksit kontrollib süsteemipredikaat is_list(X), näiteks
Nimistute töötlemisel on peale [Pea|Keha] notatsiooni kõige tähtsamad
memberchk(Term, List)
- kontrollib, kas Term esineb nimistus List (seda
ei saa kasutada tagurpidi, s.t. nimistu List kõigi elementide genereerimiseks
muutujas Term; ka selles suunas töötav predikaat on kirjeldatud eelmises peatükis), sort(Nimistu,
Järjestatud) - sorteerib (järjestab) nimistu elemendid ja eemaldab korduvad
elemendid, msort(Nimistu,
Järjestatud) - sama kui eelmine, kuid korduvaid ei eemalda, length(Nimistu,
Pikkus) jne. Väga kasulik on
Swi-Prologi predsort(Pred,Nimistu, Järjestatud),
kus Pred peab olema predikaadi nimi, mille
abil on defineeritud suhted
<, >, = ja see peab olema kirjeldatud formaadis
Pred(Suhe, Term1, Term2). Kui programmis on näiteks kirjeldatud predikaat order, võib seda kasutada auastmete järgi
järjestamisel:
order(<, E1, E2):-
order(>, E2, E1),!.
?- predsort(order,[jyri,rektor,dekaan],J).
J = [jyri, dekaan, rektor]
Termide "täht-tähelt" (muutujaid samastamata) võrdlemiseks on operaator ==:
Kui term on kujul funktor(Arg1, ...,Argn), on see Swi-Prologi terminoloogias compound (kuid näiteks Amzi-Prologi terminoloogias structure). Struktuuri süntaks on sama, mida järgitakse programmis faktide kirjeldamisel, reegli parem ja vasaku poole osad (komadega eraldatud) on struktuurid jne. Struktuuri süntaksit kontrollib süsteemipredikaat compound(X) :
Struktuursete termide (funktor + argumendid) analüüsiks on samuti
mitmesuguseid süsteemipredikaate:
- functor(Struktuur,Funktor,Argument) leiab struktuuri
Struktuur (pea)funktori Funktor ja struktuuri
argumentide arvu:
? - functor(poeg(juhan, jaan), F, A).
F = poeg
A = 2 ;
?- arg(2,poeg(juhan,jaan),V).
V = jaan ;
Kõige "võimsam" süsteemipredikaat on Term =.. Nimistu, mis muudab termi Term nimistuks [peafunktor,argument1, argument2,...] ja vastupidi:
Operaatorit =.. kasutatakse sageli uute predikaatide loomiseks
programmi töö ajal. Programm võib saada käsu (kas kasutajalt või mingi arvutuse tulemusena)
sõnade jadana (näit.: "mine,tuppa"), millest siis moodustatakse täidetav predikaat:
Predikaat var(X) kontrollib, kas muutujal X on juba väärtus (selline kontroll on sageli vajalik enne eituse not kasutamist):