# Wasm vs swish and others

**URL:** <https://swi-prolog.discourse.group/t/wasm-vs-swish-and-others/8840>\
**Category:** Tools\
**Created:** [March 1, 2025, 10:53am UTC](https://swi-prolog.discourse.group/t/wasm-vs-swish-and-others/8840 "2025-03-01T10:53:57Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![Rscho314](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/rscho314/32/2881_2.png) [@Rscho314](https://swi-prolog.discourse.group/u/Rscho314)\
**Post date:** [March 1, 2025, 10:53am UTC](https://swi-prolog.discourse.group/t/wasm-vs-swish-and-others/8840/1 "2025-03-01T10:53:57Z")

</div>

Hi,

My project aims at a web app, but it’s my first ever foray into web programming.

My understanding of the options are: http sessions, Pengines, SWISH, WASM.

Is it true that:

- Queries in the WASM case would be user-side computed, because that works by essentially downloading a swipl image on the user’s machine ?
- WASM would mean user data staying on the user’s machine only (=better privacy) ?

Thanks!

---

<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:** [March 1, 2025, 2:34pm UTC](https://swi-prolog.discourse.group/t/wasm-vs-swish-and-others/8840/2 "2025-03-01T14:34:39Z")

</div>

Yes. The WASM version runs entirely in the user’s browser and except for downloading the SWI-Prolog WASM image no server communication happens (except what your app does by itself of course). The WASM version can make networks requests using JavaScript or `fetch/3` from library(wasm).

---

<div class="post-metadata">

**Author:** ![Rscho314](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/rscho314/32/2881_2.png) [@Rscho314](https://swi-prolog.discourse.group/u/Rscho314)\
**Post date:** [March 1, 2025, 4:03pm UTC](https://swi-prolog.discourse.group/t/wasm-vs-swish-and-others/8840/3 "2025-03-01T16:03:57Z")

</div>

Thanks, that’s great! This eliminates the hosting problem for my app.

Another question: is the process for adding a pack (in my case, CLP(BNR)) to a WASM app documented somewhere ? I saw how to load scripts, and that the SWI library is included, but nothing about whole packs.

---

<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:** [March 1, 2025, 4:37pm UTC](https://swi-prolog.discourse.group/t/wasm-vs-swish-and-others/8840/4 "2025-03-01T16:37:43Z")

</div>

All this is a bit in flux. In theory, you can use `:- use_module('https://...')/` to load the main file. This is nice, but especially downloading raw files this way from github tends to be slow. I haven’t tried other sources. Alternatively you can compile the code to a single .qlf file using

```
swipl qlf compile --include mainfile.pl

```

Place the resulting main.qlf on a server and load this using use\_module/1. This however requires the same version of SWI-Prolog and if there is conditional compilation in the code, the conditions of the compiler are used.

I think it is also possible to create a saved state and use that with swipl-bundle-nodata. Not sure how though.

Just a test:

```
?- use_module('https://raw.githubusercontent.com/ridgeworks/clpBNR/refs/heads/master/prolog/clpBNR.pl').

```

Just seems to work in the WASM version 🙂

---

<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:** [March 2, 2025, 11:02am UTC](https://swi-prolog.discourse.group/t/wasm-vs-swish-and-others/8840/6 "2025-03-02T11:02:26Z")

</div>

> [@anon95304481](#):
>
> What makes the matter also more convenient, is to allow  
> URLs in the file search path and have automatically the  
> origin URL in the file search path.

That actually works, but currently you should use your own alias, i.e., not `library`. The main problem is that the normal SWI-Prolog file search may involve quite a few probes at different locations using different extensions. Due to the latency that gets pretty slow over the internet. If the target would allow getting a directory listing we could avoid a lot of probes. This doesn’t seem to work on GitHub raw content:

```prolog
curl https://raw.githubusercontent.com/JanWielemaker/chat80/refs/heads/master/prolog/
400: Invalid request

```

So, currently loading files from a URL works if

- You use an absolute URL (http or https). This can also load `.qlf` files.
- You define an alias using file\_search\_path/2. The target location is computed the normal way and the system guarantees a `.pl` extension.

Ideas are welcome. Integration with notably GIT servers seems welcome. Would also be nice if you can edit locally and upload. That could work for servers that allow for `PUT` or, for GitHub, possibly using [GitHub.js](https://github-tools.github.io/github/)

---

<div class="post-metadata">

**Author:** ![ridgeworks](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/ridgeworks/32/886_2.png) [@ridgeworks](https://swi-prolog.discourse.group/u/ridgeworks)\
**Post date:** [March 3, 2025, 10:47pm UTC](https://swi-prolog.discourse.group/t/wasm-vs-swish-and-others/8840/8 "2025-03-03T22:47:18Z")

</div>

Maybe a new WASM topic, but given that there’s some interest in `clpBNR` on WASM, I thought I should do some minimal testing using [SWI-Tinker](https://wasm.swi-prolog.org/wasm/tinker). As noted above, loading via a URL from GitHub really works and the code appears to be somewhat functional. Unfortunately simple tests expose some current flaws, as noted in the following examples:

1. Result is OK but leaves unnecessary choicepoint? On local version:

```prolog
?- X::real.
X::real(-1.0e+16, 1.0e+16).

```

same on WASM:

```prolog
?- X::real.
X::real(-1.0e+16, 1.0e+16) ;
false. 

```

1. Incorrect answer formatting of narrow intervals (32 bit arithmetic?); local:

```prolog
?- {Y>=0, Y**2==X}, {X==3}.
X = 3,
Y:: 1.732050807568877... .

```

WASM:

```prolog
?- {Y>=0, Y**2==X}, {X==3}.
Y = 1.7320508075688772,
X = 3.

```

1. Incorrect results; local:

```prolog
?- {X==cos(X)}.
X:: 0.73908513321516... .

?- X::real, {17*X **256+35*X** 17-99*X==0}, solve(X).
X:: 0.0000000000000000... ;
X:: 1.005027892894011... .

```

WASM:

```prolog
?- {X==cos(X)}.
false. 

?- X::real, {17*X **256+35*X** 17-99*X==0}, solve(X).
X = 0 ;
false. 

```

At this point I stopped further testing. I suspect 2. has something to do with supporting the answer formatting hooks - there is some platform specific code required for SWISH and it may be a similar issue here. The others may just be bugs or related to 32 bit implementation and associated libraries - all insights welcome. (I don’t currently have the skill set to dig deeper.)

I understand that WASM is still a work in progress, so I’m inclined to just keep trying these simple tests as new releases become available. But I did want to give a heads up to those adventurous souls who may be trying to use `clpBNR` on WASM.

---

<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:** [March 4, 2025, 9:25am UTC](https://swi-prolog.discourse.group/t/wasm-vs-swish-and-others/8840/9 "2025-03-04T09:25:03Z")

</div>

I’m a little surprised. Where SWISH redefines most of the toplevel, SWI-Tinker does not. It only redefines _reading_ the next query to use _yield_, get a string from the browser and parse it. It also redefines waiting for the user response after a qeury completes with a choicepoint. Output is basically unaffected.

Would be nice to add the ‘\*’ command to the toplevel such that we can see the choicepoint.

As for the wrong answers, the WASM version passes the arithmetic tests (many by you) when using node (v22) to run it. I guess that arithmetic may also depend on the WASM engine, i.e., on the browser used.

Note that you can use the usual command line debugger tools such as spy/1, trace/0, etc. to see what is going. Also trace/1 works.

---

<div class="post-metadata">

**Author:** ![ridgeworks](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/ridgeworks/32/886_2.png) [@ridgeworks](https://swi-prolog.discourse.group/u/ridgeworks)\
**Post date:** [March 4, 2025, 3:29pm UTC](https://swi-prolog.discourse.group/t/wasm-vs-swish-and-others/8840/11 "2025-03-04T15:29:39Z")

</div>

> [@jan](#):
>
> I’m a little surprised. Where [SWISH](https://swish.swi-prolog.org/) redefines most of the toplevel, SWI-Tinker does not. It only redefines _reading_ the next query to use _yield_, get a string from the browser and parse it. It also redefines waiting for the user response after a qeury completes with a choicepoint. Output is basically unaffected.

Noting your surprise, I dug a little deeper. FWIW, I see similar behaviour on Chrome and Firefox.

I tried setting spy points and they indeed work, but “creep” seems to skip (as if flag `generate_debug_info` was set to false for the module), so it’s difficult to get to the details, including what’s leaving the choicepoint.

I think both the answer format and incorrect answers can be attributed to bad rounding (at least for now). Using the `?- {Y>=0, Y**2==X}, {X==3}.` example boils down to:

Local version:

```prolog
?- Zl is roundtoward(3**1r2,to_negative), Zh is roundtoward(3**1r2,to_positive).
Zl = 1.732050807568877,
Zh = 1.7320508075688774.

```

WASM:

```prolog
?- Zl is roundtoward(3**1r2,to_negative), Zh is roundtoward(3**1r2,to_positive).
Zl = Zh, Zh = 1.7320508075688772.

```

Without proper outward rounding, the interval narrows to a point which is not a solution. Also the “point” interval will be unified with this value explaining the top level result.

IIRC this rounding control was done through the `fsetround` function in C, but I don’t know which library browsers use.

If you get the same result on node as I see in the browser, there’s obviously a hole in the arithmetic tests that needs to be filled.

---

<div class="post-metadata">

**Author:** ![ridgeworks](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/ridgeworks/32/886_2.png) [@ridgeworks](https://swi-prolog.discourse.group/u/ridgeworks)\
**Post date:** [March 4, 2025, 4:58pm UTC](https://swi-prolog.discourse.group/t/wasm-vs-swish-and-others/8840/12 "2025-03-04T16:58:49Z")

</div>

> [@ridgeworks](#):
>
> If you get the same result on node as I see in the browser, there’s obviously a hole in the arithmetic tests that needs to be filled.

You should at least get warnings from the tests in `tests/rational/test_ieee754.pl`, e.g., in MacOS-Firefox:

```prolog
?- test_roundto(2**0.5).
Warning: [Thread 1] IEEE 754 dubious rounding: 2**0.5: z = 1.4142135623730951, p = 1.4142135623730951
Warning: [Thread 1] IEEE 754 dubious rounding: 2**0.5: n = 1.4142135623730951, p = 1.4142135623730951
true.

```

Oh, just noticed the following in the test module doc:

> **Note** : the Emscripten (WASM) version fails most tests. Rounding modes  
> are not implemented and several operations are very imprecise. For now  
> we disabled this test on WASM.

---

<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:** [March 4, 2025, 5:23pm UTC](https://swi-prolog.discourse.group/t/wasm-vs-swish-and-others/8840/13 "2025-03-04T17:23:47Z")

</div>

> [@ridgeworks](#):
>
> Oh, just noticed the following in the test module doc:
> 
> > **Note** : the Emscripten (WASM) version fails most tests. Rounding modes  
> > are not implemented and several operations are very imprecise. For now  
> > we disabled this test on WASM.

I had totally forgotten about that … Seems clpBNR is no option for the WASM version ☹

---

<div class="post-metadata">

**Author:** ![ridgeworks](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/ridgeworks/32/886_2.png) [@ridgeworks](https://swi-prolog.discourse.group/u/ridgeworks)\
**Post date:** [March 4, 2025, 9:21pm UTC](https://swi-prolog.discourse.group/t/wasm-vs-swish-and-others/8840/14 "2025-03-04T21:21:23Z")

</div>

> [@jan](#):
>
> I had totally forgotten about that … Seems clpBNR is no option for the WASM version ☹

Actually less headaches for me in the short term; we’ll see how things evolve.

I’ll monitor new WASM releases via SWI-Tinker so I can see if anything changes - no expectations.

---

<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:** [March 5, 2025, 8:36am UTC](https://swi-prolog.discourse.group/t/wasm-vs-swish-and-others/8840/15 "2025-03-05T08:36:26Z")

</div>

WASM/SWI-Tinker support probably involves few headaches. Unless people start pushing the WASM implementers, it is unlikely that the rounding issues will be fixed any time soon. The only short term solution I see is to include our own float libraries. Possibly we could lift the LibBF float facilities? That does mean headaches though ☹

---

<div class="post-metadata">

**Author:** ![ridgeworks](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/ridgeworks/32/886_2.png) [@ridgeworks](https://swi-prolog.discourse.group/u/ridgeworks)\
**Post date:** [March 5, 2025, 3:12pm UTC](https://swi-prolog.discourse.group/t/wasm-vs-swish-and-others/8840/16 "2025-03-05T15:12:14Z")

</div>

> [@jan](#):
>
> Unless people start pushing the WASM implementers, it is unlikely that the rounding issues will be fixed any time soon.

It appears that the Emscripten front end compiles C to JavaScript. Standard JS (ECMAScript) has no support for alternative rounding modes. Paraphrasing ECMA-262:

> (This procedure corresponds exactly to the behaviour of the [IEEE 754-2019](https://262.ecma-international.org/15.0/index.html?_gl=1*zdgovo*_ga*MTc3ODU1NDQ1NC4xNzQxMTg2NTQ0*_ga_TDCK4DWEPP*MTc0MTE4NjU0My4xLjAuMTc0MTE4NjU0My4wLjAuMA..#sec-bibliography) roundTiesToEven mode.)

So no, I have no expectation this will be fixed.

> [@jan](#):
>
> The only short term solution I see is to include our own float libraries.

Hard to see what the motivation would be for this; use local or SWISH instead.

---

<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:** [March 5, 2025, 6:32pm UTC](https://swi-prolog.discourse.group/t/wasm-vs-swish-and-others/8840/17 "2025-03-05T18:32:34Z")

</div>

> [@ridgeworks](#):
>
> It appears that the Emscripten front end compiles C to JavaScript. Standard JS (ECMAScript) has no support for alternative rounding modes

That is, AFAIK, not correct. In the early days, Emscripten compiled C to JavaScript. Now it compiles to WASM, which is a low-level VM. At least, that is what I understand. I’m happy to stand corrected. But, I assume that the WASM standard looks at the JavaScript standard for many low-level operations.

---

<div class="post-metadata">

**Author:** ![ridgeworks](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/ridgeworks/32/886_2.png) [@ridgeworks](https://swi-prolog.discourse.group/u/ridgeworks)\
**Post date:** [March 5, 2025, 7:45pm UTC](https://swi-prolog.discourse.group/t/wasm-vs-swish-and-others/8840/18 "2025-03-05T19:45:52Z")

</div>

Yes, I should have read the Emscripten doc more carefully:

> _Emcc_ uses [Clang](https://emscripten.org/docs/site/glossary.html#term-Clang) and LLVM to compile to WebAssembly. Emcc also emits JavaScript that provides API support to the compiled code. That JavaScript can be executed by [Node.js](https://emscripten.org/docs/site/glossary.html#term-node.js), or from within HTML in a browser.

Now there appears be a WASM development fork to implement a form of rounding control ([rounding-mode-control/proposals/rounding-mode-control/Overview.md at 8af7ebe401f432b563c1814e846d188bffa2040f · WebAssembly/rounding-mode-control · GitHub](https://github.com/WebAssembly/rounding-mode-control/blob/8af7ebe401f432b563c1814e846d188bffa2040f/proposals/rounding-mode-control/Overview.md)) but it doesn’t appear to be very compatible with C’s `fenv.h` based model. Rather than using the C model which sets a mode in the floating point environment for the evaluation of an expression (or greater), it provides individual VM instructions for each primitive arithmetic operation. So it’s hard to imagine existing C code that could be compiled to WASM using that model. This would also apply to power and all the elementary functions (not hardware instructions) implemented in software libraries.

So the conclusion is the same - not likely anytime soon.

---

<div class="post-metadata">

**Author:** ![ridgeworks](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/ridgeworks/32/886_2.png) [@ridgeworks](https://swi-prolog.discourse.group/u/ridgeworks)\
**Post date:** [March 6, 2025, 4:47pm UTC](https://swi-prolog.discourse.group/t/wasm-vs-swish-and-others/8840/20 "2025-03-06T16:47:44Z")

</div>

> [@anon95304481](#):
>
> Since JavaScript allows to access float bitpatterns, you can  
> implement certain stuff by yourself.

While you can usually implement some form of rounding mode control in software, I believe there are two significant disadvantages:

1. It is grossly inefficient compared to rounding with machine instructions.
2. If you’re implementing interval arithmetic, the result is two ULP’s wide, whereas ideally it is only 1, as defined in the IEEE754 standard. (Elementary functions in libraries aren’t quite there yet.)

C compilers and libraries provide pretty direct access as defined historically by Intel’s floating point co-processors; other languages and implementations vary.

---

<div class="post-metadata">

**Author:** ![CapelliC](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/capellic/32/17_2.png) [@CapelliC](https://swi-prolog.discourse.group/u/CapelliC)\
**Post date:** [March 18, 2025, 5:30pm UTC](https://swi-prolog.discourse.group/t/wasm-vs-swish-and-others/8840/23 "2025-03-18T17:30:13Z")

</div>

I stumbled on [floating point - Rounding Modes in JavaScript - Stack Overflow](https://stackoverflow.com/q/62976095/874024), so I wonder if the simple solution could be of any help for the topic at hand.  
Here is a test in node

```js
// from https://stackoverflow.com/a/70947557/874024

const MAGIC_ROUND_C = 1.1113332476497816e-16 // just above machine epsilon / 2
const POSITIVE_NORMAL_MIN = 2.2250738585072014e-308
const POSITIVE_DENORMAL_MIN = Number.MIN_VALUE

function roundUp (x) {
  if (x >= -POSITIVE_NORMAL_MIN && x < POSITIVE_NORMAL_MIN) {
    // denormal numbers
    return x + POSITIVE_DENORMAL_MIN
  } else if (x === -Infinity) {
    // special case
    return -Number.MAX_VALUE
  }

  return x + Math.abs(x) * MAGIC_ROUND_C
}

function roundDown (x) {
  if (x > -POSITIVE_NORMAL_MIN && x <= POSITIVE_NORMAL_MIN) {
    return x - POSITIVE_DENORMAL_MIN
  } else if (x === Infinity) {
    return Number.MAX_VALUE
  }

  return x - Math.abs(x) * MAGIC_ROUND_C
}

var Zl = roundDown(3**0.5)
var Zh = roundUp(3**0.5)
console.log({Zl,Zh})

```

the outcome is promising:

```prolog
C:\Program Files\nodejs\node.exe .\float_rounding.js
{Zl: 1.732050807568877, Zh: 1.7320508075688774}

```

---

<div class="post-metadata">

**Author:** ![ridgeworks](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/ridgeworks/32/886_2.png) [@ridgeworks](https://swi-prolog.discourse.group/u/ridgeworks)\
**Post date:** [March 18, 2025, 8:02pm UTC](https://swi-prolog.discourse.group/t/wasm-vs-swish-and-others/8840/24 "2025-03-18T20:02:12Z")

</div>

Implementation of rounding modes is done in the SWIP arithmetic core C code using the floating point environment control defined by `fenv.h`, so the issue is how to emulate that environment in software when it’s not supported on the platform, in this case WASM. Furthermore, rounding mode is global (per thread), so without direct hardware support every floating point function has to (conditionally) apply something like `roundUp/roundDown`, after evaluating with the platform default (assume round to nearest), depending on the current mode. In fact, this is exactly how the elementary functions (sin,cos, exp, log, etc.) are currently implemented in the absence of a C math library that supports correct rounding, so we already have the piece parts. I just don’t think there’s much justification for adding a new platform variant to support the rest of the arithmetic float functions on WASM.

BTW, the example shows that the software implementation doesn’t result in the tightest interval:

```prolog
% round to nearest, enclosing float
?- Z is sqrt(3),bounded_number(Zl,Zh,Z).
Z = 1.7320508075688772,
Zl = 1.732050807568877,
Zh = 1.7320508075688774.

% hardware rounding using SWIP/clpBNR 
?- {Z is sqrt(3)}, domain(Z,DZ).
DZ = real(1.7320508075688772, 1.7320508075688774),
Z:: 1.732050807568877... .

```

That might not seem like a big deal, but the “fuzziness” can accumulate over many operations (one of the big criticisms of functional interval arithmetic).

---

<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:** [March 19, 2025, 8:42am UTC](https://swi-prolog.discourse.group/t/wasm-vs-swish-and-others/8840/25 "2025-03-19T08:42:44Z")

</div>

> [@CapelliC](#):
>
> `function roundUp (x) {`

Note that this works fine in the WASM version:

```prolog
?-A is nexttoward(1, 10).✎✕
A = 1.0000000000000002.

```

That doesn’t help as @ridgeworks says. I think the only way out is to use a C library that implements software floats with correct rounding. That has been on the table with @ridgeworks . I forgot the name of the library. If I recall well though, the portability was non-trivial (which will hurt here) and the library is not maintained AFAIK. The other possibility is to use LibBF, which is already used in the WASM version for big ints and rationals because it is so much smaller than libGMP The library also implements arbitrary precision floats and, if I recall correctly, rounding modes. It implements the usual +, -, \* and / and a couple of functions:

```prolog
int bf_const_log2(bf_t *T, limb_t prec, bf_flags_t flags);
int bf_const_pi(bf_t *T, limb_t prec, bf_flags_t flags);
int bf_exp(bf_t *r, const bf_t *a, limb_t prec, bf_flags_t flags);
int bf_log(bf_t *r, const bf_t *a, limb_t prec, bf_flags_t flags);
#define BF_POW_JS_QUIRKS (1 << 16) /* (+/-1)^(+/-Inf) = NaN, 1^NaN = NaN */
int bf_pow(bf_t *r, const bf_t *x, const bf_t *y, limb_t prec, bf_flags_t flags)
;
int bf_cos(bf_t *r, const bf_t *a, limb_t prec, bf_flags_t flags);
int bf_sin(bf_t *r, const bf_t *a, limb_t prec, bf_flags_t flags);
int bf_tan(bf_t *r, const bf_t *a, limb_t prec, bf_flags_t flags);
int bf_atan(bf_t *r, const bf_t *a, limb_t prec, bf_flags_t flags);
int bf_atan2(bf_t *r, const bf_t *y, const bf_t *x,
             limb_t prec, bf_flags_t flags);
int bf_asin(bf_t *r, const bf_t *a, limb_t prec, bf_flags_t flags);
int bf_acos(bf_t *r, const bf_t *a, limb_t prec, bf_flags_t flags);

```

That could be used to implement double operations for a subset of the SWI-Prolog float functions with rounding. A little macro layer can than be used to select these rather than the C library versions. I.e, just introduce `#define PL_SIN(x) sin(x)`, etc.

I think that route keep the code fairly elegant and is quite feasible.

---

<div class="post-metadata">

**Author:** ![joseph-vidal-rosset](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/joseph-vidal-rosset/32/2594_2.png) [@joseph-vidal-rosset](https://swi-prolog.discourse.group/u/joseph-vidal-rosset)\
**Post date:** [November 11, 2025, 5:30am UTC](https://swi-prolog.discourse.group/t/wasm-vs-swish-and-others/8840/26 "2025-11-11T05:30:35Z")

</div>

Hello. I’ve managed to compile SWI-Prolog with WASM. Unfortunately, despite my efforts, I don’t understand how to achieve an environment similar to [SWI-Tinker](https://wasm.swi-prolog.org/wasm/tinker), either locally or on my dedicated server. The documentation lacks clear explanations for beginners like me: how do I manipulate each file (HTML, JS, PL, etc.) step by step to obtain the same result? I would be grateful if I could consult this documentation and follow the instructions. I hope I’m not the only one encountering this problem.

[Next page](https://swi-prolog.discourse.group/t/wasm-vs-swish-and-others/8840.md?page=2)
