"Prolog" är ett programmeringsspråk eller grunden för artificiell intelligens. Logisk programmering. Grunderna i Prolog-språket Var används prolog?

Varför är han fantastisk? Jag kan ett par dussin språk och det är inte ett problem för mig att lära mig ett nytt, jag ser bara inte behovet längre.

Prologen är unik. Det är det enda språket som representerar det deklarativa programmeringsparadigmet; det är ett språk som har hundratals olika implementeringar, men de kallas fortfarande Prolog, och lägger bara till prefix och suffix till namnet; det är ett levande språk där inga betydande förändringar har skett på mer än 20 år; Detta är förmodligen det enda programmeringsspråket som är så populärt som inte har någon tillämpning i riktig programmering. Varför Prolog?

Prologen är unik till sin natur, den dök upp på grund av ett lyckligt sammanträffande (världens mystiska struktur). En gång i tiden på 60-talet utvecklades teorin om automatisk satsbevisning väldigt snabbt, och Robinson föreslog en upplösningsalgoritm som gjorde det möjligt att bevisa vilken sann sats som helst (härleda den från axiom) på en begränsad tid (för vilket det inte är känd). Som det visade sig senare är detta den bästa lösningen på ett allmänt problem, det är omöjligt att bevisa satsen i ett begränsat antal operationer. Med enkla ord är algoritmen en bredd-först genomgång av en (vanligtvis oändlig) graf. Naturligtvis är förutsägbarheten för algoritmens operation praktiskt taget lika med 0; följaktligen är detta absolut inte lämpligt för ett programmeringsspråk. Och i det ögonblicket fann Kalmarow en briljant försmalning av problemet, tack vare vilken beviset för vissa teorem såg ut som en procedurmässig exekvering av programmet. Det är värt att notera att klassen av bevisbara teorem är ganska bred och mycket väl tillämpbar på klassen av programmerbara problem. Det var så Prolog kom till 1972.

I den här artikeln ska jag försöka prata om Prolog som ett verktyg för att lösa generella logiska problem. Det här ämnet kommer att vara av intresse för dem som redan känner till Prolog-syntaxen och vill förstå den från insidan, såväl som för de som absolut inte känner till språkets syntax, men som vill förstå dess "lust" utan att spendera extra tid lära sig syntaktiska strukturer.


Huvuddragen i Prolog är att det kan vara lätt att läsa, men väldigt svårt att skriva, vilket skiljer sig i grunden från alla vanliga språk, som säger att skrivandet har blivit ännu lättare, ett steg till och du kan skriva på en surfplatta, dra fungerar moduler som vänner på Google+, vi vet alla att kvaliteten på själva koden lider mycket av detta. Det verkar som att varje rad är tydlig, men hur systemet fungerar är bortom förståelse även för utvecklare, som man säger i Hindustan. Det förefaller mig som om de i alla böcker om undervisning i Prolog gör samma misstag, att de startar en berättelse om fakta, relationer, frågor och en person utvecklar en attityd till språket som ett expertsystem eller en databas. Det är mycket viktigare att lära sig att läsa program korrekt och läsa dussintals av dem på det sättet :)

Hur man läser prologprogram korrekt

Att läsa program är väldigt enkelt, eftersom språket har väldigt få speciella symboler och nyckelord och de är lätta att översätta till naturligt språk. Det största misstaget för en programmerare är att han omedelbart vill föreställa sig hur programmet fungerar, och inte läsa vad programmet beskriver, så det verkar för mig som att det är mycket lättare att träna en vanlig människas okomnade hjärna än en programmerare.
Begrepp
Det finns 2 begrepp i språket predikat(villkor) och föremål(de är också variabler och termer). Predikat uttrycka ett visst villkor, till exempel ett grönt objekt eller ett primtal, det är naturligt att villkoren har ingångsparametrar. Till exempel green_object(Objekt), primtal (tal). Antalet parametrar i ett predikat bestämmer predikatets aritet. Föremål- är termer, konstanter och variabler. Konstanter- det här är siffror och strängar, variabler- uttrycka ett okänt föremål, eventuellt det som söks, och betecknas som linjer med stor brev. Låt oss lämna villkoren för nu och överväga det enklaste programmet.
Program
Ett program är en uppsättning regler för formuläret Om villkor1 och villkor2 och... så är villkoret sant. Formellt kombineras dessa regler genom OCH, men det är omöjligt att få en motsägelse, eftersom det inte finns någon logisk negation i Prolog, och endast ett predikat (villkor) kan vara närvarande i konnektivet That.

A:- B_1, B_2. %-regeln lyder som: Om B_1 och B_2, då A
odd_prime(Number) :- prime(Number), udda(Number).
% Om "Number" är primtal och udda, då är "Number" udda_prime

