Iată recomandările privind stilul de programare din Visual Prolog, dezvoltat în cadrul companiei Prolog Development Center (PDC).
Aceste recomandări se aplică codurilor nou create. În acest caz, PDC nu intenționează să aducă codurile deja existente la respectarea acestor recomandări. Prin urmare, codurile distribuite cu sistemul de programare Visual Prolog pot să nu respecte aceste standarde.
Recomandări generale
- Clauzele predicatelor ar trebui, de regulă, să fie mai mici de 20 de linii. Prin urmare, este necesar să se prevadă predicate suplimentare pentru organizarea subrutinelor. Situațiile în care predicatul poate ocupa mai mult de 20 de linii, se referă la cazuri cum ar fi, de exemplu, 50 de proprietăți trebuie să fie setate pentru același obiect prin referire la acesta.
- Utilizați nume complet calificate (adică, someClass :: method) - acest lucru oferă întotdeauna programului o imagine mai clară.
- Metodele de clasă trebuie să aibă nume semnificative care sunt citite în legătură cu numele clasei. Evitați repetarea numelui clasei în numele metodei, adică numele trebuie să fie:
- Un predicat trebuie să îndeplinească exact o sarcină. Prin urmare, dacă aveți un predicat care face ceva cu fiecare element al listei, ia în considerare posibilitatea de a se împărți în două predicate: una face o trecere prin listă, iar cea de-a doua efectuează o operație asupra elementului. Avantajul suplimentar al acestei abordări este acela că predicatul devine mai simplu (și, prin urmare, mai ușor de modificat și de înțeles).
- În general, dacă trebuie să existe o variabilă pe o parte a semnului egal ("="), atunci puneți-o pe dreapta. dacă este conectat.
Valori booleene
Valorile booleene ar trebui folosite dacă ceva este adevărat sau fals. Nu utilizați astfel de valori pentru a stabili diferențele de cazuri, cum ar fi stânga și dreapta, sau orizontal și vertical. În astfel de cazuri, este mai bine să folosiți domenii specializate.
Clipping (Cut)
Clipping (ie) este un predicat care taie nondeterminismul, adică întrerupe posibilitatea dezvoltării unor soluții ulterioare (conform propriului nume).
Clipped nondeterminismul poate fi împărțit în două grupuri (deși în unele cazuri, tăierea poate să aparțină ambelor):
- Cut-urile care taie abilitatea de a executa alte clauze (în ordine) ale predicatului curent.
- Clipping, care elimină posibilitatea de a genera noi soluții pentru apelurile predicate nondeterministe.
Nu există alte motive semnificative pentru utilizarea tăierii, cu excepția celor menționate mai sus. Dacă aceste obiective sunt clare, atunci este foarte ușor să puneți tăierea în locul potrivit:
- sau tăierea este plasată într-un loc în care nu mai este necesară o căutare a clauzelor consecutive și / sau
- se pune după apelarea unui predicat nedeterminat (adică calificativ nondeterm sau multi), pentru care numai o singură soluție este importantă.
Primul motiv poate fi ilustrat prin exemplul următor
În acest exemplu, am tăiat după verificarea X> 13. Acesta este un caz tipic de utilizare a primului motiv: „clauzele noastre reacționează la valoarea variabilei de intrare și dintr-o dată (ceea ce înseamnă că, imediat, imediat după verificarea X> 13) găsim soluția potrivită.“
De obicei, astfel de limite sunt plasate imediat după capul clauzei sau după verificare, cel mai apropiat de capul clauzei.
Al doilea motiv poate fi ilustrat prin următorul exemplu:
În acest exemplu, tăierea este plasată imediat după predicatul nondeterminist, de la care se așteaptă o singură soluție.
Deasupra am scos imediat cuvântul imediat de două ori, pentru că cuvântul cheie din locul tăierii este cuvântul imediat. acestea ar trebui plasate cât mai devreme posibil în clauză.
Ar trebui să fii suspicios de clauze care conțin mai multe tăieturi. Prezența a mai mult de o tăiere într-o singură clauză indică de multe ori prezența unei erori în program.
Roșu și verde tăiat
În general, nu încurajăm tăieri verzi, ne comportăm destul de mult cu tăierea roșie.
Comunitatea Prolog tradițională a dat o definiție a reducerilor roșii și verzi. Pe scurt, este vorba despre: tăierea verde este o tăiere care nu schimbă semantica predicatului în care este utilizată, iar tăierea roșie schimbă semantica.
Este clar că toate întreruperile care întrerup toate soluțiile ulterioare ale predicatelor nondeterministe sunt roșii prin natura lor. Prin urmare, diferențele dintre tăierea roșu și verde sunt semnificative numai pentru acele tăieturi care împiedică retrogradarea la clauzele următoare.
În predicatul de mai sus, tăierea este verde. deoarece dacă îl ștergem, predicatul se va comporta în același mod. Atunci când tăierea este în prima clauză, verificați X <= 0 во втором клаузе в действительности не нужна (второй клауз соответствует всем остальным случаям, кроме X<0 - прим. Переводчика):
Dar fără această verificare, cu toate acestea, decupajul devine roșie, ca și acum predicatul se va comporta diferit dacă eliminăm cut-off (predicat devine nedeterminat, deoarece chiar dacă X> 0, există o altă soluție - bine, dacă este inofensiv - aprox. interpret).
Decuparea verde poate părea inutilă, dar în realitate acestea sunt folosite pentru a exclude retrageri inutile (în principal din motive de viteză). În sistemul Visual Prolog, ele pot fi totuși necesare pentru a arăta compilatorului că unele predicate sunt predicate de un anumit tip, de exemplu proceduri.
Control folosind combinația de date de intrare
Controlul folosind o combinație de date de intrare (dispecerizare) trebuie utilizat cu prudență. Problema cu utilizarea fluxurilor de intrare este că această structură simplă poate răspunde la multe situații diferite. Prin urmare, codurile care sunt logic puternic interdependente ar trebui împărțite în fragmente relativ independente și aranjate secvențial.
În acest caz, codurile legate în mod logic sunt plasate în predicatele de procesare situate în același modul de clasă, astfel încât dispecerul să le solicite numai. În acest caz, dispecerul însuși și codurile de procesare rămân în imediata vecinătate.
Pentru acest gen de management se recomandă respectarea regulilor:
- Dacă predicatul se ocupă de mai multe variante de seturi de date de intrare, susțineți fiecare variantă cu una simplă.
- Nu creați niciodată mai multe clauze pentru aceeași variantă de intrare, dacă predicatul se ocupă și de "alte" cazuri.
Prima regulă este o regulă a acțiunii directe. A doua regulă poate fi ilustrată prin următorul exemplu:
Secțiunea de mai sus clauze scrise în stil săraci, deoarece are două clauze pentru același set de intrare (17, W, E, R, 13, Y). Nu ar fi groaznic dacă predicatul a lucrat numai cu acest set. Dar aici există clauze pentru alte seturi. Noi credem că predicatul unei astfel de livrare trebuie să fie rescrise, astfel încât fiecare clauză a predicat qwerty ar reacționa doar la un set special de intrare, lăsând restul prelucrării predicate de nivel inferior:
În acest cod, predicatul qwerty conține acum ceasuri, fiecare dintre acestea răspunzând unei anumite combinații de date de intrare. Nu este esențial ca pentru anumite combinații de date de intrare să se utilizeze un apel predicat unic. Principalul lucru este că nu treceți prin clauze pe același set de date de intrare.
Această regulă este utilă în special în construcția de manipulare eveniment - nu ar trebui să fie mai mult decât clauza pentru evenimentul „închidere“ (sau similar), în același handler. Handler eveniment este adesea situat pe mai multe pagini de ecran, astfel încât, dacă nu urmați regula tratamentului de un singur tip de intrare stabilește o clauză, atunci va trebui pentru a vedea toate handler clauze pentru a afla cum iterată printr-un set specific de intrare.
Excepții și manipularea erorilor
- Când apare o eroare sau o excepție, ridicați o excepție utilizând excepția :: raise.
- Blocați capcana excepției dacă doriți să o procesați.
- Utilizați în cele din urmă dacă aveți nevoie să executați un anumit cod, chiar dacă apare o excepție, și apoi continuați cu excepția.
- Familiarizați-vă cu Manualul de excepții.
Erori interne și alte
Trebuie să faceți distincția între erorile interne și erorile legate de utilizarea unui pachet, a unui modul, a unei clase sau a unei componente. Dacă invarianța internă este încălcată, atunci aceasta este o eroare internă. Exemple tipice de erori interne sunt:
- Faptul că baza de date care trebuie definită nu este cu adevărat definită.
- Un predicat care ar trebui să fie o procedură, dar compilatorul nu este capabil să recunoască acest lucru, este transformat într-o procedură prin adăugarea unei clauze "inactive". Dacă se ajunge la o astfel de defăimare, rezultă din faptul că presupunerea că clauza anterioară nu poate fi încheiată cu succes a fost incorectă.
Erori interne trebuie să genereze o excepție pentru fiecare. Utilizarea excepțiilor respectă principiul: unul pentru fiecare eroare de utilizator și unul pentru fiecare eroare internă.
Erori tipice ale utilizatorilor:
- Indicele de iesire dincolo de intervalul permis
- indicatorul "greșit" la fereastră
- încălcarea ordinii predicatelor
Blocarea (încercare / captura) a programului poate fi furnizată din două motive:
- Există dorința de a face față excepției. De exemplu, dacă deschideți un fișier, apare o întrerupere, indicând faptul că fișierul nu există. În acest caz, există dorința de a bloca finalizarea programului și de a afișa un mesaj de eroare care indică faptul că fișierul nu există. Firește, dacă o astfel de excepție nu este singura posibilă, atunci ar trebui continuată o excepție.
- Există dorința de a face ceva indiferent dacă predicatul este întrerupt. Un exemplu tipic este faptul că blocați ceva (apucați o resursă), apoi faceți ceva și, în final, resetați blocarea (eliberați resursa). Aici trebuie să fii sigur că blocarea este resetată (resursa este eliberată), chiar dacă execuția este întreruptă. În acest scop, încercați / în cele din urmă este utilizat.
Tipuri și fluxuri de intrare-ieșire
În mod implicit, predicatele au un tip de procedură. Nu este necesar să scrieți procedura de calificare până când acest lucru este necesar (dar, în acest caz, poate fi necesar să se ia în considerare necesitatea de a schimba numele predicatului).
În mod implicit, sunt introduse toate argumentele predicatelor. Combinațiile I / O neutilizate nu trebuie să fie scrise.
Direct cu argumentele pot fi folosite calificativele [in] și [out]. Nu scrie [in]. deoarece argumentele sunt intrările implicite.
Dacă prick-ul are o singură variantă a fluxurilor de intrare-ieșire, trebuie să utilizați [out] în locul șablonului.
În mod implicit, faptele sunt nedeterministe - nedeterminate. Nu scrieți nedeterminat. dacă nu există o nevoie specială pentru acest lucru (dar ar trebui să luați în considerare, eventual, schimbarea denumirii faptului).