r/prolog 4m ago

Finished SQL Injection: 2M data

Thumbnail github.com
Upvotes

CPU AMD FX-8300 (8 Cores), Total RAM 8 GB (Shared with GPU). You can check metrics here:
Mass Data Injection: 2,000,000 rows

The system mailbox queue in 141.08 seconds

speed : 14,176.81 TPS.


r/prolog 3h ago

stress test database injection: 1,500,000 data

2 Upvotes

Processor (CPU) : AMD64 Family 23 Model 17 Stepping 0, AuthenticAMD (8 Threads/Cores)Memory Available : 8 GB RAM

You can check out metrics here:
https://github.com/lokinpendawa/logicbiz


r/prolog 5h ago

After Stress Tesst 1M Transaction

1 Upvotes

r/prolog 8h ago

Just Finished a local concurrency 100 virtual cashiers @ 1000 transactions

Thumbnail gallery
3 Upvotes

I wanted to share these statistics because I am truly amazed by the efficiency of SWI-Prolog. I run a simulation involving 100 virtual cashiers operating concurrently, processing a total of 100,000 transactions.

- Each transaction was broken down into 5 physical SQL queries dispatched via asynchronous background worker threads.

- The system actively applied SQLCipher AES-256-bit encryption and generated SHA-256 signatures for every invoice.

- The test completed successfully with absolutely no deadlocks over the course of a 3.5-hour cycle.

- Even though my amateur code forced the engine to perform over 64 billion logical inferences...

- Active internal memory usage (Global Stack) hovered around 25 MB (with a 32 MB allocation).

- The temporary internal memory footprint even dipped as low as 1,115 KB.


r/prolog 1d ago

I kept working on my small database engine project, and this is where it is now

Thumbnail gallery
10 Upvotes

r/prolog 3d ago

help Need Help about my project to make it production. IDK why everytime my email otp verification is crashing in production.

Post image
0 Upvotes

Hello guys, I just finished a live chat mern app and making to production. I used vercel for frontend hosting and Render for backend and redis for chache, MongoDb is used for db. I got a majour issue in my server side. I have email otp verification for new users. I have used gmail smtp for sending emails because it is a small project so i think it will work but when I tested after succefull deply, nodemailer crashed during authentication. I used ChatGpt to debug the issue but it says to use Brevo. After migrating Brevo, again same issue. Everything worked in localhost but on prod, crashing evrytime. I need help to figure out what the poroblem is actually? Is render crashing the nodemailer or it's the issues from my code.

Here I'm giving the otp sening function

import
 nodemailer 
from
 "nodemailer";


const transporter 
=
 nodemailer.createTransport({
  host: "smtp.gmail.com",
  port: 465,
  secure: true,
  auth: {
    user: process.env.GMAIL_USER,
    pass: process.env.GMAIL_APP_PASSWORD,
  },
});


export
 const verifySMTP 
=
 async () => {
  
try
 {
    
await
 transporter.verify();
    console.log("Gmail SMTP Connected");
  } 
catch
 (err) {
    console.error("SMTP verify failed:", err);
  }
};


export
 const sendMail 
=
 async (email, otp) => {
  
try
 {
    const mailOptions 
=
 {
      from: `"ChatApp" <${process.env.GMAIL_USER}>`,
      to: email,
      subject: "OTP for Confirmation",
      text: `Your One-Time Password (OTP) is:


      ${otp}


      Do not share this OTP with anyone.`,
    };


    const info 
=

await
 transporter.sendMail(mailOptions);


    console.log("Email sent:", info.messageId);
    
return
 true;
  } 
catch
 (error) {
    console.error("Send mail error:", error);
    
return
 false;
  }
};

r/prolog 3d ago

A crazy idea: compiling recursive Prolog predicates into one giant C function

12 Upvotes

I've started experimenting with SCBM2, a new execution model for M-Prolog.

The idea is rather unconventional: compile all recursive nondeterministic predicates into a single large C function, and implement both success and failure continuations by jumping between labels with goto.

