Wiki Discussion: Using WSL on Windows with SWI-Prolog

This is a topic to discuss the Wiki

Using WSL on Windows with SWI-Prolog

The Windows Subsystem for Linux lets developers run a GNU/Linux environment – including most command-line tools, utilities, and applications – directly on Windows, unmodified, without the overhead of a traditional virtual machine or dualboot setup. (ref)

Personal notes

Developing in WSL with Visual Studio Code (ref)

The Visual Studio Code Remote - WSL extension lets you use the Windows Subsystem for Linux (WSL) as your full-time development environment right from VS Code. You can develop in a Linux-based environment, use Linux-specific toolchains and utilities, and run and debug your Linux-based applications all from the comfort of Windows.

So if I understand this correctly then one can think of Windows and WSL 2 working like X Window System. The GUI client is Windows with all of the Windows apps available like Visual Studio Code and the server and files are on an a Linux system running in WSL on Windows.

Since I started using WSL when it was beta and version 1, many things have changed so I have to read and unlearn the old ways to be more effective with the new ways.

Based on this I am considering dropping my use of using SWI-Prolog on Windows for using SWI-Prolog on Linux and running it with Ubuntu on WSL and continuing to use Visual Studio Code to do the editing. Now just need to understand the best way to run SWI-Prolog on the server while having access to gtrace and such.

Introducing the Docker Desktop WSL 2 Backend

As I always use the professional version of Windows or higher (server) I have to be aware of many who run Windows home version, e.g.

In a longer term, it also opens the door to supporting Windows versions where Hyper-V is not available but WSL 2 is (Windows Home edition in particular).

Of related interest:
Visual Studio Code (GitHub)
Windows Terminal (GitHub)

Question posted on Docker Forum: Is there a pictorial diagram of how WSL 2, Docker, Docker-desktop … are related?

The complete diagram of the WSL2 Architecture, as shown at Build 2k19

Containers engines war: Why Docker is not necessarily the best choice? MicroVMs Solutions Part2

Introducing the Docker Desktop WSL 2 Backend

Developing in WSL


WSL Docker diagram

Example of using SWI-Prolog 8.3.4 on Unbuntu 18.04 on WSL 2 and accessing a Prolog source file on Windows 10

Steps to use the SWI-Prolog pack callgraph

  1. Start WSL 2
    Since I have it on the task bar a click on the icon starts it up.

  2. Install graphviz

$ sudo apt-get install graphviz
  1. Locate the Windows directory of the source file to be used as input for callgraph.

  2. Change to the Windows directory

groot@WINDOWS-8B295QT: cd "/mnt/c/users/groot/documents"
  1. Start swipl
groot@WINDOWS-8B295QT:/mnt/c/.../documents$ swipl
  1. Install pack callgraph
?- pack_install(callgraph).
  1. Load callgraph
?- use_module(library(callgraph)).
  1. Load source file using consult/1.
?- [rfc5234_structures].
  1. Use callgraph on source file.
?- module_dotpdf(rfc5234_structures,[]).
  1. Open PDF file in same directory as source file.

Using module_dot/2 the file will be output as a dot file which can be converted to SVG.


Note: To better see or resize the image open it in a new Internet browser tab.

Personal note on uploading SVG files

Discourse does not look for the height and width values beyond the first hundred charters or so.

<svg width="1338pt" height="1268pt"

When graphviz generates an SVG it puts a comment before the height and width which puts the height and width beyond what Discourse will seek. So by simply deleting the comment from the SVG file, which is text, and then saving the file, Discourse will then see the height and width and not complain.

Personal note on printing

Trying to print an SVG from an Internet browser or even just trying to print an SVG file loaded into another application just does not seem to work. Only one page is printed which is a fraction of the entire SVG.

A better way to print the image is to convert the output to a PDF file and then print.
Using Adobe Acrobat is a reasonable way to open the PDF for printing.
To print from Adobe Acrobat, use the menu options to access the print dialog, i.e. File -> Print.
Then in the middle of the dialog click on Poster.
Select Tile Scale and using the keyboard up and down arrows look to the right at the preview to see how the image will be printed. As you scale the number of pages needed to print will change.
Once the scale is set, click Print.

Since these were not cut and paste copies of the actual commands they may have some errors.

Note: The reason WSL 2 was used instead of using Windows 10 is that the pack callgraph uses pack swipe which exclusively uses Linux pipes. Trying callgraph on Windows 10 will only result in errors.

Side note:

Some SWI-Prolog packs rely on MinGW or MSYS and will report an error like

