"Prologue" is a programming language or the basis of artificial intelligence. Logic programming. Basics of the Prolog language Where is prolog used?

Why is he amazing? I know a couple of dozen languages ​​and it’s not a problem for me to learn another new one, I just don’t see the need anymore.

The prologue is unique. It is the only language that represents the declarative programming paradigm; it is a language that has hundreds of different implementations, but they are still called Prolog, adding only prefixes and suffixes to the name; it is a living language in which no significant changes have occurred for more than 20 years; This is probably the only programming language that is so popular that has no application in real programming. Why Prolog?

The prologue is unique in nature, it appeared due to a happy coincidence (the mysterious structure of the world). Once upon a time in the 60s, the theory of automatic theorem proving was developing very rapidly, and Robinson proposed a resolution algorithm that made it possible to prove any true theorem (derive it from axioms) in a finite time (for which it is not known). As it turned out later, this is the best solution to a general problem; it is impossible to prove the theorem in a limited number of operations. In simple words, the algorithm is a breadth-first traversal of a (generally infinite) graph. Naturally, the predictability of the algorithm’s operation is practically equal to 0; accordingly, this is absolutely not suitable for a Programming Language. And at that moment Kalmarow found a brilliant narrowing of the problem, thanks to which the proof of some theorems looked like a procedural execution of the program. It is worth noting that the class of provable theorems is quite wide and very well applicable to the class of programmable problems. That's how Prolog came into being in 1972.

In this article I will try to talk about Prolog as a tool for solving general logical problems. This topic will be of interest to those who already know Prolog syntax and want to understand it from the inside, as well as to those who absolutely do not know the syntax of the language, but want to understand its “zest” without spending extra time learning syntactic structures.


The main feature of Prolog is that it can be easy to read, but very difficult to write, which is fundamentally different from all mainstream languages, which say that writing has become even easier, one more step and you can write on a tablet, dragging working modules like friends on Google+ , we all know that the quality of the code itself suffers greatly from this. It seems that every line is clear, but how the system works is beyond understanding even for developers, as they say in Hindustan. It seems to me that in all books on teaching Prolog, they make the same mistake, starting a story about facts, relationships, queries, and a person develops an attitude towards the language as an Expert System or Database. It’s much more important to learn how to read programs correctly and read dozens of them that way :)

How to read prologue programs correctly

Reading programs is very easy, since the language has very few special symbols and keywords and they are easily translated into natural language. The main mistake of a programmer is that he wants to immediately imagine how the program works, and not read what the program describes, so it seems to me that it is much easier to train the unclouded brain of an ordinary person than a programmer.
Concepts
There are 2 concepts in the language predicates(conditions) and objects(they are also variables and terms). Predicates express a certain condition, for example, a green object or a prime number; it is natural that the conditions have input parameters. For example green_object(Object), prime_number(Number). The number of parameters in a predicate determines the arity of the predicate. Objects- are terms, constants and variables. Constants- these are numbers and strings, variables- express an unknown object, possibly the one being sought, and are designated as lines with big letters. Let's leave the terms for now and consider the simplest program.
Program
A program is a set of rules of the form If condition1 and condition2 and... then the condition is true. Formally, these rules are combined through AND, but it is impossible to obtain a contradiction, since there is no logical negation in Prolog, and only one predicate (condition) can be present in the connective That.

A:- B_1, B_2. The % rule reads as: If B_1 and B_2, then A
odd_prime(Number) :- prime(Number), odd(Number).
% If "Number" is prime and odd, then "Number" is odd_prime

As you can see, the variable name has a scope - this is the rule. Mathematically correct, the rule sounds: for any variable - “Number”, if it is prime and odd, then it is prime_odd. Similarly, it can be rephrased as follows: If there is a “Number” that is odd and prime, then it is odd_prime. Therefore, the variable name is very important! If on the left side (before:-) we replace Number with Number2, then the rule will change its meaning: For any Number2 and Number, if Number is prime and odd, then Number2 is simple odd. It turns out that all numbers are prime_odd! This is the most common error in Prolog.

A:- B_1, B_2. The % rule reads as: If B_1 and B_2, then A odd_prime(Number) :- prime(Number), odd(Number). % If "Number" is prime and odd, then "Number" is odd_prime