Som du kan se har variabelnamnet ett omfång - detta är regeln. Matematiskt korrekt låter regeln: för vilken variabel som helst - "Number", om den är primtal och udda, så är den prime_odd. På liknande sätt kan det omformuleras enligt följande: Om det finns ett "tal" som är udda och primtal, så är det udda_primtal. Därför är variabelnamnet väldigt viktigt! Om vi ​​på vänster sida (före:-) ersätter Tal med Tal2, så kommer regeln att ändra sin innebörd: För alla Tal2 och Tal, om Tal är primtal och udda, så är Tal2 enkel udda. Det visar sig att alla tal är primtal_udda! Detta är det vanligaste felet i Prolog.

A:- B_1, B_2. %-regeln lyder som: Om B_1 och B_2, då A udda_prime(Number) :- prime(Number), odd(Number). % Om "Number" är primtal och udda, då är "Number" udda_prime

Exempel - perfekta siffror
perfekt_tal(N) :- antal(N), summa_av_delare_utan_tal(N, SummaDivisorer), lika med(Summa_avDivisorer, H). perfekt_nummer(1). lika (Objekt, Objekt). summa_of_divisors_without_number(1, 1). summa_of_divisors_without_number(Number, Sum) :- number_previous(Number, Previous), summa_of_divisors_of_number_to_number(Number, Sum, Previous). summa_of_number_divisors_to_number(tal, 1, 1). summa_of_number_divisors_to_number(Number, Sum, Divisor) :- dividerat_by(Number, Divisor), number_previous(Divisor, Previous), summa_of_number_divisors_to_number(Number, SumPrev, Previous), add(SumPrev, Divisor, Summa). summa_of_number_divisors_to_number(Number, Sum, Divisor) :- not_divisible_by(Number, Divisor), number_previous(Divisor, Previous), summa_of_number_divisors_to_number(antal, summa, previous).

Låt oss först formellt läsa vad reglerna betyder:

  1. Om "H" är ett tal och för "H" och "SumDivisors" är villkoret summa_divisors_without_number uppfyllt, med andra ord, SumDivisors är summan av divisorerna för talet "H", och "H" är lika med "SumDivisors" , då är "H" ett perfekt tal.
  2. 1 är ett perfekt tal. Regler kanske inte har villkor, i så fall kallas de fakta.
  3. Varje objekt "O" är lika med "O". I princip finns det ett standardpredikat "=", men du kan helt ersätta det med ditt eget.
  4. Det faktum att summan_av_delare_utan_talet 1 är lika med 1.
  5. Om summan av divisorerna "Number" upp till det föregående talet "Number" är lika med "Summa", så är detta summan_av_delare_utan_tal. På så sätt uttrycks det att summan av dividerarna för X är mindre än eller lika med Y, eftersom X är delbart med X, så vi tar Y = X - 1.
  6. Därefter bestämmer 3 predikat summan av divisorer som är mindre än eller lika med Y (Divisor), 1:a fallet Y är lika med 1, 2:a fallet Antal är delbart med Y, sedan summa_of_divisors(X, Y) = summa_of_divisors(X, Y- 1) + Y och 3:e fallet Antalet är inte delbart med Y, då summa_av_delare(X, Y) = summa_av_delare(X, Y-1).
Ett program är som en uppsättning definitioner
Det finns ett andra sätt att läsa dessa regler, mindre matematiskt och mer naturligt, baserat på "definitioner". Du kan märka att i Prolog innehåller alla regler till vänster (i den dåvarande delen) bara ett villkor, vilket i huvudsak är en "definition" av detta villkor.
Till exempel är den första regeln definitionen av perfekta tal. "H" är ett perfekt tal när "H" är ett tal och summan av divisorerna för "H" är lika med "H". Identiska predikat grupperas efter namn med villkoret "eller". Det vill säga, du kan lägga till i definitionen: "H" är ett perfekt tal när... eller när "H" är 1.

Denna läsmetod används flitigt, eftersom den låter predikat kombineras till homogena grupper och hjälper till att förstå i vilken ordning tolken lindar upp predikat för att
kontrollera sanningen i något påstående. Till exempel är det uppenbart att om ett predikat inte har en enda definition, så är det omöjligt att bevisa sanningen i ett påstående med det. I exempel nr 1 har predikatet "delat med" ingen definition.

Ett intressant faktum är att det i Prolog inte finns några loopar, inga variabeltilldelningar, inga typdeklarationer, och kommer vi också ihåg termer och klippning blir språket algoritmiskt komplett.

