Basic modeling help

I’ve spent quite a bit of time reading tutorials and docs recently, but when I finally put fingers to keys to solve something I realized that even though I know how to make Prolog calculate the Fibonacci sequence (with memoization!), I don’t really understand how to model some pretty basic data.

I’d like to build a knowledge base of related software systems and their components following Simon Brown’s C4 Model. After I do that, I have all kinds of fun ideas for automatic graph rendering, CHANGELOG generation, migration assistance, querying git repos, etc.

So I’m looking for the best way to describe the basic facts of the architecture.

Here’s my first try at the example system diagram and I think it’s probably way off base:

person(customer, "Personal Banking Customer", "A customer of the bank, with personal bank accounts").
system(internet_banking, "Internet Banking System", "Allows customers to view information about thier bank accounts, and make payments.").
system(email, "E-mail System", "The internal Microsoft Exchange e-mail system").
system(mainframe_banking, "Mainframe Banking System", "Stores all of the core banking information about customers, accounts, transasctions, etc.").

connection(customer, internet_banking, "Views account balances, and makes payments using").
connection(internet_banking, email, "Sends e-mail using").
connection(email, customer, "Sends e-mail to").
connection(internet_banking, mainframe_banking, "Gets account information from, and makes payment using").

I’m guessing it should look more like:


…but then my question is how should I add the display name and description text? How should I represent a connection between two system level nodes (which also has descriptive text).

The C4 Model also includes hierarchical relationships (Systems > Containers > Components). How should I model those?

Thanks in advance.

Prolog, as far as my understanding goes, doesn’t have built-in modeling capabilities as you seek. However, there exists a number of tools to do modeling including:

  • the semantic web library offering RDFS – if interoperability is important to you.
  • logtalk – a wrapper of prolog with the ability to represent objects
  • terminus – apparently a open source DB based on prolog with a semantic schema description aligned with RDF/OWL standard

As Daniel noted TerminusDB might be worth looking into.

Thanks for the replies. Maybe I don’t mean “modeling” the same way… I’m looking for how to represent basic facts and relations (regardless of whether the data was originally in RDF, JSON, etc.).

To go back to examples we’ve all probably seen, if I have a family tree like this, I can find ancestors. How do I add a display friendly name for each person? How do I add other data like each persons’ height so I can find the tallest ancestor (or whatever other query I might come up with)?

Something like this, where I define a relation for every property?

name(jack, "Jack").
height(jack, 200).

Suppose names and heights come from different data sources (say RDF and CSV). I don’t think I want to have to write any rules or queries referencing rdf or the raw dictionaries directly, right?

(Also, I agree: TerminusDB looks really cool. I was already thinking of including it at some point. But I wanted to make sure I understood the basics first.)

1 Like

This is a really good question. It touches on how to represent the world in logic in general. Prolog also plays a role though as some representations are more efficient than others. Luckily Prolog macro expansion (term_expansion/2) can often be used to translate the representation you would like to see as user to the one Prolog likes best. Relational modelling has of course also been studied in the relational DB world. Unlike Prolog, there are no function symbols and the relational DB world deals poorly with recursion.

I don’t have the answers. I have done this type of modelling quite a few times, but I still consider it more an art than a craft. I’d be interested in good literature.

The one take home message I have is to advice to consider this problem just by looking at the domain and the tasks you want to do in this world. Try to find a representation of the world that “looks natural” and a description of tasks that looks naturally. Once you have that, try to make it work on a small sample. First do that as simple as possible. Slowly you can introduce program transformations to speed it up, possibly deciding the best solution is to generate a C/… program to do parts of the job.


I think there is also the question whether the representation needs a schema or can be schema less.

For example, if you want to ensure that 200 in height(jack, 200) is indeed a valid measure of height, then you somehow need to represent the measurement of height as a concept of its own and link height(jack, 200) as its instance.

When you also work with multiple data sources, schema may also play a role to confirm or transform source fields to target fields – this is where technologies such as RDFS and OWL come in … but, i guess, it can also be done more directly.