Example - perfect numbers
perfect_number(N) :- number(N), sum_of_divisors_without_number(N, SumofDivisors), equal to(Sum_ofDivisors, H). perfect_number(1). equals(Object, Object). sum_of_divisors_without_number(1, 1). sum_of_divisors_without_number(Number, Sum) :- number_previous(Number, Previous), sum_of_divisors_of_number_to_number(Number, Sum, Previous). sum_of_number_divisors_to_number(Number, 1, 1). sum_of_number_divisors_to_number(Number, Sum, Divisor) :- divided_by(Number, Divisor), number_previous(Divisor, Previous), sum_of_number_divisors_to_number(Number, SumPrev, Previous), add(SumPrev, Divisor, Sum). sum_of_number_divisors_to_number(Number, Sum, Divisor) :- not_divisible_by(Number, Divisor), number_previous(Divisor, Previous), sum_of_number_divisors_to_number(Number, Sum, Previous).

First, let’s formally read what the rules mean:

  1. If “H” is a number and for “H” and “SumDivisors” the condition sum_divisors_without_number is met, in other words, SumDivisors is the sum of the divisors of the number “H”, and “H” is equal to “SumDivisors”, then “H” is a perfect number.
  2. 1 is a perfect number. Rules may not have conditions, in which case they are called facts.
  3. Every object "O" is equal to "O". In principle, there is a standard predicate "=", but you can completely replace it with your own.
  4. The fact that the sum_of_divisors_without_the number 1 is equal to 1.
  5. If the sum of the divisors "Number" up to the previous number "Number" is equal to "Sum", then this is the sum_of_divisors_without_number. This way it is expressed that the sum of the divisors of X is less than or equal to Y, since X is divisible by X, so we take Y = X - 1.
  6. Next, 3 predicates determine the sum of divisors number less than or equal to Y (Divisor), 1st case Y is equal to 1, 2nd case Number is divisible by Y, then sum_of_divisors(X, Y) = sum_of_divisors(X, Y-1) + Y , and 3rd case The number is not divisible by Y, then sum_of_divisors(X, Y) = sum_of_divisors(X, Y-1).
A program is like a set of definitions
There is a second way to read these rules, less mathematical and more natural, based on “definitions”. You can notice that in Prolog all the rules on the left (in the then part) contain only one condition, which is essentially a “definition” of this condition.
For example, the 1st rule is the definition of perfect numbers. "H" is a perfect number when "H" is a number and the sum of the divisors of "H" is equal to "H". Identical predicates are grouped by name using the “or” condition. That is, you can add to the definition: “H” is a perfect number when.., or when “H” is 1.

This reading method is widely used, as it allows predicates to be combined into homogeneous groups and helps to understand in what order the interpreter unwinds predicates in order to
check the truth of some statement. For example, it is obvious that if a predicate does not have a single definition, then it is impossible to prove the truth of a statement with it. In example No. 1, the predicate “divided by” has no definition.

An interesting fact is that in Prolog there are no loops, no variable assignments, no type declarations, and if we also remember about terms and clipping, the language becomes algorithmically complete.

Thermal Baths
Thermal Baths have a recursive definition as a named collection of objects. Term = "name"(object, object, ...), example person("Name", "Surname"), "+"(1, 2), person(address("Some address"), surname("Last name"), phone("Phone")). If we consider a term as a mathematical concept, then the term is a function, or more precisely a functor, that is, “+”(1, 2) means that there is an object that is equal to 1+2. This does not mean at all that 1+2 = 3; in Prolog this expression is not true, just as in the group of remainders modulo 2, there 3 does not exist at all. Again, from a mathematical point of view, Variables are connected by the word For All, and if in a statement the word exists, then a term (functor) is used for this purpose. For any number there is a factorial number: factorial(X, fact(X)).

From a programming point of view, terms can be explained much more simply: a term is an object with a set of attributes, the attributes can be other terms or constants or variables (that is, undefined). The main difference is that all objects in Prolog are immutable, that is, you cannot change the attributes in them, but there is a special state - a variable.