To be honest, I wasn't sure this would actually work. It sounded a bit crazy even to me.

This weekend I reached the point where a simple mappend/3 (renamed from append/3 to avoid clashing with the built-in predicate) successfully performs forward recursive computation.

I'm still surprised to see recursion being driven entirely by goto.

Forced backtracking isn't implemented yet, so there's still plenty of work ahead. But the initial experiment suggests that this approach is viable.

I'm sure Edsger Dijkstra would not approve of my enthusiastic use of goto, but for implementing Prolog's backtracking, it may turn out to be a surprisingly practical technique.

M-Prolog SCBM2 Begins. I have started experimenting with a… | by Kenichi Sasagawa | Jul, 2026 | Medium


r/prolog 5d ago

Langception XVII: embedding an ISO-compliant Prolog in Pipefish

Thumbnail
3 Upvotes

r/prolog 8d ago

M-Prolog SCBM: Lessons Learned and the Next Compiler Design

15 Upvotes

I have published a follow-up on the development of M-Prolog, my experimental Prolog compiler that generates C code directly without using the WAM.

The first version of SCBM (Sasagawa & Chat Backtracking Mechanism) successfully handled recursive and nondeterministic predicates, and now executes both Church numeral prime programs and the Queens problem.

However, after extensive testing with the Queens benchmark, I discovered an important limitation.

The current SCBM reconstructs the C call stack by replaying skipped computations during backtracking. While this works correctly, it becomes increasingly inefficient for recursive nondeterministic programs with large search spaces. The first solution is found successfully, but searching for subsequent solutions requires many skipped computations, making the approach impractical.

Rather than continuing to optimize an increasingly complex design, I have decided to start the second stage of the project.

The new idea (SCBM2) completely eliminates dependence on the C runtime stack. Instead of generating C function calls, every predicate will become a label inside one large C function, and execution will proceed using goto together with an explicit SCBM execution stack managed by the compiler itself.

This should greatly simplify backtracking while allowing tail-recursive execution to become simple loops.

The article describes what worked, what did not, and why I decided to redesign the compiler architecture.

Medium article:
The Second Stage of M-Prolog SCBM | by Kenichi Sasagawa | Jul, 2026 | Medium

As always, comments and suggestions from the Prolog community are greatly appreciated.


r/prolog 9d ago

resource I’m building a database engine in Prolog, and reservoir.pl became its strongest line of defense

Thumbnail gallery
4 Upvotes

r/prolog 9d ago

I finally open-sourced AsaDB, my small database engine written in Prolog

Post image
28 Upvotes

r/prolog 10d ago

My Prolog database now plays random sounds depending on whether your SQL succeeds

Post image
8 Upvotes

I originally started this project in VB.NET.

After getting tired of looking at `Console.WriteLine`, I considered rewriting it

in V or Erlang. Their setup annoyed me, so I tried Prolog instead.

That somehow turned into a local SQL database engine.

It is called **AsaDB**.

It currently has:

- a custom SQL lexer and parser

- local `.asa` database files and journals

- tables, indexes, views, users, and permissions

- joins, aggregates, grouping, unions, and subqueries

- transaction snapshots

- a Windows CLI and portable executable

- a browser-based administration panel called AsAPanel

- SQL import and export tools

The import path now sends selected SQL files through the Prolog backend instead

of requiring the browser to hold the complete file in memory.

One current validation dataset contains:

- 5,500 rows

- 62 statements

- 0 errors

My next goal is to make imports of around **100,000 rows** reasonably fast.

I am currently investigating insert batching, list/term reconstruction,

checkpoint and journal overhead, and whether indexes should be updated per row

or rebuilt after a bulk import.

The newest release, v1.2.0, is mainly a UX polish release. It adds random query

sounds with four success and four failure variants.

Successful SQL:

> Asa Terima ❤️

Failed SQL:

> Asa Tidak Suka! 😡

The sound system is deliberately isolated from query execution, so browsers

blocking audio cannot break the database operation.

Repository:

https://github.com/kocoygroup-id/AsaDB

