Antipatterns of stability

In the last few weeks, I was reading the exceptional book Release It! Design and Deploy Production-Ready Software by Michael T. Nygard, this book is fantastic and I pretty recommend the reading for everyone, one of the chapters that have caught my attention was the part that he talks about patterns and antipatterns of stability.

System stability and availability is always a recurrent topic, it’s a mistake to think that errors will not occur, it always occurs and on the worst time. Based on this, you need to defend your system of common events that when occurs kill your application and user experience.

At this post, I’ll write my points of view about some systems stability antipatterns, some of these presented by Nygard at his book.

It’s important to note that I don’t show all the antipatterns presented by the author and that I made changes in some patterns to adapt to my point of view and explanation.

Antipatterns

We’ll talk about the antipatterns, they can fuck up your app if you don’t pay attention to them. Each of these antipatterns will create, accelerate or multiply or system failure.

Integration Points

All integration points is a risk to your systems, everyone can kill your operations or cause a headache to your team. And it’s important to remember that database call is an integration point too.

Let’s see an example, suppose that you have an application that needs to communicate with a 3rd party API that will give you essential information to your customer sign up, your customer can’t continue the registration flow while the external service doesn’t respond.

Integration Point Failure

You can find similar scenarios across multiple companies, on this image we have a lot of possible events that may cause an error in your operation. Most developers when first look at this image, will think “Ok, there’s a problem! If the external application goes down, I’ll have a 404 response, my system will crash and I’ll not have users register while they don’t come back.”. This assumption is true but isn’t the only problem. How your system will behave if…

  • The provider receives your request but never respond? If you don’t handle it, your user can wait forever!

  • The provider receives your request and responds after 60 seconds? It can occur if the 3rd API is facing a DDoS attack, an exceptional number of requests or database high percentage of use.

  • The response comes with a status code that you don’t know how to handle, like “423 Locked”. Probably you’ll get an error at your error tracking service.

  • The response comes with a content type that you don’t know how to handle. It will go to your error tracking service too.

  • And finally, you can get your response. But the response doesn’t come with the information that you expects. Imagine that you’re waiting for a JSON with the key “name”, but the JSON came without this key, what will happen on your application? If you don’t handle it, probably you’ll get an error trying to access this key. And again you’ll have a new error at your exception tracker.

Integration points are the number one risk of your application stability, but it’s unavoidable, today most applications are composed of microservices architecture and SaaS APIs, this is the main reason that I don’t consider it as an antipattern, for me the antipattern is each problem that came with each integration point.

Each of the problems described can give rise to a different antipattern, and you need to treat and don’t let it warm your system, the antipatterns can be named as:

  • The endless request
  • The long request
  • The unexpected response code
  • The unexpected content type.
  • The unexpected content.

A lot of patterns that I’ll describe above (at “Patterns of Stability” section), can help you against each of these problems, for example, the famous circuit breaker pattern.

Every integration point will fail, and you need to be prepared.

Cascading Failure

Check my last posts:

A cascading failure occurs when an error in one system affects others, with the initial failure walking down into your systems layer causing other errors.

Today majority of our applications are composed of microservices communicating between each one, and each service has its own dependencies, like a database, Redis and other services, each service has it’s callers too, which probably depends directly on its stability.

Microservices communicating between each other

What will happen if one of these services goes down or have a bug that makes the service unable to respond to one endpoint incoming requests?

Fail communication between services

Of course, the callers of these endpoints will have problems too, but how they handle it will define its future, or it will fail and start a cascading of failures or it will handle it correctly and don’t start a crisis in your system.

This problem is similar to problems related to integration points, but it’s more about the mash of your systems itself. Circuit Breakers and failure modes can defend your system against this kind of problem, you shouldn’t trust your system stability, always be ready for any issue, because it will always occur.

Users

Don’t store user sessions in memory, if you have a lot of users and crawlers navigating on your website, it can start an out of memory problem on your application.

Blocked Threads

Follow my blog to get notified every new post:

Blocked Threads is a point of attention, many failures like the chain of reactions and cascading failure start with a blocked thread. Like cascading failures, it usually occurs around a resource pool and integration points.

Use timeouts, especially on database connection to avoid problems with blocked thread. If you use any ORM it should already implement a friendly way to set timeout and threads pools on databases, ActiveRecord does it.

And obviously, use circuit breaker timeout on callers too.

Self-denial Attacks

Self-denial Attacks occur when someone tries to kill your own website, it’s like a suicide!

Let’s see an example: Your marketing pays U$5M for LeBron James tweet something about your company, but they don’t tell anything to technology guys… What will happen when he sends the tweet for 40M people? Of course, your website will be a burst of visitors, and how it will behave with this? And if I tell you that your marketing team asked LeBron to tweet a deep link to a promotion, your application will still available?

Good marketing can kill your system, to prevent this kind of situation communication is the key factor, create static landing pages for users first interaction is recommended, and remember, never send deep links that bypass your CDN.

Shared Resource

If you have a many-to-one or many-to-few resource relationship you probably will have a side effect when scaling. Let’s see a famous example, you have three applications using the same Redis:

Three services using the same redis

If you increase by 2,3,4…x the number of services using this Redis instance, probably you’ll start to have a bottleneck.

Seven services using the same redis

To avoid this kind of problem, on the book Michael T. Nygard propose a “shared-nothing” architecture by reducing the shared resources, reducing the number of services calling the shared resource.