Example - Integer Arithmetic
nat(0). nat(number(Number)) :- nat(Number). plus(0, Number, Number). plus(number(N1), N2, number(Res)) :- plus(N1, N2, Res). multiply(0, Number, 0). multiply(number(Ch1), Ch2, Res2) :- multiply(Ch1, Ch2, Res), plus(Res, Ch2, Res2).
  1. Definition of the property nat (natural number). 0 is a natural number, if the Number is natural, then there is an object number(Number), which is also a natural number. Mathematically, the term “number” expresses the function +1; from a programming point of view, “number” is a recursive data structure, here are its elements: number(0), number(number(0)), number(number(number(0))).
  2. The plus ratio is 0 + Number = Number. If Ch1 + Ch2 = Res, then (Ch1+1) + Ch2 = (Res+1).
  3. The ratio to multiply is 0 * Number = 0. If Ch1 * Ch2 = Res and Res + Ch2 = Res2, then (Ch1+1) * Ch2 = Res2.
Obviously these statements are true for ordinary arithmetic, but then why didn’t we include the same obvious ones as Number + 0 = Number. The answer is simple: redundancy is very bad by any definition. Yes, this can help calculations, a kind of premature optimization, but the side effects can be contradictions in definitions, ambiguous output of a statement, and looping of the interpreter.

How Prolog understands predicates and how it proves statements

Of course, reading programs helps to get a feel for the Prolog style, but it does not make it clear why and how these definitions can be used. The examples given above cannot be called a full-fledged program because there is not enough entry point. The entry point to Prolog is a query, analogous to a query against a SQL database or analogous to calling a main function in functional programming. Examples of queries: nat(Number) - find a natural number, plus(0, 0, Result) - find the result of adding 0 and 0 in the Result variable, nat(0) - check whether 0 is a natural number, etc.

Of course, the results of queries are not difficult to predict from logical considerations, but it is extremely important to understand how the program obtained them. After all, Prolog is not a black box, but a programming language, and unlike a database, where a SQL plan is built and the query can be executed differently on different Databases, Prolog has a very specific execution order. The fact is that in the Database we completely know what answer we want to get based on the data in the table, unfortunately, looking at the Prolog of the program it is quite difficult to say which statements are logically deducible, so it is much easier to understand how the Prolog interpreter works.

Let's look at an example request plus(0, 0, Result) :
1. We find a match (a kind of pattern-matching, resolution) of this request with the left part of one of the rules. For this query, plus(0, Number, Number). Let's correlate all the query arguments with the rule one by one and get: 0 = 0, 0 = Number, Result = Number. These equations involve 2 variables (Number and Result), solving them we get that Number = Result = 0. Since this rule has no conditions, we received the answer to the question asked. Answer: yes and Result = 0.

Request nat(Number) :
1. We find the 1st match with the rule, the nat(0) rule, by solving the equations by correspondence, in other words, by finding the resolution, we get Number = 0. Answer: yes and Number = 0.

Request plus(Result, 0, number(0)) :
1. Find a resolution with the rule plus(0, Number, Number): Result = 0, 0 = Number, number(0) = Number, but (!) Number = 0 = number(0) - not possible since 0 is the same number (0). Therefore, we are looking for a resolution with the following rule.
2. Find the resolution with the rule plus(number(N1), Ch2, number(Res)), we get number(N1) = Result, Ch2 = 0, number(Res) = number(0), hence Res = 0. This rules, there are conditions that we must check, taking into account the results of the resolution (variable values), plus(Ch1, Ch2, Res) -> plus(Ch1, 0, 0). We remember the value of the variables on the stack and create a new request plus(H1, 0, 0)
3*. Solving the query plus(Х1, 0, 0) we find a resolution with plus(0, Number, Number) and get Х1 = 0 and Number = 0.
4. We return along the stack to the previous variables Result = number(N1) = number(0). The answer was found number(0). Accordingly, the prolog machine has now solved the equation X + 0 = 1.

Competently compiling rules in the Prolog language is a very difficult thing, but if you compose them compactly, you can get not only direct answers and solutions, but also reverse ones.

Example request plus(Number, Number, Number) : the answer is yes, Number = 0.

Example request plus(0, 0, 0) : the answer is no, on the first attempt all resolutions are not fulfilled.