Termalbad
Termalbad har en rekursiv definition som en namngiven samling av objekt. Term = "namn"(objekt, objekt, ...), exempel person("Namn", "Efternamn"), "+"(1, 2), person(adress("Någon adress"), efternamn("Efternamn"), telefon("Telefon")). Om vi ​​betraktar en term som ett matematiskt begrepp, så är termen en funktion, eller mer exakt en funktor, det vill säga "+"(1, 2) betyder att det finns ett objekt som är lika med 1+2. Detta betyder inte alls att 1+2 = 3, i Prolog är detta uttryck inte sant, precis som i gruppen av rester modulo 2, finns det 3 inte alls. Återigen, ur en matematisk synvinkel, är variabler förbundna med ordet för alla, och om ordet existerar i ett påstående används en term (functor) för detta ändamål. För vilket tal som helst finns ett faktortal: factorial(X, fact(X)).

Ur programmeringssynpunkt kan termer förklaras mycket enklare: en term är ett objekt med en uppsättning attribut, attributen kan vara andra termer eller konstanter eller variabler (det vill säga odefinierade). Den största skillnaden är att alla objekt i Prolog är oföränderliga, det vill säga du kan inte ändra attributen i dem, men det finns ett speciellt tillstånd - en variabel.

Exempel - Heltalsaritmetik
nat(0). nat(nummer(Number)) :- nat(Number). plus(0, siffra, siffra). plus(tal(N1), N2, tal(Res)):- plus(N1, N2, Res). multiplicera (0, Tal, 0). multiplicera(tal(Ch1), Ch2, Res2) :- multiplicera(Ch1, Ch2, Res), plus(Res, Ch2, Res2).
  1. Definition av egenskapen nat (naturligt nummer). 0 är ett naturligt tal, om talet är naturligt så finns det ett objektnummer(Number), som också är ett naturligt tal. Matematiskt uttrycker termen "tal" funktionen +1; ur programmeringssynpunkt är "tal" en rekursiv datastruktur, här är dess element: nummer(0), nummer(nummer(0)), nummer(nummer) (nummer(0))).
  2. Plusförhållandet är 0 + Tal = Tal. Om Ch1 + Ch2 = Res, då (Ch1+1) + Ch2 = (Res+1).
  3. Förhållandet att multiplicera är 0 * Tal = 0. Om Ch1 * Ch2 = Res och Res + Ch2 = Res2, då (Ch1+1) * Ch2 = Res2.
Uppenbarligen är dessa påståenden sanna för vanlig aritmetik, men varför inkluderade vi då inte samma uppenbara som Tal + 0 = Tal. Svaret är enkelt: redundans är mycket dåligt av någon definition. Ja, detta kan hjälpa beräkningar, en sorts för tidig optimering, men bieffekterna kan vara motsägelser i definitioner, tvetydig utmatning av ett påstående och looping av tolken.

Hur Prolog förstår predikat och hur det bevisar påståenden

Naturligtvis hjälper läsningsprogram att få en känsla för Prolog-stilen, men det framgår inte varför och hur dessa definitioner kan användas. Exemplen ovan kan inte kallas ett fullfjädrat program eftersom det inte finns tillräckligt med startpunkt. Ingångspunkten till Prolog är en fråga, analog med en fråga mot en SQL-databas eller analog med att anropa en huvudfunktion i funktionell programmering. Exempel på frågor: nat(Number) - hitta ett naturligt tal, plus(0, 0, Result) - hitta resultatet av att lägga till 0 och 0 i resultatvariabeln, nat(0) - kontrollera om 0 är ett naturligt tal, etc. .

Naturligtvis är resultaten av frågor inte svåra att förutsäga utifrån logiska överväganden, men det är extremt viktigt att förstå hur programmet fick dem. Prolog är trots allt inte en svart låda, utan ett programmeringsspråk, och till skillnad från en databas, där en SQL-plan byggs och frågan kan exekveras olika på olika databaser, har Prolog en mycket specifik exekveringsordning. Faktum är att i databasen vet vi helt vilket svar vi vill få baserat på data i tabellen, tyvärr är det ganska svårt att se på programmets prolog att säga vilka påståenden som är logiskt härledbara, så det är mycket lättare för att förstå hur Prolog-tolken fungerar.

Låt oss titta på ett exempel på begäran plus(0, 0, resultat) :
1. Vi hittar en matchning (en sorts mönstermatchning, upplösning) av denna begäran med den vänstra delen av en av reglerna. För den här frågan, plus(0, Number, Number). Låt oss korrelera alla frågeargument med regeln en efter en och få: 0 = 0, 0 = Antal, Resultat = Antal. Dessa ekvationer involverar 2 variabler (Antal och Resultat), när vi löser dem får vi att Antal = Resultat = 0. Eftersom denna regel inte har några villkor fick vi svaret på frågan. Svar: ja och resultat = 0.

Begäran nat(nummer) :
1. Vi hittar den 1:a matchningen med regeln, nat(0)-regeln, genom att lösa ekvationerna med överensstämmelse, med andra ord, genom att hitta upplösningen får vi Tal = 0. Svar: ja och Tal = 0.

