Pentru a descrie acest predicat în secțiunea de țintă a programului, puteți folosi construcția:
arată: - câini (X), print_list (X).
Dacă este necesar să se stabilească prezența unui element în listă, se aplică regula:
find_it (X, [_ | Y]): - find_it (X, [Y]).
În prima descriere, obiectul de căutare și capul listei curente sunt comparate. Dacă această comparație este nereușită, apare răsturnarea și încercarea de repetare cu a doua variantă.
PREDICĂ câini (câine_list). find_it (simbol, dog_list).
find_it ("lapdog", ["husky", "mastiff"]), scrie ("da"). CLAUZE
Prima regulă descrie situația în care elementul dorit X coincide cu capul listei.
A doua regulă este utilizată atunci când prima regulă eșuează și descrie un apel nou la prima regulă, dar deja cu o listă trunchiată, în care nu există primul element etc. Dacă nu există elemente în listă (listă goală), regula a doua nu reușește.
Programul nu se imprimă Da, deoarece câinele de tip lap-top nu se află pe lista câinilor.
Următorul exemplu calculează suma tuturor elementelor din lista de numere.
summa_sp ([H | T], S): summa_sp (T, S1), S = H + S1.
Luați în considerare funcționarea fuzionării a două liste.
Fie L1 și L2 două variabile care reprezintă listele de intrare. L3 este lista de rezultate obținută prin fuziunea L1 și L2.
adăugați ([N | L1], L2, [N | L3]): - adăugați (L1, L2, L3).
Prima versiune a acestei reguli este executată atunci când prima listă este goală, cea de-a doua funcționează în celelalte cazuri.
Luați în considerare utilizarea acestui predicat la următorul apel:
Aici prima variantă a regulii nu funcționează mai întâi, deoarece prima listă nu este goală.
A doua regulă începe să funcționeze, deoarece a treia listă este goală, operația de împărțire a capului și a coada nu este aplicabilă. În ceea ce privește prima listă, în procesul de apeluri recursive se supune divizării în cap și coadă și în cele din urmă devine goală (elementele sale intră în stivă)
După aceasta, se declanșează prima variantă a regulii, iar a treia listă este inițializată de a doua:
În cele din urmă, pentru a finaliza apelurile recursive, PROLOG extrage din stivă (în ordine inversă) elementele primei liste și le returnează, în conformitate cu descrierea celui de al doilea exemplu de realizare reguli listele 1 și 3:
Luați în considerare modul de utilizare liste și mecanismul recursivitatii în soluția de faimoasa problema a țăranului, lupul, capra și varza.
(de la est, est, est, est), state (vest, vest, vest, vest), scrie ("
calea (S, G, [S], L), nl, scrie ("O soluție este:"), nl,
calea (S, G, L, L1): - mutare (S, S1), nu (nesigur (S1)), nu (membru (S1, L)), calea (S1, G, [S1 | L], L1 ).
calea (G, G, T, T):. / * Rezultate stare finală, lista L este copiat în L1 * / mutare (stare (X, X, G, C), stare (Y, Y, G, C)): - opus (X, Y). / * om și lup * / mișcare (stare (X, W, X, C), stare (Y, W, Y, C)): - opusă (X, Y). / * Omul și capra * / mutare (stare (X, W, G, X), stare (Y, W, G, Y)): - opus (X, Y). / * Omul și varză * / mutare (stare (X, W, G, C), stare (Y, W, G, C)): - opus (X, Y). / * un singur om * /
(vest, est):. / * descrierea părților opuse * /
nesigur (stare (F, X, X, _)): - opusă (F, X)
/ * lupul mănâncă capra * /
nesigur (starea (F, _, X, X)): - opusă (F, X).
/ * capra mănâncă varză * /
membru (X, [_ | L]): - membru (X, L) / * verificare pentru stările care au fost deja * /
readchar (_), write_move (H1, H2), calea de scriere ([H2 | T]). cale_de_cartare ([]).
write_move (starea (X, W, G, C), starea (Y, W, G, C)):. scrie ("Un om traversează râul cu", X, "on", Y), nl. write_move (starea (X, X, G, C), starea (Y, Y, G, C)):. scrie ("Un om poartă un lup cu", X, "shore on", Y), nl. write_move (starea (X, W, X, C), starea (Y, W, Y, C)):. scrie ("Un om poartă o capră cu", X, "țărm pe", Y), nl. write_move (starea (X, W, G, X), starea (Y, W, G, Y)):. scrie ("Un om conduce o varză cu", X, "shore on", Y), nl.
8. DECIZIE DE SARCINI LOGICE
Abilitatea de a descrie sarcini logice este partea cea mai puternică a PROLOG.
Multe probleme logice sunt legate de luarea în considerare a mai multor seturi finite cu același număr de elemente, între care se stabilește o corespondență unu-la-unu. În Prolog, aceste seturi pot fi descrise ca baze de date, iar dependențele dintre obiecte pot fi stabilite utilizând reguli.
Luați în considerare o problemă logică simplă. exemplu:
"În cursele de ciclism, primele trei locuri au fost luate de Alyosha, Petya și Kolya. Ce loc a ocupat fiecare dintre ei, dacă Petya nu a ocupat al doilea și al treilea loc, iar Kolya - nu al treilea? "
Soluția problemei este de a stabili relația dintre sportivi și locuri, care pot fi descrise în tabelul. 2 (liniuțele indică informații cunoscute):
La descrierea acestei sarcini pe PROLOGUE, se obține următorul program.
PREDICATES nume (simbol) mesto (simbol) prizer (simbol, simbol)
nume (alex). numele (pier). nume (nike). mesto (odin). mesto (doi). mesto (tri).
(X, Y): - numele (X), mesto (Y), X = pier, nu (Y = doi), nu (Y = tri); numele (X), orașul (Y), X = nike, nu (Y = tri); numele (X), mesto (Y), nu (X = pier), nu (X = nike). (X1, Y1, X2, Y2, X3, Y3): - numele (X1), numele (X2), numele (X3)
(X1, Y3), prelata (X2, Y2), prelata (X3, Y3), Y1<>Y2, Y2<>Y3, Y1<>Y3, X1<>X2, X2<>X3, X1<>X3.
Desigur, în acest exemplu, este mai rapid să folosiți masa pentru a obține o soluție. Cu toate acestea, în cazuri mai complexe, tabelele devin multidimensionale. Să luăm în considerare încă un exemplu - o problemă logică (Știința și viața, nr. 3 1968):
"Cinci studenți merg cu bicicletele.
Numele lor sunt Serghei, Boris, Leonid, Grigory și Victor.
Bicicletele sunt realizate în cinci orașe: Riga, Penza, Lviv, Kharkov și Moscova.
Fiecare dintre studenți sa născut într-unul din aceste orașe, dar niciunul dintre elevi nu călărește o bicicletă făcută în patria sa.
Serghei conduce o bicicletă făcută în Riga. Boris vine din Riga, are o bicicletă din Penza.
Victor are o bicicletă de la Moscova.
Grigory are o bicicletă din Harkov. Victor este din Lviv.
Un nativ din Penza călărește o bicicletă făcută în patria lui Leonid. Cine sunt studenți de la Moscova? "Pentru a rezolva această problemă, putem propune următoarele programe pro-
Luați în considerare descrierea faptelor și regulilor din acest program.
Primele două reguli descriu posibile restricții asupra valorilor predicatelor student și gorod. Acest lucru este necesar pentru a pune în aplicare substituții admise în căutarea unei soluții.
Faptele indicate de numărul trei descriu datele cunoscute despre locul în care sunt produse bicicletele unor studenți.
Numeralul 4 denotă o regulă care descrie apartenența unei biciclete la un student. Regula este alcătuită din două părți alternative, separate de un ";". Prima parte a regulii spune că un student al lui X deține o bicicletă Y dacă știm acest fapt. A doua parte a regulii vă permite să faceți orice schimbări, dacă nu contravine faptelor cunoscute. Predicatul de oprire "!" Aici oprește căutarea de noi variante dacă toate condițiile anterioare au fost îndeplinite. Această operație se numește tăiere.
Figura 5 indică fapte cunoscute despre locul de naștere al studenților.
Figura 6 descrie ideea elevilor care pot fi de la Penza. Nu poate fi Boris sau Victor, pentru că știm că s-au născut în alte orașe și trebuie să existe un student a cărui bicicletă a fost făcută în patria lui Leonid.
O regulă de patru părți 7 descrie idei comune despre patria fiecărui student. În primul rând, acest fapt poate fi cunoscut și apoi nu este nevoie să se ia în considerare alte opțiuni. A doua parte a regulii descrie cine poate fi un nativ din Penza. A treia parte a regulii descrie locul de naștere al lui Leonid. Și, în sfârșit, a patra parte a regulii descrie din ce oraș, cu excepția Penza, pot exista studenți, cu excepția lui Leonid. Descărcând acest program, puteți obține soluția dorită.
Una dintre sarcinile practice care apar frecvent este sarcina programării. Luați în considerare un exemplu de problemă similară (preluată din revista Science and Life):
"Cinci studenți trebuie să participe la cursuri toată săptămâna, dar în conformitate cu regulile pe care le-au stabilit, și anume:
1. Dacă au venit Andrew și Dmitri, atunci Boris nu ar trebui să fie, dar dacă Dmitri nu a venit, atunci ar trebui să fie Boris și Victor nu ar trebui să fie.
2. Dacă Victor a venit, atunci Andrew nu ar trebui să fie și invers.
3. Dacă a venit Dmitry, atunci Gregory nu ar trebui să fie.
4. Dacă nu există Boris, atunci ar trebui să fie Dmitri, dar dacă nu este Victor și dacă Victor este acolo, nu ar trebui să fie Dmitri, dar trebuie să fie Grigore.
5. În fiecare zi studenții trebuie să vină în diferite combinații. Care sunt aceste combinații?
Pentru a rezolva această problemă, se poate propune un program:
st_A (s) st_D (s) st_B (s) st_V (s) st_G (s) ogr1 (s, s, s, s, s) ogr2 (s, s, s, s, s) spisok (s, s, s, s, s)
NORM1 (s, s, s, s, s) NORM2 (s, s, s, s, s) norm3 (s, s, s, s, s) norm4 (s, s, s, s, s)
Clauzele st_A (A): - A = andre; A = net.
st_D (D): - D = dmitri; D = net. st_B (B): - B = bor; B = net. st_V (V): - V = victor; V = net. st_G (G): - G = grig; G = net.
ogr1 (andre, _, _, net, _). ogr1 (net, _, _, victor, _). ogr2 (_, dmitri, _, _, net). ogr2 (_, net, _, _, _).
st_A (A), st_D (D), st_B (B), st_V (V), st_G (G), nu (NORM1 (A, D, B, V, G)), nu (NORM2 (A, D, B , V, G)), nu (norm3 (A, D, B, V, G)), nu (norm4 (A, D, B, V, G)), ogr1 (A, D, B, V, G ), ogr2 (A, D, B, V, G).
Poate, o soluție software mai elegantă poate fi formulată decât cea de mai sus. Atunci când căutarea lui pentru cititorul poate fi sigur că în astfel de cazuri este foarte important este alegerea predicate și reguli, care pot fi determinate non-unic. Dacă regulile sunt nereușite, puteți lua decizii deliberate false sau puteți epuiza resursele calculatorului când cuibuiți o regulă în alta.
9. BAZA DE BAZĂ ȘI CUNOȘTINȚE PE BAZA UNUI PROLOG
Faptele descrise în clauzele secțiunii pot fi considerate ca o bază de date statică (DB). Aceste fapte fac parte din codul programului și nu pot fi schimbate rapid. Pentru a crea o bază de date dinamică în PROLOGe, există o bază de date specială.
Predicțiile din această secțiune pot avea aceeași formă de reprezentare ca și în partea statică a programului PROLOG, dar trebuie să aibă un nume diferit.
Să luăm în considerare un exemplu simplu.
nume = simbol rost, ves = întreg
dplayer (nume, rost, ves) PREDICATES
jucător (nume, rost, ves) CLAUZE
jucator ("Mikhaylov", 180, 87) jucator ("Petrov", 187, 93) jucator ("Kharlamov", 177, 80)
Să presupunem că după pornirea programului, mutați datele din baza de date statică în cea dinamică. Pentru a face acest lucru, puteți descrie următoarea regulă:
assert_database: -playerul (N, R, V), assertz (dplayer (N, R, V)), eșuează.
Această regulă utilizează predicatul built-in assertz, care plasează instrucțiunea în baza de date după toate instrucțiunile deja existente. Există, de asemenea, predicate încorporate pentru ștergerea declarațiilor (retractare), citirea de pe disc (consultați), scrierea bazelor de date pe disc (salvarea) și colectarea datelor din baza de date din listă (findall).
Principalul avantaj al DB pe Prolog, ca orice altă bază de date, este capacitatea de a accesa rapid selectiv informațiile. De exemplu, în exemplul de mai sus, aceasta ar putea fi o interogare:
GOAL: player (N, R, V), R> 180
Dacă comparăm conceptele de bază ale PROLOG și bazele de date relaționale, vom obține următorul tabel.