Example request plus(Number, Number, number(Number)) : The answer is yes, Number = 1. Solving the equation X + X = X + 1.

Try outputting for multiply(Number, number(0), number(0)), this will require pushing variables onto the stack 2 times and calculating a new query. The essence of the Prolog machine is that you can discard the 1st result, then Prolog will return to the previous state and continue the calculation. For example request nat(Number) , will first apply the 1st rule and output 0, and then apply the 2nd rule + 1st rule and output the number (0), you can repeat and get an infinite sequence of all natural numbers. Another example, request plus(Number, number(0), Number2) , will produce a sequence of all pairs of solutions to the equation X + 1 = Y.

Conclusion

Unfortunately, the reasonable size of the topic did not allow me to get close to the main topic, namely solving complex logical problems in Prolog, without having a strategy for solving them. Large chunks of Prolog code can scare off not only beginners, but even experienced programmers. The purpose of this article is to show that Prolog programs can simply read in natural language, and executed by a simple interpreter.
The main feature of Prolog is that it is not a black box or a library that solves complex logical problems; you can enter an algebraic equation into Mathematica and it will produce a solution, but the sequence of steps performed is unknown. Prolog cannot solve general logical problems (it lacks logical “or” and “negation”), otherwise its output would be non-deterministic as a linear resolution. Prolog is the golden mean between a simple interpreter and a theorem proving machine; a shift in any direction leads to the loss of one of the properties.

In the next article I would like to talk about how sorting problems are solved, about the sequence of transfusions, Miss Manners and other well-known logical problems. For those who feel unsatisfied, I want to offer next task (the first person to solve the prize):
Write a predicate, which would generate an infinite sequence of natural numbers, starting with 3. These should be standard numbers in Prolog, operations on which are performed using the is predicate: X is 3 + 1 => X=4.

For many millennia, humanity has been accumulating, processing and transmitting knowledge. For these purposes, new means are constantly being invented and old ones are being improved: speech, writing, mail, telegraph, telephone, etc. The advent of computers played a major role in knowledge processing technology.

In October 1981, the Japanese Ministry of International Trade and Industry announced the creation of a research organization - the Institute for New Generation Computer Technology Research Center. The goal of this project was to create knowledge-based information processing systems. It was assumed that these systems would provide ease of management due to the ability to communicate with users using natural language. These systems were supposed to be self-learning, use the knowledge accumulated in memory to solve various kinds of problems, provide users with expert advice, and the user was not required to be a specialist in computer science. It was assumed that a person would be able to use a fifth-generation computer as easily as any household electrical appliance such as a TV, tape recorder and vacuum cleaner. Soon after the Japanese one, American and European projects started.

The emergence of such systems could change technology through the use of knowledge bases and expert systems. The main essence of the qualitative transition to the fifth generation of computers was the transition from data processing to knowledge processing. The Japanese hoped that they would be able not to adjust human thinking to the principles of computer operation, but to bring computer operation closer to the way a person thinks, while moving away from the von Neumann architecture of computers. In 1991, it was planned to create the first prototype of fifth-generation computers.

It is now clear that the set goals were never fully achieved, but this project served as an impetus for the development of a new round of research in the field of artificial intelligence and caused an explosion of interest in logic programming. Since the traditional von Neumann architecture was not suitable for efficient implementation, specialized logic programming computers PSI and PIM were created.

The following was chosen as the main methodology for developing software for the fifth generation computer project: logic programming, a prominent representative of which is the Prolog language. It seems that at present Prolog remains the most popular artificial intelligence language in Japan and Europe (in the USA, traditionally, another artificial intelligence language is more widespread - the functional programming language Lisp).

The name of the language "Prolog" comes from the words LOGIC PROGRAMMING(PROgrammation en LOGique in French and PROgramming in LOGic in English).

Prolog is based on such a branch of mathematical logic as predicate calculus. More precisely, its basis is the procedure for proving theorems resolution method For Horn clauses. The next lecture will be devoted to this topic.

In the history of the emergence and development of the Prolog language, the following stages can be distinguished.

