Prolog language for PostgreSQL proof of concept
github.com
github.com
I had one experience with Prolog in the 1980s that blew my mind. I had an IR&D project to build a complete prototype of an air/land battle simulator (yes, I was a defense contractor back then) in Common Lisp given 6 weeks of coverage to write it and demo it. After a month I was satisfied with the functionality and after demoing it I asked permission to rewrite it in ExperProlog on the Mac (I had done the Common Lisp version in my Xerox 1108 Lisp Machine). In ten days time it was done, and also had nice graphics and UI extensions that the Common Lisp version did not have. Anyway, except for few small open source things, that was the only large project I ever did in Prolog.
To me, the most natural approach is simply a time-stepped battlespace model. With event uncertainty (e.g., did the bullet hit its target?) modeled as random draws that get baked into the outcome.
One of the downsides of this approach where it appears in games is that it results in unit behaviors that look robotic and overly micromanaged, often using tactics similar to early computer chess AI.
Are you implying it's because a rewrite took less time than the first version?
really readable, nice syntax imo
Click on the SQL tab.
> Among database theoreticians Datalog and SQL are known to be equivalent. And indeed the conversion from Datalog to SQL and back is often straightforward.
I was skeptical, and indeed the sample I linked to shows 8 lines of Datalog turning into 265 lines of SQL. In defense of SQL, I note WITH RECURSIVE wasn't used.
CREATE TABLE edges (
source INT,
target INT
);
INSERT INTO edges (source, target)
SELECT generate_series as source, generate_series + 1 as target
FROM generate_series(0, 999);
WITH RECURSIVE path_lengths AS (
-- Base case: Direct paths from edges
SELECT source, target, 1 AS distance
FROM edges
UNION ALL
-- Recursive step: Double the path length by joining on intermediate nodes
SELECT p.source, e.target, p.distance + 1 AS distance
FROM path_lengths AS p
JOIN edges AS e ON p.target = e.source
WHERE p.distance < 256 -- Control the recursion depth (2^8=256 for C8 equivalent)
)
-- Final query to select paths from source 0, similar to the logic program's final goal
, final_paths AS (
SELECT source, target, MIN(distance) AS distance
FROM path_lengths
WHERE source = 0
GROUP BY source, target
)
SELECT * FROM final_paths
ORDER BY source, target;
You can confirm the output matches by pasting it and clicking run here: https://extendsclass.com/postgresql-online.htmlHope to see this develop even further, as Prolog has its place with relational databases.
I will say, though, that the .NET authors did seem to learn some lessons from Java's worse API decisions and the .NET API is more uniform and reasonable overall.
Boxing is rarely something you have to think about if ever in general purpose code, nor is garbage collection outside of not insisting on doing things less efficient and often more painful way (doing int.Parse(text.Substring(0, 4)) over int.Parse(text.AsSpan(0..4)), something the analyzer prompts you to fix).
If you care about performance as indicated by message content, then any JVM language is a very big downgrade as many patterns are simply not expressible with it the way they are with C#/C++/Rust.
There are also significant differences in tooling as .NET one is much more aligned with what you expect from using Rust/Go/even Node interacting via CLI (dotnet build/run/publish).
Then SQL being a slang of DataLog, which comes from Prolog implies Prolog is ternary, no? Indeed Prolog's handling of "unknown" is more procedural than a true ternary logic.
So it has slightly different notion. Even though I'm more a Prolog amateur (s.o. who loves it), a a failed query in Prolog implies the unknown state. It's about the provability within the system, not about a third truth value.
What you're saying is that Negation as Failure (NAF) introduces a concept of uncertainty, that we can consider a third truth value. Prolog doesn't have classical negation, where negating a logical atom (a "fact") makes it false, unconditionally and with certainty; it only has NAF, where an atom is true only if it cannot be disproved (since we prove by refutation).
Intuitively speaking, that is right. NAF is the simplest way to treat uncertainty, or in any case there is no simpler way: just set aside what you cannot know with certainty, and proceed based on what you can (dis)prove with certainty. There's even a name for that: non-monotonic reasoning, and it's a powerful technique. There's an argument that's it's a good model of how humans reason about uncertainty. I'm agnostic on that front [1].
Formally speaking, thinking of Prolog as a ternary logic because of NAF is not right. NAF is just one way to assign truth values to atoms, but there are still only two truth values to assign, true or false. We might have uncertainty about the assignment, but that's still uncertainty about assignment of one of two values [2].
A bit more precisely, there are only two possible outcomes to a query: either it succeeds (one or more times, nondeterministically), or it fails. If the query succeeds we say that it was "true", for some values of the variables in the query, and if it fails we say it was "false", or there are no values of its variables that make it true.
In other words, Prolog will never return a NULL, like SQL. The uncertainty is baked-in to the success or failure of a query.
But that's a really cool subject and you are on the right track thinking of NAF in terms of uncertainty.
__________________
[1] Answer Set Programming (ASP) is a different logic programming language where the difference between classical negation and NAF is part of the semantics of the language, and for the purpose of non-monotonic reasoning. I don't really know that literature very well so I can't recommend specific texts.
[2] Also keep in mind that uncertainty exists only about the result of a query. Anything we declare as part of a Prolog program, "facts" and "rules", are axiomatically true. Since queries are proved by refutation that means that only falsehood is uncertain. We can know truth with certainty and un-truth with uncertainty.
Link: https://github.com/kaspermarstal/plprql
Previous discussion: https://news.ycombinator.com/item?id=39428609
One could imagine representing queries as compound terms, like: q(user(id=Id, name=like("Bob%"), email=Email))
which would query, from user table and bind Id and Email for all matches. I plan to experiment with something like that.
Because that's not what this is - this is for when you write e.g. `language plpgsql` in defining some function; instead of that (with this installed) you could write `language plprolog` and use prolog.
https://gerrit-review.googlesource.com/Documentation/prolog-...
Prolog was introduced in 2.2.2 (2012), and deprecated in 3.6 (2022)
How cool would be be, if all relations in a Postgres database would be lifted into the scope of a prolog process to work directly on the relations.
What I've usually seen instead is starting from Datalog (declarative, order-independent) instead of Prolog, and converting that into the relevant SQL queries then loading the results into variables within the datalog context. This splits the knowledge base into IDB and EDB parts.
I think he meant lifting the database schema, not the whole database. This would help with auto completion and other static checks before trying to run queries.
parent(alice,bob).
is duplicating information that could already be found in the schema's relationships.(This can already be done using joins, but that is not very ergonomical, especially when a lot of relations are at play)
Unfortunately, searches for “PostgreSQL Tutorial D” don't issue useful results for obvious reasons.
[1]: https://www.dcs.warwick.ac.uk/~hugh/TTM/index.html
[2]: https://www.postgresql.org/docs/current/sql-createtype.html
* https://www.postgresql.org/list/
The catch-all "general" one is probably good enough if nothing else seems like a closer match. :)
I mean, can those prolog stored procedures use the db as a source of facts for prolog, or otherwise write queries?
JSONB, HSTORE, LTREE, Full Text Search, Logical Replication, Range Types, BRIN Indexes, GIN Indexes, GiST Indexes, SP-GiST Indexes, Table Inheritance, Foreign Data Wrappers, XML Support, UUID-OSSP, pg_trgm, Cube, Earthdistance, pg_prolog, pg_partman, pgvector, TimescaleDB, PostGIS, Citus, pg_cron, BDR (Bi-Directional Replication), PL/Python, PL/Java, PL/V8, pg_stat_statements, pg_prewarm, pg_hint_plan, pg_repack, pgAudit, pgRouting, Multicorn (FDW), HypoPG, pg_squeeze, pglogical, Postgres-XL, Wal2json
Postgres essentially made every other RDMS obsolete except for some niche circumstantial cases (e.g. vendor lock-in)
> enterprise level
Postgres is enterprise level (whatever that means). Blazingly fast, Web 3, cloud-native, etc etc, pick your own buzzwords
Usually, it is a great way for many organizations to have a database as free beer.
And for the other 1%, it sometimes happens that their need for a specific feature in Oracle DB turns out to be entirely unnecessary.
Not to mention that the vast majority of products turn out to be fancy CRUD apps. Doesn't matter though, Oracle will convince you that you NEED their DB regardless.
But don’t get me wrong. Postgres is an awesome database system.
They have multiple tiers of support as well, pretty interesting read
Because I suspect it does not mean what I think you think it means.
(Typically the EULA of all those non-Postgres systems are 'this is sold as is, no warranty as to suitability to your purpose, yada yada'
Often times people believe that if they're paying many monies for a support contract, that means they can relocate their liability to that company. Almost every time, that company has better lawyers / contract writers.
Potsgres is the one general purpose DBMS out there that you can hire a company to actually solve your problems.
And on the very uncommon cases that you need really something that Postgres doesn't do, Oracle, MS SQL, DB2, and co do not provide enough of a difference, and what you actually need is an specialized DBMS.
I've got software to write, I don't want to find out that script I copied from stackoverflow to backup the database doesn't work in all the scenarios I thought it would because something changed a minor version ago.
it has issues in several choke points: HA setup is complicated, it doesn't utilize multi-core machines well on heavy queries.
It means "non-technical executives/managers recognize the name and will approve its use". Like Oracle.
Performance monitoring is pretty much absent, all you have is pg_stat_statements and friends. So for any serious scale you need 3d party solution (or you're writing your own) straight away.
HA is complicated. Patroni is the best option now, but it's quite far from experience SQL Server or Oracle provide.
Optimizer is still quite a bit simpler than in SQL server/Oracle. One big thing that is missing for me is "adaptive" query processing (there's AQP extension, but it's not a part of distribution). Even basic adaptive features help a lot when optimizer is doing stupid things (I'm not gonna bring up query hints here :))