literalForResolution/3 — literal pentru rezoluție
Pentru acest exercițiu, veți calcula rezolventul a două clauze.
O clauză se numește trivială atunci când conține atât o variabilă propozițională p, cât și negarea ei non(p). De exemplu, o clauză [a, non(b), non(c), non(a)] este trivială, întrucât conține atât a, cât și non(a).
În acest exercițiu, considerăm că toate clauzele sunt NETRIVIALE (i.e. nicio clauză nu este trivială).
Scrieți un predicat literalForResolution/3 care primește două clauze C1 și C2, și returnează primul literal care poate fi utilizat în rezoluție. În cazul în care nu există un astfel de literal, se va întoarce false.
Un literal se definește ca literal ::= p | non(p), unde p este un atom propozițional (din Var).
Un literal poate fi utilizat în rezoluție dacă apare într-o clauză, iar în cealaltă apare negat, sau vice-versa. De exemplu, dacă p apare în C1, și non(p) apare în C2, atunci p este un literal care poate fi utilizat în rezoluție. La fel, dacă non(p) apare în C1, și p apare în C2, atunci p este un literal care poate fi utilizat în rezoluție.
?- literalForResolution([a, non(b), non(c)], [b, non(a)], L).
L = a
?- literalForResolution([d, non(b), non(c)], [b, non(a), c], L).
L = b
?- literalForResolution([d, non(b), non(c)], [x, non(y), z], L).
false
Hint: două clauze recursive pe capul lui
C1. DacăHe atom șinon(H)∈C2, returneazăH. DacăH = non(P)șiP ∈ C2, returneazăP. Altfel, recursia pe coadă.
literalForResolution([H | _], C2, H) :-
atom(H),
member(non(H), C2), !.
literalForResolution([non(H) | _], C2, H) :-
member(H, C2), !.
literalForResolution([_ | T], C2, L) :-
literalForResolution(T, C2, L).
Tastează o interogare (ex. father_of(sandra, X).) și apasă Enter — sau apasă pe un caz de test de mai jos.
literalForResolution([a, non(b), non(c)], [b, non(a)], L).
așteptat: L = a
literalForResolution([d, non(b), non(c)], [b, non(a), c], L).
așteptat: L = b
literalForResolution([d, non(b), non(c)], [x, non(y), z], L).
așteptat: false