Windows release:

https://github.com/kocoygroup-id/AsaDB/releases/tag/v1.2.0

The public repository currently contains the packaged Windows runtime rather

than the internal engine source.

I would love feedback about efficient large-state representation, bulk inserts,

index construction, and profiling this kind of workload in SWI-Prolog.


r/prolog 17d ago

I want to know if this Claude generated code resemble anything a human Prolog programmer would generate.

4 Upvotes
I am trying to learn Prolog by using Claude to complete a year of Advent of COde, working through various algorithms.  

The problem statements is bewlow along withthe Prolog solution.  Can anyone tell me if the is good code? 


## --- Day 3: Toboggan Trajectory ---


With the toboggan login problems resolved, you set off toward the airport. While travel by toboggan might be easy, it's certainly not safe: there's very minimal steering and the area is covered in trees. You'll need to see which angles will take you near the fewest trees.


Due to the local geology, trees in this area only grow on exact integer coordinates in a grid. You make a map (your puzzle input) of the open squares (`.`) and trees (`#`) you can see. For example:


```text
..##.......
#...#...#..
.#....#..#.
..#.#...#.#
.#...##..#.
..#.##.....
.#.#.#....#
.#........#
#.##...#...
#...##....#
.#..#...#.#


```


These aren't the only trees, though; due to something you read about once involving arboreal genetics and biome stability, the same pattern repeats to the right many times:


```text
*..##.......*..##.........##.........##.........##.........##.......  --->
*#...#...#..*#...#...#..#...#...#..#...#...#..#...#...#..#...#...#..
*.#....#..#.*.#....#..#..#....#..#..#....#..#..#....#..#..#....#..#.
*..#.#...#.#*..#.#...#.#..#.#...#.#..#.#...#.#..#.#...#.#..#.#...#.#
*.#...##..#.*.#...##..#..#...##..#..#...##..#..#...##..#..#...##..#.
*..#.##.....*..#.##.......#.##.......#.##.......#.##.......#.##.....  --->
*.#.#.#....#*.#.#.#....#.#.#.#....#.#.#.#....#.#.#.#....#.#.#.#....#
*.#........#*.#........#.#........#.#........#.#........#.#........#
*#.##...#...*#.##...#...#.##...#...#.##...#...#.##...#...#.##...#...
*#...##....#*#...##....##...##....##...##....##...##....##...##....#
*.#..#...#.#*.#..#...#.#.#..#...#.#.#..#...#.#.#..#...#.#.#..#...#.#  --->


```


You start on the open square (`.`) in the top-left corner and need to reach the bottom (below the bottom-most row on your map).


The toboggan can only follow a few specific slopes (you opted for a cheaper model that prefers rational numbers); start by *counting all the trees* you would encounter for the slope *right 3, down 1*:


From your starting position at the top-left, check the position that is right 3 and down 1. Then, check the position that is right 3 and down 1 from there, and so on until you go past the bottom of the map.


The locations you'd check in the above example are marked here with `*O*` where there was an open square and `*X*` where there was a tree:


```text
..##.........##.........##.........##.........##.........##.......  --->
#..*O*#...#..#...#...#..#...#...#..#...#...#..#...#...#..#...#...#..
.#....*X*..#..#....#..#..#....#..#..#....#..#..#....#..#..#....#..#.
..#.#...#*O*#..#.#...#.#..#.#...#.#..#.#...#.#..#.#...#.#..#.#...#.#
.#...##..#..*X*...##..#..#...##..#..#...##..#..#...##..#..#...##..#.
..#.##.......#.*X*#.......#.##.......#.##.......#.##.......#.##.....  --->
.#.#.#....#.#.#.#.*O*..#.#.#.#....#.#.#.#....#.#.#.#....#.#.#.#....#
.#........#.#........*X*.#........#.#........#.#........#.#........#
#.##...#...#.##...#...#.*X*#...#...#.##...#...#.##...#...#.##...#...
#...##....##...##....##...#*X*....##...##....##...##....##...##....#
.#..#...#.#.#..#...#.#.#..#...*X*.#.#..#...#.#.#..#...#.#.#..#...#.#  --->


```