Each service with a unique resource

Dogpile

Let’s suppose that you are working for a big newspaper and the homepage executes a big query to list all the latest news by relevance, this query takes 6 seconds on average. You’re a good engineer and decides to use Memcached to stores this query result, after this the query is only executed to the first user to hit the homepage, after this your application stores the result on Memcached and the next users will have an instant response from cache, it’s working.

But what will occur when this cache expires? If your application is expiring the cache every five minutes, your query will be executed again every 5 minutes. If you have only one concurrent user it’s not a problem, but let’s imagine if you have four concurrent users, 24 requests will hit your server and executes the same query that consumes high CPU usage. Depending on the size of your application and the number of concurrent users, it can be harmful.

It is the most famous kind of dogpile and the solution is to code a “smart cache system”, you can find this solution on the internet for your favorite language.

Another common type of dogpile is with cached assets on your CDN, pay attention when you invalidate it, if you have all your user base hitting the CDN to view a common image or asset and you invalidate it, all these users will hit your server directly.

Slow Responses

Slow responses are worse than a quick failure, it can be a result of excessive demand, or can also be a symptom of a problem like memory leaks or lack of a server. Slow responses can trig a cascading failure on the caller services (if they don’t implement timeout) or result in more traffic if you have users waiting for responses on your frontend.

To avoid this kind of problem, fail fast is the solution, every time that your system is slow it’s preferable to send an error. Don’t forget to use timeouts on the callers too.

Unbounded Result Sets

Most applications don’t limit a query on the database, sometimes you can be surprised by a query that would return hundreds of results returning a million and your application crashing, this is a small antipattern but pays attention to your query, always limit them and use pagination.

This pattern avoids slow responses and together with timeouts, it can help avoid cascading failures Improves overall system stability.

Conclusion

Stability and resilience are essential nowadays, the antipatterns that I wrote at this post is not all, and they don’t prevent all possible failures, this topic is a vast ocean of knowledge and you can’t stop studying.

No system is perfect, all systems have failures and you need to work to prevent it, but don’t fall into the trap of perfection, you as a developer need to be pragmatic, and sometimes some solutions are over-engineering for your objective.

Final thought

If you have any questions that I can help you with, please ask! Send an email (otaviopvaladares@gmail.com), pm me on my Twitter or comment on this post!

Follow my blog to get notified every new post:

Types of Memory Allocation, a brief view

A few months ago, I started a series of posts about important topics of C programming and computer architecture, the first post was about pointers and you can check here, on this post I’ll talk about types of memory allocation.

I’ve many criticisms about some ways that people usually teach C programming, one of these is that is very difficult to find someone that explains the difference between each type of variable and allocation, they usually only say “that is a variable and use it” or “look, this is a malloc(), start using it”, on this text I’ll try to show the difference between each type, for those who didn’t learn it learn and for those who learned it remember it!

This is a topic that I see few authors writing about, and I think few people have learned about this while studying C programming, on this post(and on the next talking about C memory layout), I hope I help people understand better this part of computer programs.

Types of Allocation

Follow my blog to get notified every new post:

Automatic Memory Allocation

How to use

Automatic memory allocation corresponds to the automatic variables, also known as “stack” memory, it’s memory allocated at runtime when you enter into a new scope, each time that a function is called it’s auto variables are pushed to the stack.

Worried because you don’t know what is the stack, don’t panic, this will be explained on the next post.

What it really means? An auto variable is every variable that you declare and doesn’t use any keyword (like static), simplifying, variables that you declare inside your main function or inside any function can be considered auto variables, therefore, automatic memory allocation.

#include <stdio.h>


int main() {
    int a = 1;
    int b = 2;

    printf("Sum: %d", a+b);

    return 0;
}

In the previous example, both variables a and b are auto variables. It’s important to remember that in C you have the keyword auto to specify this kind of variable, but by default every variable inside a block/scope it’s an auto variable, so you don’t need to use this keyword.

This example is the same as the previous:

#include <stdio.h>


int main() {
    auto int a = 1;
    auto int b = 2;

    printf("Sum: %d", a+b);

    return 0;
}

Variables declared inside scopes are auto too:

if (a < b) {
    int c = 10;
}

The lifetime of automatic variables is only during the execution of its scope/block when the function/block is called the variable is pushed to the stack and start your life, after the end of the function/block it is popped off of the stack and doesn’t exist anymore.

void anyThing() {
    int autoVariable = 10;

    autoVariable += 10;
}

int main() {
    anyThing();
    /* The variable autoVariable doesn't existis here */
    /* it only exists inside its function*/

    return 0;
}

It can look obvious to the majority of programmers but I think that few ask themselves about why it occurs.

Summarize

Every variable declared without any keyword(or auto keyword) at any function will be considered “auto” variables, and will be automatically allocated during runtime of the software at memory using the program’s stack, this kind of variable lifetime is only during the execution of the function block or scope, after this, the variable is pushed out of the stack.

Static Memory Allocation

Static variables are another type of variables and memory allocation, the major difference is that they preserve its value, they aren’t created/destroyed each time that your program calls a function. It corresponds to file scope variables and local static variables, their lifetime is the lifetime of the program.

How to use

To declare a static variable, the only thing that you need to do is to use static keyword, as the following example:

static int age = 18;