In 1965, in the paper "A machine oriented logic based on the resolution principle", published in the 12th issue of the Journal of the ACM, J. Robinson presented a method for automatically finding proofs of theorems in first-order predicate calculus, called " principle of resolution". This work can be read in translation: Robinson J. Machine-oriented logic based on principle of the resolution// Cybernetic collection. - Vol. 7 (1970). In fact, the idea for this method was proposed by Herbrand in 1931, when there were no computers yet (Herbrand, “Une methode de demonstration”, These, Paris, 1931). Robinson modified this method so that it became suitable for automatic, computer use, and, in addition, developed an effective unification algorithm that forms the basis of his method.

In 1973, the "artificial intelligence group" led by Alain Colmeroe created a program at the University of Marseille designed to prove theorems. This program has been used to build natural language text processing systems. The theorem proving program was called Prolog (from Programmation en Logique). It served as the prototype for Prologue. Legend has it that the author of this name was Alan Colmeroe's wife. The program was written in Fortran and ran rather slowly.

The work of Robert Kowalski was of great importance for the development of logic programming. Predicate logic How programming language"(Kowalski R. Predicate Logic as Programming Language. IFIP Congress, 1974), in which he showed that in order to achieve efficiency, one must limit oneself to the use of a set Horn clauses. By the way, it is known that Kowalski and Colmeroe worked together during one summer.

In 1976, Kowalski, together with his colleague Maarten van Emden, proposed two approaches to reading logic program texts: procedural and declarative. These approaches will be discussed in the third lecture.

In 1977 in Edinburgh, Warren and Pereira created a very efficient Prolog compiler for the DEC-10 computer, which served as the prototype for many subsequent implementations of Prolog. Interestingly,

The lecture is devoted to solving problems using a state space graph. The state space is described in the form of a set of states - graph vertices, a set of transitions from state to state - graph arcs, a set of initial states and a set of final states. The solution to the problem is represented as a path on the state space graph connecting the initial state to the final state. If the state space of the problem is small, then all optimal solutions will be found using depth-first search. In problems with a large state space, only one optimal solution will be calculated through breadth-first search. Universal solvers are applied to problems. States in different tasks can belong to different domains. To remember the best solutions found, a “variable variable” varM is used. The compiler itself finds the necessary types. Visual Prolog version 7.5, not yet published. Its publication is planned for 2014, but the exact date is not yet known. Visual Prolog 7.4 is now available to everyone.

The appearance of Prologue was due to the development of logic, mathematics and programming. The latter played the most significant role. Specialists in logic and mathematics made an attempt to put programming on the “right path,” but the development of information technology showed a completely different result.

Pragmatic imperative programming turned out to be more promising. “Prolog” succeeded as a programming language, but did not become the basis for artificial intelligence.

Classical programming vs logic

A person makes difficult decisions logically and reasonably. Almost without thinking, a person acts wisely. If we do not take into account decisions that require collecting information, analyzing it and complex calculations, then any result is fast, accurate and reasonable.

This fact has always given an illusory reason to consider the creation of a decision-making tool to be a simple matter. With the advent of Prologue, it seemed that the issue of artificial intelligence was a matter of technology, and Homo sapiens came up with three laws of robotics. However, artificial intelligence remained a ghost, and the three laws of robotics turned out to be from a fairy tale - “do this, I don’t know what.”

Programming in the classical sense of the word (the terms “procedural”, “imperative” or “functional” are often used) has developed and successfully overcome the “troubled times” of the 80-90s, when there were countless programming languages.

The demonstration struggle between “Pascal” and “Si” lasted a long time and was brutal, but ended neutrally and quietly. What remains is the idea of ​​a good programming language and several successful implementations of it.

This is not to say that Prolog as a programming language has not evolved. But he did not achieve his stated goals. Today we can not only say, but also justify: “Prologue” is an academic language for:

  • learning objectives;
  • predicate logic;
  • mathematics;
  • narrow application.

It is doubtful that this assertion can be refuted. Artificial intelligence is not only widely used, but also a very serious event that radically changes the social structure and the picture of the world.

Programming in the Prolog language for artificial intelligence did not take place: for more than forty years of history of the language, there has not been a single radically new event that is relevant to the public consciousness, indicating the opposite.

The objective reality is this: it is not so much the strongest that survives, but rather what is in demand and relevant.

"Prolog" is a declarative programming language

