# Wiki Discussion: SWI-Prolog in the browser using WASM

**URL:** <https://swi-prolog.discourse.group/t/wiki-discussion-swi-prolog-in-the-browser-using-wasm/5651>\
**Category:** Wiki Discussion\
**Created:** [August 3, 2022, 8:21pm UTC](https://swi-prolog.discourse.group/t/wiki-discussion-swi-prolog-in-the-browser-using-wasm/5651 "2022-08-03T20:21:56Z")\
**Posts on this page:** 20\
**Page:** 2

<div class="post-metadata">

**Author:** ![jan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jan/32/4_2.png) [@jan](https://swi-prolog.discourse.group/u/jan)\
**Post date:** [August 8, 2022, 8:34pm UTC](https://swi-prolog.discourse.group/t/wiki-discussion-swi-prolog-in-the-browser-using-wasm/5651/37 "2022-08-08T20:34:33Z")

</div>

> [@josderoo](#):
>
> Got the following error while building:

I know. Need to find a clean work around ☹

---

<div class="post-metadata">

**Author:** ![josderoo](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/josderoo/32/3752_2.png) [@josderoo](https://swi-prolog.discourse.group/u/josderoo)\
**Post date:** [August 8, 2022, 8:38pm UTC](https://swi-prolog.discourse.group/t/wiki-discussion-swi-prolog-in-the-browser-using-wasm/5651/38 "2022-08-08T20:38:08Z")

</div>

> [@jan](#):
>
> > [@josderoo](#):
> >
> > although I am not sure why the latter return `undefined` instead of `true`
> 
> The foreign yield has a bug that causes the block of _“well known terms”_, among which the well formed semantics (WFS) _delay list_ to be garbage collected ☹ That is my TODO for this morning … Thanks for reporting.

This is now working fine i.e. returning `true`

---

<div class="post-metadata">

**Author:** ![EricGT](https://avatars.discourse-cdn.com/v4/letter/e/f1d935/32.png) [@EricGT](https://swi-prolog.discourse.group/u/EricGT)\
**Post date:** [August 8, 2022, 8:38pm UTC](https://swi-prolog.discourse.group/t/wiki-discussion-swi-prolog-in-the-browser-using-wasm/5651/39 "2022-08-08T20:38:41Z")

</div>

If you want to keep up with the changes as fast as they are committed and can read Prolog, C, CMake, JSON, HTML and JavaScript then just check the SWI-Prolog development repository commits that start with `WASM`

> **[Commits · SWI-Prolog/swipl-devel](https://github.com/SWI-Prolog/swipl-devel/commits/master)**
>
> SWI-Prolog Main development repository. Contribute to SWI-Prolog/swipl-devel development by creating an account on GitHub.

Note: AFAIK there is no way on GitHub to limit the search for commits by name.

---

<div class="post-metadata">

**Author:** ![josderoo](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/josderoo/32/3752_2.png) [@josderoo](https://swi-prolog.discourse.group/u/josderoo)\
**Post date:** [August 8, 2022, 9:10pm UTC](https://swi-prolog.discourse.group/t/wiki-discussion-swi-prolog-in-the-browser-using-wasm/5651/40 "2022-08-08T21:10:56Z")

</div>

Nice to see that many people love it [https://twitter.com/josderoo/status/1554960976553844743](https://twitter.com/josderoo/status/1554960976553844743) esp. also for semantic web [https://twitter.com/josderoo/status/1555934486545801217](https://twitter.com/josderoo/status/1555934486545801217)

---

<div class="post-metadata">

**Author:** ![jfmc](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jfmc/32/3308_2.png) [@jfmc](https://swi-prolog.discourse.group/u/jfmc)\
**Post date:** [August 9, 2022, 6:56am UTC](https://swi-prolog.discourse.group/t/wiki-discussion-swi-prolog-in-the-browser-using-wasm/5651/42 "2022-08-09T06:56:20Z")

</div>

Excuse me but I need to clarify some things:

- 48 hours do not reflect all the work and people involved in this work
- academic papers are not just code that do what others have done before (if it does not teach anything that people knew before, there is no point in publishing it)
- there exists excellent research papers about implementation details, where multiple decisions were considered and benchmarking evaluates them

Research is complementary to this industrial work. Sometimes 3 years are really necessary to find, write, and review a solution. Usually it is much less (around 6 months).

I sincerely believe that Prolog ignoring research is shooting oneself in the foot. If the language is nice, runs fast, or can do things that others cannot do, it is because someone did really hard research work.

---

<div class="post-metadata">

**Author:** ![jfmc](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jfmc/32/3308_2.png) [@jfmc](https://swi-prolog.discourse.group/u/jfmc)\
**Post date:** [August 9, 2022, 7:17am UTC](https://swi-prolog.discourse.group/t/wiki-discussion-swi-prolog-in-the-browser-using-wasm/5651/43 "2022-08-09T07:17:24Z")

</div>

Thanks @jan. We have the same set of benchmarks then. I’m curious about other aspects of the execution (loading code, indexing, etc.) that may affect uses of Prolog code in real life.

---

<div class="post-metadata">

**Author:** ![herme](https://avatars.discourse-cdn.com/v4/letter/h/74df32/32.png) [@herme](https://swi-prolog.discourse.group/u/herme)\
**Post date:** [August 9, 2022, 7:52am UTC](https://swi-prolog.discourse.group/t/wiki-discussion-swi-prolog-in-the-browser-using-wasm/5651/45 "2022-08-09T07:52:39Z")

</div>

I would not like to get into a discussion of “industrial work” vs “academia”, first because this is not the forum and also because it should be obvious to everyone that they are both necessary and quite complementary, but an important characteristic of academic research is that it is refereed, to ensure correctness, relevance, and originality. All of this is important and takes time, and is how we ‘build on the shoulders of giants’. Without this process we are condemned to reinvent the wheel, as mentioned by @jfmc.

> [@anon95304481](#):
>
> Well the requirements for industry work are much harder:
> 
> **Industry:** Having 10 ideas in 1 program code page.  
> **Academy:** Presenting 1 idea on 10 publish paper pages.
> 
> But this doesn’t dimish the value of academy. Especially when you  
> want to get slow paced careful introductions to some topics, reading  
> a paper might or might not be the choice.

---

<div class="post-metadata">

**Author:** ![jan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jan/32/4_2.png) [@jan](https://swi-prolog.discourse.group/u/jan)\
**Post date:** [August 9, 2022, 7:58am UTC](https://swi-prolog.discourse.group/t/wiki-discussion-swi-prolog-in-the-browser-using-wasm/5651/47 "2022-08-09T07:58:28Z")

</div>

> [@jan](#):
>
> > [@josderoo](#):
> >
> > Got the following error while building:
> 
> I know. Need to find a clean work around ☹

Pushed some cmake magic to fix this. Note that the build dependencies are still incorrect in the sense that just pulling the source and running `ninja` doesn’t always get the _preload directory_ right. The ugly but safe way to rebuild after pulling the source is

```
rm -rf src/wasm-preload && ninja

```

The `src/wasm-preload` directory must be populated with what must appear in the `/swipl` directory of the WASM version (the Prolog home). That needs to be assembled from `home` and generated Prolog files for the various packages and may (unlike `home`) not use symlinks as that will result in symlinks to nowhere in the final WASM .data file ☹ So, we copy some directories using `cmake -E`, but this is not automatically redone if some Prolog library file changes ☹

---

<div class="post-metadata">

**Author:** ![herme](https://avatars.discourse-cdn.com/v4/letter/h/74df32/32.png) [@herme](https://swi-prolog.discourse.group/u/herme)\
**Post date:** [August 9, 2022, 8:15am UTC](https://swi-prolog.discourse.group/t/wiki-discussion-swi-prolog-in-the-browser-using-wasm/5651/48 "2022-08-09T08:15:36Z")

</div>

As for **Lightweight compilation of (C)LP to JavaScript** I think you are being a bit dismissive? Just to give some examples, it talks about several problems and possible solutions, and, it provides some performance figures, which have allowed other people to have an idea about how far you can get with that approach, without having to redo all the work (which is the point of publishing research). And all of that checked by reviewers, with references, etc. I honestly do not understand why you have a problem with it.  
And yes, if to explain something well it takes several papers or a book, there is no problem with that. And note that that paper came with publicly available code in a repo.

I do agree that blogs, stack overflow, etc., are wonderfully useful, but they do not replace academic publications. Looking at some language implementations nowadays this is painfully obvious: many great ideas that are very carefully described in papers are systematically ignored and the mistakes and solutions are repeated over an over again, with the respective authors living in the illusion that they have invented something.  
But, hey, I may just be an oldtimer, totally willing to accept that. 😉

> [@anon95304481](#):
>
> Lightweight compilation of (C)LP to JavaScript

---

<div class="post-metadata">

**Author:** ![jfmc](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jfmc/32/3308_2.png) [@jfmc](https://swi-prolog.discourse.group/u/jfmc)\
**Post date:** [August 9, 2022, 8:34am UTC](https://swi-prolog.discourse.group/t/wiki-discussion-swi-prolog-in-the-browser-using-wasm/5651/50 "2022-08-09T08:34:53Z")

</div>

```prolog
bar :- bar.

```

Seems to hang forever in SWI WASM and it cannot be aborted.

---

<div class="post-metadata">

**Author:** ![jfmc](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jfmc/32/3308_2.png) [@jfmc](https://swi-prolog.discourse.group/u/jfmc)\
**Post date:** [August 9, 2022, 8:50am UTC](https://swi-prolog.discourse.group/t/wiki-discussion-swi-prolog-in-the-browser-using-wasm/5651/51 "2022-08-09T08:50:52Z")

</div>

BTW, we do not need 10 years to produce something useful 😉

---

<div class="post-metadata">

**Author:** ![jfmc](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jfmc/32/3308_2.png) [@jfmc](https://swi-prolog.discourse.group/u/jfmc)\
**Post date:** [August 9, 2022, 9:11am UTC](https://swi-prolog.discourse.group/t/wiki-discussion-swi-prolog-in-the-browser-using-wasm/5651/53 "2022-08-09T09:11:19Z")

</div>

Good to know that the traditional Prolog toxic discussions are also possible in Discourse 🙂

---

<div class="post-metadata">

**Author:** ![herme](https://avatars.discourse-cdn.com/v4/letter/h/74df32/32.png) [@herme](https://swi-prolog.discourse.group/u/herme)\
**Post date:** [August 9, 2022, 9:20am UTC](https://swi-prolog.discourse.group/t/wiki-discussion-swi-prolog-in-the-browser-using-wasm/5651/54 "2022-08-09T09:20:11Z")

</div>

😀 😀 Long live Prolog!  
Thanks @anon95304481 for the nice words on Ciao, btw.

---

<div class="post-metadata">

**Author:** ![jan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jan/32/4_2.png) [@jan](https://swi-prolog.discourse.group/u/jan)\
**Post date:** [August 9, 2022, 10:50am UTC](https://swi-prolog.discourse.group/t/wiki-discussion-swi-prolog-in-the-browser-using-wasm/5651/56 "2022-08-09T10:50:14Z")

</div>

> [@EricGT](#):
>
> Now that we have persistent Prolog files need way to remove or delete the files since they are stored in the browsers cache.
> 
> Tried this for Chorme but **it does not work.**
> 
> Press F12 to open developer tools.  
> Go back to Chrome, right click reload button, select `hard reset and clear cache`

It is not the cache but the browser localStorage. The cache merely avoids re-fetching pages. The localStorage is a way to associate key/value pairs with a given document (web page) that persist. Deleting works (for me) in Chromium as well. Note that it deletes the current file and switches to “program.pl”. You cannot delete “program.pl” itself (but you can blank it).

> [@EricGT](#):
>
> Seems that file names with `_` in them are not valid.

That is now allowed. It only allows for a limited set of characters to avoid nasty injection attacks. Simple but effective 🙂

> [@EricGT](#):
>
> The hello world [example](https://swish.swi-prolog.org/example/io.pl) from [SWISH](https://swish.swi-prolog.org/) behaves badly.
> 
> ```prolog
> hello_world :-
> writeln('Hello World!'),
> sleep(1),
> hello_world.
> 
> ```

That was a bit of a challenge. That it behaves badly was to be expected: it executes a sleep in WASM, so if all is right it nicely writes, but as the browser event loop isn’t triggered nothing appears. This is now handled by redefining sleep/1 in library(wasm) to use js\_yield/2. Then the wrapper around yieldable calls returns an object classified as `builtin` that can be executed and aborted. The execution calls setTimeout() and the abort clearTimeout() followed by resuming using `wasm_abort`.

---

<div class="post-metadata">

**Author:** ![EricGT](https://avatars.discourse-cdn.com/v4/letter/e/f1d935/32.png) [@EricGT](https://swi-prolog.discourse.group/u/EricGT)\
**Post date:** [August 9, 2022, 11:53am UTC](https://swi-prolog.discourse.group/t/wiki-discussion-swi-prolog-in-the-browser-using-wasm/5651/57 "2022-08-09T11:53:06Z")

</div>

> [@jan](#):
>
> It is not the cache but the browser localStorage.

Thanks.

For others using Chrome and wondering how to see _Local Storage_ see

> **[View and edit local storage  |  Chrome DevTools  | ...](https://developer.chrome.com/docs/devtools/storage/localstorage/)**
>
> How to view and edit \`localStorage\` with the Local Storage pane and the Console.

* * *

Of note to other using Chrome on Windows

While I can see the entry for the key and value removed (deleted) in the Chrome developer tools (F12) I can not see the file removed on the [site](https://dev.swi-prolog.org/wasm/shell). At present I am not worried about this nor is it high enough on my list to hunt down the root cause for this.

* * *

* * *

> [@jan](#):
>
> > [@EricGT](#):
> >
> > Seems that file names with `_` in them are not valid.
> 
> That is now allowed.

Thanks.

Saw the [commit](https://github.com/SWI-Prolog/swipl-devel/commit/1b4eafeb8672de97d68d6c88fff2d7853239b8e1) yesterday.

* * *

* * *

> [@jan](#):
>
> > [@EricGT](#):
> >
> > The hello world [example](https://swish.swi-prolog.org/example/io.pl) from [SWISH](https://swish.swi-prolog.org/) behaves badly.
> > 
> > ```prolog
> > hello_world :-
> > writeln('Hello World!'),
> > sleep(1),
> > hello_world.
> > 
> > ```
> 
> That was a bit of a challenge.

Thanks.  
Now works as expected.

![image](https://global.discourse-cdn.com/free1/uploads/swiprolog/original/2X/e/e61af1d0d6e7b8005c07fa32f0d63768dd1189e0.png)

> <https://github.com/SWI-Prolog/swipl-devel/commit/7be5b6088f58197d015260f0ed4b33d65c87e6a6>

* * *

Note that this defines sleep/1 in `user`, overruling system:sleep/1.

That just reaffirms

#### “Learn the rules like a pro, so you can break them like an artist.”

― Pablo Picasso

---

<div class="post-metadata">

**Author:** ![EricGT](https://avatars.discourse-cdn.com/v4/letter/e/f1d935/32.png) [@EricGT](https://swi-prolog.discourse.group/u/EricGT)\
**Post date:** [August 9, 2022, 11:59am UTC](https://swi-prolog.discourse.group/t/wiki-discussion-swi-prolog-in-the-browser-using-wasm/5651/58 "2022-08-09T11:59:36Z")

</div>

@jan

So as not to overload you with a large number of possible issues by doing this all at once I plan during those short pauses in the day to use code I find on SWISH and try them with #wasm\_demo.

Are there items you want me to prioritize and others that I should disregard?

---

<div class="post-metadata">

**Author:** ![rla](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/rla/32/6863_2.png) [@rla](https://swi-prolog.discourse.group/u/rla)\
**Post date:** [August 9, 2022, 12:41pm UTC](https://swi-prolog.discourse.group/t/wiki-discussion-swi-prolog-in-the-browser-using-wasm/5651/59 "2022-08-09T12:41:19Z")

</div>

To me it seems that having a working terminal for wasm version of SWI-Prolog is essentially a solved problem 🙂

The last commits by @jan are especially nice.

Since we use some JSON to communicate with JavaScript now ([WASM: Handle sleep/1 using JavaScript setTimeout() · SWI-Prolog/swipl-devel@7be5b60 · GitHub](https://github.com/SWI-Prolog/swipl-devel/commit/7be5b6088f58197d015260f0ed4b33d65c87e6a6#diff-6a3fa589c59e74b386786fb77654a9e83af48406110c9e9d5e0da238639e2c59R87)) then would it be possible to use full JSON support (from http package) so that we would not have to manually construct JSON strings? Could we extract it from http and put it into the core?

---

<div class="post-metadata">

**Author:** ![jan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jan/32/4_2.png) [@jan](https://swi-prolog.discourse.group/u/jan)\
**Post date:** [August 9, 2022, 2:19pm UTC](https://swi-prolog.discourse.group/t/wiki-discussion-swi-prolog-in-the-browser-using-wasm/5651/60 "2022-08-09T14:19:30Z")

</div>

> [@EricGT](#):
>
> Are there items you want me to prioritize and others that I should disregard?

I’m still not sure how to continue. The current shell.html is a demo and experimentation platform to get the communication working and verify that the WASM version functions normally. Eventually it should be able to verify the core Prolog engine using `ctest` under Node.js.

The open question is how to interact with JavaScript. There are several issues to that

- Calling Prolog from JavaScript. This is ultimately done through the C API but we surely want something more high level.
- Calling JavaScript from Prolog. Now there is js\_call/1 that takes a string that is passed to emscripten\_run\_script(). If the script raises an exception the page is broken ☹ Still wondering how to handle this.
- Yield still has its limitations ☹

> [@rla](#):
>
> To me it seems that having a working terminal for wasm version of [SWI-Prolog](https://www.swi-prolog.org/pldoc/doc_for?object=manual) is essentially a solved problem 🙂

Well, I’m not that far ☹ The progress has been better than I feared. One issue is how to call JavaScript from Prolog, so we can manipulate the DOM. I see:

- emscripten\_run\_script() can call anything, but we get no return value and I’m unsure we can handle exceptions.
- `EM_JS()` allows calling a fixed JavaScript function. Possibly we can make this work by first placing the function (name) and arguments somewhere, use this and fetch the results from some other well known place?
- We could use js\_yield(Request, Response)

First step seems a good bidirectional default translation between Prolog data and JavaScript.

> [@rla](#):
>
> then would it be possible to use full JSON support (from http package) so that we would not have to manually construct JSON strings? Could we extract it from http and put it into the core?

Unfortunately this makes another problem surface: the http package contains too much. json support should never have been there and neither should most of the html support. The whole HTTP infrastructure requires threads. The WASM version clearly wants the HTML, JavaScript and JSON support, but not the HTTP server libraries.

---

<div class="post-metadata">

**Author:** ![EricGT](https://avatars.discourse-cdn.com/v4/letter/e/f1d935/32.png) [@EricGT](https://swi-prolog.discourse.group/u/EricGT)\
**Post date:** [August 9, 2022, 2:39pm UTC](https://swi-prolog.discourse.group/t/wiki-discussion-swi-prolog-in-the-browser-using-wasm/5651/62 "2022-08-09T14:39:21Z")

</div>

> [@jan](#):
>
> Eventually it should be able to verify the core Prolog engine using `ctest` under Node.js.

Thanks.

I will use that as a destination and see what becomes of that journey.

---

<div class="post-metadata">

**Author:** ![rla](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/rla/32/6863_2.png) [@rla](https://swi-prolog.discourse.group/u/rla)\
**Post date:** [August 9, 2022, 3:36pm UTC](https://swi-prolog.discourse.group/t/wiki-discussion-swi-prolog-in-the-browser-using-wasm/5651/63 "2022-08-09T15:36:32Z")

</div>

> [@jan](#):
>
> Eventually it should be able to verify the core Prolog engine using `ctest` under Node.js.

Running tests under Node.js brings decision whether we should build both browser and node.js variants of the WebAssembly version. The main difference is:

- Browser variant uses virtual filesystem and you need to inject files before reading them from Prolog;
- Node.js variant uses Node.js filesystem APIs and reads native (host) files.

I think so far we built both variants.

I would lean a bit to the side where we only have the browser variant because:

- If you can run Node.js then you can probably run SWI in easier ways than through WebAssembly;
- Having only the browser variant would bring less confusion.

Edit: running browser variant in Node.js would just use virtual filesystem.

Of course, the best case would be a configurable option whether you get the virtual filesystem or Node.js API-based IO.

[Previous page](https://swi-prolog.discourse.group/t/wiki-discussion-swi-prolog-in-the-browser-using-wasm/5651.md?page=1)

[Next page](https://swi-prolog.discourse.group/t/wiki-discussion-swi-prolog-in-the-browser-using-wasm/5651.md?page=3)