This characteristic can be used to do interesting things, the variable is not destroyed when your software get out of the scope, so you can use it to count how many times one function is called, this is the most popular example of static variables:

#include <stdio.h>


void count() {
    static int counter = 0;
    counter++;
    printf("Counter = %d\n", counter);
}

int main() {
    count();
    count();
    count();
    count();

    return 0;
}

The scope of a static variable is the scope of the function, the only difference is that they aren’t destroyed on the final of the function call, if you try to access a static variable outside of its scope you’ll get a compilation error.

They are allocated on compile time that fixes their addresses and sizes (so, the executable of the software already have the location and size of these variables), the name “static” is because they do not vary in location or size during the lifetime of the program (because the compiler already fixed it at executable).

It’s important to know that they aren’t stored at stack like automatic allocation, or at the heap (like the dynamic allocation that we’ll see below), this kind of variable is stored in the data segment of the programs address space if they are initialized or the BSS segment if they aren’t initialized.

Worried because you don’t know what is BSS/Data Segment/Stack/Heap? Don’t panic, this will be explained on the next post.

The compiler fixes the address and size of the static variable at compile time, so a static variable can only be initialized using constant literals, because the compiler needs to know the value of the variable, you can’t initialize a static variable with a returned value of a function for example, the following program will generate a compile error:

#include <stdio.h>


int initializer(void) {
    return 50;
}

int main() {
    static int i = initializer();
    printf(" value of i = %d", i);
    getchar();

    return 0;
}

Some people can think that static variables and global variables are the same things, but they aren’t, they have different scopes, you can’t access static variable of one function int count() inside the function int sum(), while the global variable can be accessed in any function. But some question may appear, like, if we put a static variable on the global scope, it will be the same as a global variable? and the answer is no. Let’s take a look:

#include <stdio.h>


static int counter x;
int counter y;

int main () {
  // anything
}

On this example, we have two global scoped variables but the x is of the static type, now you can ask me, what’s the difference? x will have static linkage (file scope), the variable is only accessible in the current file, while the y has an external linkage and you can refer to this variable if you declare it with extern in another file, both variables follow the same rules to be stored (as I described before).

Summarize

Static variables are statically allocated and their size and addresses are fixed at compile time, the major difference is that it preserves its value, they aren’t created/destroyed each time that your program calls a function, they have function scope and are stored at data/BSS segment.

Dynamic Memory Allocation

The famous dynamic memory(aka DMA) allocation that scares a bunch of people at the college, it isn’t brain surgery and I’ll prove to you, dynamic memory allocation can be very interesting and fun if you really understand it from the beginning.

Reinforcing the importance of pointers to dynamic memory allocation, I suggest that you have a solid knowledge of pointers, you can read any tutorial on the internet, or the one that I have here, on my blog.

Different from previous examples, dynamic memory is allocated on the heap, that I’ll explain in details on next post.

To dynamically allocate memory in C language(this part its different from C++), you need to include stdlib.h to have access to functions that C provides to dynamic allocation, you can check all functions that you’ll gain access here but on this post, we’ll only take a look at only four of them:

void *malloc(size_t size);
void free(void *ptr);
void *calloc(size_t nmemb, size_t size);
void *realloc(void *ptr, size_t size);

malloc()

Check my last posts:

Let’s start with void *malloc(size_t size) probably one of the most famous functions of computer science. It allocates n bytes of memory and returns as a pointer, it’s important to be careful because n needs to be the exact number of bytes that you need to store your data, for example, if we want to store simple information of the type int as we remember we’ll need 8 bytes, so, you pass 4 to the malloc() and it’ll return a pointer to the first byte of this block of memory:

int *number = malloc(4);

Now your variable number is a pointer to a block of 4 bits of memory, the necessary to store an integer:

#include <stdio.h>

#include <stdlib.h>


int main () {
    int *number = malloc(4);

    *number = 1234;

    printf("%d", *number);
}

If you try to store a number that has more than 4 bits you’ll get an overflow error.

You probably are asking yourself if you’ll need to know the size of each data that you’ll store, and fortunately, the answer is no, you don’t have to know all the data size, we have a function that returns the data size and is called sizeof(), to use it is very simple, just pass the variable type(or a variable of the type) that you want. Combining it with the previous malloc() you’ll have great power in your hands.

#include <stdio.h>

#include <stdlib.h>


int main () {
    int *number = malloc(sizeof(int));

    *number = 1234;

    printf("%d", *number);
}

If you need to create an array dynamically just multiply the size by the number of items of your array, for example, if you want an array of 10 ints, just do that:

int *numbers = malloc(sizeof(int)* 10);

free()

Another important function from stdlib.h is free(), it’s so important to your memory management and if you forgot to use free() you’ll have a memory leak. Simplifying, C programming language doesn’t have a garbage collector, it means that all memory that is dynamically allocated don’t get destroyed by the language in runtime, and you need to manage memory use by yourself while coding if you allocate a new memory using malloc() when you stop using this variable you SHOULD free it.

#include <stdio.h>

#include <stdlib.h>


int main () {
    int *numbers = malloc(sizeof(int) * 10);

    for(int i = 0; i < 10; i++) {
        numbers[i] = i + 10;
        printf("%d\n", numbers[i]);
    }


    free(numbers);
}

calloc() and realloc()

We have also two more functions to discuss here, calloc() and realloc(), they are very simple if you understand the concept of malloc() let’s start with calloc().

