Definite clause grammars (DCG): alternativni zapis predikatov. Primeren za zapis formalnih jezikov (množic besed). Pri tem imamo:
Primer: jezik besed s sodim številom a-jev (a^(2n), n ≥ 0).
s --> []. % s --> [] | [a,a], s. s --> [a,a], s.
Na levi strani puščice je (en) neterminal, na desni zaporedje terminalov (v oglatih oklepajih) in neterminalov, v katero se prepiše.
Primeri poizvedb (generiranje oz. prepoznavanje besed):
?- s(Word, []). [a,a] ; [a,a,a,a] ; … ?- s([a,a,a], []). false.
Narišemo in razložimo drevo izpeljave za [a,a,a,a]
.
Gramatiki iz uvoda dodamo še pravilo
s --> s, [a,a].
in narišemo še drugo drevo izpeljave za [a,a,a,a]
. Poveš, zakaj je dvoumnost
slaba (recimo primer iz C-ja
if (…) if (…) A else B,
kjer ne vemo, kateremu if
pripada else B
).
Razložiš tudi, da gre spet za DFS in da prolog poskuša pravila po vrsti. Prav tako dodaja oz. expanda terminale / neterminale na desni strani puščice.
Jezik, ki opisuje zaporedja golov na nogometni tekmi.
s --> goal. s --> goal, s. goal --> [a]. goal --> [b]. % Še dve možnosti za zapis pravil za goal: % goal --> [a] | [b]. % goal --> [X], { memb(X, [a,b]) }.
Dodamo pomen:
goal(1) --> [a]. goal(-1) --> [b]. s(Diff) --> goal(Diff). s(Diff) --> goal(Diff1), s(Diff2), { Diff is Diff1 + Diff2 }.
Primer poizvedbe:
?- conc(Goals, _, _), s(Result, Goals, []).
Napiši gramatike v prologu za naslednje jezike:
+++–+++
?- number(N, [1,2,3,4], [])
?- paren(D, ['(','(',')',')','(',')'], []).
+
in *
; podizraze lahko združujemo z oklepajiexpr(N, ['(',2,'+',1,')','*','(',3,'+',4,')'], []).