Prolog first steps: predicates, metapredicates, lambdas

I first became interested in Prolog after I watched a talk by Joe Armstrong, creator of Erlang, in which he mentioned this small, niche language twice. The first time, he explains how took inspiration from the Prolog syntax to write Erlang’s. The secon…


This content originally appeared on DEV Community and was authored by P. Schreiber ๐Ÿง™๐Ÿปโ€โ™‚๏ธ๐Ÿ”ฎ๐Ÿ

I first became interested in Prolog after I watched a talk by Joe Armstrong, creator of Erlang, in which he mentioned this small, niche language twice. The first time, he explains how took inspiration from the Prolog syntax to write Erlang's. The second, he mentions that if he were to choose only 4 languages to learn, Prolog would be among them.

I have always found it super instructive to learn languages that are very distinct from one another. There isn't much to learn from a third dynamically-typed imperative language. But coming from, say, imperative to fuctional or, in this case, logical paradigm is quite the mind-bending experience. It makes us see things we think we know from a different angle, and provides new ways of expressing ideas and operations.

This is my first contact with logical programming, so everything here is basic and rudimentary. It is a first step in learning how logical programming works and why it is interesting.

Deductions

Prolog provides a very interesting functionality, one that I haven't seen in other languages. While all languages provide results for problems such as,

Let X = A, Y = B, what is the result R of X + Y ?

Prolog provides a way to find all possible values of variables that make a problem true. For example,

Let X + Y = R, what are the possible values of X and Y for which R = C

Our data set

In Prolog, we define relations between terms. These predicates are statements that evaluate to true. Let us define some.

% astrology.pl 

ruler(aries, mars). 
ruler(taurus, venus). 
ruler(gemini, mercury). 
ruler(cancer, moon). 
ruler(leo, sun). 
ruler(virgo, mercury). 
ruler(libra, venus). 
ruler(scorpio, mars). 
ruler(sagittarius, jupiter). 
ruler(capricorn, saturn). 
ruler(aquarius, saturn). 
ruler(pisces, jupiter). 

element(taurus, earth).
element(virgo, earth).
element(capricorn, earth).
element(aquarius, air).
element(libra, air).
element(gemini, air).
element(pisces, water).
element(cancer, water).
element(scorpio, water).
element(aries, fire).
element(sagittarius, fire).
element(leo, fire).

Undefined possible relations such as ruler(aries, pluto) evaluate to false.

Get sign with a certain element and ruler

Suppose we have two friends of whom we do not know the star sign, but we can imagine, from their personality, their ruler planets and elements. We can deduce their star sign based on those traits.

?- element(Sign, fire), ruler(Sign, sun).
Sign = Leo.

Alfred is has a fiery spirit and a sunny personality. By deduction, his sign is no other than Leo.

?- element(Sign, water), ruler(Sign, mars).
Sign = scorpio.

Beth loves the ocean, and is very combative, like the god Ares. By deduction, her sign has to be scorpio.

?- element(Sign, water), ruler(Sign, venus) .
false.

Charles is also loves the ocean, and is beautiful like Aphrodite. But there is no sign that fits this combination. Our assumptions about him must be wrong.

Get planets with a certain element

In our premises, we have not defined any direct relation between planets and elements. However, planets rule signs, and we can establish indirect relations. For example, we can ask for planets of the earth element; in other words, "what is the planet X that rules some sign Y of the earth element?"

?- element(Y, earth), ruler(Y, X).
Y = taurus,
X = venus ;
Y = virgo,
X = mercury ;
Y = capricorn,
X = saturn.

Prolog is telling us that Venus, Mercury, and Saturn are ruled by earth signs (taurus, virgo, capricorn). It is noteworthy in our dataset, while a single sign has a single element (1-n), a single planet may have multiple elements (n-n).

?- element(Y, air), ruler(Y, X).
Y = aquarius,
X = saturn ;
Y = libra,
X = venus ;
Y = gemini,
X = mercury.

We see that Saturn and Mercury are also air planets in this world.

(For the Sailor Moon nerds out there, it may be sad to learn that Mercury is not a water planet, nor Jupiter earth.)

Get elements of a planet

As we saw, a planet may have multiple elements based on its ruled signs. Let us try now to get the elements of a certain. This time, we will wrap those in a list, using the buit-in predicate findall/3.

elem(El, Planet) :-
    element(Sign, El), ruler(Sign, Planet).

?- findall(El, elem(El, mercury), Elements).
    Elements = [earth, air].

First, we wrap the query for elements of some planet in a function (more precisely, in a conditional predicate). Functions in Prolog are Horn clauses, a form of implication that reverses the position of p -> q to q <- p, or "q if p", in natural language.

We state that, "E is the element of a planet P if E is the element of a sign S, and the sign S is the ruler of the planet P".

Then we find the elements of the planet Mercury, and throw those in a list. The built-in predicate findall/3 evaluates all elements for which P(El, ...) is true, and appends them to a list of valid elements.

Metapredicates

Metapredicates are the logical programming equivalents of higher-order functions in functional programming. They are predicates that have predicates as conditions. The predicate findall/3 mentioned earlier is such an example.

Metapredicates are very useful generalizations on common operations. We may go beyond the metapredicates already predefined in the standard library, and define our own.