Having a tool to describe facts and rules is good, but what's the point? Facts and rules fit perfectly into a regular database. A qualified classical programmer provides an interactive dialogue for the user, and the latter solves his problems.

If necessary, the programmer refines the dialogue, and the user supplements the database of facts and rules. An absolutely working and decades-tested option for implementing a mass of already solved and solvable problems.

A declarative presentation of facts and rules in any implementation of the Prolog programming language is a convention, an attempt to formalize reality in its intellectual state. Conventional programming does not touch the intellect. Classical programming is satisfied with the position: description and processing of data. There are a lot of problems here, but there are a lot of brilliant solutions that work.

"Prolog" as a programming language is the facts:

  • mother (Maria, Natasha); - Maria - Natasha’s mother;
  • dad (Evgeniy, Marina); - Evgeniy is Marina’s dad.

Here, a fact is immediately overboard: “Maria” and “Marina” are different names. Nothing prevents you from adding the fact:

  • dad (Eugene, Maria); - Evgeniy is Maria’s dad.

These descriptions give life to the rules:

  • parent(x,y)<- папа (x, y);
  • parent(x,y)<- мама (x, y);

But they do not allow us to conclude that dad is Marina’s father, and Marina is Maria’s mother. This problem can be solved; you can add one more rule, add one more fact. But how many of these actions should be taken in a real situation?

In fact, “Prolog” as a programming language is an example of a declaration of facts and rules, but not the logic to which the consciousness of a classical programmer is accustomed. "Prolog" positions itself as a predicate logic language, but you can learn programming in it only through examples and sample descriptions from the developers of a specific implementation of the language.

The Prologue Family

France is considered the birthplace of Prologue, and 1973 is the year of birth. Interest in the language was periodically renewed, but subsided with enviable stability. The motto of the language: “Predicate logic is elementary! This is a way to explain how thinking works” - and remained the motto.

Any implementation of the Prolog programming language strictly followed predicate logic, but always included classical ideas of procedural programming. It is more correct to say "imperative", since this term is used with more formality than procedural, functional, object-oriented, or other.

Any programming is about data and its processing. Language constructs must describe the problem being solved as accurately as possible, which is why all known implementations of Prolog: Turbo Prolog, Win Prolog, SWI Prolog, GNU Prolog, Visual Prolog and others contain, in addition to declarative constructs, ordinary imperative expressions.

It is believed that the Prologue family is developed in academic and research organizations and therefore can only be spoken of as a common language in a conceptual sense. Nevertheless, the very fact that the concept of “Prolog” is alive and developing can be considered: this language has a scope, and it is in demand in a certain range of tasks.

The basis of artificial intelligence

Interest in artificial intelligence has never waned, they just start talking about it when the next occasion arises, but Prolog has never been associated with artificial intelligence more than an ordinary classical programming language.

At the end of the 80s there was a real, relevant and popular intellectual project “The Inventing Machine”. There was a real attempt to use Prolog to formalize a huge practical knowledge base (data) on inventions, physical, chemical and other laws.

The result was not achieved; too many facts and rules had to be written in Prolog as a programming language, which were of a banal imperative nature. Meanwhile, a lot of successful software products were implemented in parallel in ordinary languages.

In the early 90s, a project of a real intellectual system was successfully implemented that simulated the behavior of a child under 3 years of age on an EU computer! The option of using Prolog was not even considered.

This intellectual system not only “figured out” what mom and dad were, and how Maria differed from Marina, but also, without much effort, independently jumped from the acquired knowledge on these issues to balls and their differences from cubes, to the colors of objects and... (!) to elementary mathematics: simple arithmetic operations turned out to be within her capabilities based on the knowledge acquired by solving completely different problems.

One cannot say that classical programming is ahead of Prolog in terms of mastering the territory of artificial intelligence, but it gives real results.

As for intelligence as a task, apparently the question here lies not in the language, but in the idea of ​​implementation. If the 1991 assembler could “become the basis” for an intelligent system of situational intelligence, then the issue clearly lies not in the implementation language, but in the idea.

Prolog programming language is one of the leading logic programming languages. It was created by Alain Colmerauer in the 1970s. It was an attempt to make a programming language for beginners that makes it possible to express logic, rather than carefully specifying what you want to achieve with instructions on a computer screen.