ERROR: Cannot find MinGW and/or MSYS.
ERROR: source_sink `path(make)' does not exist

While the pack will not work directly on Windows, installing the pack as demonstrated in this post is a viable workaround if you can use WSL 2. Remember that many organizations may not allow for the installation of WSL in which case this is not a viable workaround.

Of interest: Visual Studio Code Remote Development Extension Pack

The Remote Development extension pack allows you to open any folder in a container, on a remote machine, or in the Windows Subsystem for Linux (WSL) and take advantage of VS Code’s full feature set.


Example of using absolute files paths allowing the code to be used by either OS without errors.

:- if(current_prolog_flag(windows,true)).
:- working_directory(_,'C:/Users/Groot/Documents').
:- elif(current_prolog_flag(unix,true)).
:- working_directory(_,'/mnt/c/Users/Groot/Documents').
:- endif.


From: Comparing WSL 1 and WSL 2

We recommend against working across operating systems with your files, unless you have a specific reason for doing so. For the fastest performance speed, store your files in the WSL file system if you are working in a Linux command line (Ubuntu, OpenSUSE, etc). If you’re working in a Windows command line (PowerShell, Command Prompt), store your files in the Windows file system.

How to use a USB drive with WSL 2.

  1. Find which drive letters are being used using findmnt
groot@WINDOWS-5B763MT:~$ findmnt
TARGET                          SOURCE       FSTYPE      OPTIONS
/                               /dev/sdb     ext4        rw,relatime,discard,errors=remount-ro,data=ordered
├─/mnt/wsl                      tmpfs        tmpfs       rw,relatime
├─/init                         tools[/init] 9p          ro,relatime,dirsync,aname=tools;fmask=022,loose,access=client,trans=fd,rfd=6,wfd=6
├─/dev                          none         devtmpfs    rw,nosuid,relatime,size=3208872k,nr_inodes=802218,mode=755
│ └─/dev/pts                    devpts       devpts      rw,nosuid,noexec,noatime,gid=5,mode=620,ptmxmode=000
├─/sys                          sysfs        sysfs       rw,nosuid,nodev,noexec,noatime
│ └─/sys/fs/cgroup              tmpfs        tmpfs       rw,nosuid,nodev,noexec,relatime,mode=755
│   ├─/sys/fs/cgroup/unified    cgroup2      cgroup2     rw,nosuid,nodev,noexec,relatime,nsdelegate
│   ├─/sys/fs/cgroup/cpuset     cgroup       cgroup      rw,nosuid,nodev,noexec,relatime,cpuset
│   ├─/sys/fs/cgroup/cpu        cgroup       cgroup      rw,nosuid,nodev,noexec,relatime,cpu
│   ├─/sys/fs/cgroup/cpuacct    cgroup       cgroup      rw,nosuid,nodev,noexec,relatime,cpuacct
│   ├─/sys/fs/cgroup/blkio      cgroup       cgroup      rw,nosuid,nodev,noexec,relatime,blkio
│   ├─/sys/fs/cgroup/memory     cgroup       cgroup      rw,nosuid,nodev,noexec,relatime,memory
│   ├─/sys/fs/cgroup/devices    cgroup       cgroup      rw,nosuid,nodev,noexec,relatime,devices
│   ├─/sys/fs/cgroup/freezer    cgroup       cgroup      rw,nosuid,nodev,noexec,relatime,freezer
│   ├─/sys/fs/cgroup/net_cls    cgroup       cgroup      rw,nosuid,nodev,noexec,relatime,net_cls
│   ├─/sys/fs/cgroup/perf_event cgroup       cgroup      rw,nosuid,nodev,noexec,relatime,perf_event
│   ├─/sys/fs/cgroup/net_prio   cgroup       cgroup      rw,nosuid,nodev,noexec,relatime,net_prio
│   ├─/sys/fs/cgroup/hugetlb    cgroup       cgroup      rw,nosuid,nodev,noexec,relatime,hugetlb
│   ├─/sys/fs/cgroup/pids       cgroup       cgroup      rw,nosuid,nodev,noexec,relatime,pids
│   └─/sys/fs/cgroup/rdma       cgroup       cgroup      rw,nosuid,nodev,noexec,relatime,rdma
├─/proc                         proc         proc        rw,nosuid,nodev,noexec,noatime
│ └─/proc/sys/fs/binfmt_misc    binfmt_misc  binfmt_misc rw,relatime
├─/run                          none         tmpfs       rw,nosuid,noexec,noatime,mode=755
│ ├─/run/lock                   none         tmpfs       rw,nosuid,nodev,noexec,noatime
│ ├─/run/shm                    none         tmpfs       rw,nosuid,nodev,noatime
│ └─/run/user                   none         tmpfs       rw,nosuid,nodev,noexec,noatime,mode=755
└─/mnt/c                        C:\          9p          rw,noatime,dirsync,aname=drvfs;path=C:\;uid=1000;gid=1000;symlinkroot=/mnt/,mmap,access=client,msize=65536,trans=fd,rfd=8,wfd=8

Since C is used and D is not used, will use letter d for drive name.

  1. Make a directory for the USB drive
groot@WINDOWS-5B763MT:~$ sudo mkdir /mnt/d
  1. Mount the USB drive
groot@WINDOWS-5B763MT:~$ sudo mount -t drvfs D: /mnt/d

Now the USB drive is accessible as any other drive, e.g.

groot@WINDOWS-5B763MT:~$ cd /mnt/d

To remove the USB drive

  1. Unmount the drive
groot@WINDOWS-5B763MT:~$ sudo umount /mnt/d

Accessing Linux directories/files on Ubuntu on WSL from SWI-Prolog on Windows.

  1. Get the Linux distribution name
    Using the Windows command line
C:\Users\Groot>wsl -l
Windows Subsystem for Linux Distributions:
Ubuntu-18.04 (Default)
  1. The WSL distribution needs to be running.

  2. Using SWI-Prolog on Windows

?- working_directory(D,'//wsl$/Ubuntu-18.04').
D = '//wsl$/ubuntu-18.04/'.

?- pwd.
% //wsl$/ubuntu-18.04/

?- exists_file('//wsl$/Ubuntu-18.04/usr/bin/make').
Other Examples
?- working_directory(D,D),directory_member(D,Member,[]).
D = '//wsl$/ubuntu-18.04/',
Member = '//wsl$/ubuntu-18.04/home' ;
D = '//wsl$/ubuntu-18.04/',
Member = '//wsl$/ubuntu-18.04/srv' ;
D = '//wsl$/ubuntu-18.04/',
Member = '//wsl$/ubuntu-18.04/etc' ;
D = '//wsl$/ubuntu-18.04/',
Member = '//wsl$/ubuntu-18.04/opt' ;
D = '//wsl$/ubuntu-18.04/',
Member = '//wsl$/ubuntu-18.04/root' ;
D = '//wsl$/ubuntu-18.04/',
Member = '//wsl$/ubuntu-18.04/lib' ;
D = '//wsl$/ubuntu-18.04/',
Member = '//wsl$/ubuntu-18.04/mnt' ;
D = '//wsl$/ubuntu-18.04/',
Member = '//wsl$/ubuntu-18.04/usr' ;
D = '//wsl$/ubuntu-18.04/',
Member = '//wsl$/ubuntu-18.04/media' ;
D = '//wsl$/ubuntu-18.04/',
Member = '//wsl$/ubuntu-18.04/lib64' ;
D = '//wsl$/ubuntu-18.04/',
Member = '//wsl$/ubuntu-18.04/sys' ;
D = '//wsl$/ubuntu-18.04/',
Member = '//wsl$/ubuntu-18.04/dev' ;
D = '//wsl$/ubuntu-18.04/',
Member = '//wsl$/ubuntu-18.04/sbin' ;
D = '//wsl$/ubuntu-18.04/',
Member = '//wsl$/ubuntu-18.04/boot' ;
D = '//wsl$/ubuntu-18.04/',
Member = '//wsl$/ubuntu-18.04/bin' ;
D = '//wsl$/ubuntu-18.04/',
Member = '//wsl$/ubuntu-18.04/run' ;
D = '//wsl$/ubuntu-18.04/',
Member = '//wsl$/ubuntu-18.04/init' ;
D = '//wsl$/ubuntu-18.04/',
Member = '//wsl$/ubuntu-18.04/proc' ;
D = '//wsl$/ubuntu-18.04/',
Member = '//wsl$/ubuntu-18.04/snap' ;
D = '//wsl$/ubuntu-18.04/',
Member = '//wsl$/ubuntu-18.04/tmp' ;
D = '//wsl$/ubuntu-18.04/',
Member = '//wsl$/ubuntu-18.04/var' ;
D = '//wsl$/ubuntu-18.04/',
Member = '//wsl$/ubuntu-18.04/lost+found' ;

You can also map the WSL directory to a Windows Network drive (TODO: explain steps), e.g.

?- working_directory(D,'S:/').
D = '//wsl$/ubuntu-18.04/'.

?- pwd.
% s:/

?- exists_file('S:/usr/bin/make').