For example, suppose we want to judge whether all planets in a list of planets are rulers of some sign. We may define for that a predicate all_rulers, such as:

all_rulers([]).
all_rulers([P|Ps] :-
    ruler(_, P),
    all_rulers(Ps). ?- all_rulers([mercury, sun]).
true

?- all_rulers([mercury, pluto, sun]).
false

The predicate is defined recursively, and states simply that all planets are rulers if the first element of the list is a ruler, and all other elements are also rulers.

Judging whether all elements in a list are true according to some condition is so useful that we would be wise to define a general operation that accepts not just ruler/, but any condition.

ruler(P) :- ruler(_, P)

all(n[], _).
all([E|Es], Pred) :-
    call(Pred, E),
    all(Es, Pred).

?- all([mercury, sun], ruler).
true

Lambdas

We have an inconvenient limitation in our program: all/2/ only accepts as arguments predicates with arity 1 (i.e. accepting one argument). That is becase we make use of call(Pred, E), which applies the current element to the predicate.

To further generalize our metapredicate, we can make use of lambdas, anonymous predicates which allow us not only to use predicates of different arities, but also to define predicates on runtime (which is awesome).

Let's define another metapredicate any, which judges whether any element in a list is valid according to a condition.


any([], _) :- false.
any([E|Es], Pred) :-
    call(Pred, E);
    any(Es, Pred).

?- pack_install(lambda).
true.

?- use_module(library(lambda)).
true.

?- any([pluto, mercury, uranus], \X^ruler(_,X)).
true

?- any([pluto, uranus], \X^ruler(_,X)).
false.

The metapredicate any/2 is very similar to all/2, except that instead of using AND operators (,), it uses OR operators (;); in other words, any is true if the predicate for the first element is true, or if it is true for some subsequent element.

This time, we are not passing a predicate previously defined in compilation, but rather a dynamic predicate with a lambda (we install and require the lambda package first). Lambdas empower us to call a 2-arity predicate such as ruler/2 by wrapping it in an anonymous 1-arity anonymous predicate.

Conclusion

Prolog is an interesting language, with a mind-bending paradigm. In this article, we have explore some of its features, such as:

  • defining functions as Horn clauses;
  • finding multiple possible solutions to a problem by applying values to statements that evaluate to true;
  • generalizing particular predicates into metapredicates;
  • stating anonymous predicates with lambdas.

I hope you liked this article, and I look forward to exploring Prolog further. This is only my first or second day of using this language, so I apologize for any incorrect terminology or explanations. If you have any comments or suggestions, I'll be happy to read them.


This content originally appeared on DEV Community and was authored by P. Schreiber ๐Ÿง™๐Ÿปโ€โ™‚๏ธ๐Ÿ”ฎ๐Ÿ


Print Share Comment Cite Upload Translate Updates
APA

P. Schreiber ๐Ÿง™๐Ÿปโ€โ™‚๏ธ๐Ÿ”ฎ๐Ÿ | Sciencx (2024-06-30T00:11:24+00:00) Prolog first steps: predicates, metapredicates, lambdas. Retrieved from https://www.scien.cx/2024/06/30/prolog-first-steps-predicates-metapredicates-lambdas/

MLA
" » Prolog first steps: predicates, metapredicates, lambdas." P. Schreiber ๐Ÿง™๐Ÿปโ€โ™‚๏ธ๐Ÿ”ฎ๐Ÿ | Sciencx - Sunday June 30, 2024, https://www.scien.cx/2024/06/30/prolog-first-steps-predicates-metapredicates-lambdas/
HARVARD
P. Schreiber ๐Ÿง™๐Ÿปโ€โ™‚๏ธ๐Ÿ”ฎ๐Ÿ | Sciencx Sunday June 30, 2024 » Prolog first steps: predicates, metapredicates, lambdas., viewed ,<https://www.scien.cx/2024/06/30/prolog-first-steps-predicates-metapredicates-lambdas/>
VANCOUVER
P. Schreiber ๐Ÿง™๐Ÿปโ€โ™‚๏ธ๐Ÿ”ฎ๐Ÿ | Sciencx - » Prolog first steps: predicates, metapredicates, lambdas. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2024/06/30/prolog-first-steps-predicates-metapredicates-lambdas/
CHICAGO
" » Prolog first steps: predicates, metapredicates, lambdas." P. Schreiber ๐Ÿง™๐Ÿปโ€โ™‚๏ธ๐Ÿ”ฎ๐Ÿ | Sciencx - Accessed . https://www.scien.cx/2024/06/30/prolog-first-steps-predicates-metapredicates-lambdas/
IEEE
" » Prolog first steps: predicates, metapredicates, lambdas." P. Schreiber ๐Ÿง™๐Ÿปโ€โ™‚๏ธ๐Ÿ”ฎ๐Ÿ | Sciencx [Online]. Available: https://www.scien.cx/2024/06/30/prolog-first-steps-predicates-metapredicates-lambdas/. [Accessed: ]
rf:citation
» Prolog first steps: predicates, metapredicates, lambdas | P. Schreiber ๐Ÿง™๐Ÿปโ€โ™‚๏ธ๐Ÿ”ฎ๐Ÿ | Sciencx | https://www.scien.cx/2024/06/30/prolog-first-steps-predicates-metapredicates-lambdas/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.