In this example, traversing the map using this slope would cause you to encounter `*7*` trees.


Starting at the top-left corner of your map and following a slope of right 3 and down 1, *how many trees would you encounter?*


--- Part Two ---
Time to check the rest of the slopes - you need to minimize the probability of a sudden arboreal stop, after all.


Determine the number of trees you would encounter if, for each of the following slopes, you start at the top-left corner and traverse the map all the way to the bottom:


- Right 1, down 1.
- Right 3, down 1. (This is the slope you already checked.)
- Right 5, down 1.
- Right 7, down 1.
- Right 1, down 2.


In the above example, these slopes would find `2`, `7`, `3`, `4`, and `2` tree(s) respectively; multiplied together, these produce the answer `336`.


What do you get if you multiply together the number of trees encountered on each of the listed slopes?

:- module(day03, [parse_input/2, part1/2, part2/2, solve/3,
                  slope_trees/4]).


% Day 3: Toboggan Trajectory.
% The map is a grid of open squares (.) and trees (#) whose pattern
% repeats infinitely to the right. Starting at the top-left and stepping
% Right columns / Down rows at a time, count the trees hit before
% falling off the bottom. Part 1: slope right 3, down 1. Part 2: product
% of the counts over five fixed slopes.


% parse_input(+Raw, -Rows)
% Rows is a list of rows, each a list of char atoms ('.' or '#').
parse_input(Raw, Rows) :-
    split_string(Raw, "\n", " \t\r", Lines0),
    exclude(=(""), Lines0, Lines),
    maplist(string_chars, Lines, Rows).


% slope_trees(+Rows, +Right, +Down, -Count)
% Count is the number of trees on the slope: starting at the top-left,
% visit column I*Right (mod row width — the pattern repeats rightward)
% of every Down-th row, and count the '#' cells.
slope_trees(Rows, Right, Down, Count) :-
    slope_trees_(Rows, Right, Down, 0, 0, Count).


% slope_trees_(+Rows, +Right, +Down, +Col, +Acc, -Count)
% Accumulator walk: check the head row at Col (wrapped), then step to
% the row Down below (drop Down-1 of the remaining rows) at Col+Right.
slope_trees_([], _, _, _, Count, Count).
slope_trees_([Row|Rest], Right, Down, Col, Acc0, Count) :-
    length(Row, Width),
    Index is Col mod Width,
    nth0(Index, Row, Cell),
    (   Cell == '#'
    ->  Acc1 is Acc0 + 1
    ;   Acc1 = Acc0
    ),
    Col1 is Col + Right,
    Skip is Down - 1,
    drop(Skip, Rest, Rest1),
    slope_trees_(Rest1, Right, Down, Col1, Acc1, Count).


% drop(+N, +List, -Rest)
% Rest is List without its first N elements ([] if List is shorter).
drop(0, List, List) :- !.
drop(_, [], []) :- !.
drop(N, [_|Xs], Rest) :-
    N > 0,
    N1 is N - 1,
    drop(N1, Xs, Rest).


% slope_trees_pair(+Rows, +Right-Down, -Count)
% slope_trees/4 with the slope packed as a Right-Down pair, so it can
% be partially applied under maplist/3.
slope_trees_pair(Rows, Right-Down, Count) :-
    slope_trees(Rows, Right, Down, Count).


% part1(+Rows, -Answer)
part1(Rows, Answer) :-
    slope_trees(Rows, 3, 1, Answer).


% part2(+Rows, -Answer)
% Product of the tree counts over the five slopes from the statement.
part2(Rows, Answer) :-
    Slopes = [1-1, 3-1, 5-1, 7-1, 1-2],
    maplist(slope_trees_pair(Rows), Slopes, Counts),
    foldl([X, Acc0, Acc]>>(Acc is Acc0 * X), Counts, 1, Answer).


% solve(+Raw, -Part1, -Part2)
solve(Raw, Part1, Part2) :-
    parse_input(Raw, Rows),
    part1(Rows, Part1),
    part2(Rows, Part2).

r/prolog 17d ago

A different approach to compiling Prolog without WAM (SCBM)

10 Upvotes

I've been experimenting with a different approach to implementing a Prolog compiler.

For more than 40 years, the Warren Abstract Machine (WAM) has been the standard implementation technique for efficient Prolog systems. Rather than trying to improve WAM, I asked a different question:

This led me to an experimental architecture that I call SCBM (Sasagawa & Chat Backtracking Mechanism).

The key idea is to separate continuation information into two independent dimensions:

  • recursive execution
  • conjunction (non-deterministic predicate) execution

Instead of preserving the entire execution state, SCBM reconstructs previously successful execution paths during backtracking. Recursive and non-recursive non-deterministic predicates are handled differently, which keeps the generated C code relatively simple while still supporting recursive backtracking.

The current implementation successfully runs recursive examples such as append/3 and a recursive prime number generator based on Church numerals. Of course, this is still experimental, and there is much more work to do before claiming general applicability.

One interesting aspect of this project is that it was developed through continuous collaboration with ChatGPT. The architecture itself is my own design, but AI proved extremely useful for reviewing generated code, analyzing execution traces, and discussing alternative designs during implementation.

I've written a detailed description of the architecture here:

Medium:
SCBM: A New Backtracking Architecture for Direct C Compilation of Prolog | by Kenichi Sasagawa | Jul, 2026 | Medium

I'd be very interested in hearing feedback from people familiar with Prolog implementation or WAM. In particular, I'd appreciate comments on possible weaknesses, edge cases, or related work that I may have overlooked.


r/prolog 22d ago

Building a Simpler Alternative to the Warren Abstract Machine: After Many Dead Ends, a New Idea Emerged

13 Upvotes

A few days ago, I posted here about my attempt to design a simpler Prolog compiler architecture as an alternative to the classic Warren Abstract Machine (WAM).

Since then, I have been struggling quite a bit while trying to implement the idea. For simple examples, everything worked well. However, when dealing with complex backtracking involving deeply intertwined recursion, I found myself completely stuck. At one point, I even began to wonder whether the entire idea itself was fundamentally flawed.

After spending many long hours discussing the problem with AI, I finally managed to arrive at a much simpler conceptual model.

The core idea is inspired by weaving fabric.

I began to think of recursion as the vertical threads and conjunctions as the horizontal threads. By separating these two dimensions clearly, it now seems possible to handle backtracking without the conceptual confusion that had been causing so many problems.

At last, I feel that the original idea I had envisioned is starting to take shape.

Of course, there is still a major unanswered question: whether this approach can achieve practical execution speed comparable to Warren Abstract Machine remains completely uncertain.

But after many difficult days, the design is finally beginning to look real.

I have written a more detailed explanation in my Medium article. If this sounds interesting to you, I would be very grateful if you took a look and shared any thoughts or feedback. The Hardest Challenge in M-Prolog: Recursive Backtracking and AI as a Research Partner | by Kenichi Sasagawa | Jun, 2026 | Medium


r/prolog 27d ago

How to make Qwen 35B A3B and other small models punch above their weight using Prolog

Thumbnail deepclause.substack.com
8 Upvotes

r/prolog 27d ago

Building a Prolog Compiler Without the Warren Abstract Machine (WAM) — Entering Full-Scale Implementation

37 Upvotes

For some time, I have been developing a new Prolog compiler called M-Prolog, exploring whether it is possible to achieve practical performance with a significantly simpler architecture than the traditional Warren Abstract Machine (WAM).

The motivation behind this project is a simple question:

Does efficient Prolog execution really require all the complexity of WAM?

Over the past several months, I have been conducting a series of experimental implementations to test alternative execution strategies.

The central idea of M-Prolog is to exploit the execution model of the C language itself, rather than constructing a sophisticated abstract machine layer.

In this design, recursive backtracking is not simulated through a virtual machine. Instead, execution state is restored by re-invoking C functions, allowing the native C stack to naturally reconstruct recursive control flow.

This approach worked well for individual nondeterministic predicates, and preliminary benchmarks have been very encouraging.

However, I encountered a difficult problem when handling backtracking across conjunctions involving multiple nondeterministic predicates.

At first, I underestimated the problem. But after many experiments, I gradually reached a deeper understanding of what is actually happening during recursive and conjunctive backtracking.

I believe I have now finally solved the architectural problem, and the design has stabilized.

This means I am now entering the phase of full-scale implementation.

My long-term goal is to demonstrate that practical Prolog compilation may not necessarily require the complexity of WAM, and that a much simpler architecture can still achieve competitive performance.

Perhaps Prolog implementation has been over-engineered for decades.I’m not trying to criticize WAM. I simply want to explore whether modern hardware allows simpler alternatives.

It has been a fascinating journey so far.M-Prolog: A Two-Dimensional Backtracking Architecture | by Kenichi Sasagawa | Jun, 2026 | Medium


r/prolog 28d ago

discussion Is it really true: Many massive airline and railway companies use Prolog’s Constraint Logic Programming (CLP) behind the scenes to solve complex crew rotas and gate scheduling problems that would crash standard databases?

17 Upvotes

??


r/prolog Jun 21 '26

ExDatalog v0.4.0 — Datalog DSL for Elixir

Thumbnail
7 Upvotes

r/prolog Jun 18 '26

announcement read my new Prolog Book online

29 Upvotes

I am not a prolog expert but have enjoyed the language for decades. With the caveat that I am not a Prolog expert, you still may want to read my new book online: https://leanpub.com/read/AI-Prolog

Open Source examples.

Manuscript (included with examples) is Open Content.

For Prolog experts here: any feedback will be appreciated, thanks in advance.


r/prolog Jun 15 '26

M-Prolog development update: I finally defeated the final boss

18 Upvotes

I spent the entire weekend working on a very difficult problem in my new compiler for M-Prolog.

The challenge was implementing backtracking for recursive nondeterministic predicates.

After thinking about it literally all day long, debugging endlessly, and discussing the problem with AI, I finally got it working.

The test case was this simple program:

mappend([],X,X).
mappend([A|X],Y,[A|Z]) :-
    mappend(X,Y,Z).

apptest :-
    mappend(X,Y,[1,2,3]),
    write(X),
    write(Y),
    fail.

And now it correctly produces all solutions:

?- apptest.
[][1,2,3]
[1][2,3]
[1,2][3]
[1,2,3][]
no

Why this was difficult

M-Prolog compiles proof trees directly into C code.

To implement backtracking, execution returns from the predicate once, and then re-enters using goto while restoring the previous execution state.

For ordinary nondeterministic predicates, this already worked.

But recursive predicates kept failing.

The program entered infinite recursion and eventually crashed with a segmentation fault.

I kept thinking:

I inserted debug prints, trace steps, and tried many different ideas.

Nothing worked.

The breakthrough

Then I stopped looking at the code and asked myself:

What is append/3 actually doing during backtracking?

Consider:

mappend(R,S,[1,2,3])

First solution:

R = []
S = [1,2,3]

Backtrack.

Second solution:

R = [1]
S = [2,3]

Backtrack again.

Third solution:

R = [1,2]
S = [3]

And then:

R = [1,2,3]
S = []

Then I realized something fundamental.

The solutions are not independent.

Variable bindings are connected incrementally:

R = [] -> [1] -> [1,2] -> [1,2,3]

That was the missing piece.

I had to preserve not only the execution state, but also the addresses of variables from the previous successful state, so that when execution re-enters through goto, the previous structure can continue growing correctly.

Once I understood this, the implementation became straightforward.

Result

The final boss is defeated.

The implementation became a bit more complicated, and execution speed dropped slightly.

But correctness comes first.

Now that the hardest part is solved, I can go back to squeezing performance again 😄

Building a Prolog compiler is fun.


r/prolog Jun 11 '26

resource pydatalog

14 Upvotes

The author released https://pypi.org/project/pyDatalog/0.22.0/.

Here is their email:

Hi all,

Good news: due to popular interest (300+ stars on GitHub ! Thanks !) and citations of pyDatalog in scientific papers, I have decided to restart maintenance of pyDatalog.

I have fixed the pending issues and created a brand new documentation site.

Feel free to post issues and comments on GitHub !

Pierre Carbonnelle

--
You received this message because you are subscribed to the Google Groups "pyDatalog" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [[email protected]](mailto:[email protected]).
To view this discussion visit https://groups.google.com/d/msgid/pydatalog/73a140fc-e6ec-4862-829b-f7594d61b82fn%40googlegroups.com.


r/prolog Jun 10 '26

Prolog in Production Usecase

17 Upvotes

Hi everyone, just exploring is there any usecase or success story on how to bring Prolog in Production on realtime system? I've some usecase that I've in mind but struggle to find justification that made the tradeoffs not overengineering and nische. I've some playground setup to simplify Production usecase but might be hard to justify since it means introducing new language and not everybody might be welcome about this.

My usecase is complex Pricing logics with clpqr or clpfd.


r/prolog Jun 09 '26

M-Prolog Progress Report: A Small Benchmark Now Edges Past SWI-Prolog

18 Upvotes

I have been continuing work on the M-Prolog compiler.

M-Prolog takes a different approach from traditional WAM-based systems. Instead of interpreting WAM instructions, it generates C code directly from Prolog predicates. Proof trees are translated into C control flow, and backtracking is implemented using stacks and goto-based state transitions.

After a number of recent optimizations, M-Prolog now slightly outperforms SWI-Prolog on a simple nondeterministic benchmark on my Linux Mint / AMD Ryzen system.

Benchmark program:

n(1). n(2). n(3). n(4). n(5).
n(6). n(7). n(8). n(9). n(10).

bench :-
    n(X),
    n(Y),
    n(Z),
    n(A),
    n(B),
    fail.
bench.

Executed as:

between(1,1000,_), bench, fail.

The improvements came mostly from simplifying generated code, reducing unnecessary unify/unbind operations, and generating code that GCC can optimize more effectively.

This is only a small benchmark, so I do not claim that M-Prolog is generally faster than SWI-Prolog. There is still a lot of work to do, especially for cuts, disjunctions, and more realistic programs.

My next goal is to integrate mode inference and generate specialized code for function-like predicates while remaining within standard Prolog syntax.

I first encountered Prolog around 1980, so it is very satisfying to finally see some of these ideas working in practice.

Comments and suggestions are welcome.

M-Prolog Partially Surpasses SWI-Prolog | by Kenichi Sasagawa | Jun, 2026 | Medium


r/prolog Jun 03 '26

Update on M-Prolog: Direct C Generation for Nondeterministic Predicates

16 Upvotes

A few days ago I asked for feedback about M-Prolog's compilation strategy. Thank you to everyone who took the time to comment and share references. The suggestions were very helpful.

I wanted to give a quick update on the project.

The basic idea is to compile Prolog proof trees directly into C code rather than generating WAM instructions. At first I wasn't sure whether this approach would work well for nondeterministic predicates, but after debugging and benchmarking, it now appears to be a viable approach.

Recently I focused on reducing runtime overhead. In particular, I eliminated several dynamically linked runtime calls by combining backtracking-related operations and removing unnecessary state saves. These changes significantly improved performance.

On WSL2 running on an Intel Core i7 system, M-Prolog now exceeds 40 MLIPS on my benchmark. Under the same benchmark conditions, execution time is now within about 12% of SWI-Prolog.

There is still a lot of work to do, and this is only one benchmark, so I do not want to overstate the result. However, I think it provides some evidence that direct C generation can be a practical alternative to the traditional WAM-based approach.

Thanks again for the comments and encouragement. They helped me continue exploring this rather unusual direction. M-Prolog Almost Catches Up with SWI-Prolog | by Kenichi Sasagawa | Jun, 2026 | Medium