Begäran plus(Resultat, 0, nummer(0)) :
1. Hitta en upplösning med regeln plus(0, Tal, Tal): Resultat = 0, 0 = Tal, tal(0) = Tal, men (!) Tal = 0 = tal(0) - inte möjligt eftersom 0 är samma nummer (0). Därför letar vi efter en lösning med följande regel.
2. Hitta upplösningen med regeln plus(tal(N1), Ch2, nummer(Res)), vi får tal(N1) = Resultat, Ch2 = 0, tal(Res) = nummer(0), därav Res = 0 Detta regler, det finns villkor som vi måste kontrollera, med hänsyn till resultaten av upplösningen (variabelvärden), plus(Ch1, Ch2, Res) -> plus(Ch1, 0, 0). Vi kommer ihåg värdet på variablerna på stacken och skapar en ny begäran plus(H1, 0, 0)
3*. När vi löser frågan plus(Х1, 0, 0) hittar vi en upplösning med plus(0, Number, Number) och får Х1 = 0 och Number = 0.
4. Vi återgår längs stacken till de föregående variablerna Resultat = nummer(N1) = nummer(0). Svaret hittades nummer(0). Följaktligen har prologmaskinen nu löst ekvationen X + 0 = 1.

Att kompetent sammanställa regler på Prolog-språket är en mycket svår sak, men om du komponerar dem kompakt kan du inte bara få direkta svar och lösningar utan även omvända.

Exempelbegäran plus(Nummer, Antal, Antal) : svaret är ja, tal = 0.

Exempelbegäran plus(0, 0, 0) : svaret är nej, vid första försöket är inte alla resolutioner uppfyllda.

Exempelbegäran plus(Number, Number, Number(Number)) : Svaret är ja, Tal = 1. Lösa ekvationen X + X = X + 1.

Försök att mata ut för multiplicering (Number, nummer(0), nummer(0)), detta kommer att kräva att variabler skjuts upp i stacken 2 gånger och beräknas en ny fråga. Kärnan i Prolog-maskinen är att du kan kassera det första resultatet, sedan kommer Prolog att återgå till det tidigare tillståndet och fortsätta beräkningen. Till exempel begäran nat(nummer) , kommer först att tillämpa den 1:a regeln och mata ut 0, och sedan tillämpa den 2:a regeln + 1:a regeln och mata ut talet (0), du kan upprepa och få en oändlig sekvens av alla naturliga tal. Ett annat exempel, begäran plus(tal, nummer(0), nummer2) , kommer att producera en sekvens av alla par av lösningar till ekvationen X + 1 = Y.

Slutsats

Tyvärr tillät den rimliga storleken på ämnet mig inte att komma nära huvudämnet, nämligen att lösa komplexa logiska problem i Prolog, utan att ha en strategi för att lösa dem. Stora bitar av Prolog-kod kan skrämma bort inte bara nybörjare, utan även erfarna programmerare. Syftet med denna artikel är att visa att Prolog-program kan helt enkelt läsa på naturligt språk, och utförs av en enkel tolk.
Huvuddragen i Prolog är att det inte är en svart låda eller ett bibliotek som löser komplexa logiska problem; du kan skriva in en algebraisk ekvation i Mathematica och det kommer att producera en lösning, men sekvensen av steg som utförs är okänd. Prolog kan inte lösa allmänna logiska problem (den saknar logiskt "eller" och "negation"), annars skulle dess utdata vara icke-deterministisk som en linjär upplösning. Prolog är den gyllene medelvägen mellan en enkel tolk och en satsbevisande maskin; en förskjutning i valfri riktning leder till att en av egenskaperna försvinner.

I nästa artikel skulle jag vilja prata om hur sorteringsproblem löses, om sekvensen av transfusioner, Miss Manners och andra välkända logiska problem. För den som känner sig missnöjd vill jag bjuda på nästa uppgift (den första personen att lösa priset):
Skriv ett predikat, vilket skulle generera en oändlig sekvens av naturliga tal, som börjar med 3. Dessa bör vara standardtal i Prolog, operationer som utförs med predikatet is: X är 3 + 1 => X=4.

I många årtusenden har mänskligheten ackumulerat, bearbetat och överfört kunskap. För dessa ändamål uppfinns ständigt nya medel och gamla förbättras: tal, skrift, post, telegraf, telefon etc. Datorernas tillkomst spelade en stor roll i kunskapsbearbetningstekniken.