calloc() is equal to malloc() with two differences: calloc() it initializes all values of your block with 0 while malloc() initializes each block with garbage values, and it takes two arguments, the number of blocks to be allocated and size of each block, with this, if you want to allocate an array of 10 ints, you don’t need to multiply 10 by the size of each block, you just need to pass ten as argument.

int *numbers = calloc(10, sizeof(int));

realloc() as the name says you can re-allocate a memory previously allocated using in other words, if you have an array previously allocated with 5 ints using malloc() and you want to resize it to 10 ints, you can use realloc(). To use it, you only need to pass the previous pointer and the new size. Using it, you’ll resize the allocated space on the heap.

int *numbers = malloc(sizeof(int)* 5);

int *newNumbers = realloc(numbers, sizeof(int)* 10);

I’ll not enter in details of how to use malloc(), realloc(), calloc() and free because isn’t the objective of the text, on a future post I’ll only write about how to use this functions with mastery.

Why use DMA?

Follow my blog to get notified every new post:

I think one of the most common doubts among students is “Why did I need to use dynamic memory allocation, I don’t need it!!” or something like “Why did I need another way of creating variables?”. The most common case to use dynamic memory allocation is when you don’t know the input on compile-time and need to manage memory at runtime of the program, what it means? For example, you have to store n integers from the user’s input and you don’t know how many integers the user will store on the compile-time, in this case, you have three ways…

You can create a large array of integers as in the following example we use int numbers[500], the trade-off of this way is that if your user store less than 500 numbers you have a memory leak, because a smaller array would be better, and if your user wants to store more than 500 numbers your software wouldn’t support it.

#include <stdio.h>


int main() {
    int numbers[500];
    int counter;

    printf("How many numbers you will store? ");
    scanf("%d", &counter);

    for(int i = 0; i < counter; i++) {
        printf("Enter with number %d: ", i+1);
        scanf("%d", &numbers[i]);
    }

    /* any logic .. */

    return 0;
}

The other way is to use variable-length arrays (also called VLA), this solution is very close to the previous, the only difference is the use of VLA when creating the array.

#include <stdio.h>


int main() {
    int counter;

    printf("How many numbers you will store? ");
    scanf("%d", &counter);

    int numbers[counter];

    for(int i = 0; i < counter; i++) {
        printf("Enter with number %d: ", i+1);
        scanf("%d", &numbers[i]);
    }

    /* any logic .. */

    return 0;
}

It partially solves our problem, we won’t waste memory but use VLA is controversial and if you search on the internet (and I encourage you to search) you’ll find a lot of people talking about why you shouldn’t use VLAs. But we have two main problems with this solution, the first is that our array will be automatically allocated, it means that it will be allocated on stack memory, this is a problem because stack memory is not a large memory and if you try to allocate a large array you’ll get stackoverflow error, other problem, as you know, is that automatic variables only exist on the current scope. Another small problem with this solution is that VLA was introduced on C99 and old compilers will not compile it.

The other solution is to use dynamic memory allocation with malloc() to reserve a block of memory with the exact size that we need, this is the best solution is almost all cases:

#include <stdio.h>

#include <stdlib.h>


int main() {
    int counter;

    printf("How many numbers you will store? ");
    scanf("%d", &counter);

    int *numbers = malloc(sizeof(int) * counter);

    for(int i = 0; i < counter; i++) {
        printf("Enter with number %d: ", i+1);
        scanf("%d", &numbers[i]);
    }

    /* any logic .. */

    free(numbers);
    return 0;
}

This is the best solution and it’s using DMA in the right way, you’re using heap memory and you have full control of when you want to free this block of memory using free(), another good thing is that you can use realloc() if you want to resize our block.

Summarize

The necessity of dynamically allocated memory is a reality on everyday programmers day, you’ll need to know how to use malloc() to allocate heap memory at runtime, the advantages are many, you have full control of your memory, you choose when you want to free this memory, and you gain control over memory usage of your software.

Conclusion

Understand the difference between each type of memory allocation is good to understand correctly how your C software works under a microscope, on this post we discussed about each type and on next post we’ll talk about memory layout of C programs, with both knowledge, you’ll have a complete understanding of this part of C software and will write and understand your software better.

Unfortunately, this is a part of programming that I see few authors writing about, on this post and on the next I hope I can help people understand the software better.

Final thought

If you have any questions that I can help you with, please ask! Send an email (otaviopvaladares@gmail.com), pm me on my Twitter or comment on this post!

Links

Misc

What’s the overhead of using VLAs

How to use VLAs

C data types

Dynamic, static and automatic memory

Difference between automatic, static and dynamic variable

Types of variables

Dynamic memory allocation

Wikpedia of dynamic memory allocation
What is dynamic memory allocation
C dynamic memory allocation
Differente between static and dynamic memory allocation
C function malloc
stdlib.h
Nice guide about malloc

Static memory allocation

Static memory allocation
Static variables in C
Wikipedia page of Static variable
Difference between global and static global
Difference between the global and static variable in C
Static vs Global variables
Difference between the global and static variable in C
Local global and static variable

Follow my blog to get notified every new post:

Logic Programming