Prolog is used in many artificial intelligence programs, but its syntax and semantics are very simple and clear (the original purpose was to provide a tool for computer illiterate linguists). The name Prolog is an acronym for LOGIC PROGRAMMING and is widely known in teaching the basics of programming.

Prolog is based on predicate calculus (more precisely, first-order predicate calculus), but it is limited to Horn's formulas. Prolog programs are effective for proving theorems to a first approximation. Basic concepts of join, tail recursion and tracking.

Data types

Prolog does not use data types in the way that we are accustomed to in common programming languages. We can talk about Prolog lexical elements instead of data types, which is unusual in programming for dummies.

The constant text is entered using atoms. An atom is a sequence of letters, numbers, and an underscore that begins with a lowercase letter. Usually, if these are not alphanumeric atoms, then it is necessary to frame them with apostrophes (for example, "+" is an atom, + is an operator).

Most Prolog implementations do not distinguish between real and fractional numbers.

Variables

Variables are identified by a string consisting of letters, numbers, and underscores, starting with an uppercase letter. In the Prolog environment, a variable is not a container that can be assigned (unlike procedural programming languages). Its behavior is closer to a model that is similar to joins.

So-called anonymous variables are written as a single underscore (_).

Terms are the only way Prolog can represent complex data. The term consists of a head, also called a functor (which must be an atom) and parameters (not limited to types). The number of parameters, the so-called arities of the term, is important. A term is defined by its head and arity, usually written as functor/arity.
Lists

A list is not a standalone data type because it is defined by recursive construction (using the term /2 "."):

Atom - empty list

For the convenience of the programmer, lists can be constructed and destroyed in different ways.

If L is a list and X is an element, then "." (X, L) is a member of the list. The first element X followed by the contents of the context L is syntactically represented as.

For the convenience of the programmer, lists can be built and destroyed in different ways.

Item listing:
Preface of one element:
Preliminary several elements:
Term extension: "."(abc, "."(1, "."(f(x), "."(Y, "."(g(A,rst), )))))

Strings are usually written as a sequence of characters within quotation marks. They are often represented as lists of ASCII character codes.

Programming in PROLOG is very different from working with procedural languages. In Prolog you work with databases of facts and rules, you can run database queries. The basic unit of Prolog is a predicate that is defined to be true. A predicate consists of a head and a number of arguments. For example:

Here "cat" is the head and "tom" is the argument. Here are some example queries you can run using the Prolog translator based on this fact:

Cat(tom).
yes.

Cat(X).
X = tom;
no.

Predicates are usually defined to express a fact by which a program knows about the world. In most cases, the use of predicates requires certain conventions. So which of the following would mean that Pat is Sally's father?

Father(sally,pat).
father(pat,sally).

"father" in both cases is the head, and "sally" and "pat" are the arguments. However, in the first case, Sally is in first place in the list of arguments, and Pat is in second place and vice versa. The first case is an example of a definition in the order Verb Subject and Object, but in the second example the order is Verb Object Subject. Since Prolog doesn't understand English, both versions are fine, but it is considered good programming style to stick to one style, called a convention, while writing one program, rather than having to write something like:

Father(pat,sally). father(jessica,james).

Certain predicates are built into the language and allow Prolog to reduce the drudgery of everyday activities (such as input/output using graphics and other communication with the operating system). For example, write predicates can be used for display like this:

Write ("hello")

Will display the word "Hello" on the screen.

Rules

The second type of statement in Prolog is rules. Example rule:

Light(on) :- switch(on).

":-" means "if", this rule means light(on) is true (on) if switch(on) is true (else if switch is on then there is light). Rules can also use variables; variables begin with a capital letter while constants begin with lowercase letters. For example,

Father(X,Y) :- parent(X,Y),male(Y).

This means, "if someone is a parent and he is a man, then he is a father." Causes and effects can also be in reverse order, so this does not contradict ordinary logic. You can place multiple predicates in the consequence section by combining them together, for example:

Which is equivalent to several declarations:

A:- d. b:- d. c:- d.

But instructions like:

Which is the equivalent of "if c then a or b". This is due to the limitation imposed by Horn's formula.