I oktober 1981 tillkännagav det japanska ministeriet för internationell handel och industri skapandet av en forskningsorganisation - Institute for New Generation Computer Technology Research Center. Målet med detta projekt var att skapa kunskapsbaserade informationsbehandlingssystem. Det antogs att dessa system skulle ge enkel hantering på grund av förmågan att kommunicera med användare med naturligt språk. Dessa system var tänkta att vara självlärande, använda kunskapen som samlats i minnet för att lösa olika typer av problem, ge användarna expertråd, och användaren behövdes inte vara specialist på datavetenskap. Det antogs att en person skulle kunna använda en femte generationens dator lika lätt som vilken elektrisk hushållsapparat som helst som TV, bandspelare och dammsugare. Strax efter det japanska startade amerikanska och europeiska projekt.

Framväxten av sådana system skulle kunna förändra tekniken genom användning av kunskapsbaser och expertsystem. Huvudessensen av den kvalitativa övergången till den femte generationens datorer var övergången från databehandling till kunskapsbehandling. Japanerna hoppades att de inte skulle kunna anpassa det mänskliga tänkandet till principerna för datordrift, utan att föra datordrift närmare hur en person tänker, samtidigt som de flyttar bort från datorernas von Neumann-arkitektur. 1991 var det planerat att skapa den första prototypen av femte generationens datorer.

Det står nu klart att de uppsatta målen aldrig uppnåddes fullt ut, men detta projekt fungerade som en drivkraft för utvecklingen av en ny forskningsrunda inom området artificiell intelligens och orsakade en explosion av intresse för logisk programmering. Eftersom den traditionella von Neumann-arkitekturen inte var lämplig för effektiv implementering skapades specialiserade logikprogrammeringsdatorer PSI och PIM.

Följande valdes som huvudmetod för att utveckla programvara för femte generationens datorprojekt: logisk programmering, en framstående representant för vilken är prologspråket. Det verkar som att Prolog för närvarande förblir det mest populära artificiella intelligensspråket i Japan och Europa (i USA är traditionellt ett annat artificiell intelligensspråk mer utbrett - det funktionella programmeringsspråket Lisp).

Namnet på språket "Prolog" kommer från orden LOGISK PROGRAMMERING(PROgrammation en LOGique på franska och PROgrammering i LOGic på engelska).

Prolog bygger på en sådan gren av matematisk logik som predikatkalkyl. Mer exakt är dess grund förfarandet för att bevisa satser upplösningsmetod För Hornklausuler. Nästa föreläsning kommer att ägnas åt detta ämne.

I historien om uppkomsten och utvecklingen av Prolog-språket kan följande stadier urskiljas.

År 1965, i artikeln "A machine oriented logic based on the resolution principle", publicerad i 12:e numret av Journal of the ACM, presenterade J. Robinson en metod för att automatiskt hitta bevis för satser i första ordningens predikatkalkyl, kallad " upplösningsprincipen". Detta arbete kan läsas i översättning: Robinson J. Machine-oriented logic based on principen för resolutionen// Cybernetisk samling. - Vol. 7 (1970). Faktum är att idén till denna metod föreslogs av Herbrand 1931, när det ännu inte fanns några datorer (Herbrand, "Une methode de demonstration", These, Paris, 1931). Robinson modifierade denna metod så att den blev lämplig för automatisk datoranvändning, och utvecklade dessutom en effektiv föreningsalgoritm som ligger till grund för hans metod.

1973 skapade "gruppen för artificiell intelligens" under ledning av Alain Colmeroe ett program vid universitetet i Marseille utformat för att bevisa teorem. Detta program har använts för att bygga naturliga textbehandlingssystem. Satsbevisprogrammet hette Prolog (från Programmation en Logique). Den fungerade som prototypen för Prologue. Legenden säger att författaren till detta namn var Alan Colmeroes fru. Programmet skrevs i Fortran och gick ganska långsamt.

Robert Kowalskis arbete var av stor betydelse för utvecklingen av logisk programmering. Predikatlogik Hur programmeringsspråk"(Kowalski R. Predicate Logic as Programming Language. IFIP Congress, 1974), där han visade att för att uppnå effektivitet måste man begränsa sig till användningen av en uppsättning Hornklausuler. Det är förresten känt att Kowalski och Colmeroe arbetade tillsammans under en sommar.

1976 föreslog Kowalski, tillsammans med sin kollega Maarten van Emden, två tillvägagångssätt för att läsa logikprogramtexter: procedurella och deklarativa. Dessa tillvägagångssätt kommer att diskuteras i den tredje föreläsningen.

År 1977 i Edinburgh skapade Warren och Pereira en mycket effektiv Prolog-kompilator för DEC-10-datorn, som fungerade som prototyp för många efterföljande implementeringar av Prolog. Intressant,

Föreläsningen ägnas åt att lösa problem med hjälp av en tillståndsrymdgraf. Tillståndsrummet beskrivs i form av en uppsättning tillstånd - grafens hörn, en uppsättning övergångar från tillstånd till tillstånd - grafbågar, en uppsättning initialtillstånd och en uppsättning sluttillstånd. Lösningen på problemet representeras som en väg på tillståndsrymdgrafen som förbinder det initiala tillståndet med det slutliga tillståndet. Om tillståndsutrymmet för problemet är litet, kommer alla optimala lösningar att hittas med hjälp av djup-först-sökning. I problem med ett stort statligt utrymme kommer endast en optimal lösning att beräknas genom bredd-först-sökning. Universallösare appliceras på problem. Stater i olika uppgifter kan tillhöra olika domäner. För att komma ihåg de bästa lösningarna som hittats används en "variabel variabel" varM. Kompilatorn hittar själv de nödvändiga typerna. Visual Prolog version 7.5, ännu inte publicerad. Dess publicering är planerad till 2014, men det exakta datumet är ännu inte känt. Visual Prolog 7.4 är nu tillgängligt för alla.

Uppkomsten av Prologue berodde på utvecklingen av logik, matematik och programmering. Den senare spelade den viktigaste rollen. Specialister inom logik och matematik gjorde ett försök att sätta programmering på "rätt väg", men utvecklingen av informationsteknologi visade ett helt annat resultat.

Pragmatisk imperativ programmering visade sig vara mer lovande. "Prolog" lyckades som programmeringsspråk, men blev inte grunden för artificiell intelligens.

Klassisk programmering vs logik

En person fattar svåra beslut logiskt och rimligt. Nästan utan att tänka, agerar en person klokt. Om vi ​​inte tar hänsyn till beslut som kräver att vi samlar in information, analyserar den och komplexa beräkningar, då är varje resultat snabbt, korrekt och rimligt.

Detta faktum har alltid gett en illusorisk anledning att betrakta skapandet av ett beslutsfattande verktyg som en enkel sak. Med tillkomsten av Prologue verkade det som att frågan om artificiell intelligens var en fråga om teknik, och Homo sapiens kom med tre lagar för robotik. Men artificiell intelligens förblev ett spöke, och de tre lagarna för robotik visade sig vara från en saga - "gör det här, jag vet inte vad."

Programmering i ordets klassiska betydelse (begreppen "procedurell", "imperativ" eller "funktionell" används ofta) har utvecklats och framgångsrikt övervunnit de "oroliga tiderna" på 80-90-talet, då det fanns otaliga programmeringsspråk.

Demonstrationskampen mellan "Pascal" och "Si" varade länge och var brutal, men slutade neutralt och tyst. Det som återstår är idén om ett bra programmeringsspråk och flera framgångsrika implementeringar av det.

Därmed inte sagt att Prolog som programmeringsspråk inte har utvecklats. Men han uppnådde inte sina uttalade mål. Idag kan vi inte bara säga, utan också motivera: "Prolog" är ett akademiskt språk för:

  • lärandemål;
  • predikatslogik;
  • matematik;
  • smal tillämpning.

Det är tveksamt att detta påstående kan vederläggas. Artificiell intelligens används inte bara flitigt, utan också en mycket allvarlig händelse som radikalt förändrar den sociala strukturen och världsbilden.

Programmering på prologspråket för artificiell intelligens ägde inte rum: under mer än fyrtio år av språkets historia har det inte funnits en enda radikalt ny händelse som är relevant för det allmänna medvetandet, vilket tyder på motsatsen.

Den objektiva verkligheten är denna: det är inte så mycket den starkaste som överlever, utan snarare det som efterfrågas och är relevant.

"Prolog" är ett deklarativt programmeringsspråk

Att ha ett verktyg för att beskriva fakta och regler är bra, men vad är poängen? Fakta och regler passar perfekt in i en vanlig databas. En kvalificerad klassisk programmerare ger en interaktiv dialog för användaren, och den senare löser sina problem.

Vid behov förfinar programmeraren dialogen och användaren kompletterar databasen med fakta och regler. Ett absolut fungerande och årtionden testat alternativ för att implementera en mängd redan lösta och lösbara problem.

En deklarativ presentation av fakta och regler i varje implementering av programmeringsspråket Prolog är en konvention, ett försök att formalisera verkligheten i dess intellektuella tillstånd. Konventionell programmering berör inte intellektet. Klassisk programmering är nöjd med positionen: beskrivning och bearbetning av data. Det finns många problem här, men det finns många briljanta lösningar som fungerar.

"Prolog" som programmeringsspråk är fakta:

  • mamma (Maria, Natasha); - Maria - Natashas mamma;
  • pappa (Evgeniy, Marina); - Evgeniy är Marinas pappa.

Här är ett faktum omedelbart överbord: "Maria" och "Marina" är olika namn. Inget hindrar dig från att tillägga faktum:

  • pappa (Eugene, Maria); - Evgeniy är Marias pappa.

Dessa beskrivningar ger liv åt reglerna:

  • förälder(x,y)<- папа (x, y);
  • förälder(x,y)<- мама (x, y);

Men de tillåter oss inte att dra slutsatsen att pappa är Marinas pappa och Marina är Marias mamma. Det här problemet kan lösas; du kan lägga till ytterligare en regel, lägga till ytterligare ett faktum. Men hur många av dessa åtgärder bör vidtas i en verklig situation?

Faktum är att "Prolog" som programmeringsspråk är ett exempel på en deklaration av fakta och regler, men inte den logik som en klassisk programmerares medvetande är van vid. "Prolog" positionerar sig som ett predikatlogiskt språk, men du kan bara lära dig programmering i det genom exempel och exempelbeskrivningar från utvecklarna av en specifik implementering av språket.

Familjen Prolog

Frankrike anses vara födelseplatsen för Prologue, och 1973 är födelseåret. Intresset för språket förnyades periodvis, men avtog med avundsvärd stabilitet. Språkets motto: ”Predikatslogik är elementär! Detta är ett sätt att förklara hur tänkande fungerar” - och förblev mottot.

Varje implementering av programmeringsspråket Prolog följde strikt predikatlogik, men inkluderade alltid klassiska idéer om procedurprogrammering. Det är mer korrekt att säga "imperativ", eftersom denna term används med mer formalitet än procedurmässigt, funktionellt, objektorienterat eller annat.

All programmering handlar om data och dess bearbetning. Språkkonstruktioner måste beskriva problemet som löses så noggrant som möjligt, varför alla kända implementeringar av Prolog: Turbo Prolog, Win Prolog, SWI Prolog, GNU Prolog, Visual Prolog och andra innehåller, förutom deklarativa konstruktioner, vanliga imperativa uttryck.

Man tror att Prologue-familjen är utvecklad i akademiska och forskningsorganisationer och därför endast kan talas om som ett gemensamt språk i begreppsmässig mening. Ändå kan själva det faktum att begreppet "Prolog" är levande och utvecklas övervägas: detta språk har en räckvidd och det är efterfrågat i ett visst antal uppgifter.

Grunden för artificiell intelligens

Intresset för artificiell intelligens har aldrig avtagit, de börjar bara prata om det när nästa tillfälle dyker upp, men Prolog har aldrig förknippats med artificiell intelligens mer än ett vanligt klassiskt programmeringsspråk.

I slutet av 80-talet fanns det ett verkligt, relevant och populärt intellektuellt projekt "The Inventing Machine". Det gjordes ett verkligt försök att använda Prolog för att formalisera en enorm praktisk kunskapsbas (data) om uppfinningar, fysikaliska, kemiska och andra lagar.

Resultatet uppnåddes inte, för många fakta och regler måste skrivas i Prolog som programmeringsspråk, vilket var av banal imperativ karaktär. Samtidigt implementerades många framgångsrika mjukvaruprodukter parallellt på vanliga språk.

I början av 90-talet genomfördes framgångsrikt ett projekt med ett verkligt intellektuellt system som simulerade beteendet hos ett barn under 3 år på en EU-dator! Alternativet att använda Prolog övervägdes inte ens.

Detta intellektuella system "får inte bara reda på" vad mamma och pappa var och hur Maria skilde sig från Marina, utan hoppade också, utan större ansträngning, självständigt från den förvärvade kunskapen om dessa frågor till bollar och deras skillnader från kuber, till färgerna på objekt och... (!) till elementär matematik: enkla aritmetiska operationer visade sig ligga inom hennes förmåga baserat på den kunskap som förvärvats genom att lösa helt andra problem.

Man kan inte säga att klassisk programmering ligger före Prolog när det gäller att bemästra den artificiella intelligensens territorium, men det ger verkliga resultat.

När det gäller intelligens som en uppgift, ligger frågan här tydligen inte i språket, utan i idén om implementering. Om assembleraren från 1991 kunde "bli grunden" för ett intelligent system för situationell intelligens, så ligger frågan uppenbarligen inte i implementeringsspråket, utan i idén.

Prolog programmeringsspråkär ett av de ledande logiska programmeringsspråken. Den skapades av Alain Colmerauer på 1970-talet. Det var ett försök att göra ett programmeringsspråk för nybörjare som gör det möjligt att uttrycka logik, snarare än att noggrant specificera vad man vill uppnå med instruktioner på en datorskärm.

Prolog används i många artificiell intelligensprogram, men dess syntax och semantik är mycket enkel och tydlig (det ursprungliga syftet var att tillhandahålla ett verktyg för datoranalfabeter). Namnet Prolog är en akronym för LOGIC PROGRAMMING och är allmänt känt för att lära ut grunderna i programmering.

Prolog är baserad på predikatkalkyl (mer exakt första ordningens predikatkalkyl), men den är begränsad till Horns formler. Prolog-program är effektiva för att bevisa satser till en första approximation. Grundläggande begrepp för sammanfogning, svansrekursion och spårning.

Datatyper

Prolog använder inte datatyper på det sätt som vi är vana vid i vanliga programmeringsspråk. Vi kan prata om Prolog lexikaliska element istället för datatyper, vilket är ovanligt vid programmering för dummies.

Den konstanta texten skrivs in med hjälp av atomer. En atom är en sekvens av bokstäver, siffror och ett understreck som börjar med en liten bokstav. Vanligtvis, om dessa inte är alfanumeriska atomer, är det nödvändigt att rama in dem med apostrof (till exempel är "+" en atom, + är en operator).

De flesta Prolog-implementationer skiljer inte mellan reella och bråktal.

Variabler

Variabler identifieras av en sträng som består av bokstäver, siffror och understreck, som börjar med en stor bokstav. I Prolog-miljön är en variabel inte en behållare som kan tilldelas (till skillnad från procedurprogrammeringsspråk). Dess beteende är närmare en modell som liknar sammanfogningar.

Så kallade anonyma variabler skrivs som ett enda understreck (_).

Termer är det enda sättet som Prolog kan representera komplexa data. Termen består av ett huvud, även kallat en funktor (som måste vara en atom) och parametrar (ej begränsat till typer). Antalet parametrar, termens så kallade arities, är viktigt. En term definieras av dess huvud och aritet, vanligen skrivet som funktor/aritet.
Listor

En lista är inte en fristående datatyp eftersom den definieras av rekursiv konstruktion (med termen /2 "."):

Atom - tom lista

För programmerarens bekvämlighet kan listor konstrueras och förstöras på olika sätt.

Om L är en lista och X är ett element, då "." (X, L) är medlem i listan. Det första elementet X följt av innehållet i sammanhanget L representeras syntaktisk som.

För programmerarens bekvämlighet kan listor byggas och förstöras på olika sätt.

Artikellista:
Förord ​​till ett element:
Preliminärt flera element:
Term extension: "."(abc, "."(1, "."(f(x), "."(Y, "."(g(A,första), ))))))

Strängar skrivs vanligtvis som en sekvens av tecken inom citattecken. De representeras ofta som listor med ASCII-teckenkoder.

Programmering i PROLOG skiljer sig mycket från att arbeta med procedurspråk. I Prolog arbetar du med databaser med fakta och regler, du kan köra databasfrågor. Grundenheten i Prolog är ett predikat som definieras som sant. Ett predikat består av ett huvud och ett antal argument. Till exempel:

Här är "katt" huvudet och "tom" är argumentet. Här är några exempelfrågor du kan köra med Prolog-översättaren baserat på detta faktum:

Cat(tom).
ja.

Katt(X).
X = tom;
Nej.

Predikat definieras vanligtvis för att uttrycka ett faktum genom vilket ett program känner till världen. I de flesta fall kräver användningen av predikat vissa konventioner. Så vilket av följande skulle betyda att Pat är Sallys far?

Far (sally, pat).
far (klapp, sally).

"far" är i båda fallen huvudet, och "sally" och "klapp" är argumenten. Men i det första fallet är Sally på första plats i listan över argument, och Pat är på andra plats och vice versa. Det första fallet är ett exempel på en definition i ordningen Verb Subject och Object, men i det andra exemplet är ordningen Verb Object Subject. Eftersom Prolog inte förstår engelska är båda versionerna bra, men det anses vara bra programmeringsstil att hålla sig till en stil, kallad konvention, medan du skriver ett program, snarare än att behöva skriva något i stil med:

Far (pat, sally). pappa (jessica, james).

Vissa predikat är inbyggda i språket och gör det möjligt för Prolog att minska slitet i vardagliga aktiviteter (såsom input/output med grafik och annan kommunikation med operativsystemet). Till exempel kan skrivpredikat användas för visning så här:

Skriv ("hej")

Kommer att visa ordet "Hej" på skärmen.

Regler

Den andra typen av påstående i Prolog är regler. Exempelregel:

Ljus(på) :- strömbrytare(på).

":-" betyder "om", den här regeln betyder att ljus(tänd) är sant (på) om switch(på) är sant (annars om strömbrytaren är på så finns det ljus). Regler kan också använda variabler; variabler börjar med stor bokstav medan konstanter börjar med små bokstäver. Till exempel,

Far(X,Y):- förälder(X,Y),man(Y).

Detta betyder, "om någon är en förälder och han är en man, då är han en far." Orsaker och effekter kan också vara i omvänd ordning, så detta motsäger inte vanlig logik. Du kan placera flera predikat i konsekvenssektionen genom att kombinera dem, till exempel:

Vilket motsvarar flera deklarationer:

A:-d. b:- d. CD.

Men instruktioner som:

Vilket är motsvarigheten till "om c då a eller b". Detta beror på begränsningen i Horns formel.