Let’s talk about logic programming, I think everybody who completed the college or study computer science by yourself (like me), already have heard about logic programming, what it’s exactly? When talking about programming we have a lot of paradigms of programming languages and logic is one of them, but unfortunately isn’t very popular, to be sincere Prolog is most used by academia. But don’t worry learn logic programming can be good to expand your knowledge and see things from other perspectives, understanding a new paradigm of programming is a new way of thinking.

In this post, I’ll talk about what I’ve liked on Prolog and how to get started.

Warning

  • I’m not an expert of Prolog
  • This post doesn’t have advanced content
  • Every example of this post will be written in Prolog
  • This post has a strong theoretical content, if you don’t like, feel free to jump to "First Steps" paragraph.

“The inception of logic is tied with that of scientific thinking. Logic provides a precise language for the explicit expression of one’s goals, knowledge, and assumptions. Logic provides the foundation for deducing consequences from premises; for studying the truth or falsity of statements given the truth or falsity of other statements; fir establishing the consistency of one’s claims; and for verifying the validity of one’s arguments.” – Sterling, 1986 The art of Prolog.

What is logic?

I think the key to understanding logic programming is not your background in computer systems, the key is your knowledge of philosophy, you need to know and understand what is the Aristotelian logic, I’m not a philosopher so I’ll try to explain from my point of view on the simplest way, not going deep on advanced topics, only a resume.

Let’s go back to our high school and talk about mid 350 B.C, Aristotle the Ancient Greek philosopher developed something named term logic aka traditional logic or Aristotelian logic.

Aristotle

Warning: If you want only the hands-on part, stop here and go to “First Steps”.

Aristotle’s logical work is collected in the six texts that are collectively known as the Organon. Two of these texts, in particular, namely the Prior Analytics and De Interpretatione, contain the heart of Aristotle’s treatment of judgments and formal inference, and it is principally this part of Aristotle’s works that is about term logic.

Aristotle

The fundamental assumption behind the theory is that propositions are composed of two terms, where terms is a part of speech representing something, and that the reasoning process is in turn built from propositions.

Propositions need to follow the Three Laws of Thought.

  • Law of Identity, A is A. Everything is the same as itself.
  • The Law of Noncontradiction, NOT ( A and not A) – Nothing can both exist and not exist at the same time and in the same respect, or no statement can be both true and false.
  • Law of Excluded Middle, EITHER (A or not A) – Something either exists or doesn’t exists, or every statement is either true or false.

This reasoning process is often called syllogism (“conclusion, inference”), that is when you apply deductive reasoning to arrive at a conclusion based on two or more propositions that are asserted or assumed to be true.

The syllogism is basically one conclusion based on prepositions.

When talking about syllogism, the most common example is the one given by Socrates.

All men are mortal.
Socrates is a man.
Therefore, Socrates is mortal.

Each syllogism consists of three parts:

Major premise
Minor premise
Conclusion

In the rest of this text, you’ll learn that Prolog can do that, based on fact and rules.

This is only a simple resume of what is logic and syllogism, if you felt interested, you can continue studying by yourself.

“Logic is an instrument for advancing knowledge”

What is Logic Programming?

Most programmers at day to day work deal with imperative languages, the main characteristic of imperative languages is the way that you change the programs state giving a statement, step by step (How to).

Programs written in a logic programming languages, computation is dealing with relations rather than with single-valued functions, these relations are defined by a set of rules about some problem domain and these rules are written by the programmer, this concept leads us to one of the main characteristics of logic programming:

“Logic programming is composed of two things, the logic, and the control.”

The logic component is the definition of the problem while the control is more like the way to get the solution, the rules.

We can define a logic programming algorithm by the following formula:

Algorithm = Logic + Control

Where “Logic” represents a logic program and “Control” represents different theorem-proving strategies.

Logic programming is a type of programming paradigm which is largely based on formal logic, that’s more like “What is”, with you asking the computer for answers, it is known as “declarative programming”.

So, in a simple conclusion, logic programming is much like telling the system the problem, the rules based on formal logic, the facts, and asking for the answer (declarative) than giving a step by step instructions to solve the problem.

What is Prolog?

Follow my blog to get notified every new post:

It’s hard to talk about logic programming without talk about Prolog. Prolog is a logic programming language based on first-order logic and formal logic, designed in 1970 by Alain Colmerauer. The program logic is expressed in terms of relations, represented as facts and rules. A computation is initiated by running a query over these relations. Today, I think Prolog is the most popular logic programming language.

The name is a French abbreviation for “Programming in Logic”.

First Steps

All the pillars of logic programming inherit from logic (that we studied above), terms and statements.

We’ve three basic statements: Facts, Rules and Queries and a single data structure called Logical Term

Facts

The simplest kind of statement in Prolog is called fact, and we’ll start our study talking about it.

Fact is basically the relation the objects hold between each other:

mother(elizabeth, charles).

This is the most basic example of the fact, it holds the relation between Elizabeth and Charles a tell that this relation is a mother.

We say atoms to refer to the name of the things that the predicate is telling the relations, on this example, Elizabeth and Charles are both atoms.

You can also speak predicate, fact, and predicate means the same.

Note that both predicate and atoms start with a lowercase letter, the reason we’ll talk soon.

A set of facts can describe a situation or a series of relations, which will be used by Prolog to execute computations.

In Prolog, you need to use dot to say that you finished your statement, don’t forget the dot.

With facts we can define simple relations, for example, a family tree, this example is considered the “Hello World program of Prolog”, and that’s what we’re going to do now.

For this example, we’ll use the left side of the Britsh royal family tree. (We’ll use only the left side because the entire tree is too big, and would escape the main goal of this text).

Left side of royal family tree

Ok, take a look at this tree, how many facts can we define? I think that we can define a lot of predicates, since parental relations till dates like birth or marriage.

To keep this example as simple as possible, let’s define only three, mother, father, male/female.

female(elizabeth).
female(charlotte).

male(philip).
male(harry).
male(george).
male(louis).
male(charles).
male(william).

father(philip, charles).
father(charles, william).
father(charles, harry).
father(william, george).
father(william, charlotte).
father(william, louis).

mother(elizabeth, charles).
mother(diana, william).
mother(diana, harry).
mother(catherine, george).
mother(catherine, charlotte).
mother(catherine, louis).

You can download this fact [at this gist.

A little bit big, right? Now imagine if we wrote all the facts about the royal family, like dates, marriage, etc.

Now would be fabulous if we can consult these facts, would it?

Queries

Queries are the second form of a statement in logic programs, they are the way to retrieve information from facts. We can also speak the goal.

A query asks Prolog what’s the relationship between objects, for example, we want to know if Charles is the father of William, just ask for Prolog:

?- father(charles, william).

During this text every time that you see ?- before a statement is because we’re working on query context.

And Prolog will return true, and it will return false with we ask something that’s not true:

?- father(diana, william).

One nice trick is to think like we’re asking a question, and Prolog will respond based on facts that it already knows, this is possible because we’re working with declarative programming.

The prolog interpreter

When working with simple problems like this, we usually load our prolog file into Prolog interpreter to start querying, assuming that you’re using SWI-prlog, you’ve two ways:

  • Start prolog shell using swipl and after this load prolog file writing consult('path/to/file.pl').
  • Already loads swipl with your database, using -s option, for example: swipl -s royal_family.pl

Some useful commands that can help you in your Prolog journey:

  • halt. closes your interpreter.
  • listing. shows facts and rules loaded.
  • help. obviusly.
  • assert(fact). adds fact to your base.
  • retract(fact). removes fact of your base.

Don’t feel scared, this is like any REPL of an interpreted language.

This aspect of Prolog can look strange and make some people feel confused at the beginning but don’t worry.

Syntactically both queries and facts can look the same, but you can easily differ by the context.

The logical variables

Related Posts

Unlike facts or queries, variables aren’t a statement, but we need to talk about it too.

Variables in Prolog is very different from other languages, they don’t store a specific value at is memory, so, the first step is to stop thinking that variables are to store values, not here. Variables in logic programming stand for an unspecified entity and the interpreter will try to instantiate the variables for us respecting the facts previously defined. Let’s understand it better by example, imagine that you want to know who is William’s children?

?- father(william, X).

Remember, this is query context, not fact context.

The first thing we note at this query is that for the first time, we’re using uppercase letter at X, this is because variables in Prolog start with an uppercase letter. This query now has a variable, what’s it means?

If we run the previous query, you’ll get the following result:

X = george

Ok, Prolog has solved it for you, they found that William is the father of George, now he’s telling you that, but… William is father of more children and Prolog has returned only one, simple, when Prolog is promoting something to you and your variable can have more than one result, you can press dot for end your query (signaling to Prolog that this answer is ok for you), or you press semicolon to go to the next answer (this doesn’t work when Prolog found only one possible answer).

?- father(william, X).
X = george ;
X = charlotte ;
X = louis.

Prolog gives to us all possibles value for X.

This can look very hard, but it isn’t when talking about rules this can look more simple. One way to better understand what we’re asking to Prolog is to read the query like:

“Does there exist an X such that William is the father of X?”

Rules

Rules are the third and the most important statement of Prolog.

Rules are the way of define patterns/rules to Prolog make decisions based on facts previously defined. Let’s think about, on our base we’ve all the information about father, moms, and sex. We’re humans and if our intelligence we can make conclusions based on these facts, Prolog can make conclusions too, but we need to teach how to make these conclusions.

For example, we can define who is grandparents of each other, right? What is the rule for define grandparent?

Grandparents Rules

The rule is simple, for someone to be your grandfather, he needs to be the father of your father, right? How do we define that in Prolog? Simple, we create a rule, it will be called grandfather.

grandfather(X, Y) :-
father(X, Z),
father(Z, Y).

We can read this rule like this:

For all X, Y. X is the grandfather of Y, if X is the father of Z and Z is the father of Y.

Now if we reload our base at Prolog interpreter, we can use our new rule! Let’s try it:

?- grandfather(X, louis).
X = charles.

Nice, we have found Louis grandfather and it’s Charles. How our rule behaved when we asked who is the grandfather of Louis?

First, of step, Louis on our rule is the Y, so every Y becomes Louis.

grandfather(X, luis) :-
father(X, Z),
father(Z, louis).

The second step, solve father(Z, louis). and found that Z = william.

grandfather(X, luis) :-
father(X, william),
father(william, louis).

The last step, now fallowing your defined rule, we need to solve father(X, william). to find who is the grandfather of Louis, the answer is X = charles, and we have found our goal.

grandfather(charles, luis) :-
father(charles, william),
father(william, louis).

It’s not that hard, right? The most interesting thing about this rule is that it can find grandchildren too, just replace X by the name of grandfather and find all grandchildren:

?- grandfather(philip, Y).
Y = william,
Y = harry

And obviously, we can make assertions without variables:

?- grandfather(philip, william).
true

You can use one rule to define another rule, for example, you can use grandfather/2 rule, inside the great-grandfather rule.

greatgrandfather(X, Y) :-
father(X, Z),
grandfather(Z, Y).

With this power, you actually can build nice things using logic programming.

Now we know the three states of logic programming, and solved the most basic exercise of Prolog, the “family tree”, this problem as I said, is like the “hello world” of Prolog.

With our current knowledge, we can rewrite the most famous example of a syllogism that we discussed above in Prolog:

All men are mortal.
Socrates is a man.
Therefore, Socrates is mortal.

mortal(X) :- man(X).
man(socrates).

...

? - mortal(socrates).
true

Solving Four color theorem

Check my last posts:

The four color theorem is a nice example of something that would use a lot of lines to be completed in most common programming languages like Java or Python that in Prolog consume only a few lines of code.

The four color theorem is a theorem of mathematics. It says that in any plane surface with regions in it (people think of them as maps), the regions can be colored with no more than four colors. Two regions that have a common border must not get the same color. They are called adjacent (next to each other) if they share a segment of the border, not just a point. Interested? Read more about it here.

On this example, I’ll paint the map of an imaginary country that has only five states, I think that’s enough for this exercise.

Map

To get started, the best thing to do is to define the facts, we can start defining the four colors of our map. What colors do you like? Choose four.

color(black).
color(byzantine).
color(sapphire_blue).
color(screamin green).

With the colors of our map defined, it’s time to define the rule of the problem, two adjacent states can’t have the same color. We will need to use the =/= not equal operator.

We’ll create a rule that says "if two states are neighbors they don’t have the same color"

adjacent(state1Color, state2Color) :-
color(state1Color), color(state2Color),
state1Color =/= state2Color.

And now map all states that are adjacent to each other, defining a new rule called country/5.

country(A, B, C, D, E) :-
adjacent(A, B), adjacent(A, C), adjacent(A, D),
adjacent(B, E), adjacent(B, C),
adjacent(C, D), adjacent(C, E),
adjacent(D, E).

Note, if we already defined adjacent(A, C) we don’t need to define adjacent(C,A).

If you open your prolog shell now and call your country rule, you’ll get the output with the colors needed.

?- country(A, B, C, D, E).
A = black,
B = D, D = byzantine,
C = sapphire_blue,
E = screamin_green

If we paint our map again based on Prolog output.

Colored Map

And the problem is done, you can replicate this problem to every map and we’ll have a correct answer.

One courious think about this problem, is that it was the first major theorem to be proved using a computer.

My conclusion about logic programming

Follow my blog to get notified every new post:

On the last months I’ve been studying logic programming and I’m loved it, it opened the doors for a new way of thinking and the way of logic programming works has fascinated me.

Unfortunately, as I said, my feeling is that logic programming and Prolog is most used in academia, when I search for big cases of use, I don’t find many things.

It’s very funny to solve a lot of problems like four color theorem or N-queens problem using Prolog, I think Prolog shines on that kind of problem, I tried to build an API using prolog, it’s possible, but it very complex, it’s not a thing that you’ll choose over tradional languages.

The best thing in Prolog that gained my attention is the capacity of query over the database of facts, for me, it’s incredible how prolog solve and express queries, on this cases, Prolog for me is very straightforward and powerful.

My conclusion is that Prolog is worth learning to open your mind and learn new things, the documentation is good and community too.

What’s next?

If you feel interested in Prolog, you can continue studying by a lot of ways, while writing this post, I was reading Art Of Prolog and it was very good. On the internet, you can find a lot of excellent tutorials, and an official site of SWI-Prolog you can find the documentation and tutorials.

Here’s my list of interesting resources to keep studying Prolog:

Final thought

I’m glad if I helped you understand Prolog or remember it, I hope you enjoyed.

If you have any question that I can help you, please ask! Send an email (otaviopvaladares@gmail.com), pm me on my Twitter or comment on this post!

Appendix

Execute Prolog without installing it

Just enter on this site https://swish.swi-prolog.org/ and start using, on the left side your base and at right bottom corner your queries, just click on "run" and the magic begins.

Reference / Useful Links

Follow my blog to get notified every new post:

Pointers, a brief view

Some weeks ago I was reading Pat Shaughnessy, Ruby Under a Microscope that is an excellent book about all the engineering behinds Ruby language, and when reading, sometimes I was feeling lost with myself when reading some C codes from Ruby implementation then I decided to stop reading the book and start a little review about C programming language because the last time that I wrote some C code that wasn’t on Arduino was ~3 years ago at my university. When I was at my first university, I clearly remember how some students feel lost and some students feel delighted with the theory and concept of pointers, and for me, it was fascinating.

In this post, I’ll try to explain in a simple and practical way all the theory behind C pointers, for on the next posts I write about topics like Static and Dynamic memory allocation and function pointers.

It’s easy to create programs impossible to read and alter if you don’t give the appropriate attention to the pointers that you’re creating.

This post talks about

  • What are pointers
  • How to use pointers
  • Strings and Arrays
  • Pass by reference and pass by value

The computer memory

To understand pointers correctly, first, we need to understand from a top-level view of how the computer memory works.

The computer memory is like an array, is a block of consecutively memory cells order by their addresses, that memory can be manipulated alone or in groups.

Computer Memory

When you create an integer for example:

int counter = 0;

The C Lang picks 4 consecutive memory cells (bytes) from the memory and stores the value that you assigned to the variable.

Memory with integer allocated

And remember each memory cells that you requested to store your integer have a memory address that can be referenced by hexadecimal.

Address of allocated memory

This address will vary on each execution of the program.

To see this address of a variable in C we can use the ampersand operator:

int counter = 0;

printf("Variable Address: %p\n", &counter);
Variable Address: 0x7ffeccd5f0d4

The %p is the correct specifier to an output the memory address.

Another good experiment to do is to create two variables and see the address of each one:

int counter = 0;
int age = 0;


printf("Variable Address: %p\n", &counter);
printf("Variable Address: %p\n", &age);
Variable Address: 0x7ffe3606fd60
Variable Address: 0x7ffe3606fd64

Pay attention to how C allocates the variable age exactly 4 bytes after the first one, this is because the integer needs 4 bytes to be stored.

The memory address is very interesting and it would be good that we can store it at variables and make nice operations this, and that’s is what pointers consist.

Pointers

Follow my blog to get notified every new post:

Pointers in computer science is an object (usually a variable) that stores the memory address of another value. In C you can declare a pointer using an asterisk before the name of the variable and store an address of a variable of the same type of the pointer.

int counter = 0;

int *pointerCounter = &counter;

Note: Pointers always point to a specific data type, we have one exception on type void.

In C we can see the value stored at the address of pointed memory too, for this, use the asterisk before the name of the pointer:

printf("Pointer value of the pointed memory: %i\n", *pointerCounter);

When a pointer is pointing to a value, the pointer only stores the address of the first byte of this value, when asked, C uses the data type of the pointer to walk over the next `n` bytes to see the full pointed value.

For example, if we’re pointing to an integer and the first byte of this integer is located on 0x7ffe3bc5e164 (see the previus image), the pointer will only store the 0x7ffe3bc5e164 and when asked for the vallue will know to walk +4 right because integer is a datatype of 4 bytes.

To understand better, is nice to examine and run the fallowing example:

int counter = 10;
int *pointerCounter = &counter;

printf("Variable counter address: %p\n", &counter);

printf("Pointer value: %p\n", pointerCounter);

printf("Pointer address: %p\n", &pointerCounter);

printf("Pointer vale of the pointed memory: %i\n", *pointerCounter);
Variable counter address: 0x7ffe19cd26fc
Pointer value: 0x7ffe19cd26fc
Pointer address: 0x7ffe19cd2700
Pointer vale of the pointed memory: 10

It is nice to note that the address of a counter variable is exactly the value pointed by the pointer.

You can do arithmetic and logic operations with pointers too, on this example I sum 10 to the value pointed by pointerCounter.

int counter = 10;
int *pointerCounter = &counter;

*pointerCounter = *pointerCounter + 10;

printf("Pointer vale of the pointed memory: %i\n", *pointerCounter);

printf("Pointer vale of the pointed memory: %i\n", counter);
Pointer vale of the pointed memory: 20
Pointer vale of the pointed memory: 20

“Ok, this is so cool but what can I do with that? I’m only storing the address of some value into one kind of variable.”

With pointers we can do a lot of things, one of the main things is pass values by reference to functions.

Pass by reference and pass by value

When you pass a something to a function in C and make changes to it, that changes won’t exist outside of that function scope, what its means?

void sum(int counter, int age) {
    counter = counter + age;

    printf("counter value: %i\n", counter);
}

int main() {
    int counter = 10;
    int age = 5;

    sum(counter, age);

    printf("response value: %i\n", counter);
}
counter value: 15
response value: 10

On this example, we send the counter variable to the void function sum that stores at counter the sum of counter and age, after this, we print the value of counter inside the function an we see the value 15 printed, but on the printf outside the function at main, we got 10, why? This is what we call pass by value and C passes arguments to function by value, almost all languages pass by value (Java, C#, Ruby, Python), and there isn’t a direct way for the called function to alter a variable in the calling function.

Pass by value

But in C we can do what we call pass by reference, we call the function passing variable address and receiving as a pointer, doing this you’re saying to function “Hey, that’s the value memory address, pick this and alter as you want”.

Pass by reference

void sum(int *counter, int age) {
    *counter = *counter + age;

    printf("counter value: %i\n", *counter);
}

int main() {
    int counter = 10;
    int age = 5;

    sum(&counter, age);

    printf("response value: %i\n", counter);
}

If you run this code you’ll realize that on the last printf the counter is 15, that’s why we’ve passed the counter address to sum function, and at the function, we do the operation directly on the counter address on memory. This is what we call pass by reference, we aren’t passing the value to function but it’s a reference at the memory.

What’s next?

On this post we talked about all the basics behind pointers in C, it’s not a simple topic and if you don’t understand keep trying and run the examples of this post on your own machine, you can also read the sections 5.1 and 5.2 of the legendary K&R C Programming Language that’s, in my opinion, is the best book of ANSI C.

On next three posts I’ll talk more about pointers, I will write about pointers in arrays and strings, dynamic and static memory allocation and function pointers.

Feel free to ask any questions at my twitter, email or comment on this post.

Follow my blog to get notified every new post: